diff options
Diffstat (limited to 'chromium/media/renderers/video_renderer_impl_unittest.cc')
-rw-r--r-- | chromium/media/renderers/video_renderer_impl_unittest.cc | 182 |
1 files changed, 108 insertions, 74 deletions
diff --git a/chromium/media/renderers/video_renderer_impl_unittest.cc b/chromium/media/renderers/video_renderer_impl_unittest.cc index 6786e64323c..e7a09efb984 100644 --- a/chromium/media/renderers/video_renderer_impl_unittest.cc +++ b/chromium/media/renderers/video_renderer_impl_unittest.cc @@ -47,7 +47,7 @@ MATCHER_P(HasTimestamp, ms, "") { } class VideoRendererImplTest - : public testing::TestWithParam<bool /* new_video_renderer */> { + : public testing::Test { public: VideoRendererImplTest() : tick_clock_(new base::SimpleTestTickClock()), @@ -61,13 +61,11 @@ class VideoRendererImplTest base::Bind(&MockCB::FrameReceived, base::Unretained(&mock_cb_)), message_loop_.task_runner())); - renderer_.reset(new VideoRendererImpl(message_loop_.task_runner(), - null_video_sink_.get(), - decoders.Pass(), true, - nullptr, // gpu_factories - new MediaLog())); - if (!GetParam()) - renderer_->disable_new_video_renderer_for_testing(); + renderer_.reset(new VideoRendererImpl( + message_loop_.task_runner(), message_loop_.task_runner().get(), + null_video_sink_.get(), decoders.Pass(), true, + nullptr, // gpu_factories + new MediaLog())); renderer_->SetTickClockForTesting(scoped_ptr<base::TickClock>(tick_clock_)); null_video_sink_->set_tick_clock_for_testing(tick_clock_); time_source_.set_tick_clock_for_testing(tick_clock_); @@ -166,17 +164,17 @@ class VideoRendererImplTest // A clip that is four frames long: "0 10 20 30" // A clip that has a decode error: "60 70 error" void QueueFrames(const std::string& str) { - std::vector<std::string> tokens; - base::SplitString(str, ' ', &tokens); - for (size_t i = 0; i < tokens.size(); ++i) { - if (tokens[i] == "abort") { + for (const std::string& token : + base::SplitString(str, " ", base::TRIM_WHITESPACE, + base::SPLIT_WANT_ALL)) { + if (token == "abort") { scoped_refptr<VideoFrame> null_frame; decode_results_.push_back( std::make_pair(VideoDecoder::kAborted, null_frame)); continue; } - if (tokens[i] == "error") { + if (token == "error") { scoped_refptr<VideoFrame> null_frame; decode_results_.push_back( std::make_pair(VideoDecoder::kDecodeError, null_frame)); @@ -184,19 +182,16 @@ class VideoRendererImplTest } int timestamp_in_ms = 0; - if (base::StringToInt(tokens[i], ×tamp_in_ms)) { + if (base::StringToInt(token, ×tamp_in_ms)) { gfx::Size natural_size = TestVideoConfig::NormalCodedSize(); scoped_refptr<VideoFrame> frame = VideoFrame::CreateFrame( - VideoFrame::YV12, - natural_size, - gfx::Rect(natural_size), - natural_size, - base::TimeDelta::FromMilliseconds(timestamp_in_ms)); + PIXEL_FORMAT_YV12, natural_size, gfx::Rect(natural_size), + natural_size, base::TimeDelta::FromMilliseconds(timestamp_in_ms)); decode_results_.push_back(std::make_pair(VideoDecoder::kOk, frame)); continue; } - CHECK(false) << "Unrecognized decoder buffer token: " << tokens[i]; + CHECK(false) << "Unrecognized decoder buffer token: " << token; } } @@ -304,6 +299,8 @@ class VideoRendererImplTest WallClockTimeSource time_source_; + base::MessageLoop message_loop_; + private: void DecodeRequested(const scoped_refptr<DecoderBuffer>& buffer, const VideoDecoder::DecodeCB& decode_cb) { @@ -338,8 +335,6 @@ class VideoRendererImplTest MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); - base::MessageLoop message_loop_; - // Used to protect |time_|. base::Lock lock_; base::TimeDelta time_; @@ -361,21 +356,21 @@ class VideoRendererImplTest DISALLOW_COPY_AND_ASSIGN(VideoRendererImplTest); }; -TEST_P(VideoRendererImplTest, DoNothing) { +TEST_F(VideoRendererImplTest, DoNothing) { // Test that creation and deletion doesn't depend on calls to Initialize() // and/or Destroy(). } -TEST_P(VideoRendererImplTest, DestroyWithoutInitialize) { +TEST_F(VideoRendererImplTest, DestroyWithoutInitialize) { Destroy(); } -TEST_P(VideoRendererImplTest, Initialize) { +TEST_F(VideoRendererImplTest, Initialize) { Initialize(); Destroy(); } -TEST_P(VideoRendererImplTest, InitializeAndStartPlayingFrom) { +TEST_F(VideoRendererImplTest, InitializeAndStartPlayingFrom) { Initialize(); QueueFrames("0 10 20 30"); EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); @@ -384,7 +379,7 @@ TEST_P(VideoRendererImplTest, InitializeAndStartPlayingFrom) { Destroy(); } -TEST_P(VideoRendererImplTest, InitializeAndEndOfStream) { +TEST_F(VideoRendererImplTest, InitializeAndEndOfStream) { Initialize(); StartPlayingFrom(0); WaitForPendingRead(); @@ -402,12 +397,12 @@ TEST_P(VideoRendererImplTest, InitializeAndEndOfStream) { Destroy(); } -TEST_P(VideoRendererImplTest, DestroyWhileInitializing) { +TEST_F(VideoRendererImplTest, DestroyWhileInitializing) { CallInitialize(NewExpectedStatusCB(PIPELINE_ERROR_ABORT), false, PIPELINE_OK); Destroy(); } -TEST_P(VideoRendererImplTest, DestroyWhileFlushing) { +TEST_F(VideoRendererImplTest, DestroyWhileFlushing) { Initialize(); QueueFrames("0 10 20 30"); EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); @@ -418,7 +413,7 @@ TEST_P(VideoRendererImplTest, DestroyWhileFlushing) { Destroy(); } -TEST_P(VideoRendererImplTest, Play) { +TEST_F(VideoRendererImplTest, Play) { Initialize(); QueueFrames("0 10 20 30"); EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); @@ -427,7 +422,7 @@ TEST_P(VideoRendererImplTest, Play) { Destroy(); } -TEST_P(VideoRendererImplTest, FlushWithNothingBuffered) { +TEST_F(VideoRendererImplTest, FlushWithNothingBuffered) { Initialize(); StartPlayingFrom(0); @@ -437,11 +432,18 @@ TEST_P(VideoRendererImplTest, FlushWithNothingBuffered) { Destroy(); } -TEST_P(VideoRendererImplTest, DecodeError_Playing) { +TEST_F(VideoRendererImplTest, DecodeError_Playing) { Initialize(); QueueFrames("0 10 20 30"); EXPECT_CALL(mock_cb_, FrameReceived(_)).Times(testing::AtLeast(1)); + + // Consider the case that rendering is faster than we setup the test event. + // In that case, when we run out of the frames, BUFFERING_HAVE_NOTHING will + // be called. EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); + EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_NOTHING)) + .Times(testing::AtMost(1)); + StartPlayingFrom(0); renderer_->OnTimeStateChanged(true); time_source_.StartTicking(); @@ -453,14 +455,14 @@ TEST_P(VideoRendererImplTest, DecodeError_Playing) { Destroy(); } -TEST_P(VideoRendererImplTest, DecodeError_DuringStartPlayingFrom) { +TEST_F(VideoRendererImplTest, DecodeError_DuringStartPlayingFrom) { Initialize(); QueueFrames("error"); StartPlayingFrom(0); Destroy(); } -TEST_P(VideoRendererImplTest, StartPlayingFrom_Exact) { +TEST_F(VideoRendererImplTest, StartPlayingFrom_Exact) { Initialize(); QueueFrames("50 60 70 80 90"); @@ -470,7 +472,7 @@ TEST_P(VideoRendererImplTest, StartPlayingFrom_Exact) { Destroy(); } -TEST_P(VideoRendererImplTest, StartPlayingFrom_RightBefore) { +TEST_F(VideoRendererImplTest, StartPlayingFrom_RightBefore) { Initialize(); QueueFrames("50 60 70 80 90"); @@ -480,7 +482,7 @@ TEST_P(VideoRendererImplTest, StartPlayingFrom_RightBefore) { Destroy(); } -TEST_P(VideoRendererImplTest, StartPlayingFrom_RightAfter) { +TEST_F(VideoRendererImplTest, StartPlayingFrom_RightAfter) { Initialize(); QueueFrames("50 60 70 80 90"); @@ -490,7 +492,7 @@ TEST_P(VideoRendererImplTest, StartPlayingFrom_RightAfter) { Destroy(); } -TEST_P(VideoRendererImplTest, StartPlayingFrom_LowDelay) { +TEST_F(VideoRendererImplTest, StartPlayingFrom_LowDelay) { // In low-delay mode only one frame is required to finish preroll. But frames // prior to the start time will not be used. InitializeWithLowDelay(true); @@ -520,7 +522,7 @@ TEST_P(VideoRendererImplTest, StartPlayingFrom_LowDelay) { } // Verify that a late decoder response doesn't break invariants in the renderer. -TEST_P(VideoRendererImplTest, DestroyDuringOutstandingRead) { +TEST_F(VideoRendererImplTest, DestroyDuringOutstandingRead) { Initialize(); QueueFrames("0 10 20 30"); EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); @@ -533,12 +535,12 @@ TEST_P(VideoRendererImplTest, DestroyDuringOutstandingRead) { Destroy(); } -TEST_P(VideoRendererImplTest, VideoDecoder_InitFailure) { +TEST_F(VideoRendererImplTest, VideoDecoder_InitFailure) { InitializeRenderer(false, false); Destroy(); } -TEST_P(VideoRendererImplTest, Underflow) { +TEST_F(VideoRendererImplTest, Underflow) { Initialize(); QueueFrames("0 30 60 90"); @@ -564,10 +566,7 @@ TEST_P(VideoRendererImplTest, Underflow) { // start rendering frames on its own thread, so the first frame may be // received. time_source_.StartTicking(); - if (GetParam()) - EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(30))).Times(0); - else - EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(30))).Times(AnyNumber()); + EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(30))).Times(0); EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(60))).Times(0); EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(90))) @@ -586,10 +585,6 @@ TEST_P(VideoRendererImplTest, Underflow) { EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_NOTHING)) .WillOnce(RunClosure(event.GetClosure())); AdvanceTimeInMs(30); - // The old rendering path needs wall clock time to increase too. - if (!GetParam()) - AdvanceWallclockTimeInMs(30); - event.RunAndWait(); Mock::VerifyAndClearExpectations(&mock_cb_); } @@ -610,11 +605,7 @@ TEST_P(VideoRendererImplTest, Underflow) { // Verifies that the sink is stopped after rendering the first frame if // playback hasn't started. -TEST_P(VideoRendererImplTest, RenderingStopsAfterFirstFrame) { - // This test is only for the new rendering path. - if (!GetParam()) - return; - +TEST_F(VideoRendererImplTest, RenderingStopsAfterFirstFrame) { InitializeWithLowDelay(true); QueueFrames("0"); @@ -641,11 +632,7 @@ TEST_P(VideoRendererImplTest, RenderingStopsAfterFirstFrame) { // Verifies that the sink is stopped after rendering the first frame if // playback ha started. -TEST_P(VideoRendererImplTest, RenderingStopsAfterOneFrameWithEOS) { - // This test is only for the new rendering path. - if (!GetParam()) - return; - +TEST_F(VideoRendererImplTest, RenderingStopsAfterOneFrameWithEOS) { InitializeWithLowDelay(true); QueueFrames("0"); @@ -673,11 +660,7 @@ TEST_P(VideoRendererImplTest, RenderingStopsAfterOneFrameWithEOS) { // Tests the case where the video started and received a single Render() call, // then the video was put into the background. -TEST_P(VideoRendererImplTest, RenderingStartedThenStopped) { - // This test is only for the new rendering path. - if (!GetParam()) - return; - +TEST_F(VideoRendererImplTest, RenderingStartedThenStopped) { Initialize(); QueueFrames("0 30 60 90"); @@ -695,6 +678,14 @@ TEST_P(VideoRendererImplTest, RenderingStartedThenStopped) { EXPECT_EQ(0u, last_pipeline_statistics_.video_frames_dropped); } + // Consider the case that rendering is faster than we setup the test event. + // In that case, when we run out of the frames, BUFFERING_HAVE_NOTHING will + // be called. And then during SatisfyPendingReadWithEndOfStream, + // BUFFER_HAVE_ENOUGH will be called again. + EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)) + .Times(testing::AtMost(1)); + EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_NOTHING)) + .Times(testing::AtMost(1)); renderer_->OnTimeStateChanged(true); time_source_.StartTicking(); @@ -718,11 +709,7 @@ TEST_P(VideoRendererImplTest, RenderingStartedThenStopped) { Destroy(); } -TEST_P(VideoRendererImplTest, StartPlayingFromThenFlushThenEOS) { - // This test is only for the new rendering path. - if (!GetParam()) - return; - +TEST_F(VideoRendererImplTest, StartPlayingFromThenFlushThenEOS) { Initialize(); QueueFrames("0 30 60 90"); @@ -750,11 +737,58 @@ TEST_P(VideoRendererImplTest, StartPlayingFromThenFlushThenEOS) { Destroy(); } -INSTANTIATE_TEST_CASE_P(OldVideoRenderer, - VideoRendererImplTest, - testing::Values(false)); -INSTANTIATE_TEST_CASE_P(NewVideoRenderer, - VideoRendererImplTest, - testing::Values(true)); +namespace { +class MockGpuMemoryBufferVideoFramePool : public GpuMemoryBufferVideoFramePool { + public: + MockGpuMemoryBufferVideoFramePool(std::vector<base::Closure>* frame_ready_cbs) + : frame_ready_cbs_(frame_ready_cbs) {} + void MaybeCreateHardwareFrame(const scoped_refptr<VideoFrame>& video_frame, + const FrameReadyCB& frame_ready_cb) override { + frame_ready_cbs_->push_back(base::Bind(frame_ready_cb, video_frame)); + } + + private: + std::vector<base::Closure>* frame_ready_cbs_; +}; +} + +class VideoRendererImplAsyncAddFrameReadyTest : public VideoRendererImplTest { + public: + VideoRendererImplAsyncAddFrameReadyTest() { + scoped_ptr<GpuMemoryBufferVideoFramePool> gpu_memory_buffer_pool( + new MockGpuMemoryBufferVideoFramePool(&frame_ready_cbs_)); + renderer_->SetGpuMemoryBufferVideoForTesting(gpu_memory_buffer_pool.Pass()); + } + + protected: + std::vector<base::Closure> frame_ready_cbs_; +}; + +TEST_F(VideoRendererImplAsyncAddFrameReadyTest, InitializeAndStartPlayingFrom) { + Initialize(); + QueueFrames("0 10 20 30"); + EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); + EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); + StartPlayingFrom(0); + ASSERT_EQ(1u, frame_ready_cbs_.size()); + + uint32_t frame_ready_index = 0; + while (frame_ready_index < frame_ready_cbs_.size()) { + frame_ready_cbs_[frame_ready_index++].Run(); + message_loop_.RunUntilIdle(); + } + Destroy(); +} + +TEST_F(VideoRendererImplAsyncAddFrameReadyTest, SequenceTokenDiscardOneFrame) { + Initialize(); + QueueFrames("0 10 20 30"); + StartPlayingFrom(0); + Flush(); + ASSERT_EQ(1u, frame_ready_cbs_.size()); + // This frame will be discarded. + frame_ready_cbs_.front().Run(); + Destroy(); +} } // namespace media |