Home | History | Annotate | Download | only in webm
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/logging.h"
      6 #include "media/base/channel_layout.h"
      7 #include "media/formats/webm/tracks_builder.h"
      8 #include "media/formats/webm/webm_constants.h"
      9 #include "media/formats/webm/webm_tracks_parser.h"
     10 #include "testing/gmock/include/gmock/gmock.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 
     13 using ::testing::InSequence;
     14 using ::testing::Return;
     15 using ::testing::_;
     16 
     17 namespace media {
     18 
     19 static const double kDefaultTimecodeScaleInUs = 1000.0;  // 1 ms resolution
     20 
     21 class WebMTracksParserTest : public testing::Test {
     22  public:
     23   WebMTracksParserTest() {}
     24 };
     25 
     26 static void VerifyTextTrackInfo(const uint8* buffer,
     27                                 int buffer_size,
     28                                 TextKind text_kind,
     29                                 const std::string& name,
     30                                 const std::string& language) {
     31   scoped_ptr<WebMTracksParser> parser(new WebMTracksParser(LogCB(), false));
     32 
     33   int result = parser->Parse(buffer, buffer_size);
     34   EXPECT_GT(result, 0);
     35   EXPECT_EQ(result, buffer_size);
     36 
     37   const WebMTracksParser::TextTracks& text_tracks = parser->text_tracks();
     38   EXPECT_EQ(text_tracks.size(), WebMTracksParser::TextTracks::size_type(1));
     39 
     40   const WebMTracksParser::TextTracks::const_iterator itr = text_tracks.begin();
     41   EXPECT_EQ(itr->first, 1);  // track num
     42 
     43   const TextTrackConfig& config = itr->second;
     44   EXPECT_EQ(config.kind(), text_kind);
     45   EXPECT_TRUE(config.label() == name);
     46   EXPECT_TRUE(config.language() == language);
     47 }
     48 
     49 TEST_F(WebMTracksParserTest, SubtitleNoNameNoLang) {
     50   InSequence s;
     51 
     52   TracksBuilder tb;
     53   tb.AddTextTrack(1, 1, kWebMCodecSubtitles, "", "");
     54 
     55   const std::vector<uint8> buf = tb.Finish();
     56   VerifyTextTrackInfo(&buf[0], buf.size(), kTextSubtitles, "", "");
     57 }
     58 
     59 TEST_F(WebMTracksParserTest, SubtitleYesNameNoLang) {
     60   InSequence s;
     61 
     62   TracksBuilder tb;
     63   tb.AddTextTrack(1, 1, kWebMCodecSubtitles, "Spock", "");
     64 
     65   const std::vector<uint8> buf = tb.Finish();
     66   VerifyTextTrackInfo(&buf[0], buf.size(), kTextSubtitles, "Spock", "");
     67 }
     68 
     69 TEST_F(WebMTracksParserTest, SubtitleNoNameYesLang) {
     70   InSequence s;
     71 
     72   TracksBuilder tb;
     73   tb.AddTextTrack(1, 1, kWebMCodecSubtitles, "", "eng");
     74 
     75   const std::vector<uint8> buf = tb.Finish();
     76   VerifyTextTrackInfo(&buf[0], buf.size(), kTextSubtitles, "", "eng");
     77 }
     78 
     79 TEST_F(WebMTracksParserTest, SubtitleYesNameYesLang) {
     80   InSequence s;
     81 
     82   TracksBuilder tb;
     83   tb.AddTextTrack(1, 1, kWebMCodecSubtitles, "Picard", "fre");
     84 
     85   const std::vector<uint8> buf = tb.Finish();
     86   VerifyTextTrackInfo(&buf[0], buf.size(), kTextSubtitles, "Picard", "fre");
     87 }
     88 
     89 TEST_F(WebMTracksParserTest, IgnoringTextTracks) {
     90   InSequence s;
     91 
     92   TracksBuilder tb;
     93   tb.AddTextTrack(1, 1, kWebMCodecSubtitles, "Subtitles", "fre");
     94   tb.AddTextTrack(2, 2, kWebMCodecSubtitles, "Commentary", "fre");
     95 
     96   const std::vector<uint8> buf = tb.Finish();
     97   scoped_ptr<WebMTracksParser> parser(new WebMTracksParser(LogCB(), true));
     98 
     99   int result = parser->Parse(&buf[0], buf.size());
    100   EXPECT_GT(result, 0);
    101   EXPECT_EQ(result, static_cast<int>(buf.size()));
    102 
    103   EXPECT_EQ(parser->text_tracks().size(), 0u);
    104 
    105   const std::set<int64>& ignored_tracks = parser->ignored_tracks();
    106   EXPECT_TRUE(ignored_tracks.find(1) != ignored_tracks.end());
    107   EXPECT_TRUE(ignored_tracks.find(2) != ignored_tracks.end());
    108 
    109   // Test again w/o ignoring the test tracks.
    110   parser.reset(new WebMTracksParser(LogCB(), false));
    111 
    112   result = parser->Parse(&buf[0], buf.size());
    113   EXPECT_GT(result, 0);
    114 
    115   EXPECT_EQ(parser->ignored_tracks().size(), 0u);
    116   EXPECT_EQ(parser->text_tracks().size(), 2u);
    117 }
    118 
    119 TEST_F(WebMTracksParserTest, AudioVideoDefaultDurationUnset) {
    120   // Other audio/video decoder config fields are necessary in the test
    121   // audio/video TrackEntry configurations. This method does only very minimal
    122   // verification of their inclusion and parsing; the goal is to confirm
    123   // TrackEntry DefaultDuration defaults to -1 if not included in audio or
    124   // video TrackEntry.
    125   TracksBuilder tb;
    126   tb.AddAudioTrack(1, 1, "A_VORBIS", "audio", "", -1, 2, 8000);
    127   tb.AddVideoTrack(2, 2, "V_VP8", "video", "", -1, 320, 240);
    128   const std::vector<uint8> buf = tb.Finish();
    129 
    130   scoped_ptr<WebMTracksParser> parser(new WebMTracksParser(LogCB(), true));
    131   int result = parser->Parse(&buf[0], buf.size());
    132   EXPECT_LE(0, result);
    133   EXPECT_EQ(static_cast<int>(buf.size()), result);
    134 
    135   EXPECT_EQ(kNoTimestamp(),
    136             parser->GetAudioDefaultDuration(kDefaultTimecodeScaleInUs));
    137   EXPECT_EQ(kNoTimestamp(),
    138             parser->GetVideoDefaultDuration(kDefaultTimecodeScaleInUs));
    139 
    140   const VideoDecoderConfig& video_config = parser->video_decoder_config();
    141   EXPECT_TRUE(video_config.IsValidConfig());
    142   EXPECT_EQ(320, video_config.coded_size().width());
    143   EXPECT_EQ(240, video_config.coded_size().height());
    144 
    145   const AudioDecoderConfig& audio_config = parser->audio_decoder_config();
    146   EXPECT_TRUE(audio_config.IsValidConfig());
    147   EXPECT_EQ(CHANNEL_LAYOUT_STEREO, audio_config.channel_layout());
    148   EXPECT_EQ(8000, audio_config.samples_per_second());
    149 }
    150 
    151 TEST_F(WebMTracksParserTest, AudioVideoDefaultDurationSet) {
    152   // Confirm audio or video TrackEntry DefaultDuration values are parsed, if
    153   // present.
    154   TracksBuilder tb;
    155   tb.AddAudioTrack(1, 1, "A_VORBIS", "audio", "", 12345678, 2, 8000);
    156   tb.AddVideoTrack(2, 2, "V_VP8", "video", "", 987654321, 320, 240);
    157   const std::vector<uint8> buf = tb.Finish();
    158 
    159   scoped_ptr<WebMTracksParser> parser(new WebMTracksParser(LogCB(), true));
    160   int result = parser->Parse(&buf[0], buf.size());
    161   EXPECT_LE(0, result);
    162   EXPECT_EQ(static_cast<int>(buf.size()), result);
    163 
    164   EXPECT_EQ(base::TimeDelta::FromMicroseconds(12000),
    165             parser->GetAudioDefaultDuration(kDefaultTimecodeScaleInUs));
    166   EXPECT_EQ(base::TimeDelta::FromMicroseconds(985000),
    167             parser->GetVideoDefaultDuration(5000.0));  // 5 ms resolution
    168   EXPECT_EQ(kNoTimestamp(), parser->GetAudioDefaultDuration(12346.0));
    169   EXPECT_EQ(base::TimeDelta::FromMicroseconds(12345),
    170             parser->GetAudioDefaultDuration(12345.0));
    171   EXPECT_EQ(base::TimeDelta::FromMicroseconds(12003),
    172             parser->GetAudioDefaultDuration(1000.3));  // 1.0003 ms resolution
    173 }
    174 
    175 TEST_F(WebMTracksParserTest, InvalidZeroDefaultDurationSet) {
    176   // Confirm parse error if TrackEntry DefaultDuration is present, but is 0ns.
    177   TracksBuilder tb(true);
    178   tb.AddAudioTrack(1, 1, "A_VORBIS", "audio", "", 0, 2, 8000);
    179   const std::vector<uint8> buf = tb.Finish();
    180 
    181   scoped_ptr<WebMTracksParser> parser(new WebMTracksParser(LogCB(), true));
    182   EXPECT_EQ(-1, parser->Parse(&buf[0], buf.size()));
    183 }
    184 
    185 TEST_F(WebMTracksParserTest, HighTrackUID) {
    186   // Confirm no parse error if TrackEntry TrackUID has MSb set
    187   // (http://crbug.com/397067).
    188   TracksBuilder tb(true);
    189   tb.AddAudioTrack(1, 1ULL << 31, "A_VORBIS", "audio", "", 40, 2, 8000);
    190   const std::vector<uint8> buf = tb.Finish();
    191 
    192   scoped_ptr<WebMTracksParser> parser(new WebMTracksParser(LogCB(), true));
    193   EXPECT_GT(parser->Parse(&buf[0], buf.size()),0);
    194 }
    195 
    196 }  // namespace media
    197