summaryrefslogtreecommitdiff
path: root/chromium/media/renderers/video_renderer_impl_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/media/renderers/video_renderer_impl_unittest.cc')
-rw-r--r--chromium/media/renderers/video_renderer_impl_unittest.cc182
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], &timestamp_in_ms)) {
+ if (base::StringToInt(token, &timestamp_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