| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 <stdint.h> | 5 #include <stdint.h> |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 | 44 |
| 45 namespace media { | 45 namespace media { |
| 46 | 46 |
| 47 MATCHER_P(HasTimestampMatcher, ms, "") { | 47 MATCHER_P(HasTimestampMatcher, ms, "") { |
| 48 *result_listener << "has timestamp " << arg->timestamp().InMilliseconds(); | 48 *result_listener << "has timestamp " << arg->timestamp().InMilliseconds(); |
| 49 return arg->timestamp().InMilliseconds() == ms; | 49 return arg->timestamp().InMilliseconds() == ms; |
| 50 } | 50 } |
| 51 | 51 |
| 52 class VideoRendererImplTest : public testing::Test { | 52 class VideoRendererImplTest : public testing::Test { |
| 53 public: | 53 public: |
| 54 ScopedVector<VideoDecoder> CreateVideoDecodersForTest() { |
| 55 decoder_ = new NiceMock<MockVideoDecoder>(); |
| 56 ScopedVector<VideoDecoder> decoders; |
| 57 decoders.push_back(decoder_); |
| 58 EXPECT_CALL(*decoder_, Initialize(_, _, _, _, _)) |
| 59 .WillOnce(DoAll(SaveArg<4>(&output_cb_), |
| 60 RunCallback<3>(expect_init_success_))); |
| 61 // Monitor decodes from the decoder. |
| 62 ON_CALL(*decoder_, Decode(_, _)) |
| 63 .WillByDefault(Invoke(this, &VideoRendererImplTest::DecodeRequested)); |
| 64 ON_CALL(*decoder_, Reset(_)) |
| 65 .WillByDefault(Invoke(this, &VideoRendererImplTest::FlushRequested)); |
| 66 return decoders; |
| 67 } |
| 68 |
| 54 VideoRendererImplTest() | 69 VideoRendererImplTest() |
| 55 : tick_clock_(new base::SimpleTestTickClock()), | 70 : tick_clock_(new base::SimpleTestTickClock()), |
| 56 decoder_(new NiceMock<MockVideoDecoder>()), | 71 decoder_(nullptr), |
| 57 demuxer_stream_(DemuxerStream::VIDEO) { | 72 demuxer_stream_(DemuxerStream::VIDEO) { |
| 58 ScopedVector<VideoDecoder> decoders; | |
| 59 decoders.push_back(decoder_); | |
| 60 | |
| 61 null_video_sink_.reset(new NullVideoSink( | 73 null_video_sink_.reset(new NullVideoSink( |
| 62 false, base::TimeDelta::FromSecondsD(1.0 / 60), | 74 false, base::TimeDelta::FromSecondsD(1.0 / 60), |
| 63 base::Bind(&MockCB::FrameReceived, base::Unretained(&mock_cb_)), | 75 base::Bind(&MockCB::FrameReceived, base::Unretained(&mock_cb_)), |
| 64 message_loop_.task_runner())); | 76 message_loop_.task_runner())); |
| 65 | 77 |
| 66 renderer_.reset(new VideoRendererImpl( | 78 renderer_.reset(new VideoRendererImpl( |
| 67 message_loop_.task_runner(), message_loop_.task_runner().get(), | 79 message_loop_.task_runner(), message_loop_.task_runner().get(), |
| 68 null_video_sink_.get(), std::move(decoders), true, | 80 null_video_sink_.get(), |
| 81 base::Bind(&VideoRendererImplTest::CreateVideoDecodersForTest, |
| 82 base::Unretained(this)), |
| 83 true, |
| 69 nullptr, // gpu_factories | 84 nullptr, // gpu_factories |
| 70 new MediaLog())); | 85 new MediaLog())); |
| 71 renderer_->SetTickClockForTesting( | 86 renderer_->SetTickClockForTesting( |
| 72 std::unique_ptr<base::TickClock>(tick_clock_)); | 87 std::unique_ptr<base::TickClock>(tick_clock_)); |
| 73 null_video_sink_->set_tick_clock_for_testing(tick_clock_); | 88 null_video_sink_->set_tick_clock_for_testing(tick_clock_); |
| 74 time_source_.set_tick_clock_for_testing(tick_clock_); | 89 time_source_.set_tick_clock_for_testing(tick_clock_); |
| 75 | 90 |
| 76 // Start wallclock time at a non-zero value. | 91 // Start wallclock time at a non-zero value. |
| 77 AdvanceWallclockTimeInMs(12345); | 92 AdvanceWallclockTimeInMs(12345); |
| 78 | 93 |
| 79 demuxer_stream_.set_video_decoder_config(TestVideoConfig::Normal()); | 94 demuxer_stream_.set_video_decoder_config(TestVideoConfig::Normal()); |
| 80 | 95 |
| 81 // We expect these to be called but we don't care how/when. | 96 // We expect these to be called but we don't care how/when. |
| 82 EXPECT_CALL(demuxer_stream_, Read(_)).WillRepeatedly( | 97 EXPECT_CALL(demuxer_stream_, Read(_)).WillRepeatedly( |
| 83 RunCallback<0>(DemuxerStream::kOk, | 98 RunCallback<0>(DemuxerStream::kOk, |
| 84 scoped_refptr<DecoderBuffer>(new DecoderBuffer(0)))); | 99 scoped_refptr<DecoderBuffer>(new DecoderBuffer(0)))); |
| 85 } | 100 } |
| 86 | 101 |
| 87 virtual ~VideoRendererImplTest() {} | 102 virtual ~VideoRendererImplTest() {} |
| 88 | 103 |
| 89 void Initialize() { | 104 void Initialize() { |
| 90 InitializeWithLowDelay(false); | 105 InitializeWithLowDelay(false); |
| 91 } | 106 } |
| 92 | 107 |
| 93 void InitializeWithLowDelay(bool low_delay) { | 108 void InitializeWithLowDelay(bool low_delay) { |
| 94 // Monitor decodes from the decoder. | |
| 95 ON_CALL(*decoder_, Decode(_, _)) | |
| 96 .WillByDefault(Invoke(this, &VideoRendererImplTest::DecodeRequested)); | |
| 97 ON_CALL(*decoder_, Reset(_)) | |
| 98 .WillByDefault(Invoke(this, &VideoRendererImplTest::FlushRequested)); | |
| 99 | |
| 100 // Initialize, we shouldn't have any reads. | 109 // Initialize, we shouldn't have any reads. |
| 101 InitializeRenderer(low_delay, true); | 110 InitializeRenderer(&demuxer_stream_, low_delay, true); |
| 102 } | 111 } |
| 103 | 112 |
| 104 void InitializeRenderer(bool low_delay, bool expect_success) { | 113 void InitializeRenderer(MockDemuxerStream* demuxer_stream, |
| 114 bool low_delay, |
| 115 bool expect_success) { |
| 105 SCOPED_TRACE(base::StringPrintf("InitializeRenderer(%d)", expect_success)); | 116 SCOPED_TRACE(base::StringPrintf("InitializeRenderer(%d)", expect_success)); |
| 117 expect_init_success_ = expect_success; |
| 106 WaitableMessageLoopEvent event; | 118 WaitableMessageLoopEvent event; |
| 107 CallInitialize(event.GetPipelineStatusCB(), low_delay, expect_success); | 119 CallInitialize(demuxer_stream, event.GetPipelineStatusCB(), low_delay, |
| 120 expect_success); |
| 108 event.RunAndWaitForStatus(expect_success ? PIPELINE_OK | 121 event.RunAndWaitForStatus(expect_success ? PIPELINE_OK |
| 109 : DECODER_ERROR_NOT_SUPPORTED); | 122 : DECODER_ERROR_NOT_SUPPORTED); |
| 110 } | 123 } |
| 111 | 124 |
| 112 void CallInitialize(const PipelineStatusCB& status_cb, | 125 void CallInitialize(MockDemuxerStream* demuxer_stream, |
| 126 const PipelineStatusCB& status_cb, |
| 113 bool low_delay, | 127 bool low_delay, |
| 114 bool expect_success) { | 128 bool expect_success) { |
| 115 if (low_delay) | 129 if (low_delay) |
| 116 demuxer_stream_.set_liveness(DemuxerStream::LIVENESS_LIVE); | 130 demuxer_stream->set_liveness(DemuxerStream::LIVENESS_LIVE); |
| 117 EXPECT_CALL(*decoder_, Initialize(_, _, _, _, _)) | |
| 118 .WillOnce( | |
| 119 DoAll(SaveArg<4>(&output_cb_), RunCallback<3>(expect_success))); | |
| 120 EXPECT_CALL(mock_cb_, OnWaitingForDecryptionKey()).Times(0); | 131 EXPECT_CALL(mock_cb_, OnWaitingForDecryptionKey()).Times(0); |
| 121 renderer_->Initialize(&demuxer_stream_, nullptr, &mock_cb_, | 132 renderer_->Initialize(demuxer_stream, nullptr, &mock_cb_, |
| 122 base::Bind(&WallClockTimeSource::GetWallClockTimes, | 133 base::Bind(&WallClockTimeSource::GetWallClockTimes, |
| 123 base::Unretained(&time_source_)), | 134 base::Unretained(&time_source_)), |
| 124 status_cb); | 135 status_cb); |
| 125 } | 136 } |
| 126 | 137 |
| 127 void StartPlayingFrom(int milliseconds) { | 138 void StartPlayingFrom(int milliseconds) { |
| 128 SCOPED_TRACE(base::StringPrintf("StartPlayingFrom(%d)", milliseconds)); | 139 SCOPED_TRACE(base::StringPrintf("StartPlayingFrom(%d)", milliseconds)); |
| 129 const base::TimeDelta media_time = | 140 const base::TimeDelta media_time = |
| 130 base::TimeDelta::FromMilliseconds(milliseconds); | 141 base::TimeDelta::FromMilliseconds(milliseconds); |
| 131 time_source_.SetMediaTime(media_time); | 142 time_source_.SetMediaTime(media_time); |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 Destroy(); | 436 Destroy(); |
| 426 } | 437 } |
| 427 | 438 |
| 428 protected: | 439 protected: |
| 429 // Fixture members. | 440 // Fixture members. |
| 430 std::unique_ptr<VideoRendererImpl> renderer_; | 441 std::unique_ptr<VideoRendererImpl> renderer_; |
| 431 base::SimpleTestTickClock* tick_clock_; // Owned by |renderer_|. | 442 base::SimpleTestTickClock* tick_clock_; // Owned by |renderer_|. |
| 432 NiceMock<MockVideoDecoder>* decoder_; // Owned by |renderer_|. | 443 NiceMock<MockVideoDecoder>* decoder_; // Owned by |renderer_|. |
| 433 NiceMock<MockDemuxerStream> demuxer_stream_; | 444 NiceMock<MockDemuxerStream> demuxer_stream_; |
| 434 | 445 |
| 446 bool expect_init_success_; |
| 447 |
| 435 // Use StrictMock<T> to catch missing/extra callbacks. | 448 // Use StrictMock<T> to catch missing/extra callbacks. |
| 436 class MockCB : public MockRendererClient { | 449 class MockCB : public MockRendererClient { |
| 437 public: | 450 public: |
| 438 MOCK_METHOD1(FrameReceived, void(const scoped_refptr<VideoFrame>&)); | 451 MOCK_METHOD1(FrameReceived, void(const scoped_refptr<VideoFrame>&)); |
| 439 }; | 452 }; |
| 440 StrictMock<MockCB> mock_cb_; | 453 StrictMock<MockCB> mock_cb_; |
| 441 | 454 |
| 442 // Must be destroyed before |renderer_| since they share |tick_clock_|. | 455 // Must be destroyed before |renderer_| since they share |tick_clock_|. |
| 443 std::unique_ptr<NullVideoSink> null_video_sink_; | 456 std::unique_ptr<NullVideoSink> null_video_sink_; |
| 444 | 457 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 EXPECT_CALL(mock_cb_, OnEnded()); | 543 EXPECT_CALL(mock_cb_, OnEnded()); |
| 531 SatisfyPendingDecodeWithEndOfStream(); | 544 SatisfyPendingDecodeWithEndOfStream(); |
| 532 event.RunAndWait(); | 545 event.RunAndWait(); |
| 533 } | 546 } |
| 534 // Firing a time state changed to true should be ignored... | 547 // Firing a time state changed to true should be ignored... |
| 535 renderer_->OnTimeProgressing(); | 548 renderer_->OnTimeProgressing(); |
| 536 EXPECT_FALSE(null_video_sink_->is_started()); | 549 EXPECT_FALSE(null_video_sink_->is_started()); |
| 537 Destroy(); | 550 Destroy(); |
| 538 } | 551 } |
| 539 | 552 |
| 553 TEST_F(VideoRendererImplTest, ReinitializeForAnotherStream) { |
| 554 Initialize(); |
| 555 StartPlayingFrom(0); |
| 556 Flush(); |
| 557 NiceMock<MockDemuxerStream> new_stream(DemuxerStream::VIDEO); |
| 558 new_stream.set_video_decoder_config(TestVideoConfig::Normal()); |
| 559 InitializeRenderer(&new_stream, false, true); |
| 560 } |
| 561 |
| 540 TEST_F(VideoRendererImplTest, DestroyWhileInitializing) { | 562 TEST_F(VideoRendererImplTest, DestroyWhileInitializing) { |
| 541 CallInitialize(NewExpectedStatusCB(PIPELINE_ERROR_ABORT), false, PIPELINE_OK); | 563 CallInitialize(&demuxer_stream_, NewExpectedStatusCB(PIPELINE_ERROR_ABORT), |
| 564 false, PIPELINE_OK); |
| 542 Destroy(); | 565 Destroy(); |
| 543 } | 566 } |
| 544 | 567 |
| 545 TEST_F(VideoRendererImplTest, DestroyWhileFlushing) { | 568 TEST_F(VideoRendererImplTest, DestroyWhileFlushing) { |
| 546 Initialize(); | 569 Initialize(); |
| 547 QueueFrames("0 10 20 30"); | 570 QueueFrames("0 10 20 30"); |
| 548 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0))); | 571 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0))); |
| 549 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); | 572 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
| 550 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber()); | 573 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber()); |
| 551 EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1); | 574 EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1); | 741 EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1); |
| 719 StartPlayingFrom(0); | 742 StartPlayingFrom(0); |
| 720 | 743 |
| 721 // Check that there is an outstanding Read() request. | 744 // Check that there is an outstanding Read() request. |
| 722 EXPECT_TRUE(IsReadPending()); | 745 EXPECT_TRUE(IsReadPending()); |
| 723 | 746 |
| 724 Destroy(); | 747 Destroy(); |
| 725 } | 748 } |
| 726 | 749 |
| 727 TEST_F(VideoRendererImplTest, VideoDecoder_InitFailure) { | 750 TEST_F(VideoRendererImplTest, VideoDecoder_InitFailure) { |
| 728 InitializeRenderer(false, false); | 751 InitializeRenderer(&demuxer_stream_, false, false); |
| 729 Destroy(); | 752 Destroy(); |
| 730 } | 753 } |
| 731 | 754 |
| 732 TEST_F(VideoRendererImplTest, Underflow) { | 755 TEST_F(VideoRendererImplTest, Underflow) { |
| 733 BasicUnderflowTest(UnderflowTestType::NORMAL); | 756 BasicUnderflowTest(UnderflowTestType::NORMAL); |
| 734 } | 757 } |
| 735 | 758 |
| 736 TEST_F(VideoRendererImplTest, Underflow_LowDelay) { | 759 TEST_F(VideoRendererImplTest, Underflow_LowDelay) { |
| 737 BasicUnderflowTest(UnderflowTestType::LOW_DELAY); | 760 BasicUnderflowTest(UnderflowTestType::LOW_DELAY); |
| 738 } | 761 } |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1185 QueueFrames("0 10 20 30"); | 1208 QueueFrames("0 10 20 30"); |
| 1186 StartPlayingFrom(0); | 1209 StartPlayingFrom(0); |
| 1187 Flush(); | 1210 Flush(); |
| 1188 ASSERT_EQ(1u, frame_ready_cbs_.size()); | 1211 ASSERT_EQ(1u, frame_ready_cbs_.size()); |
| 1189 // This frame will be discarded. | 1212 // This frame will be discarded. |
| 1190 frame_ready_cbs_.front().Run(); | 1213 frame_ready_cbs_.front().Run(); |
| 1191 Destroy(); | 1214 Destroy(); |
| 1192 } | 1215 } |
| 1193 | 1216 |
| 1194 } // namespace media | 1217 } // namespace media |
| OLD | NEW |