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 <algorithm> | 5 #include <algorithm> |
6 #include <string> | 6 #include <string> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
12 #include "base/time/time.h" | 12 #include "base/time/time.h" |
13 #include "media/base/audio_decoder_config.h" | 13 #include "media/base/audio_decoder_config.h" |
14 #include "media/base/decoder_buffer.h" | 14 #include "media/base/decoder_buffer.h" |
15 #include "media/base/mock_media_log.h" | |
15 #include "media/base/stream_parser_buffer.h" | 16 #include "media/base/stream_parser_buffer.h" |
16 #include "media/base/test_data_util.h" | 17 #include "media/base/test_data_util.h" |
17 #include "media/base/text_track_config.h" | 18 #include "media/base/text_track_config.h" |
18 #include "media/base/video_decoder_config.h" | 19 #include "media/base/video_decoder_config.h" |
19 #include "media/formats/mp4/es_descriptor.h" | 20 #include "media/formats/mp4/es_descriptor.h" |
20 #include "media/formats/mp4/mp4_stream_parser.h" | 21 #include "media/formats/mp4/mp4_stream_parser.h" |
22 #include "testing/gmock/include/gmock/gmock.h" | |
21 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
22 | 24 |
25 using ::testing::InSequence; | |
26 using ::testing::StrictMock; | |
23 using base::TimeDelta; | 27 using base::TimeDelta; |
24 | 28 |
25 namespace media { | 29 namespace media { |
26 namespace mp4 { | 30 namespace mp4 { |
27 | 31 |
32 // Matchers for verifying common media log entry strings. | |
33 #define CONTAINS_STRING(arg, x) (std::string::npos != (arg).find(x)) | |
34 | |
35 MATCHER_P(VideoCodecLog, codec_string, "") { | |
36 return CONTAINS_STRING(arg, "Video codec: " + std::string(codec_string)); | |
37 } | |
38 | |
39 MATCHER_P(AudioCodecLog, codec_string, "") { | |
40 return CONTAINS_STRING(arg, "Audio codec: " + std::string(codec_string)); | |
41 } | |
42 | |
43 MATCHER(AuxInfoUnavailableLog, "") { | |
44 return CONTAINS_STRING(arg, "Aux Info is not available."); | |
45 } | |
46 | |
28 class MP4StreamParserTest : public testing::Test { | 47 class MP4StreamParserTest : public testing::Test { |
29 public: | 48 public: |
30 MP4StreamParserTest() | 49 MP4StreamParserTest() |
31 : configs_received_(false), | 50 : media_log_(new StrictMock<MockMediaLog>()), |
51 configs_received_(false), | |
32 lower_bound_( | 52 lower_bound_( |
33 DecodeTimestamp::FromPresentationTime(base::TimeDelta::Max())) { | 53 DecodeTimestamp::FromPresentationTime(base::TimeDelta::Max())) { |
34 std::set<int> audio_object_types; | 54 std::set<int> audio_object_types; |
35 audio_object_types.insert(kISO_14496_3); | 55 audio_object_types.insert(kISO_14496_3); |
36 parser_.reset(new MP4StreamParser(audio_object_types, false)); | 56 parser_.reset(new MP4StreamParser(audio_object_types, false)); |
37 } | 57 } |
38 | 58 |
39 protected: | 59 protected: |
60 scoped_refptr<StrictMock<MockMediaLog>> media_log_; | |
40 scoped_ptr<MP4StreamParser> parser_; | 61 scoped_ptr<MP4StreamParser> parser_; |
41 bool configs_received_; | 62 bool configs_received_; |
42 AudioDecoderConfig audio_decoder_config_; | 63 AudioDecoderConfig audio_decoder_config_; |
43 VideoDecoderConfig video_decoder_config_; | 64 VideoDecoderConfig video_decoder_config_; |
44 DecodeTimestamp lower_bound_; | 65 DecodeTimestamp lower_bound_; |
45 | 66 |
46 bool AppendData(const uint8* data, size_t length) { | 67 bool AppendData(const uint8* data, size_t length) { |
47 return parser_->Parse(data, length); | 68 return parser_->Parse(data, length); |
48 } | 69 } |
49 | 70 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
142 DemuxerStream::Liveness expected_liveness) { | 163 DemuxerStream::Liveness expected_liveness) { |
143 parser_->Init( | 164 parser_->Init( |
144 base::Bind(&MP4StreamParserTest::InitF, base::Unretained(this), | 165 base::Bind(&MP4StreamParserTest::InitF, base::Unretained(this), |
145 expected_liveness), | 166 expected_liveness), |
146 base::Bind(&MP4StreamParserTest::NewConfigF, base::Unretained(this)), | 167 base::Bind(&MP4StreamParserTest::NewConfigF, base::Unretained(this)), |
147 base::Bind(&MP4StreamParserTest::NewBuffersF, base::Unretained(this)), | 168 base::Bind(&MP4StreamParserTest::NewBuffersF, base::Unretained(this)), |
148 true, | 169 true, |
149 base::Bind(&MP4StreamParserTest::KeyNeededF, base::Unretained(this)), | 170 base::Bind(&MP4StreamParserTest::KeyNeededF, base::Unretained(this)), |
150 base::Bind(&MP4StreamParserTest::NewSegmentF, base::Unretained(this)), | 171 base::Bind(&MP4StreamParserTest::NewSegmentF, base::Unretained(this)), |
151 base::Bind(&MP4StreamParserTest::EndOfSegmentF, base::Unretained(this)), | 172 base::Bind(&MP4StreamParserTest::EndOfSegmentF, base::Unretained(this)), |
152 new MediaLog()); | 173 media_log_); |
153 } | 174 } |
154 | 175 |
155 void InitializeParser() { | 176 void InitializeParser() { |
156 // Most unencrypted test mp4 files have zero duration and are treated as | 177 // Most unencrypted test mp4 files have zero duration and are treated as |
157 // live streams. | 178 // live streams. |
158 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_LIVE); | 179 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_LIVE); |
159 } | 180 } |
160 | 181 |
161 bool ParseMP4File(const std::string& filename, int append_bytes) { | 182 bool ParseMP4File(const std::string& filename, int append_bytes) { |
162 InitializeParser(); | 183 InitializeParser(); |
163 | 184 |
164 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); | 185 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); |
165 EXPECT_TRUE(AppendDataInPieces(buffer->data(), | 186 EXPECT_TRUE(AppendDataInPieces(buffer->data(), |
166 buffer->data_size(), | 187 buffer->data_size(), |
167 append_bytes)); | 188 append_bytes)); |
168 return true; | 189 return true; |
169 } | 190 } |
170 }; | 191 }; |
171 | 192 |
172 TEST_F(MP4StreamParserTest, UnalignedAppend) { | 193 TEST_F(MP4StreamParserTest, UnalignedAppend) { |
173 // Test small, non-segment-aligned appends (small enough to exercise | 194 // Test small, non-segment-aligned appends (small enough to exercise |
174 // incremental append system) | 195 // incremental append system) |
196 EXPECT_MEDIA_LOG_STRING(VideoCodecLog("avc1.6401f")); | |
197 EXPECT_MEDIA_LOG_STRING(AudioCodecLog("mp4a.40.2")); | |
175 ParseMP4File("bear-1280x720-av_frag.mp4", 512); | 198 ParseMP4File("bear-1280x720-av_frag.mp4", 512); |
176 } | 199 } |
177 | 200 |
178 TEST_F(MP4StreamParserTest, BytewiseAppend) { | 201 TEST_F(MP4StreamParserTest, BytewiseAppend) { |
179 // Ensure no incremental errors occur when parsing | 202 // Ensure no incremental errors occur when parsing |
203 EXPECT_MEDIA_LOG_STRING(VideoCodecLog("avc1.6401f")); | |
204 EXPECT_MEDIA_LOG_STRING(AudioCodecLog("mp4a.40.2")); | |
180 ParseMP4File("bear-1280x720-av_frag.mp4", 1); | 205 ParseMP4File("bear-1280x720-av_frag.mp4", 1); |
181 } | 206 } |
182 | 207 |
183 TEST_F(MP4StreamParserTest, MultiFragmentAppend) { | 208 TEST_F(MP4StreamParserTest, MultiFragmentAppend) { |
184 // Large size ensures multiple fragments are appended in one call (size is | 209 // Large size ensures multiple fragments are appended in one call (size is |
185 // larger than this particular test file) | 210 // larger than this particular test file) |
211 EXPECT_MEDIA_LOG_STRING(VideoCodecLog("avc1.6401f")); | |
212 EXPECT_MEDIA_LOG_STRING(AudioCodecLog("mp4a.40.2")); | |
186 ParseMP4File("bear-1280x720-av_frag.mp4", 768432); | 213 ParseMP4File("bear-1280x720-av_frag.mp4", 768432); |
187 } | 214 } |
188 | 215 |
189 TEST_F(MP4StreamParserTest, Flush) { | 216 TEST_F(MP4StreamParserTest, Flush) { |
190 // Flush while reading sample data, then start a new stream. | 217 // Flush while reading sample data, then start a new stream. |
218 EXPECT_MEDIA_LOG_STRING(VideoCodecLog("avc1.6401f")).Times(2); | |
219 EXPECT_MEDIA_LOG_STRING(AudioCodecLog("mp4a.40.2")).Times(2); | |
191 InitializeParser(); | 220 InitializeParser(); |
192 | 221 |
193 scoped_refptr<DecoderBuffer> buffer = | 222 scoped_refptr<DecoderBuffer> buffer = |
194 ReadTestDataFile("bear-1280x720-av_frag.mp4"); | 223 ReadTestDataFile("bear-1280x720-av_frag.mp4"); |
195 EXPECT_TRUE(AppendDataInPieces(buffer->data(), 65536, 512)); | 224 EXPECT_TRUE(AppendDataInPieces(buffer->data(), 65536, 512)); |
196 parser_->Flush(); | 225 parser_->Flush(); |
197 EXPECT_TRUE(AppendDataInPieces(buffer->data(), | 226 EXPECT_TRUE(AppendDataInPieces(buffer->data(), |
198 buffer->data_size(), | 227 buffer->data_size(), |
199 512)); | 228 512)); |
200 } | 229 } |
201 | 230 |
202 TEST_F(MP4StreamParserTest, Reinitialization) { | 231 TEST_F(MP4StreamParserTest, Reinitialization) { |
232 EXPECT_MEDIA_LOG_STRING(VideoCodecLog("avc1.6401f")).Times(2); | |
233 EXPECT_MEDIA_LOG_STRING(AudioCodecLog("mp4a.40.2")).Times(2); | |
203 InitializeParser(); | 234 InitializeParser(); |
204 | 235 |
205 scoped_refptr<DecoderBuffer> buffer = | 236 scoped_refptr<DecoderBuffer> buffer = |
206 ReadTestDataFile("bear-1280x720-av_frag.mp4"); | 237 ReadTestDataFile("bear-1280x720-av_frag.mp4"); |
207 EXPECT_TRUE(AppendDataInPieces(buffer->data(), | 238 EXPECT_TRUE(AppendDataInPieces(buffer->data(), |
208 buffer->data_size(), | 239 buffer->data_size(), |
209 512)); | 240 512)); |
210 EXPECT_TRUE(AppendDataInPieces(buffer->data(), | 241 EXPECT_TRUE(AppendDataInPieces(buffer->data(), |
211 buffer->data_size(), | 242 buffer->data_size(), |
212 512)); | 243 512)); |
213 } | 244 } |
214 | 245 |
215 TEST_F(MP4StreamParserTest, MPEG2_AAC_LC) { | 246 TEST_F(MP4StreamParserTest, MPEG2_AAC_LC) { |
247 InSequence s; | |
chcunningham
2015/08/19 19:36:18
Do you need this? Ditto for line 279.
chcunningham
2015/08/19 20:06:43
ignore... I read up on InSequence. Kinda whacky, b
wolenetz
2015/08/24 20:13:52
Acknowledged.
| |
216 std::set<int> audio_object_types; | 248 std::set<int> audio_object_types; |
217 audio_object_types.insert(kISO_13818_7_AAC_LC); | 249 audio_object_types.insert(kISO_13818_7_AAC_LC); |
218 parser_.reset(new MP4StreamParser(audio_object_types, false)); | 250 parser_.reset(new MP4StreamParser(audio_object_types, false)); |
251 EXPECT_MEDIA_LOG_STRING(AudioCodecLog("mp4a.67")); | |
252 EXPECT_MEDIA_LOG_STRING(AudioCodecLog("mp4a.40.2")); | |
219 ParseMP4File("bear-mpeg2-aac-only_frag.mp4", 512); | 253 ParseMP4File("bear-mpeg2-aac-only_frag.mp4", 512); |
220 } | 254 } |
221 | 255 |
222 // Test that a moov box is not always required after Flush() is called. | 256 // Test that a moov box is not always required after Flush() is called. |
223 TEST_F(MP4StreamParserTest, NoMoovAfterFlush) { | 257 TEST_F(MP4StreamParserTest, NoMoovAfterFlush) { |
258 EXPECT_MEDIA_LOG_STRING(VideoCodecLog("avc1.6401f")); | |
259 EXPECT_MEDIA_LOG_STRING(AudioCodecLog("mp4a.40.2")); | |
224 InitializeParser(); | 260 InitializeParser(); |
225 | 261 |
226 scoped_refptr<DecoderBuffer> buffer = | 262 scoped_refptr<DecoderBuffer> buffer = |
227 ReadTestDataFile("bear-1280x720-av_frag.mp4"); | 263 ReadTestDataFile("bear-1280x720-av_frag.mp4"); |
228 EXPECT_TRUE(AppendDataInPieces(buffer->data(), | 264 EXPECT_TRUE(AppendDataInPieces(buffer->data(), |
229 buffer->data_size(), | 265 buffer->data_size(), |
230 512)); | 266 512)); |
231 parser_->Flush(); | 267 parser_->Flush(); |
232 | 268 |
233 const int kFirstMoofOffset = 1307; | 269 const int kFirstMoofOffset = 1307; |
234 EXPECT_TRUE(AppendDataInPieces(buffer->data() + kFirstMoofOffset, | 270 EXPECT_TRUE(AppendDataInPieces(buffer->data() + kFirstMoofOffset, |
235 buffer->data_size() - kFirstMoofOffset, | 271 buffer->data_size() - kFirstMoofOffset, |
236 512)); | 272 512)); |
237 } | 273 } |
238 | 274 |
239 // Test an invalid file where there are encrypted samples, but | 275 // Test an invalid file where there are encrypted samples, but |
240 // SampleAuxiliaryInformation{Sizes|Offsets}Box (saiz|saio) are missing. | 276 // SampleAuxiliaryInformation{Sizes|Offsets}Box (saiz|saio) are missing. |
241 // The parser should fail instead of crash. See http://crbug.com/361347 | 277 // The parser should fail instead of crash. See http://crbug.com/361347 |
242 TEST_F(MP4StreamParserTest, MissingSampleAuxInfo) { | 278 TEST_F(MP4StreamParserTest, MissingSampleAuxInfo) { |
279 InSequence s; | |
280 | |
243 // Encrypted test mp4 files have non-zero duration and are treated as | 281 // Encrypted test mp4 files have non-zero duration and are treated as |
244 // recorded streams. | 282 // recorded streams. |
245 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); | 283 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); |
246 | 284 |
247 scoped_refptr<DecoderBuffer> buffer = | 285 scoped_refptr<DecoderBuffer> buffer = |
248 ReadTestDataFile("bear-1280x720-a_frag-cenc_missing-saiz-saio.mp4"); | 286 ReadTestDataFile("bear-1280x720-a_frag-cenc_missing-saiz-saio.mp4"); |
287 EXPECT_MEDIA_LOG_STRING(AudioCodecLog("mp4a.40.2")).Times(2); | |
288 EXPECT_MEDIA_LOG_STRING(AuxInfoUnavailableLog()); | |
249 EXPECT_FALSE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); | 289 EXPECT_FALSE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); |
250 } | 290 } |
251 | 291 |
252 // Test a file where all video samples start with an Access Unit | 292 // Test a file where all video samples start with an Access Unit |
253 // Delimiter (AUD) NALU. | 293 // Delimiter (AUD) NALU. |
254 TEST_F(MP4StreamParserTest, VideoSamplesStartWithAUDs) { | 294 TEST_F(MP4StreamParserTest, VideoSamplesStartWithAUDs) { |
295 EXPECT_MEDIA_LOG_STRING(VideoCodecLog("avc1.4d4028")); | |
255 ParseMP4File("bear-1280x720-av_with-aud-nalus_frag.mp4", 512); | 296 ParseMP4File("bear-1280x720-av_with-aud-nalus_frag.mp4", 512); |
256 } | 297 } |
257 | 298 |
258 TEST_F(MP4StreamParserTest, CENC) { | 299 TEST_F(MP4StreamParserTest, CENC) { |
259 // Encrypted test mp4 files have non-zero duration and are treated as | 300 // Encrypted test mp4 files have non-zero duration and are treated as |
260 // recorded streams. | 301 // recorded streams. |
261 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); | 302 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); |
262 | 303 |
263 scoped_refptr<DecoderBuffer> buffer = | 304 scoped_refptr<DecoderBuffer> buffer = |
264 ReadTestDataFile("bear-1280x720-v_frag-cenc.mp4"); | 305 ReadTestDataFile("bear-1280x720-v_frag-cenc.mp4"); |
306 EXPECT_MEDIA_LOG_STRING(VideoCodecLog("avc1.6401f")); | |
265 EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); | 307 EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); |
266 } | 308 } |
267 | 309 |
268 TEST_F(MP4StreamParserTest, NaturalSizeWithoutPASP) { | 310 TEST_F(MP4StreamParserTest, NaturalSizeWithoutPASP) { |
269 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); | 311 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); |
270 | 312 |
271 scoped_refptr<DecoderBuffer> buffer = | 313 scoped_refptr<DecoderBuffer> buffer = |
272 ReadTestDataFile("bear-640x360-non_square_pixel-without_pasp.mp4"); | 314 ReadTestDataFile("bear-640x360-non_square_pixel-without_pasp.mp4"); |
273 | 315 |
316 EXPECT_MEDIA_LOG_STRING(VideoCodecLog("avc1.6401e")); | |
274 EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); | 317 EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); |
275 EXPECT_EQ(gfx::Size(638, 360), video_decoder_config_.natural_size()); | 318 EXPECT_EQ(gfx::Size(638, 360), video_decoder_config_.natural_size()); |
276 } | 319 } |
277 | 320 |
278 TEST_F(MP4StreamParserTest, NaturalSizeWithPASP) { | 321 TEST_F(MP4StreamParserTest, NaturalSizeWithPASP) { |
279 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); | 322 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); |
280 | 323 |
281 scoped_refptr<DecoderBuffer> buffer = | 324 scoped_refptr<DecoderBuffer> buffer = |
282 ReadTestDataFile("bear-640x360-non_square_pixel-with_pasp.mp4"); | 325 ReadTestDataFile("bear-640x360-non_square_pixel-with_pasp.mp4"); |
283 | 326 |
327 EXPECT_MEDIA_LOG_STRING(VideoCodecLog("avc1.6401e")); | |
284 EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); | 328 EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); |
285 EXPECT_EQ(gfx::Size(638, 360), video_decoder_config_.natural_size()); | 329 EXPECT_EQ(gfx::Size(638, 360), video_decoder_config_.natural_size()); |
286 } | 330 } |
287 | 331 |
288 } // namespace mp4 | 332 } // namespace mp4 |
289 } // namespace media | 333 } // namespace media |
OLD | NEW |