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