Chromium Code Reviews| 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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 101 void InitializeDemuxerText(bool enable_text) { | 101 void InitializeDemuxerText(bool enable_text) { |
| 102 InitializeDemuxerWithTimelineOffset(enable_text, base::Time()); | 102 InitializeDemuxerWithTimelineOffset(enable_text, base::Time()); |
| 103 } | 103 } |
| 104 | 104 |
| 105 void InitializeDemuxer() { | 105 void InitializeDemuxer() { |
| 106 InitializeDemuxerText(false); | 106 InitializeDemuxerText(false); |
| 107 } | 107 } |
| 108 | 108 |
| 109 MOCK_METHOD2(OnReadDoneCalled, void(int, int64)); | 109 MOCK_METHOD2(OnReadDoneCalled, void(int, int64)); |
| 110 | 110 |
| 111 struct ReadExpectation { | |
|
xhwang
2014/11/10 20:14:12
This is not POD. Add a constructor? That'll also m
wolenetz
2014/11/11 22:39:41
Done.
| |
| 112 int size; | |
| 113 int64 timestamp_us; | |
| 114 base::TimeDelta discard_front_padding; | |
| 115 bool keyframe; | |
| 116 }; | |
| 117 | |
| 111 // Verifies that |buffer| has a specific |size| and |timestamp|. | 118 // Verifies that |buffer| has a specific |size| and |timestamp|. |
| 112 // |location| simply indicates where the call to this function was made. | 119 // |location| simply indicates where the call to this function was made. |
| 113 // This makes it easier to track down where test failures occur. | 120 // This makes it easier to track down where test failures occur. |
| 114 void OnReadDone(const tracked_objects::Location& location, | 121 void OnReadDone(const tracked_objects::Location& location, |
| 115 int size, | 122 ReadExpectation read_expectation, |
|
xhwang
2014/11/10 20:14:12
nit: pass by const-ref?
wolenetz
2014/11/11 22:39:41
Done.
| |
| 116 int64 timestamp_us, | |
| 117 base::TimeDelta discard_front_padding, | |
| 118 DemuxerStream::Status status, | 123 DemuxerStream::Status status, |
| 119 const scoped_refptr<DecoderBuffer>& buffer) { | 124 const scoped_refptr<DecoderBuffer>& buffer) { |
| 120 std::string location_str; | 125 std::string location_str; |
| 121 location.Write(true, false, &location_str); | 126 location.Write(true, false, &location_str); |
| 122 location_str += "\n"; | 127 location_str += "\n"; |
| 123 SCOPED_TRACE(location_str); | 128 SCOPED_TRACE(location_str); |
| 124 EXPECT_EQ(status, DemuxerStream::kOk); | 129 EXPECT_EQ(status, DemuxerStream::kOk); |
| 125 OnReadDoneCalled(size, timestamp_us); | |
| 126 EXPECT_TRUE(buffer.get() != NULL); | 130 EXPECT_TRUE(buffer.get() != NULL); |
| 127 EXPECT_EQ(size, buffer->data_size()); | 131 EXPECT_EQ(read_expectation.size, buffer->data_size()); |
| 128 EXPECT_EQ(timestamp_us, buffer->timestamp().InMicroseconds()); | 132 EXPECT_EQ(read_expectation.timestamp_us, |
| 129 EXPECT_EQ(discard_front_padding, buffer->discard_padding().first); | 133 buffer->timestamp().InMicroseconds()); |
| 134 EXPECT_EQ(read_expectation.discard_front_padding, | |
| 135 buffer->discard_padding().first); | |
| 136 EXPECT_EQ(read_expectation.keyframe, buffer->is_keyframe()); | |
| 130 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); | 137 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); |
| 138 OnReadDoneCalled(read_expectation.size, read_expectation.timestamp_us); | |
| 131 message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); | 139 message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); |
| 132 } | 140 } |
| 133 | 141 |
| 134 DemuxerStream::ReadCB NewReadCB(const tracked_objects::Location& location, | 142 DemuxerStream::ReadCB NewReadCB(const tracked_objects::Location& location, |
| 135 int size, | 143 int size, |
| 136 int64 timestamp_us) { | 144 int64 timestamp_us, |
| 145 bool keyframe) { | |
| 137 EXPECT_CALL(*this, OnReadDoneCalled(size, timestamp_us)); | 146 EXPECT_CALL(*this, OnReadDoneCalled(size, timestamp_us)); |
| 147 | |
| 148 struct ReadExpectation read_expectation = { | |
| 149 size, | |
| 150 timestamp_us, | |
| 151 base::TimeDelta(), | |
| 152 keyframe | |
| 153 }; | |
| 154 | |
| 138 return base::Bind(&FFmpegDemuxerTest::OnReadDone, | 155 return base::Bind(&FFmpegDemuxerTest::OnReadDone, |
| 139 base::Unretained(this), | 156 base::Unretained(this), |
| 140 location, | 157 location, |
| 141 size, | 158 read_expectation); |
| 142 timestamp_us, | |
| 143 base::TimeDelta()); | |
| 144 } | 159 } |
| 145 | 160 |
| 146 DemuxerStream::ReadCB NewReadCBWithCheckedDiscard( | 161 DemuxerStream::ReadCB NewReadCBWithCheckedDiscard( |
| 147 const tracked_objects::Location& location, | 162 const tracked_objects::Location& location, |
| 148 int size, | 163 int size, |
| 149 int64 timestamp_us, | 164 int64 timestamp_us, |
| 150 base::TimeDelta discard_front_padding) { | 165 base::TimeDelta discard_front_padding, |
| 166 bool keyframe) { | |
| 151 EXPECT_CALL(*this, OnReadDoneCalled(size, timestamp_us)); | 167 EXPECT_CALL(*this, OnReadDoneCalled(size, timestamp_us)); |
| 168 | |
| 169 struct ReadExpectation read_expectation = { | |
| 170 size, | |
| 171 timestamp_us, | |
| 172 discard_front_padding, | |
| 173 keyframe | |
| 174 }; | |
| 175 | |
| 152 return base::Bind(&FFmpegDemuxerTest::OnReadDone, | 176 return base::Bind(&FFmpegDemuxerTest::OnReadDone, |
| 153 base::Unretained(this), | 177 base::Unretained(this), |
| 154 location, | 178 location, |
| 155 size, | 179 read_expectation); |
| 156 timestamp_us, | |
| 157 discard_front_padding); | |
| 158 } | 180 } |
| 159 | 181 |
| 160 // TODO(xhwang): This is a workaround of the issue that move-only parameters | 182 // TODO(xhwang): This is a workaround of the issue that move-only parameters |
| 161 // are not supported in mocked methods. Remove this when the issue is fixed | 183 // are not supported in mocked methods. Remove this when the issue is fixed |
| 162 // (http://code.google.com/p/googletest/issues/detail?id=395) or when we use | 184 // (http://code.google.com/p/googletest/issues/detail?id=395) or when we use |
| 163 // std::string instead of scoped_ptr<uint8[]> (http://crbug.com/130689). | 185 // std::string instead of scoped_ptr<uint8[]> (http://crbug.com/130689). |
| 164 MOCK_METHOD3(NeedKeyCBMock, void(const std::string& type, | 186 MOCK_METHOD3(NeedKeyCBMock, void(const std::string& type, |
| 165 const uint8* init_data, int init_data_size)); | 187 const uint8* init_data, int init_data_size)); |
| 166 void NeedKeyCB(const std::string& type, | 188 void NeedKeyCB(const std::string& type, |
| 167 const std::vector<uint8>& init_data) { | 189 const std::vector<uint8>& init_data) { |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 367 } | 389 } |
| 368 | 390 |
| 369 TEST_F(FFmpegDemuxerTest, Read_Audio) { | 391 TEST_F(FFmpegDemuxerTest, Read_Audio) { |
| 370 // We test that on a successful audio packet read. | 392 // We test that on a successful audio packet read. |
| 371 CreateDemuxer("bear-320x240.webm"); | 393 CreateDemuxer("bear-320x240.webm"); |
| 372 InitializeDemuxer(); | 394 InitializeDemuxer(); |
| 373 | 395 |
| 374 // Attempt a read from the audio stream and run the message loop until done. | 396 // Attempt a read from the audio stream and run the message loop until done. |
| 375 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); | 397 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 376 | 398 |
| 377 audio->Read(NewReadCB(FROM_HERE, 29, 0)); | 399 audio->Read(NewReadCB(FROM_HERE, 29, 0, true)); |
| 378 message_loop_.Run(); | 400 message_loop_.Run(); |
| 379 | 401 |
| 380 audio->Read(NewReadCB(FROM_HERE, 27, 3000)); | 402 audio->Read(NewReadCB(FROM_HERE, 27, 3000, true)); |
| 381 message_loop_.Run(); | 403 message_loop_.Run(); |
| 382 } | 404 } |
| 383 | 405 |
| 384 TEST_F(FFmpegDemuxerTest, Read_Video) { | 406 TEST_F(FFmpegDemuxerTest, Read_Video) { |
| 385 // We test that on a successful video packet read. | 407 // We test that on a successful video packet read. |
| 386 CreateDemuxer("bear-320x240.webm"); | 408 CreateDemuxer("bear-320x240.webm"); |
| 387 InitializeDemuxer(); | 409 InitializeDemuxer(); |
| 388 | 410 |
| 389 // Attempt a read from the video stream and run the message loop until done. | 411 // Attempt a read from the video stream and run the message loop until done. |
| 390 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); | 412 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 391 | 413 |
| 392 video->Read(NewReadCB(FROM_HERE, 22084, 0)); | 414 video->Read(NewReadCB(FROM_HERE, 22084, 0, true)); |
| 393 message_loop_.Run(); | 415 message_loop_.Run(); |
| 394 | 416 |
| 395 video->Read(NewReadCB(FROM_HERE, 1057, 33000)); | 417 video->Read(NewReadCB(FROM_HERE, 1057, 33000, false)); |
| 396 message_loop_.Run(); | 418 message_loop_.Run(); |
| 397 } | 419 } |
| 398 | 420 |
| 399 TEST_F(FFmpegDemuxerTest, Read_Text) { | 421 TEST_F(FFmpegDemuxerTest, Read_Text) { |
| 400 // We test that on a successful text packet read. | 422 // We test that on a successful text packet read. |
| 401 CreateDemuxer("bear-vp8-webvtt.webm"); | 423 CreateDemuxer("bear-vp8-webvtt.webm"); |
| 402 DemuxerStream* text_stream = NULL; | 424 DemuxerStream* text_stream = NULL; |
| 403 EXPECT_CALL(host_, AddTextStream(_, _)) | 425 EXPECT_CALL(host_, AddTextStream(_, _)) |
| 404 .WillOnce(SaveArg<0>(&text_stream)); | 426 .WillOnce(SaveArg<0>(&text_stream)); |
| 405 InitializeDemuxerText(true); | 427 InitializeDemuxerText(true); |
| 406 ASSERT_TRUE(text_stream); | 428 ASSERT_TRUE(text_stream); |
| 407 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); | 429 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); |
| 408 | 430 |
| 409 text_stream->Read(NewReadCB(FROM_HERE, 31, 0)); | 431 text_stream->Read(NewReadCB(FROM_HERE, 31, 0, true)); |
| 410 message_loop_.Run(); | 432 message_loop_.Run(); |
| 411 | 433 |
| 412 text_stream->Read(NewReadCB(FROM_HERE, 19, 500000)); | 434 text_stream->Read(NewReadCB(FROM_HERE, 19, 500000, true)); |
| 413 message_loop_.Run(); | 435 message_loop_.Run(); |
| 414 } | 436 } |
| 415 | 437 |
| 416 TEST_F(FFmpegDemuxerTest, SeekInitialized_NoVideoStartTime) { | 438 TEST_F(FFmpegDemuxerTest, SeekInitialized_NoVideoStartTime) { |
| 417 CreateDemuxer("audio-start-time-only.webm"); | 439 CreateDemuxer("audio-start-time-only.webm"); |
| 418 InitializeDemuxer(); | 440 InitializeDemuxer(); |
| 419 EXPECT_EQ(0, preferred_seeking_stream_index()); | 441 EXPECT_EQ(0, preferred_seeking_stream_index()); |
| 420 } | 442 } |
| 421 | 443 |
| 422 TEST_F(FFmpegDemuxerTest, Read_VideoPositiveStartTime) { | 444 TEST_F(FFmpegDemuxerTest, Read_VideoPositiveStartTime) { |
| 423 const int64 kTimelineOffsetMs = 1352550896000LL; | 445 const int64 kTimelineOffsetMs = 1352550896000LL; |
| 424 | 446 |
| 425 // Test the start time is the first timestamp of the video and audio stream. | 447 // Test the start time is the first timestamp of the video and audio stream. |
| 426 CreateDemuxer("nonzero-start-time.webm"); | 448 CreateDemuxer("nonzero-start-time.webm"); |
| 427 InitializeDemuxerWithTimelineOffset( | 449 InitializeDemuxerWithTimelineOffset( |
| 428 false, base::Time::FromJsTime(kTimelineOffsetMs)); | 450 false, base::Time::FromJsTime(kTimelineOffsetMs)); |
| 429 | 451 |
| 430 // Attempt a read from the video stream and run the message loop until done. | 452 // Attempt a read from the video stream and run the message loop until done. |
| 431 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); | 453 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 432 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); | 454 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 433 | 455 |
| 434 const base::TimeDelta video_start_time = | 456 const base::TimeDelta video_start_time = |
| 435 base::TimeDelta::FromMicroseconds(400000); | 457 base::TimeDelta::FromMicroseconds(400000); |
| 436 const base::TimeDelta audio_start_time = | 458 const base::TimeDelta audio_start_time = |
| 437 base::TimeDelta::FromMicroseconds(396000); | 459 base::TimeDelta::FromMicroseconds(396000); |
| 438 | 460 |
| 439 // Run the test twice with a seek in between. | 461 // Run the test twice with a seek in between. |
| 440 for (int i = 0; i < 2; ++i) { | 462 for (int i = 0; i < 2; ++i) { |
| 441 video->Read(NewReadCB(FROM_HERE, 5636, video_start_time.InMicroseconds())); | 463 video->Read(NewReadCB(FROM_HERE, 5636, video_start_time.InMicroseconds(), |
| 464 true)); | |
| 442 message_loop_.Run(); | 465 message_loop_.Run(); |
| 443 audio->Read(NewReadCB(FROM_HERE, 165, audio_start_time.InMicroseconds())); | 466 audio->Read(NewReadCB(FROM_HERE, 165, audio_start_time.InMicroseconds(), |
| 467 true)); | |
| 444 message_loop_.Run(); | 468 message_loop_.Run(); |
| 445 | 469 |
| 446 // Verify that the start time is equal to the lowest timestamp (ie the | 470 // Verify that the start time is equal to the lowest timestamp (ie the |
| 447 // audio). | 471 // audio). |
| 448 EXPECT_EQ(audio_start_time, demuxer_->start_time()); | 472 EXPECT_EQ(audio_start_time, demuxer_->start_time()); |
| 449 | 473 |
| 450 // Verify that the timeline offset has not been adjusted by the start time. | 474 // Verify that the timeline offset has not been adjusted by the start time. |
| 451 EXPECT_EQ(kTimelineOffsetMs, demuxer_->GetTimelineOffset().ToJavaTime()); | 475 EXPECT_EQ(kTimelineOffsetMs, demuxer_->GetTimelineOffset().ToJavaTime()); |
| 452 | 476 |
| 453 // Seek back to the beginning and repeat the test. | 477 // Seek back to the beginning and repeat the test. |
| 454 WaitableMessageLoopEvent event; | 478 WaitableMessageLoopEvent event; |
| 455 demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB()); | 479 demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB()); |
| 456 event.RunAndWaitForStatus(PIPELINE_OK); | 480 event.RunAndWaitForStatus(PIPELINE_OK); |
| 457 } | 481 } |
| 458 } | 482 } |
| 459 | 483 |
| 460 TEST_F(FFmpegDemuxerTest, Read_AudioNoStartTime) { | 484 TEST_F(FFmpegDemuxerTest, Read_AudioNoStartTime) { |
| 461 // FFmpeg does not set timestamps when demuxing wave files. Ensure that the | 485 // FFmpeg does not set timestamps when demuxing wave files. Ensure that the |
| 462 // demuxer sets a start time of zero in this case. | 486 // demuxer sets a start time of zero in this case. |
| 463 CreateDemuxer("sfx_s24le.wav"); | 487 CreateDemuxer("sfx_s24le.wav"); |
| 464 InitializeDemuxer(); | 488 InitializeDemuxer(); |
| 465 | 489 |
| 466 // Run the test twice with a seek in between. | 490 // Run the test twice with a seek in between. |
| 467 for (int i = 0; i < 2; ++i) { | 491 for (int i = 0; i < 2; ++i) { |
| 468 demuxer_->GetStream(DemuxerStream::AUDIO) | 492 demuxer_->GetStream(DemuxerStream::AUDIO) |
| 469 ->Read(NewReadCB(FROM_HERE, 4095, 0)); | 493 ->Read(NewReadCB(FROM_HERE, 4095, 0, true)); |
| 470 message_loop_.Run(); | 494 message_loop_.Run(); |
| 471 EXPECT_EQ(base::TimeDelta(), demuxer_->start_time()); | 495 EXPECT_EQ(base::TimeDelta(), demuxer_->start_time()); |
| 472 | 496 |
| 473 // Seek back to the beginning and repeat the test. | 497 // Seek back to the beginning and repeat the test. |
| 474 WaitableMessageLoopEvent event; | 498 WaitableMessageLoopEvent event; |
| 475 demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB()); | 499 demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB()); |
| 476 event.RunAndWaitForStatus(PIPELINE_OK); | 500 event.RunAndWaitForStatus(PIPELINE_OK); |
| 477 } | 501 } |
| 478 } | 502 } |
| 479 | 503 |
| 480 // TODO(dalecurtis): Test is disabled since FFmpeg does not currently guarantee | 504 // TODO(dalecurtis): Test is disabled since FFmpeg does not currently guarantee |
| 481 // the order of demuxed packets in OGG containers. Re-enable once we decide to | 505 // the order of demuxed packets in OGG containers. Re-enable and fix keyframe |
| 482 // either workaround it or attempt a fix upstream. See http://crbug.com/387996. | 506 // expectations once we decide to either workaround it or attempt a fix |
| 507 // upstream. See http://crbug.com/387996. | |
| 483 TEST_F(FFmpegDemuxerTest, | 508 TEST_F(FFmpegDemuxerTest, |
| 484 DISABLED_Read_AudioNegativeStartTimeAndOggDiscard_Bear) { | 509 DISABLED_Read_AudioNegativeStartTimeAndOggDiscard_Bear) { |
| 485 // Many ogg files have negative starting timestamps, so ensure demuxing and | 510 // Many ogg files have negative starting timestamps, so ensure demuxing and |
| 486 // seeking work correctly with a negative start time. | 511 // seeking work correctly with a negative start time. |
| 487 CreateDemuxer("bear.ogv"); | 512 CreateDemuxer("bear.ogv"); |
| 488 InitializeDemuxer(); | 513 InitializeDemuxer(); |
| 489 | 514 |
| 490 // Attempt a read from the video stream and run the message loop until done. | 515 // Attempt a read from the video stream and run the message loop until done. |
| 491 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); | 516 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 492 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); | 517 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 493 | 518 |
| 494 // Run the test twice with a seek in between. | 519 // Run the test twice with a seek in between. |
| 495 for (int i = 0; i < 2; ++i) { | 520 for (int i = 0; i < 2; ++i) { |
| 496 audio->Read( | 521 audio->Read( |
| 497 NewReadCBWithCheckedDiscard(FROM_HERE, 40, 0, kInfiniteDuration())); | 522 NewReadCBWithCheckedDiscard(FROM_HERE, 40, 0, kInfiniteDuration(), |
| 523 true)); | |
| 498 message_loop_.Run(); | 524 message_loop_.Run(); |
| 499 audio->Read( | 525 audio->Read( |
| 500 NewReadCBWithCheckedDiscard(FROM_HERE, 41, 2903, kInfiniteDuration())); | 526 NewReadCBWithCheckedDiscard(FROM_HERE, 41, 2903, kInfiniteDuration(), |
| 527 true)); | |
| 501 message_loop_.Run(); | 528 message_loop_.Run(); |
| 502 audio->Read(NewReadCBWithCheckedDiscard( | 529 audio->Read(NewReadCBWithCheckedDiscard( |
| 503 FROM_HERE, 173, 5805, base::TimeDelta::FromMicroseconds(10159))); | 530 FROM_HERE, 173, 5805, base::TimeDelta::FromMicroseconds(10159), true)); |
| 504 message_loop_.Run(); | 531 message_loop_.Run(); |
| 505 | 532 |
| 506 audio->Read(NewReadCB(FROM_HERE, 148, 18866)); | 533 audio->Read(NewReadCB(FROM_HERE, 148, 18866, true)); |
| 507 message_loop_.Run(); | 534 message_loop_.Run(); |
| 508 EXPECT_EQ(base::TimeDelta::FromMicroseconds(-15964), | 535 EXPECT_EQ(base::TimeDelta::FromMicroseconds(-15964), |
| 509 demuxer_->start_time()); | 536 demuxer_->start_time()); |
| 510 | 537 |
| 511 video->Read(NewReadCB(FROM_HERE, 5751, 0)); | 538 video->Read(NewReadCB(FROM_HERE, 5751, 0, true)); |
| 512 message_loop_.Run(); | 539 message_loop_.Run(); |
| 513 | 540 |
| 514 video->Read(NewReadCB(FROM_HERE, 846, 33367)); | 541 video->Read(NewReadCB(FROM_HERE, 846, 33367, true)); |
| 515 message_loop_.Run(); | 542 message_loop_.Run(); |
| 516 | 543 |
| 517 video->Read(NewReadCB(FROM_HERE, 1255, 66733)); | 544 video->Read(NewReadCB(FROM_HERE, 1255, 66733, true)); |
| 518 message_loop_.Run(); | 545 message_loop_.Run(); |
| 519 | 546 |
| 520 // Seek back to the beginning and repeat the test. | 547 // Seek back to the beginning and repeat the test. |
| 521 WaitableMessageLoopEvent event; | 548 WaitableMessageLoopEvent event; |
| 522 demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB()); | 549 demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB()); |
| 523 event.RunAndWaitForStatus(PIPELINE_OK); | 550 event.RunAndWaitForStatus(PIPELINE_OK); |
| 524 } | 551 } |
| 525 } | 552 } |
| 526 | 553 |
| 527 // Same test above, but using sync2.ogv which has video stream muxed before the | 554 // Same test above, but using sync2.ogv which has video stream muxed before the |
| 528 // audio stream, so seeking based only on start time will fail since ffmpeg is | 555 // audio stream, so seeking based only on start time will fail since ffmpeg is |
| 529 // essentially just seeking based on file position. | 556 // essentially just seeking based on file position. |
| 530 TEST_F(FFmpegDemuxerTest, Read_AudioNegativeStartTimeAndOggDiscard_Sync) { | 557 TEST_F(FFmpegDemuxerTest, Read_AudioNegativeStartTimeAndOggDiscard_Sync) { |
| 531 // Many ogg files have negative starting timestamps, so ensure demuxing and | 558 // Many ogg files have negative starting timestamps, so ensure demuxing and |
| 532 // seeking work correctly with a negative start time. | 559 // seeking work correctly with a negative start time. |
| 533 CreateDemuxer("sync2.ogv"); | 560 CreateDemuxer("sync2.ogv"); |
| 534 InitializeDemuxer(); | 561 InitializeDemuxer(); |
| 535 | 562 |
| 536 // Attempt a read from the video stream and run the message loop until done. | 563 // Attempt a read from the video stream and run the message loop until done. |
| 537 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); | 564 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 538 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); | 565 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 539 | 566 |
| 540 // Run the test twice with a seek in between. | 567 // Run the test twice with a seek in between. |
| 541 for (int i = 0; i < 2; ++i) { | 568 for (int i = 0; i < 2; ++i) { |
| 542 audio->Read(NewReadCBWithCheckedDiscard( | 569 audio->Read(NewReadCBWithCheckedDiscard( |
| 543 FROM_HERE, 1, 0, base::TimeDelta::FromMicroseconds(2902))); | 570 FROM_HERE, 1, 0, base::TimeDelta::FromMicroseconds(2902), true)); |
| 544 message_loop_.Run(); | 571 message_loop_.Run(); |
| 545 | 572 |
| 546 audio->Read(NewReadCB(FROM_HERE, 1, 2902)); | 573 audio->Read(NewReadCB(FROM_HERE, 1, 2902, true)); |
| 547 message_loop_.Run(); | 574 message_loop_.Run(); |
| 548 EXPECT_EQ(base::TimeDelta::FromMicroseconds(-2902), | 575 EXPECT_EQ(base::TimeDelta::FromMicroseconds(-2902), |
| 549 demuxer_->start_time()); | 576 demuxer_->start_time()); |
| 550 | 577 |
| 551 // Though the internal start time may be below zero, the exposed media time | 578 // Though the internal start time may be below zero, the exposed media time |
| 552 // must always be greater than zero. | 579 // must always be greater than zero. |
| 553 EXPECT_EQ(base::TimeDelta(), demuxer_->GetStartTime()); | 580 EXPECT_EQ(base::TimeDelta(), demuxer_->GetStartTime()); |
| 554 | 581 |
| 555 video->Read(NewReadCB(FROM_HERE, 9997, 0)); | 582 video->Read(NewReadCB(FROM_HERE, 9997, 0, true)); |
| 556 message_loop_.Run(); | 583 message_loop_.Run(); |
| 557 | 584 |
| 558 video->Read(NewReadCB(FROM_HERE, 16, 33241)); | 585 video->Read(NewReadCB(FROM_HERE, 16, 33241, false)); |
| 559 message_loop_.Run(); | 586 message_loop_.Run(); |
| 560 | 587 |
| 561 video->Read(NewReadCB(FROM_HERE, 631, 66482)); | 588 video->Read(NewReadCB(FROM_HERE, 631, 66482, false)); |
| 562 message_loop_.Run(); | 589 message_loop_.Run(); |
| 563 | 590 |
| 564 // Seek back to the beginning and repeat the test. | 591 // Seek back to the beginning and repeat the test. |
| 565 WaitableMessageLoopEvent event; | 592 WaitableMessageLoopEvent event; |
| 566 demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB()); | 593 demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB()); |
| 567 event.RunAndWaitForStatus(PIPELINE_OK); | 594 event.RunAndWaitForStatus(PIPELINE_OK); |
| 568 } | 595 } |
| 569 } | 596 } |
| 570 | 597 |
| 571 TEST_F(FFmpegDemuxerTest, Read_EndOfStream) { | 598 TEST_F(FFmpegDemuxerTest, Read_EndOfStream) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 639 CreateDemuxer("bear-320x240.webm"); | 666 CreateDemuxer("bear-320x240.webm"); |
| 640 InitializeDemuxer(); | 667 InitializeDemuxer(); |
| 641 | 668 |
| 642 // Get our streams. | 669 // Get our streams. |
| 643 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); | 670 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 644 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); | 671 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 645 ASSERT_TRUE(video); | 672 ASSERT_TRUE(video); |
| 646 ASSERT_TRUE(audio); | 673 ASSERT_TRUE(audio); |
| 647 | 674 |
| 648 // Read a video packet and release it. | 675 // Read a video packet and release it. |
| 649 video->Read(NewReadCB(FROM_HERE, 22084, 0)); | 676 video->Read(NewReadCB(FROM_HERE, 22084, 0, true)); |
| 650 message_loop_.Run(); | 677 message_loop_.Run(); |
| 651 | 678 |
| 652 // Issue a simple forward seek, which should discard queued packets. | 679 // Issue a simple forward seek, which should discard queued packets. |
| 653 WaitableMessageLoopEvent event; | 680 WaitableMessageLoopEvent event; |
| 654 demuxer_->Seek(base::TimeDelta::FromMicroseconds(1000000), | 681 demuxer_->Seek(base::TimeDelta::FromMicroseconds(1000000), |
| 655 event.GetPipelineStatusCB()); | 682 event.GetPipelineStatusCB()); |
| 656 event.RunAndWaitForStatus(PIPELINE_OK); | 683 event.RunAndWaitForStatus(PIPELINE_OK); |
| 657 | 684 |
| 658 // Audio read #1. | 685 // Audio read #1. |
| 659 audio->Read(NewReadCB(FROM_HERE, 145, 803000)); | 686 audio->Read(NewReadCB(FROM_HERE, 145, 803000, true)); |
| 660 message_loop_.Run(); | 687 message_loop_.Run(); |
| 661 | 688 |
| 662 // Audio read #2. | 689 // Audio read #2. |
| 663 audio->Read(NewReadCB(FROM_HERE, 148, 826000)); | 690 audio->Read(NewReadCB(FROM_HERE, 148, 826000, true)); |
| 664 message_loop_.Run(); | 691 message_loop_.Run(); |
| 665 | 692 |
| 666 // Video read #1. | 693 // Video read #1. |
| 667 video->Read(NewReadCB(FROM_HERE, 5425, 801000)); | 694 video->Read(NewReadCB(FROM_HERE, 5425, 801000, true)); |
| 668 message_loop_.Run(); | 695 message_loop_.Run(); |
| 669 | 696 |
| 670 // Video read #2. | 697 // Video read #2. |
| 671 video->Read(NewReadCB(FROM_HERE, 1906, 834000)); | 698 video->Read(NewReadCB(FROM_HERE, 1906, 834000, false)); |
| 672 message_loop_.Run(); | 699 message_loop_.Run(); |
| 673 } | 700 } |
| 674 | 701 |
| 675 TEST_F(FFmpegDemuxerTest, SeekText) { | 702 TEST_F(FFmpegDemuxerTest, SeekText) { |
| 676 // We're testing that the demuxer frees all queued packets when it receives | 703 // We're testing that the demuxer frees all queued packets when it receives |
| 677 // a Seek(). | 704 // a Seek(). |
| 678 CreateDemuxer("bear-vp8-webvtt.webm"); | 705 CreateDemuxer("bear-vp8-webvtt.webm"); |
| 679 DemuxerStream* text_stream = NULL; | 706 DemuxerStream* text_stream = NULL; |
| 680 EXPECT_CALL(host_, AddTextStream(_, _)) | 707 EXPECT_CALL(host_, AddTextStream(_, _)) |
| 681 .WillOnce(SaveArg<0>(&text_stream)); | 708 .WillOnce(SaveArg<0>(&text_stream)); |
| 682 InitializeDemuxerText(true); | 709 InitializeDemuxerText(true); |
| 683 ASSERT_TRUE(text_stream); | 710 ASSERT_TRUE(text_stream); |
| 684 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); | 711 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); |
| 685 | 712 |
| 686 // Get our streams. | 713 // Get our streams. |
| 687 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); | 714 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 688 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); | 715 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 689 ASSERT_TRUE(video); | 716 ASSERT_TRUE(video); |
| 690 ASSERT_TRUE(audio); | 717 ASSERT_TRUE(audio); |
| 691 | 718 |
| 692 // Read a text packet and release it. | 719 // Read a text packet and release it. |
| 693 text_stream->Read(NewReadCB(FROM_HERE, 31, 0)); | 720 text_stream->Read(NewReadCB(FROM_HERE, 31, 0, true)); |
| 694 message_loop_.Run(); | 721 message_loop_.Run(); |
| 695 | 722 |
| 696 // Issue a simple forward seek, which should discard queued packets. | 723 // Issue a simple forward seek, which should discard queued packets. |
| 697 WaitableMessageLoopEvent event; | 724 WaitableMessageLoopEvent event; |
| 698 demuxer_->Seek(base::TimeDelta::FromMicroseconds(1000000), | 725 demuxer_->Seek(base::TimeDelta::FromMicroseconds(1000000), |
| 699 event.GetPipelineStatusCB()); | 726 event.GetPipelineStatusCB()); |
| 700 event.RunAndWaitForStatus(PIPELINE_OK); | 727 event.RunAndWaitForStatus(PIPELINE_OK); |
| 701 | 728 |
| 702 // Audio read #1. | 729 // Audio read #1. |
| 703 audio->Read(NewReadCB(FROM_HERE, 145, 803000)); | 730 audio->Read(NewReadCB(FROM_HERE, 145, 803000, true)); |
| 704 message_loop_.Run(); | 731 message_loop_.Run(); |
| 705 | 732 |
| 706 // Audio read #2. | 733 // Audio read #2. |
| 707 audio->Read(NewReadCB(FROM_HERE, 148, 826000)); | 734 audio->Read(NewReadCB(FROM_HERE, 148, 826000, true)); |
| 708 message_loop_.Run(); | 735 message_loop_.Run(); |
| 709 | 736 |
| 710 // Video read #1. | 737 // Video read #1. |
| 711 video->Read(NewReadCB(FROM_HERE, 5425, 801000)); | 738 video->Read(NewReadCB(FROM_HERE, 5425, 801000, true)); |
| 712 message_loop_.Run(); | 739 message_loop_.Run(); |
| 713 | 740 |
| 714 // Video read #2. | 741 // Video read #2. |
| 715 video->Read(NewReadCB(FROM_HERE, 1906, 834000)); | 742 video->Read(NewReadCB(FROM_HERE, 1906, 834000, false)); |
| 716 message_loop_.Run(); | 743 message_loop_.Run(); |
| 717 | 744 |
| 718 // Text read #1. | 745 // Text read #1. |
| 719 text_stream->Read(NewReadCB(FROM_HERE, 19, 500000)); | 746 text_stream->Read(NewReadCB(FROM_HERE, 19, 500000, true)); |
| 720 message_loop_.Run(); | 747 message_loop_.Run(); |
| 721 | 748 |
| 722 // Text read #2. | 749 // Text read #2. |
| 723 text_stream->Read(NewReadCB(FROM_HERE, 19, 1000000)); | 750 text_stream->Read(NewReadCB(FROM_HERE, 19, 1000000, true)); |
| 724 message_loop_.Run(); | 751 message_loop_.Run(); |
| 725 } | 752 } |
| 726 | 753 |
| 727 class MockReadCB { | 754 class MockReadCB { |
| 728 public: | 755 public: |
| 729 MockReadCB() {} | 756 MockReadCB() {} |
| 730 ~MockReadCB() {} | 757 ~MockReadCB() {} |
| 731 | 758 |
| 732 MOCK_METHOD2(Run, void(DemuxerStream::Status status, | 759 MOCK_METHOD2(Run, void(DemuxerStream::Status status, |
| 733 const scoped_refptr<DecoderBuffer>& buffer)); | 760 const scoped_refptr<DecoderBuffer>& buffer)); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 765 CreateDemuxer("bear-320x240-cues-in-front.webm"); | 792 CreateDemuxer("bear-320x240-cues-in-front.webm"); |
| 766 InitializeDemuxer(); | 793 InitializeDemuxer(); |
| 767 | 794 |
| 768 // Get our streams. | 795 // Get our streams. |
| 769 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); | 796 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 770 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); | 797 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 771 ASSERT_TRUE(video); | 798 ASSERT_TRUE(video); |
| 772 ASSERT_TRUE(audio); | 799 ASSERT_TRUE(audio); |
| 773 | 800 |
| 774 // Read a video packet and release it. | 801 // Read a video packet and release it. |
| 775 video->Read(NewReadCB(FROM_HERE, 22084, 0)); | 802 video->Read(NewReadCB(FROM_HERE, 22084, 0, true)); |
| 776 message_loop_.Run(); | 803 message_loop_.Run(); |
| 777 | 804 |
| 778 // Issue a simple forward seek, which should discard queued packets. | 805 // Issue a simple forward seek, which should discard queued packets. |
| 779 WaitableMessageLoopEvent event; | 806 WaitableMessageLoopEvent event; |
| 780 demuxer_->Seek(base::TimeDelta::FromMicroseconds(2500000), | 807 demuxer_->Seek(base::TimeDelta::FromMicroseconds(2500000), |
| 781 event.GetPipelineStatusCB()); | 808 event.GetPipelineStatusCB()); |
| 782 event.RunAndWaitForStatus(PIPELINE_OK); | 809 event.RunAndWaitForStatus(PIPELINE_OK); |
| 783 | 810 |
| 784 // Audio read #1. | 811 // Audio read #1. |
| 785 audio->Read(NewReadCB(FROM_HERE, 40, 2403000)); | 812 audio->Read(NewReadCB(FROM_HERE, 40, 2403000, true)); |
| 786 message_loop_.Run(); | 813 message_loop_.Run(); |
| 787 | 814 |
| 788 // Audio read #2. | 815 // Audio read #2. |
| 789 audio->Read(NewReadCB(FROM_HERE, 42, 2406000)); | 816 audio->Read(NewReadCB(FROM_HERE, 42, 2406000, true)); |
| 790 message_loop_.Run(); | 817 message_loop_.Run(); |
| 791 | 818 |
| 792 // Video read #1. | 819 // Video read #1. |
| 793 video->Read(NewReadCB(FROM_HERE, 5276, 2402000)); | 820 video->Read(NewReadCB(FROM_HERE, 5276, 2402000, true)); |
| 794 message_loop_.Run(); | 821 message_loop_.Run(); |
| 795 | 822 |
| 796 // Video read #2. | 823 // Video read #2. |
| 797 video->Read(NewReadCB(FROM_HERE, 1740, 2436000)); | 824 video->Read(NewReadCB(FROM_HERE, 1740, 2436000, false)); |
| 798 message_loop_.Run(); | 825 message_loop_.Run(); |
| 799 } | 826 } |
| 800 | 827 |
| 801 #if defined(USE_PROPRIETARY_CODECS) | 828 #if defined(USE_PROPRIETARY_CODECS) |
| 802 // Ensure ID3v1 tag reading is disabled. id3_test.mp3 has an ID3v1 tag with the | 829 // Ensure ID3v1 tag reading is disabled. id3_test.mp3 has an ID3v1 tag with the |
| 803 // field "title" set to "sample for id3 test". | 830 // field "title" set to "sample for id3 test". |
| 804 TEST_F(FFmpegDemuxerTest, NoID3TagData) { | 831 TEST_F(FFmpegDemuxerTest, NoID3TagData) { |
| 805 CreateDemuxer("id3_test.mp3"); | 832 CreateDemuxer("id3_test.mp3"); |
| 806 InitializeDemuxer(); | 833 InitializeDemuxer(); |
| 807 EXPECT_FALSE(av_dict_get(format_context()->metadata, "title", NULL, 0)); | 834 EXPECT_FALSE(av_dict_get(format_context()->metadata, "title", NULL, 0)); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 942 InitializeDemuxer(); | 969 InitializeDemuxer(); |
| 943 | 970 |
| 944 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 971 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 945 ASSERT_TRUE(stream); | 972 ASSERT_TRUE(stream); |
| 946 ASSERT_EQ(VIDEO_ROTATION_270, stream->video_rotation()); | 973 ASSERT_EQ(VIDEO_ROTATION_270, stream->video_rotation()); |
| 947 } | 974 } |
| 948 | 975 |
| 949 #endif | 976 #endif |
| 950 | 977 |
| 951 } // namespace media | 978 } // namespace media |
| OLD | NEW |