Index: media/filters/ffmpeg_video_decoder_unittest.cc |
diff --git a/media/filters/ffmpeg_video_decoder_unittest.cc b/media/filters/ffmpeg_video_decoder_unittest.cc |
index 228d3c8e8ce3dfbdc021069fb6ec4c8652000418..cff038e2f1828a022f3ca2113e2536845e0df718 100644 |
--- a/media/filters/ffmpeg_video_decoder_unittest.cc |
+++ b/media/filters/ffmpeg_video_decoder_unittest.cc |
@@ -59,8 +59,10 @@ class MockVideoDecodeEngine : public VideoDecodeEngine { |
MOCK_METHOD1(Stop, void(Task* done_cb)); |
MOCK_METHOD1(Pause, void(Task* done_cb)); |
MOCK_METHOD1(Flush, void(Task* done_cb)); |
+ MOCK_METHOD1(Seek, void(Task* done_cb)); |
MOCK_CONST_METHOD0(state, State()); |
MOCK_CONST_METHOD0(GetSurfaceFormat, VideoFrame::Format()); |
+ MOCK_CONST_METHOD0(ProvidesBuffer, bool()); |
scoped_ptr<FillThisBufferCallback> fill_buffer_callback_; |
scoped_ptr<EmptyThisBufferCallback> empty_buffer_callback_; |
@@ -73,23 +75,26 @@ class DecoderPrivateMock : public FFmpegVideoDecoder { |
: FFmpegVideoDecoder(engine) { |
} |
- MOCK_METHOD1(EnqueueVideoFrame, |
- void(const scoped_refptr<VideoFrame>& video_frame)); |
- MOCK_METHOD0(EnqueueEmptyFrame, void()); |
- MOCK_METHOD4(FindPtsAndDuration, TimeTuple( |
- const AVRational& time_base, |
- PtsHeap* pts_heap, |
- const TimeTuple& last_pts, |
- const VideoFrame* frame)); |
- MOCK_METHOD0(SignalPipelineError, void()); |
- MOCK_METHOD1(OnEmptyBufferDone, void(scoped_refptr<Buffer> buffer)); |
- |
// change access qualifier for test: used in actions. |
- void OnDecodeComplete(scoped_refptr<VideoFrame> video_frame) { |
- FFmpegVideoDecoder::OnDecodeComplete(video_frame); |
+ void OnEngineEmptyBufferDone(scoped_refptr<Buffer> buffer) { |
+ FFmpegVideoDecoder::OnEngineEmptyBufferDone(buffer); |
+ } |
+ void OnEngineFillBufferDone(scoped_refptr<VideoFrame> frame) { |
+ FFmpegVideoDecoder::OnEngineFillBufferDone(frame); |
+ } |
+ void OnReadComplete(Buffer* buffer) { |
+ FFmpegVideoDecoder::OnReadComplete(buffer); |
} |
}; |
+ACTION_P(SaveFillCallback, engine) { |
+ engine->fill_buffer_callback_.reset(arg3); |
+} |
+ |
+ACTION_P(SaveEmptyCallback, engine) { |
+ engine->empty_buffer_callback_.reset(arg2); |
+} |
+ |
// Fixture class to facilitate writing tests. Takes care of setting up the |
// FFmpeg, pipeline and filter host mocks. |
class FFmpegVideoDecoderTest : public testing::Test { |
@@ -98,6 +103,7 @@ class FFmpegVideoDecoderTest : public testing::Test { |
static const int kHeight; |
static const FFmpegVideoDecoder::TimeTuple kTestPts1; |
static const FFmpegVideoDecoder::TimeTuple kTestPts2; |
+ static const FFmpegVideoDecoder::TimeTuple kTestPts3; |
FFmpegVideoDecoderTest() { |
MediaFormat media_format; |
@@ -107,7 +113,8 @@ class FFmpegVideoDecoderTest : public testing::Test { |
// |
// TODO(ajwong): Break the test's dependency on FFmpegVideoDecoder. |
factory_ = FFmpegVideoDecoder::CreateFactory(); |
- decoder_ = factory_->Create<FFmpegVideoDecoder>(media_format); |
+ decoder_ = factory_->Create<DecoderPrivateMock>(media_format); |
+ renderer_ = new MockVideoRenderer(); |
engine_ = new StrictMock<MockVideoDecodeEngine>(); |
DCHECK(decoder_); |
@@ -130,6 +137,8 @@ class FFmpegVideoDecoderTest : public testing::Test { |
stream_.codec = &codec_context_; |
codec_context_.width = kWidth; |
codec_context_.height = kHeight; |
+ stream_.r_frame_rate.num = 1; |
+ stream_.r_frame_rate.den = 1; |
buffer_ = new DataBuffer(1); |
end_of_stream_buffer_ = new DataBuffer(0); |
@@ -152,10 +161,34 @@ class FFmpegVideoDecoderTest : public testing::Test { |
MockFFmpeg::set(NULL); |
} |
+ void InitializeDecoderSuccessfully() { |
+ // Test successful initialization. |
+ AVStreamProvider* av_stream_provider = demuxer_; |
+ EXPECT_CALL(*demuxer_, QueryInterface(AVStreamProvider::interface_id())) |
+ .WillOnce(Return(av_stream_provider)); |
+ EXPECT_CALL(*demuxer_, GetAVStream()) |
+ .WillOnce(Return(&stream_)); |
+ |
+ EXPECT_CALL(*engine_, Initialize(_, _, _, _, _)) |
+ .WillOnce(DoAll(SaveFillCallback(engine_), |
+ SaveEmptyCallback(engine_), |
+ WithArg<4>(InvokeRunnable()))); |
+ EXPECT_CALL(*engine_, state()) |
+ .WillOnce(Return(VideoDecodeEngine::kNormal)); |
+ EXPECT_CALL(*engine_, GetSurfaceFormat()) |
+ .WillOnce(Return(VideoFrame::YV12)); |
+ |
+ EXPECT_CALL(callback_, OnFilterCallback()); |
+ EXPECT_CALL(callback_, OnCallbackDestroyed()); |
+ |
+ decoder_->Initialize(demuxer_, callback_.NewCallback()); |
+ message_loop_.RunAllPending(); |
+ } |
// Fixture members. |
scoped_refptr<FilterFactory> factory_; |
MockVideoDecodeEngine* engine_; // Owned by |decoder_|. |
- scoped_refptr<FFmpegVideoDecoder> decoder_; |
+ scoped_refptr<DecoderPrivateMock> decoder_; |
+ scoped_refptr<MockVideoRenderer> renderer_; |
scoped_refptr<StrictMock<MockFFmpegDemuxerStream> > demuxer_; |
scoped_refptr<DataBuffer> buffer_; |
scoped_refptr<DataBuffer> end_of_stream_buffer_; |
@@ -183,6 +216,9 @@ const FFmpegVideoDecoder::TimeTuple FFmpegVideoDecoderTest::kTestPts1 = |
const FFmpegVideoDecoder::TimeTuple FFmpegVideoDecoderTest::kTestPts2 = |
{ base::TimeDelta::FromMicroseconds(456), |
base::TimeDelta::FromMicroseconds(60) }; |
+const FFmpegVideoDecoder::TimeTuple FFmpegVideoDecoderTest::kTestPts3 = |
+ { base::TimeDelta::FromMicroseconds(789), |
+ base::TimeDelta::FromMicroseconds(60) }; |
TEST(FFmpegVideoDecoderFactoryTest, Create) { |
// Should only accept video/x-ffmpeg mime type. |
@@ -208,19 +244,13 @@ TEST_F(FFmpegVideoDecoderTest, Initialize_QueryInterfaceFails) { |
EXPECT_CALL(host_, SetError(PIPELINE_ERROR_DECODE)); |
EXPECT_CALL(callback_, OnFilterCallback()); |
EXPECT_CALL(callback_, OnCallbackDestroyed()); |
+ EXPECT_CALL(*engine_, state()) |
+ .WillOnce(Return(VideoDecodeEngine::kCreated)); |
decoder_->Initialize(demuxer_, callback_.NewCallback()); |
message_loop_.RunAllPending(); |
} |
-ACTION_P(SaveFillCallback, engine) { |
- engine->fill_buffer_callback_.reset(arg3); |
-} |
- |
-ACTION_P(SaveEmptyCallback, engine) { |
- engine->empty_buffer_callback_.reset(arg2); |
-} |
- |
TEST_F(FFmpegVideoDecoderTest, Initialize_EngineFails) { |
// Test successful initialization. |
AVStreamProvider* av_stream_provider = demuxer_; |
@@ -246,27 +276,7 @@ TEST_F(FFmpegVideoDecoderTest, Initialize_EngineFails) { |
} |
TEST_F(FFmpegVideoDecoderTest, Initialize_Successful) { |
- // Test successful initialization. |
- AVStreamProvider* av_stream_provider = demuxer_; |
- EXPECT_CALL(*demuxer_, QueryInterface(AVStreamProvider::interface_id())) |
- .WillOnce(Return(av_stream_provider)); |
- EXPECT_CALL(*demuxer_, GetAVStream()) |
- .WillOnce(Return(&stream_)); |
- |
- EXPECT_CALL(*engine_, Initialize(_, _, _, _, _)) |
- .WillOnce(DoAll(SaveFillCallback(engine_), |
- SaveEmptyCallback(engine_), |
- WithArg<4>(InvokeRunnable()))); |
- EXPECT_CALL(*engine_, state()) |
- .WillOnce(Return(VideoDecodeEngine::kNormal)); |
- EXPECT_CALL(*engine_, GetSurfaceFormat()) |
- .WillOnce(Return(VideoFrame::YV12)); |
- |
- EXPECT_CALL(callback_, OnFilterCallback()); |
- EXPECT_CALL(callback_, OnCallbackDestroyed()); |
- |
- decoder_->Initialize(demuxer_, callback_.NewCallback()); |
- message_loop_.RunAllPending(); |
+ InitializeDecoderSuccessfully(); |
// Test that the output media format is an uncompressed video surface that |
// matches the dimensions specified by FFmpeg. |
@@ -355,13 +365,26 @@ TEST_F(FFmpegVideoDecoderTest, FindPtsAndDuration) { |
EXPECT_EQ(789, result_pts.duration.InMicroseconds()); |
} |
-ACTION_P2(DecodeComplete, decoder, video_frame) { |
- decoder->OnDecodeComplete(video_frame); |
+ACTION_P2(ReadFromDemux, decoder, buffer) { |
+ decoder->OnEngineEmptyBufferDone(buffer); |
+} |
+ |
+ACTION_P3(ReturnFromDemux, decoder, buffer, time_tuple) { |
+ delete arg0; |
+ buffer->SetTimestamp(time_tuple.timestamp); |
+ buffer->SetDuration(time_tuple.duration); |
+ decoder->OnReadComplete(buffer); |
} |
-ACTION_P2(DecodeNotComplete, decoder, video_frame) { |
+ACTION_P3(DecodeComplete, decoder, video_frame, time_tuple) { |
+ video_frame->SetTimestamp(time_tuple.timestamp); |
+ video_frame->SetDuration(time_tuple.duration); |
+ decoder->OnEngineFillBufferDone(video_frame); |
+} |
+ACTION_P2(DecodeNotComplete, decoder, buffer) { |
scoped_refptr<VideoFrame> null_frame; |
- decoder->OnDecodeComplete(null_frame); |
+ decoder->OnEngineFillBufferDone(null_frame); |
+ decoder->OnEngineEmptyBufferDone(buffer); |
} |
ACTION_P(ConsumePTS, pts_heap) { |
@@ -379,100 +402,80 @@ TEST_F(FFmpegVideoDecoderTest, DoDecode_TestStateTransition) { |
// 4) kDecodeFinished is never left regardless of what kind of buffer is |
// given. |
// 5) All state transitions happen as expected. |
- MockVideoDecodeEngine* mock_engine = new StrictMock<MockVideoDecodeEngine>(); |
- scoped_refptr<DecoderPrivateMock> mock_decoder = |
- new StrictMock<DecoderPrivateMock>(mock_engine); |
- mock_decoder->set_message_loop(&message_loop_); |
+ InitializeDecoderSuccessfully(); |
- // Setup decoder to buffer one frame, decode one frame, fail one frame, |
- // decode one more, and then fail the last one to end decoding. |
- EXPECT_CALL(*mock_engine, EmptyThisBuffer(_)) |
- .WillOnce(DecodeNotComplete(mock_decoder.get(), video_frame_)) |
- .WillOnce(DecodeComplete(mock_decoder.get(), video_frame_)) |
- .WillOnce(DecodeNotComplete(mock_decoder.get(), video_frame_)) |
- .WillOnce(DecodeComplete(mock_decoder.get(), video_frame_)) |
- .WillOnce(DecodeComplete(mock_decoder.get(), video_frame_)) |
- .WillOnce(DecodeNotComplete(mock_decoder.get(), video_frame_)); |
- PtsHeap* pts_heap = &mock_decoder->pts_heap_; |
- EXPECT_CALL(*mock_decoder, FindPtsAndDuration(_, _, _, _)) |
- .WillOnce(DoAll(ConsumePTS(pts_heap), Return(kTestPts1))) |
- .WillOnce(DoAll(ConsumePTS(pts_heap), Return(kTestPts2))) |
- .WillOnce(DoAll(ConsumePTS(pts_heap), Return(kTestPts1))); |
- EXPECT_CALL(*mock_decoder, EnqueueVideoFrame(_)) |
- .Times(3); |
- EXPECT_CALL(*mock_decoder, EnqueueEmptyFrame()) |
- .Times(1); |
- EXPECT_CALL(*mock_decoder, OnEmptyBufferDone(_)) |
- .Times(6); |
+ decoder_->set_fill_buffer_done_callback( |
+ NewCallback(renderer_.get(), &MockVideoRenderer::FillThisBufferDone)); |
// Setup initial state and check that it is sane. |
- ASSERT_EQ(FFmpegVideoDecoder::kNormal, mock_decoder->state_); |
- ASSERT_TRUE(base::TimeDelta() == mock_decoder->last_pts_.timestamp); |
- ASSERT_TRUE(base::TimeDelta() == mock_decoder->last_pts_.duration); |
- // Decode once, which should simulate a buffering call. |
- mock_decoder->DoDecode(buffer_); |
- EXPECT_EQ(FFmpegVideoDecoder::kNormal, mock_decoder->state_); |
- ASSERT_TRUE(base::TimeDelta() == mock_decoder->last_pts_.timestamp); |
- ASSERT_TRUE(base::TimeDelta() == mock_decoder->last_pts_.duration); |
- EXPECT_FALSE(mock_decoder->pts_heap_.IsEmpty()); |
- |
- // Decode a second time, which should yield the first frame. |
- mock_decoder->DoDecode(buffer_); |
- EXPECT_EQ(FFmpegVideoDecoder::kNormal, mock_decoder->state_); |
- EXPECT_TRUE(kTestPts1.timestamp == mock_decoder->last_pts_.timestamp); |
- EXPECT_TRUE(kTestPts1.duration == mock_decoder->last_pts_.duration); |
- EXPECT_FALSE(mock_decoder->pts_heap_.IsEmpty()); |
- |
- // Decode a third time, with a regular buffer. The decode will error |
- // out, but the state should be the same. |
- mock_decoder->DoDecode(buffer_); |
- EXPECT_EQ(FFmpegVideoDecoder::kNormal, mock_decoder->state_); |
- EXPECT_TRUE(kTestPts1.timestamp == mock_decoder->last_pts_.timestamp); |
- EXPECT_TRUE(kTestPts1.duration == mock_decoder->last_pts_.duration); |
- EXPECT_FALSE(mock_decoder->pts_heap_.IsEmpty()); |
- |
- // Decode a fourth time, with an end of stream buffer. This should |
- // yield the second frame, and stay in flushing mode. |
- mock_decoder->DoDecode(end_of_stream_buffer_); |
- EXPECT_EQ(FFmpegVideoDecoder::kFlushCodec, mock_decoder->state_); |
- EXPECT_TRUE(kTestPts2.timestamp == mock_decoder->last_pts_.timestamp); |
- EXPECT_TRUE(kTestPts2.duration == mock_decoder->last_pts_.duration); |
- EXPECT_FALSE(mock_decoder->pts_heap_.IsEmpty()); |
- |
- // Decode a fifth time with an end of stream buffer. this should |
- // yield the third frame. |
- mock_decoder->DoDecode(end_of_stream_buffer_); |
- EXPECT_EQ(FFmpegVideoDecoder::kFlushCodec, mock_decoder->state_); |
- EXPECT_TRUE(kTestPts1.timestamp == mock_decoder->last_pts_.timestamp); |
- EXPECT_TRUE(kTestPts1.duration == mock_decoder->last_pts_.duration); |
- EXPECT_TRUE(mock_decoder->pts_heap_.IsEmpty()); |
- |
- // Decode a sixth time with an end of stream buffer. This should |
- // Move into kDecodeFinished. |
- mock_decoder->DoDecode(end_of_stream_buffer_); |
- EXPECT_EQ(FFmpegVideoDecoder::kDecodeFinished, mock_decoder->state_); |
- EXPECT_TRUE(kTestPts1.timestamp == mock_decoder->last_pts_.timestamp); |
- EXPECT_TRUE(kTestPts1.duration == mock_decoder->last_pts_.duration); |
- EXPECT_TRUE(mock_decoder->pts_heap_.IsEmpty()); |
-} |
- |
-TEST_F(FFmpegVideoDecoderTest, DoDecode_FinishEnqueuesEmptyFrames) { |
- MockVideoDecodeEngine* mock_engine = new StrictMock<MockVideoDecodeEngine>(); |
- scoped_refptr<DecoderPrivateMock> mock_decoder = |
- new StrictMock<DecoderPrivateMock>(mock_engine); |
- |
- // Move the decoder into the finished state for this test. |
- mock_decoder->state_ = FFmpegVideoDecoder::kDecodeFinished; |
- |
- // Expect 2 calls, make two calls. If kDecodeFinished is set, the buffer is |
- // not even examined. |
- EXPECT_CALL(*mock_decoder, EnqueueEmptyFrame()).Times(3); |
- EXPECT_CALL(*mock_decoder, OnEmptyBufferDone(_)).Times(3); |
+ ASSERT_EQ(FFmpegVideoDecoder::kNormal, decoder_->state_); |
+ ASSERT_TRUE(base::TimeDelta() == decoder_->last_pts_.timestamp); |
+ ASSERT_TRUE(base::TimeDelta() == decoder_->last_pts_.duration); |
- mock_decoder->DoDecode(NULL); |
- mock_decoder->DoDecode(buffer_); |
- mock_decoder->DoDecode(end_of_stream_buffer_); |
- EXPECT_EQ(FFmpegVideoDecoder::kDecodeFinished, mock_decoder->state_); |
+ // Setup decoder to buffer one frame, decode one frame, fail one frame, |
+ // decode one more, and then fail the last one to end decoding. |
+ EXPECT_CALL(*engine_, FillThisBuffer(_)) |
+ .Times(4) |
+ .WillRepeatedly(ReadFromDemux(decoder_.get(), buffer_)); |
+ EXPECT_CALL(*demuxer_.get(), Read(_)) |
+ .Times(6) |
+ .WillOnce(ReturnFromDemux(decoder_.get(), buffer_, kTestPts1)) |
+ .WillOnce(ReturnFromDemux(decoder_.get(), buffer_, kTestPts3)) |
+ .WillOnce(ReturnFromDemux(decoder_.get(), buffer_, kTestPts2)) |
+ .WillOnce(ReturnFromDemux(decoder_.get(), |
+ end_of_stream_buffer_, kTestPts3)) |
+ .WillOnce(ReturnFromDemux(decoder_.get(), |
+ end_of_stream_buffer_, kTestPts3)) |
+ .WillOnce(ReturnFromDemux(decoder_.get(), |
+ end_of_stream_buffer_, kTestPts3)); |
+ EXPECT_CALL(*engine_, EmptyThisBuffer(_)) |
+ .WillOnce(DecodeNotComplete(decoder_.get(), buffer_)) |
+ .WillOnce(DecodeComplete(decoder_.get(), video_frame_, kTestPts1)) |
+ .WillOnce(DecodeNotComplete(decoder_.get(), buffer_)) |
+ .WillOnce(DecodeComplete(decoder_.get(), video_frame_, kTestPts2)) |
+ .WillOnce(DecodeComplete(decoder_.get(), video_frame_, kTestPts3)) |
+ .WillOnce(DecodeNotComplete(decoder_.get(), buffer_)); |
+ EXPECT_CALL(*renderer_.get(), FillThisBufferDone(_)) |
+ .Times(4); |
+ |
+ // First request from renderer: at first round decode engine did not produce |
+ // any frame. Decoder will issue another read from demuxer. at second round |
+ // decode engine will get a valid frame. |
+ decoder_->FillThisBuffer(video_frame_); |
+ message_loop_.RunAllPending(); |
+ EXPECT_EQ(FFmpegVideoDecoder::kNormal, decoder_->state_); |
+ ASSERT_TRUE(kTestPts1.timestamp == decoder_->last_pts_.timestamp); |
+ ASSERT_TRUE(kTestPts1.duration == decoder_->last_pts_.duration); |
+ EXPECT_FALSE(decoder_->pts_heap_.IsEmpty()); |
+ |
+ // Second request from renderer: at first round decode engine did not produce |
+ // any frame. Decoder will issue another read from demuxer. at second round |
+ // decode engine will get a valid frame. |
+ decoder_->FillThisBuffer(video_frame_); |
+ message_loop_.RunAllPending(); |
+ EXPECT_EQ(FFmpegVideoDecoder::kFlushCodec, decoder_->state_); |
+ EXPECT_TRUE(kTestPts2.timestamp == decoder_->last_pts_.timestamp); |
+ EXPECT_TRUE(kTestPts2.duration == decoder_->last_pts_.duration); |
+ EXPECT_FALSE(decoder_->pts_heap_.IsEmpty()); |
+ |
+ // Third request from renderer: decode engine will return frame on the |
+ // first round. Input stream had reach EOS, therefore we had entered |
+ // kFlushCodec state after this call. |
+ decoder_->FillThisBuffer(video_frame_); |
+ message_loop_.RunAllPending(); |
+ EXPECT_EQ(FFmpegVideoDecoder::kFlushCodec, decoder_->state_); |
+ EXPECT_TRUE(kTestPts3.timestamp == decoder_->last_pts_.timestamp); |
+ EXPECT_TRUE(kTestPts3.duration == decoder_->last_pts_.duration); |
+ EXPECT_TRUE(decoder_->pts_heap_.IsEmpty()); |
+ |
+ // Fourth request from renderer: Both input/output reach EOF. therefore |
+ // we had reached the kDecodeFinished state after this call. |
+ decoder_->FillThisBuffer(video_frame_); |
+ message_loop_.RunAllPending(); |
+ EXPECT_EQ(FFmpegVideoDecoder::kDecodeFinished, decoder_->state_); |
+ EXPECT_TRUE(kTestPts3.timestamp == decoder_->last_pts_.timestamp); |
+ EXPECT_TRUE(kTestPts3.duration == decoder_->last_pts_.duration); |
+ EXPECT_TRUE(decoder_->pts_heap_.IsEmpty()); |
} |
TEST_F(FFmpegVideoDecoderTest, DoSeek) { |
@@ -484,33 +487,47 @@ TEST_F(FFmpegVideoDecoderTest, DoSeek) { |
FFmpegVideoDecoder::kNormal, |
FFmpegVideoDecoder::kFlushCodec, |
FFmpegVideoDecoder::kDecodeFinished, |
+ FFmpegVideoDecoder::kStopped, |
}; |
+ InitializeDecoderSuccessfully(); |
+ |
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kStates); ++i) { |
SCOPED_TRACE(Message() << "Iteration " << i); |
- MockVideoDecodeEngine* mock_engine = |
- new StrictMock<MockVideoDecodeEngine>(); |
- scoped_refptr<DecoderPrivateMock> mock_decoder = |
- new StrictMock<DecoderPrivateMock>(mock_engine); |
- |
// Push in some timestamps. |
- mock_decoder->pts_heap_.Push(kTestPts1.timestamp); |
- mock_decoder->pts_heap_.Push(kTestPts2.timestamp); |
- mock_decoder->pts_heap_.Push(kTestPts1.timestamp); |
+ decoder_->pts_heap_.Push(kTestPts1.timestamp); |
+ decoder_->pts_heap_.Push(kTestPts2.timestamp); |
+ decoder_->pts_heap_.Push(kTestPts3.timestamp); |
+ |
+ decoder_->state_ = kStates[i]; |
+ |
+ // Expect a pause. |
+ // TODO(jiesun): call engine's Pause(). |
+ StrictMock<MockFilterCallback> pause_done_cb; |
+ EXPECT_CALL(pause_done_cb, OnFilterCallback()); |
+ EXPECT_CALL(pause_done_cb, OnCallbackDestroyed()); |
+ decoder_->Pause(pause_done_cb.NewCallback()); |
// Expect a flush. |
- mock_decoder->state_ = kStates[i]; |
- EXPECT_CALL(*mock_engine, Flush(_)) |
+ EXPECT_CALL(*engine_, Flush(_)) |
+ .WillOnce(WithArg<0>(InvokeRunnable())); |
+ StrictMock<MockFilterCallback> flush_done_cb; |
+ EXPECT_CALL(flush_done_cb, OnFilterCallback()); |
+ EXPECT_CALL(flush_done_cb, OnCallbackDestroyed()); |
+ decoder_->Flush(flush_done_cb.NewCallback()); |
+ |
+ // Expect Seek and verify the results. |
+ EXPECT_CALL(*engine_, Seek(_)) |
.WillOnce(WithArg<0>(InvokeRunnable())); |
+ StrictMock<MockFilterCallback> seek_done_cb; |
+ EXPECT_CALL(seek_done_cb, OnFilterCallback()); |
+ EXPECT_CALL(seek_done_cb, OnCallbackDestroyed()); |
+ decoder_->Seek(kZero, seek_done_cb.NewCallback()); |
- TaskMocker done_cb; |
- EXPECT_CALL(done_cb, Run()).Times(1); |
- // Seek and verify the results. |
- mock_decoder->DoSeek(kZero, done_cb.CreateTask()); |
- EXPECT_TRUE(mock_decoder->pts_heap_.IsEmpty()); |
- EXPECT_EQ(FFmpegVideoDecoder::kNormal, mock_decoder->state_); |
+ EXPECT_TRUE(decoder_->pts_heap_.IsEmpty()); |
+ EXPECT_EQ(FFmpegVideoDecoder::kNormal, decoder_->state_); |
} |
} |