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 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 // Fixture members. | 186 // Fixture members. |
187 scoped_ptr<FileDataSource> data_source_; | 187 scoped_ptr<FileDataSource> data_source_; |
188 scoped_ptr<FFmpegDemuxer> demuxer_; | 188 scoped_ptr<FFmpegDemuxer> demuxer_; |
189 StrictMock<MockDemuxerHost> host_; | 189 StrictMock<MockDemuxerHost> host_; |
190 base::MessageLoop message_loop_; | 190 base::MessageLoop message_loop_; |
191 | 191 |
192 AVFormatContext* format_context() { | 192 AVFormatContext* format_context() { |
193 return demuxer_->glue_->format_context(); | 193 return demuxer_->glue_->format_context(); |
194 } | 194 } |
195 | 195 |
| 196 int preferred_seeking_stream_index() const { |
| 197 return demuxer_->preferred_stream_for_seeking_.first; |
| 198 } |
| 199 |
196 void ReadUntilEndOfStream(DemuxerStream* stream) { | 200 void ReadUntilEndOfStream(DemuxerStream* stream) { |
197 bool got_eos_buffer = false; | 201 bool got_eos_buffer = false; |
198 const int kMaxBuffers = 170; | 202 const int kMaxBuffers = 170; |
199 for (int i = 0; !got_eos_buffer && i < kMaxBuffers; i++) { | 203 for (int i = 0; !got_eos_buffer && i < kMaxBuffers; i++) { |
200 stream->Read(base::Bind(&EosOnReadDone, &got_eos_buffer)); | 204 stream->Read(base::Bind(&EosOnReadDone, &got_eos_buffer)); |
201 message_loop_.Run(); | 205 message_loop_.Run(); |
202 } | 206 } |
203 | 207 |
204 EXPECT_TRUE(got_eos_buffer); | 208 EXPECT_TRUE(got_eos_buffer); |
205 } | 209 } |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 ASSERT_TRUE(text_stream); | 409 ASSERT_TRUE(text_stream); |
406 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); | 410 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); |
407 | 411 |
408 text_stream->Read(NewReadCB(FROM_HERE, 31, 0)); | 412 text_stream->Read(NewReadCB(FROM_HERE, 31, 0)); |
409 message_loop_.Run(); | 413 message_loop_.Run(); |
410 | 414 |
411 text_stream->Read(NewReadCB(FROM_HERE, 19, 500000)); | 415 text_stream->Read(NewReadCB(FROM_HERE, 19, 500000)); |
412 message_loop_.Run(); | 416 message_loop_.Run(); |
413 } | 417 } |
414 | 418 |
| 419 TEST_F(FFmpegDemuxerTest, SeekInitialized_NoVideoStartTime) { |
| 420 CreateDemuxer("audio-start-time-only.webm"); |
| 421 InitializeDemuxer(); |
| 422 EXPECT_EQ(0, preferred_seeking_stream_index()); |
| 423 } |
| 424 |
415 TEST_F(FFmpegDemuxerTest, Read_VideoPositiveStartTime) { | 425 TEST_F(FFmpegDemuxerTest, Read_VideoPositiveStartTime) { |
416 const int64 kTimelineOffsetMs = 1352550896000LL; | 426 const int64 kTimelineOffsetMs = 1352550896000LL; |
417 | 427 |
418 // Test the start time is the first timestamp of the video and audio stream. | 428 // Test the start time is the first timestamp of the video and audio stream. |
419 CreateDemuxer("nonzero-start-time.webm"); | 429 CreateDemuxer("nonzero-start-time.webm"); |
420 InitializeDemuxerWithTimelineOffset( | 430 InitializeDemuxerWithTimelineOffset( |
421 false, base::Time::FromJsTime(kTimelineOffsetMs)); | 431 false, base::Time::FromJsTime(kTimelineOffsetMs)); |
422 | 432 |
423 // Attempt a read from the video stream and run the message loop until done. | 433 // Attempt a read from the video stream and run the message loop until done. |
424 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); | 434 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 message_loop_.Run(); | 482 message_loop_.Run(); |
473 EXPECT_EQ(base::TimeDelta(), demuxer_->start_time()); | 483 EXPECT_EQ(base::TimeDelta(), demuxer_->start_time()); |
474 | 484 |
475 // Seek back to the beginning and repeat the test. | 485 // Seek back to the beginning and repeat the test. |
476 WaitableMessageLoopEvent event; | 486 WaitableMessageLoopEvent event; |
477 demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB()); | 487 demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB()); |
478 event.RunAndWaitForStatus(PIPELINE_OK); | 488 event.RunAndWaitForStatus(PIPELINE_OK); |
479 } | 489 } |
480 } | 490 } |
481 | 491 |
482 TEST_F(FFmpegDemuxerTest, Read_AudioNegativeStartTimeAndOggDiscard) { | 492 TEST_F(FFmpegDemuxerTest, Read_AudioNegativeStartTimeAndOggDiscard_Bear) { |
483 // Many ogg files have negative starting timestamps, so ensure demuxing and | 493 // Many ogg files have negative starting timestamps, so ensure demuxing and |
484 // seeking work correctly with a negative start time. | 494 // seeking work correctly with a negative start time. |
485 CreateDemuxer("bear.ogv"); | 495 CreateDemuxer("bear.ogv"); |
486 InitializeDemuxer(); | 496 InitializeDemuxer(); |
487 | 497 |
| 498 // Attempt a read from the video stream and run the message loop until done. |
| 499 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 500 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 501 |
488 // Run the test twice with a seek in between. | 502 // Run the test twice with a seek in between. |
489 for (int i = 0; i < 2; ++i) { | 503 for (int i = 0; i < 2; ++i) { |
490 demuxer_->GetStream(DemuxerStream::AUDIO)->Read( | 504 audio->Read( |
491 NewReadCBWithCheckedDiscard(FROM_HERE, 40, 0, kInfiniteDuration())); | 505 NewReadCBWithCheckedDiscard(FROM_HERE, 40, 0, kInfiniteDuration())); |
492 message_loop_.Run(); | 506 message_loop_.Run(); |
493 demuxer_->GetStream(DemuxerStream::AUDIO)->Read( | 507 audio->Read( |
494 NewReadCBWithCheckedDiscard(FROM_HERE, 41, 2903, kInfiniteDuration())); | 508 NewReadCBWithCheckedDiscard(FROM_HERE, 41, 2903, kInfiniteDuration())); |
495 message_loop_.Run(); | 509 message_loop_.Run(); |
496 demuxer_->GetStream(DemuxerStream::AUDIO)->Read(NewReadCBWithCheckedDiscard( | 510 audio->Read(NewReadCBWithCheckedDiscard( |
497 FROM_HERE, 173, 5805, base::TimeDelta::FromMicroseconds(10159))); | 511 FROM_HERE, 173, 5805, base::TimeDelta::FromMicroseconds(10159))); |
498 message_loop_.Run(); | 512 message_loop_.Run(); |
499 | 513 |
500 demuxer_->GetStream(DemuxerStream::AUDIO) | 514 audio->Read(NewReadCB(FROM_HERE, 148, 18866)); |
501 ->Read(NewReadCB(FROM_HERE, 148, 18866)); | |
502 message_loop_.Run(); | 515 message_loop_.Run(); |
503 EXPECT_EQ(base::TimeDelta::FromMicroseconds(-15964), | 516 EXPECT_EQ(base::TimeDelta::FromMicroseconds(-15964), |
504 demuxer_->start_time()); | 517 demuxer_->start_time()); |
505 | 518 |
| 519 video->Read(NewReadCB(FROM_HERE, 5751, 0)); |
| 520 message_loop_.Run(); |
| 521 |
| 522 video->Read(NewReadCB(FROM_HERE, 846, 33367)); |
| 523 message_loop_.Run(); |
| 524 |
| 525 video->Read(NewReadCB(FROM_HERE, 1255, 66733)); |
| 526 message_loop_.Run(); |
| 527 |
506 // Seek back to the beginning and repeat the test. | 528 // Seek back to the beginning and repeat the test. |
507 WaitableMessageLoopEvent event; | 529 WaitableMessageLoopEvent event; |
508 demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB()); | 530 demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB()); |
| 531 event.RunAndWaitForStatus(PIPELINE_OK); |
| 532 } |
| 533 } |
| 534 |
| 535 // Same test above, but using sync2.ogv which has video stream muxed before the |
| 536 // audio stream, so seeking based only on start time will fail since ffmpeg is |
| 537 // essentially just seeking based on file position. |
| 538 TEST_F(FFmpegDemuxerTest, Read_AudioNegativeStartTimeAndOggDiscard_Sync) { |
| 539 // Many ogg files have negative starting timestamps, so ensure demuxing and |
| 540 // seeking work correctly with a negative start time. |
| 541 CreateDemuxer("sync2.ogv"); |
| 542 InitializeDemuxer(); |
| 543 |
| 544 // Attempt a read from the video stream and run the message loop until done. |
| 545 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 546 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 547 |
| 548 // Run the test twice with a seek in between. |
| 549 for (int i = 0; i < 2; ++i) { |
| 550 audio->Read(NewReadCBWithCheckedDiscard( |
| 551 FROM_HERE, 1, 0, base::TimeDelta::FromMicroseconds(2902))); |
| 552 message_loop_.Run(); |
| 553 |
| 554 audio->Read(NewReadCB(FROM_HERE, 1, 2902)); |
| 555 message_loop_.Run(); |
| 556 EXPECT_EQ(base::TimeDelta::FromMicroseconds(-2902), |
| 557 demuxer_->start_time()); |
| 558 |
| 559 video->Read(NewReadCB(FROM_HERE, 9997, 0)); |
| 560 message_loop_.Run(); |
| 561 |
| 562 video->Read(NewReadCB(FROM_HERE, 16, 33241)); |
| 563 message_loop_.Run(); |
| 564 |
| 565 video->Read(NewReadCB(FROM_HERE, 631, 66482)); |
| 566 message_loop_.Run(); |
| 567 |
| 568 // Seek back to the beginning and repeat the test. |
| 569 WaitableMessageLoopEvent event; |
| 570 demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB()); |
509 event.RunAndWaitForStatus(PIPELINE_OK); | 571 event.RunAndWaitForStatus(PIPELINE_OK); |
510 } | 572 } |
511 } | 573 } |
512 | 574 |
513 TEST_F(FFmpegDemuxerTest, Read_EndOfStream) { | 575 TEST_F(FFmpegDemuxerTest, Read_EndOfStream) { |
514 // Verify that end of stream buffers are created. | 576 // Verify that end of stream buffers are created. |
515 CreateDemuxer("bear-320x240.webm"); | 577 CreateDemuxer("bear-320x240.webm"); |
516 InitializeDemuxer(); | 578 InitializeDemuxer(); |
517 ReadUntilEndOfStream(demuxer_->GetStream(DemuxerStream::AUDIO)); | 579 ReadUntilEndOfStream(demuxer_->GetStream(DemuxerStream::AUDIO)); |
518 } | 580 } |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
846 demuxer_->Stop(event.GetClosure()); | 908 demuxer_->Stop(event.GetClosure()); |
847 event.RunAndWait(); | 909 event.RunAndWait(); |
848 demuxer_.reset(); | 910 demuxer_.reset(); |
849 data_source_.reset(); | 911 data_source_.reset(); |
850 } | 912 } |
851 } | 913 } |
852 | 914 |
853 #endif | 915 #endif |
854 | 916 |
855 } // namespace media | 917 } // namespace media |
OLD | NEW |