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