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