OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <deque> | 6 #include <deque> |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
76 CHECK(!demuxer_); | 76 CHECK(!demuxer_); |
77 | 77 |
78 EXPECT_CALL(host_, SetTotalBytes(_)).Times(AnyNumber()); | 78 EXPECT_CALL(host_, SetTotalBytes(_)).Times(AnyNumber()); |
79 EXPECT_CALL(host_, AddBufferedByteRange(_, _)).Times(AnyNumber()); | 79 EXPECT_CALL(host_, AddBufferedByteRange(_, _)).Times(AnyNumber()); |
80 EXPECT_CALL(host_, AddBufferedTimeRange(_, _)).Times(AnyNumber()); | 80 EXPECT_CALL(host_, AddBufferedTimeRange(_, _)).Times(AnyNumber()); |
81 | 81 |
82 CreateDataSource(name); | 82 CreateDataSource(name); |
83 | 83 |
84 Demuxer::NeedKeyCB need_key_cb = | 84 Demuxer::NeedKeyCB need_key_cb = |
85 base::Bind(&FFmpegDemuxerTest::NeedKeyCB, base::Unretained(this)); | 85 base::Bind(&FFmpegDemuxerTest::NeedKeyCB, base::Unretained(this)); |
86 | |
86 demuxer_.reset(new FFmpegDemuxer(message_loop_.message_loop_proxy(), | 87 demuxer_.reset(new FFmpegDemuxer(message_loop_.message_loop_proxy(), |
87 data_source_.get(), | 88 data_source_.get(), |
88 need_key_cb, | 89 need_key_cb, |
89 new MediaLog())); | 90 new MediaLog())); |
90 } | 91 } |
91 | 92 |
92 MOCK_METHOD1(CheckPoint, void(int v)); | 93 MOCK_METHOD1(CheckPoint, void(int v)); |
93 | 94 |
94 void InitializeDemuxer() { | 95 void InitializeDemuxerText(bool enable_text) { |
95 EXPECT_CALL(host_, SetDuration(_)); | 96 EXPECT_CALL(host_, SetDuration(_)); |
96 WaitableMessageLoopEvent event; | 97 WaitableMessageLoopEvent event; |
97 demuxer_->Initialize(&host_, event.GetPipelineStatusCB()); | 98 demuxer_->Initialize(&host_, event.GetPipelineStatusCB(), enable_text); |
98 event.RunAndWaitForStatus(PIPELINE_OK); | 99 event.RunAndWaitForStatus(PIPELINE_OK); |
99 } | 100 } |
100 | 101 |
102 void InitializeDemuxer() { | |
103 InitializeDemuxerText(false); | |
104 } | |
105 | |
101 MOCK_METHOD2(OnReadDoneCalled, void(int, int64)); | 106 MOCK_METHOD2(OnReadDoneCalled, void(int, int64)); |
102 | 107 |
103 // Verifies that |buffer| has a specific |size| and |timestamp|. | 108 // Verifies that |buffer| has a specific |size| and |timestamp|. |
104 // |location| simply indicates where the call to this function was made. | 109 // |location| simply indicates where the call to this function was made. |
105 // This makes it easier to track down where test failures occur. | 110 // This makes it easier to track down where test failures occur. |
106 void OnReadDone(const tracked_objects::Location& location, | 111 void OnReadDone(const tracked_objects::Location& location, |
107 int size, int64 timestampInMicroseconds, | 112 int size, int64 timestampInMicroseconds, |
108 DemuxerStream::Status status, | 113 DemuxerStream::Status status, |
109 const scoped_refptr<DecoderBuffer>& buffer) { | 114 const scoped_refptr<DecoderBuffer>& buffer) { |
110 std::string location_str; | 115 std::string location_str; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
192 EXPECT_TRUE(data_source_->Initialize(file_path)); | 197 EXPECT_TRUE(data_source_->Initialize(file_path)); |
193 } | 198 } |
194 | 199 |
195 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerTest); | 200 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerTest); |
196 }; | 201 }; |
197 | 202 |
198 TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) { | 203 TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) { |
199 // Simulate avformat_open_input() failing. | 204 // Simulate avformat_open_input() failing. |
200 CreateDemuxer("ten_byte_file"); | 205 CreateDemuxer("ten_byte_file"); |
201 WaitableMessageLoopEvent event; | 206 WaitableMessageLoopEvent event; |
202 demuxer_->Initialize(&host_, event.GetPipelineStatusCB()); | 207 demuxer_->Initialize(&host_, event.GetPipelineStatusCB(), true); |
203 event.RunAndWaitForStatus(DEMUXER_ERROR_COULD_NOT_OPEN); | 208 event.RunAndWaitForStatus(DEMUXER_ERROR_COULD_NOT_OPEN); |
204 } | 209 } |
205 | 210 |
206 // TODO(acolwell): Uncomment this test when we discover a file that passes | 211 // TODO(acolwell): Uncomment this test when we discover a file that passes |
207 // avformat_open_input(), but has avformat_find_stream_info() fail. | 212 // avformat_open_input(), but has avformat_find_stream_info() fail. |
208 // | 213 // |
209 //TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) { | 214 //TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) { |
210 // ("find_stream_info_fail.webm"); | 215 // ("find_stream_info_fail.webm"); |
211 // demuxer_->Initialize( | 216 // demuxer_->Initialize( |
212 // &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_PARSE)); | 217 // &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_PARSE)); |
213 // message_loop_.RunUntilIdle(); | 218 // message_loop_.RunUntilIdle(); |
214 //} | 219 //} |
215 | 220 |
216 TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) { | 221 TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) { |
217 // Open a file with no streams whatsoever. | 222 // Open a file with no streams whatsoever. |
218 CreateDemuxer("no_streams.webm"); | 223 CreateDemuxer("no_streams.webm"); |
219 WaitableMessageLoopEvent event; | 224 WaitableMessageLoopEvent event; |
220 demuxer_->Initialize(&host_, event.GetPipelineStatusCB()); | 225 demuxer_->Initialize(&host_, event.GetPipelineStatusCB(), true); |
221 event.RunAndWaitForStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS); | 226 event.RunAndWaitForStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS); |
222 } | 227 } |
223 | 228 |
224 TEST_F(FFmpegDemuxerTest, Initialize_NoAudioVideo) { | 229 TEST_F(FFmpegDemuxerTest, Initialize_NoAudioVideo) { |
225 // Open a file containing streams but none of which are audio/video streams. | 230 // Open a file containing streams but none of which are audio/video streams. |
226 CreateDemuxer("no_audio_video.webm"); | 231 CreateDemuxer("no_audio_video.webm"); |
227 WaitableMessageLoopEvent event; | 232 WaitableMessageLoopEvent event; |
228 demuxer_->Initialize(&host_, event.GetPipelineStatusCB()); | 233 demuxer_->Initialize(&host_, event.GetPipelineStatusCB(), true); |
229 event.RunAndWaitForStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS); | 234 event.RunAndWaitForStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS); |
230 } | 235 } |
231 | 236 |
232 TEST_F(FFmpegDemuxerTest, Initialize_Successful) { | 237 TEST_F(FFmpegDemuxerTest, Initialize_Successful) { |
233 CreateDemuxer("bear-320x240.webm"); | 238 CreateDemuxer("bear-320x240.webm"); |
234 InitializeDemuxer(); | 239 InitializeDemuxer(); |
235 | 240 |
236 // Video stream should be present. | 241 // Video stream should be present. |
237 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 242 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
238 ASSERT_TRUE(stream); | 243 ASSERT_TRUE(stream); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
291 // Audio stream should be Vorbis. | 296 // Audio stream should be Vorbis. |
292 stream = demuxer_->GetStream(DemuxerStream::AUDIO); | 297 stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
293 ASSERT_TRUE(stream); | 298 ASSERT_TRUE(stream); |
294 EXPECT_EQ(DemuxerStream::AUDIO, stream->type()); | 299 EXPECT_EQ(DemuxerStream::AUDIO, stream->type()); |
295 EXPECT_EQ(kCodecVorbis, stream->audio_decoder_config().codec()); | 300 EXPECT_EQ(kCodecVorbis, stream->audio_decoder_config().codec()); |
296 | 301 |
297 // Unknown stream should never be present. | 302 // Unknown stream should never be present. |
298 EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::UNKNOWN)); | 303 EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::UNKNOWN)); |
299 } | 304 } |
300 | 305 |
306 TEST_F(FFmpegDemuxerTest, Initialize_MultitrackText) { | |
307 // Open a file containing the following streams: | |
308 // Stream #0: Video (VP8) | |
309 // Stream #1: Audio (Vorbis) | |
310 // Stream #2: Text (WebVTT) | |
311 | |
312 CreateDemuxer("bear-vp8-webvtt.webm"); | |
313 DemuxerStream* text_stream = NULL; | |
314 EXPECT_CALL(host_, AddTextStream(_, _)) | |
315 .WillOnce(SaveArg<0>(&text_stream)); | |
316 InitializeDemuxerText(true); | |
317 ASSERT_TRUE(text_stream); | |
318 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); | |
319 | |
320 // Video stream should be VP8. | |
321 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); | |
322 ASSERT_TRUE(stream); | |
323 EXPECT_EQ(DemuxerStream::VIDEO, stream->type()); | |
324 EXPECT_EQ(kCodecVP8, stream->video_decoder_config().codec()); | |
325 | |
326 // Audio stream should be Vorbis. | |
327 stream = demuxer_->GetStream(DemuxerStream::AUDIO); | |
328 ASSERT_TRUE(stream); | |
329 EXPECT_EQ(DemuxerStream::AUDIO, stream->type()); | |
330 EXPECT_EQ(kCodecVorbis, stream->audio_decoder_config().codec()); | |
331 | |
332 // Unknown stream should never be present. | |
333 EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::UNKNOWN)); | |
334 } | |
335 | |
301 TEST_F(FFmpegDemuxerTest, Initialize_Encrypted) { | 336 TEST_F(FFmpegDemuxerTest, Initialize_Encrypted) { |
302 EXPECT_CALL(*this, NeedKeyCBMock(kWebMEncryptInitDataType, NotNull(), | 337 EXPECT_CALL(*this, NeedKeyCBMock(kWebMEncryptInitDataType, NotNull(), |
303 DecryptConfig::kDecryptionKeySize)) | 338 DecryptConfig::kDecryptionKeySize)) |
304 .Times(Exactly(2)); | 339 .Times(Exactly(2)); |
305 | 340 |
306 CreateDemuxer("bear-320x240-av_enc-av.webm"); | 341 CreateDemuxer("bear-320x240-av_enc-av.webm"); |
307 InitializeDemuxer(); | 342 InitializeDemuxer(); |
308 } | 343 } |
309 | 344 |
310 TEST_F(FFmpegDemuxerTest, Read_Audio) { | 345 TEST_F(FFmpegDemuxerTest, Read_Audio) { |
(...skipping 19 matching lines...) Expand all Loading... | |
330 // Attempt a read from the video stream and run the message loop until done. | 365 // Attempt a read from the video stream and run the message loop until done. |
331 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); | 366 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
332 | 367 |
333 video->Read(NewReadCB(FROM_HERE, 22084, 0)); | 368 video->Read(NewReadCB(FROM_HERE, 22084, 0)); |
334 message_loop_.Run(); | 369 message_loop_.Run(); |
335 | 370 |
336 video->Read(NewReadCB(FROM_HERE, 1057, 33000)); | 371 video->Read(NewReadCB(FROM_HERE, 1057, 33000)); |
337 message_loop_.Run(); | 372 message_loop_.Run(); |
338 } | 373 } |
339 | 374 |
375 TEST_F(FFmpegDemuxerTest, Read_Text) { | |
376 // We test that on a successful text packet read. | |
377 CreateDemuxer("bear-vp8-webvtt.webm"); | |
378 DemuxerStream* text_stream = NULL; | |
379 EXPECT_CALL(host_, AddTextStream(_, _)) | |
380 .WillOnce(SaveArg<0>(&text_stream)); | |
381 InitializeDemuxerText(true); | |
382 ASSERT_TRUE(text_stream); | |
383 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); | |
384 | |
385 text_stream->Read(NewReadCB(FROM_HERE, 31, 0)); | |
386 message_loop_.Run(); | |
387 | |
388 text_stream->Read(NewReadCB(FROM_HERE, 19, 500000)); | |
389 message_loop_.Run(); | |
390 } | |
391 | |
340 TEST_F(FFmpegDemuxerTest, Read_VideoNonZeroStart) { | 392 TEST_F(FFmpegDemuxerTest, Read_VideoNonZeroStart) { |
341 // Test the start time is the first timestamp of the video and audio stream. | 393 // Test the start time is the first timestamp of the video and audio stream. |
342 CreateDemuxer("nonzero-start-time.webm"); | 394 CreateDemuxer("nonzero-start-time.webm"); |
343 InitializeDemuxer(); | 395 InitializeDemuxer(); |
344 | 396 |
345 // Attempt a read from the video stream and run the message loop until done. | 397 // Attempt a read from the video stream and run the message loop until done. |
346 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); | 398 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
347 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); | 399 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
348 | 400 |
349 // Check first buffer in video stream. | 401 // Check first buffer in video stream. |
350 video->Read(NewReadCB(FROM_HERE, 5636, 400000)); | 402 video->Read(NewReadCB(FROM_HERE, 5636, 400000)); |
351 message_loop_.Run(); | 403 message_loop_.Run(); |
352 | 404 |
353 // Check first buffer in audio stream. | 405 // Check first buffer in audio stream. |
354 audio->Read(NewReadCB(FROM_HERE, 165, 396000)); | 406 audio->Read(NewReadCB(FROM_HERE, 165, 396000)); |
355 message_loop_.Run(); | 407 message_loop_.Run(); |
356 | 408 |
357 // Verify that the start time is equal to the lowest timestamp (ie the audio). | 409 // Verify that the start time is equal to the lowest timestamp (ie the audio). |
358 EXPECT_EQ(demuxer_->GetStartTime().InMicroseconds(), 396000); | 410 EXPECT_EQ(demuxer_->GetStartTime().InMicroseconds(), 396000); |
359 } | 411 } |
360 | 412 |
361 TEST_F(FFmpegDemuxerTest, Read_EndOfStream) { | 413 TEST_F(FFmpegDemuxerTest, Read_EndOfStream) { |
362 // Verify that end of stream buffers are created. | 414 // Verify that end of stream buffers are created. |
363 CreateDemuxer("bear-320x240.webm"); | 415 CreateDemuxer("bear-320x240.webm"); |
364 InitializeDemuxer(); | 416 InitializeDemuxer(); |
365 ReadUntilEndOfStream(); | 417 ReadUntilEndOfStream(); |
366 } | 418 } |
367 | 419 |
420 TEST_F(FFmpegDemuxerTest, Read_EndOfStreamText) { | |
421 // Verify that end of stream buffers are created. | |
422 CreateDemuxer("bear-vp8-webvtt.webm"); | |
423 DemuxerStream* text_stream = NULL; | |
424 EXPECT_CALL(host_, AddTextStream(_, _)) | |
425 .WillOnce(SaveArg<0>(&text_stream)); | |
426 InitializeDemuxerText(true); | |
427 ASSERT_TRUE(text_stream); | |
428 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); | |
429 | |
430 bool got_eos_buffer = false; | |
431 const int kMaxBuffers = 10000; | |
acolwell GONE FROM CHROMIUM
2013/11/20 01:15:24
nit: Please trim this down to a smaller number. I'
Matthew Heaney (Chromium)
2013/11/20 19:23:16
Done.
| |
432 for (int i = 0; !got_eos_buffer && i < kMaxBuffers; i++) { | |
433 text_stream->Read(base::Bind(&EosOnReadDone, &got_eos_buffer)); | |
434 message_loop_.Run(); | |
435 } | |
436 | |
437 EXPECT_TRUE(got_eos_buffer); | |
438 } | |
439 | |
368 TEST_F(FFmpegDemuxerTest, Read_EndOfStream_NoDuration) { | 440 TEST_F(FFmpegDemuxerTest, Read_EndOfStream_NoDuration) { |
369 // Verify that end of stream buffers are created. | 441 // Verify that end of stream buffers are created. |
370 CreateDemuxer("bear-320x240.webm"); | 442 CreateDemuxer("bear-320x240.webm"); |
371 InitializeDemuxer(); | 443 InitializeDemuxer(); |
372 set_duration_known(false); | 444 set_duration_known(false); |
373 EXPECT_CALL(host_, SetDuration(_)); | 445 EXPECT_CALL(host_, SetDuration(_)); |
374 ReadUntilEndOfStream(); | 446 ReadUntilEndOfStream(); |
375 } | 447 } |
376 | 448 |
377 TEST_F(FFmpegDemuxerTest, Seek) { | 449 TEST_F(FFmpegDemuxerTest, Seek) { |
(...skipping 28 matching lines...) Expand all Loading... | |
406 | 478 |
407 // Video read #1. | 479 // Video read #1. |
408 video->Read(NewReadCB(FROM_HERE, 5425, 801000)); | 480 video->Read(NewReadCB(FROM_HERE, 5425, 801000)); |
409 message_loop_.Run(); | 481 message_loop_.Run(); |
410 | 482 |
411 // Video read #2. | 483 // Video read #2. |
412 video->Read(NewReadCB(FROM_HERE, 1906, 834000)); | 484 video->Read(NewReadCB(FROM_HERE, 1906, 834000)); |
413 message_loop_.Run(); | 485 message_loop_.Run(); |
414 } | 486 } |
415 | 487 |
488 TEST_F(FFmpegDemuxerTest, SeekText) { | |
489 // We're testing that the demuxer frees all queued packets when it receives | |
490 // a Seek(). | |
491 CreateDemuxer("bear-vp8-webvtt.webm"); | |
492 DemuxerStream* text_stream = NULL; | |
493 EXPECT_CALL(host_, AddTextStream(_, _)) | |
494 .WillOnce(SaveArg<0>(&text_stream)); | |
495 InitializeDemuxerText(true); | |
496 ASSERT_TRUE(text_stream); | |
497 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); | |
498 | |
499 // Get our streams. | |
500 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); | |
501 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); | |
502 ASSERT_TRUE(video); | |
503 ASSERT_TRUE(audio); | |
504 | |
505 // Read a text packet and release it. | |
506 text_stream->Read(NewReadCB(FROM_HERE, 31, 0)); | |
507 message_loop_.Run(); | |
508 | |
509 // Issue a simple forward seek, which should discard queued packets. | |
510 WaitableMessageLoopEvent event; | |
511 demuxer_->Seek(base::TimeDelta::FromMicroseconds(1000000), | |
512 event.GetPipelineStatusCB()); | |
513 event.RunAndWaitForStatus(PIPELINE_OK); | |
514 | |
515 // Audio read #1. | |
516 audio->Read(NewReadCB(FROM_HERE, 145, 803000)); | |
517 message_loop_.Run(); | |
518 | |
519 // Audio read #2. | |
520 audio->Read(NewReadCB(FROM_HERE, 148, 826000)); | |
521 message_loop_.Run(); | |
522 | |
523 // Video read #1. | |
524 video->Read(NewReadCB(FROM_HERE, 5425, 801000)); | |
525 message_loop_.Run(); | |
526 | |
527 // Video read #2. | |
528 video->Read(NewReadCB(FROM_HERE, 1906, 834000)); | |
529 message_loop_.Run(); | |
530 | |
531 // Text read #1. | |
532 text_stream->Read(NewReadCB(FROM_HERE, 19, 500000)); | |
533 message_loop_.Run(); | |
534 | |
535 // Text read #2. | |
536 text_stream->Read(NewReadCB(FROM_HERE, 19, 1000000)); | |
537 message_loop_.Run(); | |
538 } | |
539 | |
416 class MockReadCB { | 540 class MockReadCB { |
417 public: | 541 public: |
418 MockReadCB() {} | 542 MockReadCB() {} |
419 ~MockReadCB() {} | 543 ~MockReadCB() {} |
420 | 544 |
421 MOCK_METHOD2(Run, void(DemuxerStream::Status status, | 545 MOCK_METHOD2(Run, void(DemuxerStream::Status status, |
422 const scoped_refptr<DecoderBuffer>& buffer)); | 546 const scoped_refptr<DecoderBuffer>& buffer)); |
423 private: | 547 private: |
424 DISALLOW_COPY_AND_ASSIGN(MockReadCB); | 548 DISALLOW_COPY_AND_ASSIGN(MockReadCB); |
425 }; | 549 }; |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
576 TEST_F(FFmpegDemuxerTest, MP4_ZeroStszEntry) { | 700 TEST_F(FFmpegDemuxerTest, MP4_ZeroStszEntry) { |
577 #if !defined(USE_PROPRIETARY_CODECS) | 701 #if !defined(USE_PROPRIETARY_CODECS) |
578 return; | 702 return; |
579 #endif | 703 #endif |
580 CreateDemuxer("bear-1280x720-zero-stsz-entry.mp4"); | 704 CreateDemuxer("bear-1280x720-zero-stsz-entry.mp4"); |
581 InitializeDemuxer(); | 705 InitializeDemuxer(); |
582 ReadUntilEndOfStream(); | 706 ReadUntilEndOfStream(); |
583 } | 707 } |
584 | 708 |
585 } // namespace media | 709 } // namespace media |
OLD | NEW |