Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1622)

Unified Diff: media/filters/ffmpeg_video_decoder_unittest.cc

Issue 465044: Refactor FFmpegVideoDecoder to try and generalize code common to all video decoders. (Closed)
Patch Set: Fix SCOPED_TRACE since VS faults on %zd. Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/filters/ffmpeg_video_decoder.cc ('k') | media/filters/video_decode_engine.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 9c0963bc52e1f741229ec43621e801bb733061ac..7bb05a913a7eb4219a9df09b37bca75c771810bb 100644
--- a/media/filters/ffmpeg_video_decoder_unittest.cc
+++ b/media/filters/ffmpeg_video_decoder_unittest.cc
@@ -5,11 +5,13 @@
#include <deque>
#include "base/singleton.h"
+#include "base/string_util.h"
#include "media/base/data_buffer.h"
#include "media/base/filters.h"
#include "media/base/mock_ffmpeg.h"
#include "media/base/mock_filter_host.h"
#include "media/base/mock_filters.h"
+#include "media/base/mock_task.h"
#include "media/filters/ffmpeg_common.h"
#include "media/filters/ffmpeg_interfaces.h"
#include "media/filters/ffmpeg_video_decoder.h"
@@ -17,10 +19,12 @@
using ::testing::_;
using ::testing::DoAll;
+using ::testing::Message;
using ::testing::Return;
using ::testing::ReturnNull;
using ::testing::SetArgumentPointee;
using ::testing::StrictMock;
+using ::testing::WithArg;
namespace media {
@@ -39,20 +43,29 @@ class MockFFmpegDemuxerStream : public MockDemuxerStream,
DISALLOW_COPY_AND_ASSIGN(MockFFmpegDemuxerStream);
};
+class MockVideoDecodeEngine : public VideoDecodeEngine {
+ public:
+ MOCK_METHOD2(Initialize, void(AVStream* stream, Task* done_cb));
+ MOCK_METHOD4(DecodeFrame, void(const Buffer& buffer, AVFrame* yuv_frame,
+ bool* got_result, Task* done_cb));
+ MOCK_METHOD1(Flush, void(Task* done_cb));
+ MOCK_CONST_METHOD0(state, State());
+ MOCK_CONST_METHOD0(GetSurfaceFormat, VideoSurface::Format());
+};
+
// Class that just mocks the private functions.
class DecoderPrivateMock : public FFmpegVideoDecoder {
public:
+ DecoderPrivateMock(VideoDecodeEngine* engine)
+ : FFmpegVideoDecoder(engine) {
+ }
+
MOCK_METHOD3(EnqueueVideoFrame, bool(VideoSurface::Format surface_format,
const TimeTuple& time,
const AVFrame* frame));
MOCK_METHOD0(EnqueueEmptyFrame, void());
MOCK_METHOD3(CopyPlane, void(size_t plane, const VideoSurface& surface,
const AVFrame* frame));
- MOCK_METHOD1(GetSurfaceFormat,
- VideoSurface::Format(const AVCodecContext& codec_context));
- MOCK_METHOD3(DecodeFrame, bool(const Buffer& buffer,
- AVCodecContext* codec_context,
- AVFrame* yuv_frame));
MOCK_METHOD4(FindPtsAndDuration, TimeTuple(const AVRational& time_base,
const PtsHeap& pts_heap,
const TimeTuple& last_pts,
@@ -73,14 +86,17 @@ class FFmpegVideoDecoderTest : public testing::Test {
MediaFormat media_format;
media_format.SetAsString(MediaFormat::kMimeType, mime_type::kFFmpegVideo);
- // Create an FFmpegVideoDecoder.
+ // Create an FFmpegVideoDecoder, and MockVideoDecodeEngine.
factory_ = FFmpegVideoDecoder::CreateFactory();
decoder_ = factory_->Create<FFmpegVideoDecoder>(media_format);
+ engine_ = new StrictMock<MockVideoDecodeEngine>();
+
DCHECK(decoder_);
- // Inject a filter host and message loop and prepare a demuxer stream.
+ // Inject mocks and prepare a demuxer stream.
decoder_->set_host(&host_);
decoder_->set_message_loop(&message_loop_);
+ decoder_->SetVideoDecodeEngineForTest(engine_);
demuxer_ = new StrictMock<MockFFmpegDemuxerStream>();
// Initialize FFmpeg fixtures.
@@ -112,6 +128,7 @@ class FFmpegVideoDecoderTest : public testing::Test {
// Fixture members.
scoped_refptr<FilterFactory> factory_;
+ MockVideoDecodeEngine* engine_; // Owned by |decoder_|.
scoped_refptr<FFmpegVideoDecoder> decoder_;
scoped_refptr<StrictMock<MockFFmpegDemuxerStream> > demuxer_;
scoped_refptr<DataBuffer> buffer_;
@@ -169,56 +186,21 @@ TEST_F(FFmpegVideoDecoderTest, Initialize_QueryInterfaceFails) {
message_loop_.RunAllPending();
}
-TEST_F(FFmpegVideoDecoderTest, Initialize_FindDecoderFails) {
- // Test avcodec_find_decoder() returning NULL.
+TEST_F(FFmpegVideoDecoderTest, Initialize_EngineFails) {
+ // 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(*MockFFmpeg::get(), AVCodecFindDecoder(CODEC_ID_NONE))
- .WillOnce(ReturnNull());
- EXPECT_CALL(host_, SetError(PIPELINE_ERROR_DECODE));
- EXPECT_CALL(callback_, OnFilterCallback());
- EXPECT_CALL(callback_, OnCallbackDestroyed());
- decoder_->Initialize(demuxer_, callback_.NewCallback());
- message_loop_.RunAllPending();
-}
+ EXPECT_CALL(*engine_, Initialize(_, _))
+ .WillOnce(WithArg<1>(InvokeRunnable()));
+ EXPECT_CALL(*engine_, state())
+ .WillOnce(Return(VideoDecodeEngine::kError));
-TEST_F(FFmpegVideoDecoderTest, Initialize_InitThreadFails) {
- // Test avcodec_thread_init() failing.
- 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(*MockFFmpeg::get(), AVCodecFindDecoder(CODEC_ID_NONE))
- .WillOnce(Return(&codec_));
- EXPECT_CALL(*MockFFmpeg::get(), AVCodecThreadInit(&codec_context_, 2))
- .WillOnce(Return(-1));
EXPECT_CALL(host_, SetError(PIPELINE_ERROR_DECODE));
- EXPECT_CALL(callback_, OnFilterCallback());
- EXPECT_CALL(callback_, OnCallbackDestroyed());
-
- decoder_->Initialize(demuxer_, callback_.NewCallback());
- message_loop_.RunAllPending();
-}
-TEST_F(FFmpegVideoDecoderTest, Initialize_OpenDecoderFails) {
- // Test avcodec_open() failing.
- 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(*MockFFmpeg::get(), AVCodecFindDecoder(CODEC_ID_NONE))
- .WillOnce(Return(&codec_));
- EXPECT_CALL(*MockFFmpeg::get(), AVCodecThreadInit(&codec_context_, 2))
- .WillOnce(Return(0));
- EXPECT_CALL(*MockFFmpeg::get(), AVCodecOpen(&codec_context_, &codec_))
- .WillOnce(Return(-1));
- EXPECT_CALL(host_, SetError(PIPELINE_ERROR_DECODE));
EXPECT_CALL(callback_, OnFilterCallback());
EXPECT_CALL(callback_, OnCallbackDestroyed());
@@ -233,12 +215,12 @@ TEST_F(FFmpegVideoDecoderTest, Initialize_Successful) {
.WillOnce(Return(av_stream_provider));
EXPECT_CALL(*demuxer_, GetAVStream())
.WillOnce(Return(&stream_));
- EXPECT_CALL(*MockFFmpeg::get(), AVCodecFindDecoder(CODEC_ID_NONE))
- .WillOnce(Return(&codec_));
- EXPECT_CALL(*MockFFmpeg::get(), AVCodecThreadInit(&codec_context_, 2))
- .WillOnce(Return(0));
- EXPECT_CALL(*MockFFmpeg::get(), AVCodecOpen(&codec_context_, &codec_))
- .WillOnce(Return(0));
+
+ EXPECT_CALL(*engine_, Initialize(_, _))
+ .WillOnce(WithArg<1>(InvokeRunnable()));
+ EXPECT_CALL(*engine_, state())
+ .WillOnce(Return(VideoDecodeEngine::kNormal));
+
EXPECT_CALL(callback_, OnFilterCallback());
EXPECT_CALL(callback_, OnCallbackDestroyed());
@@ -259,66 +241,9 @@ TEST_F(FFmpegVideoDecoderTest, Initialize_Successful) {
EXPECT_EQ(kHeight, height);
}
-TEST_F(FFmpegVideoDecoderTest, DecodeFrame_Normal) {
- // Expect a bunch of avcodec calls.
- EXPECT_CALL(mock_ffmpeg_, AVInitPacket(_));
- EXPECT_CALL(mock_ffmpeg_,
- AVCodecDecodeVideo2(&codec_context_, &yuv_frame_, _, _))
- .WillOnce(DoAll(SetArgumentPointee<2>(1), // Simulate 1 byte frame.
- Return(0)));
-
- scoped_refptr<FFmpegVideoDecoder> decoder = new FFmpegVideoDecoder();
- EXPECT_TRUE(decoder->DecodeFrame(*buffer_, &codec_context_, &yuv_frame_));
-}
-
-TEST_F(FFmpegVideoDecoderTest, DecodeFrame_0ByteFrame) {
- // Expect a bunch of avcodec calls.
- EXPECT_CALL(mock_ffmpeg_, AVInitPacket(_));
- EXPECT_CALL(mock_ffmpeg_,
- AVCodecDecodeVideo2(&codec_context_, &yuv_frame_, _, _))
- .WillOnce(DoAll(SetArgumentPointee<2>(0), // Simulate 0 byte frame.
- Return(0)));
-
- scoped_refptr<FFmpegVideoDecoder> decoder = new FFmpegVideoDecoder();
- EXPECT_FALSE(decoder->DecodeFrame(*buffer_, &codec_context_, &yuv_frame_));
-}
-
-TEST_F(FFmpegVideoDecoderTest, DecodeFrame_DecodeError) {
- // Expect a bunch of avcodec calls.
- EXPECT_CALL(mock_ffmpeg_, AVInitPacket(_));
- EXPECT_CALL(mock_ffmpeg_,
- AVCodecDecodeVideo2(&codec_context_, &yuv_frame_, _, _))
- .WillOnce(Return(-1));
-
- scoped_refptr<FFmpegVideoDecoder> decoder = new FFmpegVideoDecoder();
- EXPECT_FALSE(decoder->DecodeFrame(*buffer_, &codec_context_, &yuv_frame_));
-}
-
-TEST_F(FFmpegVideoDecoderTest, GetSurfaceFormat) {
- AVCodecContext context;
- scoped_refptr<FFmpegVideoDecoder> decoder = new FFmpegVideoDecoder();
-
- // YV12 formats.
- context.pix_fmt = PIX_FMT_YUV420P;
- EXPECT_EQ(VideoSurface::YV12, decoder->GetSurfaceFormat(context));
- context.pix_fmt = PIX_FMT_YUVJ420P;
- EXPECT_EQ(VideoSurface::YV12, decoder->GetSurfaceFormat(context));
-
- // YV16 formats.
- context.pix_fmt = PIX_FMT_YUV422P;
- EXPECT_EQ(VideoSurface::YV16, decoder->GetSurfaceFormat(context));
- context.pix_fmt = PIX_FMT_YUVJ422P;
- EXPECT_EQ(VideoSurface::YV16, decoder->GetSurfaceFormat(context));
-
- // Invalid value.
- context.pix_fmt = PIX_FMT_NONE;
- EXPECT_EQ(VideoSurface::INVALID, decoder->GetSurfaceFormat(context));
-}
-
TEST_F(FFmpegVideoDecoderTest, FindPtsAndDuration) {
// Start with an empty timestamp queue.
PtsHeap pts_heap;
- scoped_refptr<FFmpegVideoDecoder> decoder = new FFmpegVideoDecoder();
// Use 1/2 second for simple results. Thus, calculated Durations should be
// 500000 microseconds.
@@ -333,16 +258,16 @@ TEST_F(FFmpegVideoDecoderTest, FindPtsAndDuration) {
// Simulate an uninitialized yuv_frame.
yuv_frame_.pts = AV_NOPTS_VALUE;
FFmpegVideoDecoder::TimeTuple result_pts =
- decoder->FindPtsAndDuration(time_base, pts_heap, last_pts, &yuv_frame_);
+ decoder_->FindPtsAndDuration(time_base, pts_heap, last_pts, &yuv_frame_);
EXPECT_EQ(116, result_pts.timestamp.InMicroseconds());
EXPECT_EQ(500000, result_pts.duration.InMicroseconds());
// Test that providing no frame has the same result as an uninitialized
// frame.
- result_pts = decoder->FindPtsAndDuration(time_base,
- pts_heap,
- last_pts,
- NULL);
+ result_pts = decoder_->FindPtsAndDuration(time_base,
+ pts_heap,
+ last_pts,
+ NULL);
EXPECT_EQ(116, result_pts.timestamp.InMicroseconds());
EXPECT_EQ(500000, result_pts.duration.InMicroseconds());
@@ -351,33 +276,33 @@ TEST_F(FFmpegVideoDecoderTest, FindPtsAndDuration) {
// data for the frame, which means that value is useless to us.
yuv_frame_.pts = 0;
result_pts =
- decoder->FindPtsAndDuration(time_base, pts_heap, last_pts, &yuv_frame_);
+ decoder_->FindPtsAndDuration(time_base, pts_heap, last_pts, &yuv_frame_);
EXPECT_EQ(116, result_pts.timestamp.InMicroseconds());
EXPECT_EQ(500000, result_pts.duration.InMicroseconds());
// Add a pts to the timequeue and make sure it overrides estimation.
pts_heap.Push(base::TimeDelta::FromMicroseconds(123));
- result_pts = decoder->FindPtsAndDuration(time_base,
- pts_heap,
- last_pts,
- &yuv_frame_);
+ result_pts = decoder_->FindPtsAndDuration(time_base,
+ pts_heap,
+ last_pts,
+ &yuv_frame_);
EXPECT_EQ(123, result_pts.timestamp.InMicroseconds());
EXPECT_EQ(500000, result_pts.duration.InMicroseconds());
// Add a pts into the frame and make sure it overrides the timequeue.
yuv_frame_.pts = 333;
yuv_frame_.repeat_pict = 2;
- result_pts = decoder->FindPtsAndDuration(time_base,
- pts_heap,
- last_pts,
- &yuv_frame_);
+ result_pts = decoder_->FindPtsAndDuration(time_base,
+ pts_heap,
+ last_pts,
+ &yuv_frame_);
EXPECT_EQ(166500000, result_pts.timestamp.InMicroseconds());
EXPECT_EQ(1500000, result_pts.duration.InMicroseconds());
}
-TEST_F(FFmpegVideoDecoderTest, OnDecode_TestStateTransition) {
+TEST_F(FFmpegVideoDecoderTest, DoDecode_TestStateTransition) {
// Simulates a input sequence of three buffers, and six decode requests to
- // exercise the state transitions, and bookkeeping logic of OnDecode.
+ // exercise the state transitions, and bookkeeping logic of DoDecode.
//
// We try to verify the following:
// 1) Non-EoS buffer timestamps are pushed into the pts_heap.
@@ -386,28 +311,38 @@ TEST_F(FFmpegVideoDecoderTest, OnDecode_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>();
+ new StrictMock<DecoderPrivateMock>(mock_engine);
// 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_decoder, DecodeFrame(_, _, _))
- .WillOnce(Return(false))
- .WillOnce(DoAll(SetArgumentPointee<2>(yuv_frame_), Return(true)))
- .WillOnce(Return(false))
- .WillOnce(DoAll(SetArgumentPointee<2>(yuv_frame_), Return(true)))
- .WillOnce(DoAll(SetArgumentPointee<2>(yuv_frame_), Return(true)))
- .WillOnce(Return(false));
- EXPECT_CALL(*mock_decoder, GetSurfaceFormat(_))
+ EXPECT_CALL(*mock_engine, DecodeFrame(_, _, _,_))
+ .WillOnce(DoAll(SetArgumentPointee<2>(false),
+ WithArg<3>(InvokeRunnable())))
+ .WillOnce(DoAll(SetArgumentPointee<1>(yuv_frame_),
+ SetArgumentPointee<2>(true),
+ WithArg<3>(InvokeRunnable())))
+ .WillOnce(DoAll(SetArgumentPointee<2>(false),
+ WithArg<3>(InvokeRunnable())))
+ .WillOnce(DoAll(SetArgumentPointee<1>(yuv_frame_),
+ SetArgumentPointee<2>(true),
+ WithArg<3>(InvokeRunnable())))
+ .WillOnce(DoAll(SetArgumentPointee<1>(yuv_frame_),
+ SetArgumentPointee<2>(true),
+ WithArg<3>(InvokeRunnable())))
+ .WillOnce(DoAll(SetArgumentPointee<2>(false),
+ WithArg<3>(InvokeRunnable())));
+ EXPECT_CALL(*mock_engine, GetSurfaceFormat())
.Times(3)
.WillRepeatedly(Return(VideoSurface::YV16));
- EXPECT_CALL(*mock_decoder, EnqueueVideoFrame(_, _, _))
- .Times(3)
- .WillRepeatedly(Return(true));
EXPECT_CALL(*mock_decoder, FindPtsAndDuration(_, _, _, _))
.WillOnce(Return(kTestPts1))
.WillOnce(Return(kTestPts2))
.WillOnce(Return(kTestPts1));
+ EXPECT_CALL(*mock_decoder, EnqueueVideoFrame(_, _, _))
+ .Times(3)
+ .WillRepeatedly(Return(true));
EXPECT_CALL(*mock_decoder, EnqueueEmptyFrame())
.Times(1);
@@ -419,21 +354,24 @@ TEST_F(FFmpegVideoDecoderTest, OnDecode_TestStateTransition) {
EXPECT_CALL(mock_ffmpeg_, AVFree(&yuv_frame_))
.Times(6);
+ // Setup callbacks to be executed 6 times.
+ TaskMocker done_cb;
+ EXPECT_CALL(done_cb, Run()).Times(6);
+
// Setup initial state and check that it is sane.
- mock_decoder->codec_context_ = &codec_context_;
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->OnDecode(buffer_);
+ mock_decoder->DoDecode(buffer_, done_cb.CreateTask());
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->OnDecode(buffer_);
+ mock_decoder->DoDecode(buffer_, done_cb.CreateTask());
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);
@@ -441,7 +379,7 @@ TEST_F(FFmpegVideoDecoderTest, OnDecode_TestStateTransition) {
// Decode a third time, with a regular buffer. The decode will error
// out, but the state should be the same.
- mock_decoder->OnDecode(buffer_);
+ mock_decoder->DoDecode(buffer_, done_cb.CreateTask());
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);
@@ -449,7 +387,7 @@ TEST_F(FFmpegVideoDecoderTest, OnDecode_TestStateTransition) {
// Decode a fourth time, with an end of stream buffer. This should
// yield the second frame, and stay in flushing mode.
- mock_decoder->OnDecode(end_of_stream_buffer_);
+ mock_decoder->DoDecode(end_of_stream_buffer_, done_cb.CreateTask());
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);
@@ -457,7 +395,7 @@ TEST_F(FFmpegVideoDecoderTest, OnDecode_TestStateTransition) {
// Decode a fifth time with an end of stream buffer. this should
// yield the third frame.
- mock_decoder->OnDecode(end_of_stream_buffer_);
+ mock_decoder->DoDecode(end_of_stream_buffer_, done_cb.CreateTask());
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);
@@ -465,61 +403,71 @@ TEST_F(FFmpegVideoDecoderTest, OnDecode_TestStateTransition) {
// Decode a sixth time with an end of stream buffer. This should
// Move into kDecodeFinished.
- mock_decoder->OnDecode(end_of_stream_buffer_);
+ mock_decoder->DoDecode(end_of_stream_buffer_, done_cb.CreateTask());
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, OnDecode_EnqueueVideoFrameError) {
+TEST_F(FFmpegVideoDecoderTest, DoDecode_EnqueueVideoFrameError) {
+ MockVideoDecodeEngine* mock_engine = new StrictMock<MockVideoDecodeEngine>();
scoped_refptr<DecoderPrivateMock> mock_decoder =
- new StrictMock<DecoderPrivateMock>();
+ new StrictMock<DecoderPrivateMock>(mock_engine);
// Setup decoder to decode one frame, but then fail on enqueue.
- EXPECT_CALL(*mock_decoder, DecodeFrame(_, _, _))
- .WillOnce(DoAll(SetArgumentPointee<2>(yuv_frame_), Return(true)));
- EXPECT_CALL(*mock_decoder, GetSurfaceFormat(_))
+ EXPECT_CALL(*mock_engine, DecodeFrame(_, _, _,_))
+ .WillOnce(DoAll(SetArgumentPointee<1>(yuv_frame_),
+ SetArgumentPointee<2>(true),
+ WithArg<3>(InvokeRunnable())));
+ EXPECT_CALL(*mock_engine, GetSurfaceFormat())
.WillOnce(Return(VideoSurface::YV16));
- EXPECT_CALL(*mock_decoder, EnqueueVideoFrame(_, _, _))
- .WillOnce(Return(false));
EXPECT_CALL(*mock_decoder, FindPtsAndDuration(_, _, _, _))
.WillOnce(Return(kTestPts1));
+ EXPECT_CALL(*mock_decoder, EnqueueVideoFrame(_, _, _))
+ .WillOnce(Return(false));
EXPECT_CALL(*mock_decoder, SignalPipelineError());
+ // Count the callback invoked.
+ TaskMocker done_cb;
+ EXPECT_CALL(done_cb, Run()).Times(1);
+
// Setup FFmpeg expectations for frame allocations.
EXPECT_CALL(mock_ffmpeg_, AVCodecAllocFrame())
.WillOnce(Return(&yuv_frame_));
EXPECT_CALL(mock_ffmpeg_, AVFree(&yuv_frame_));
// Attempt the decode.
- mock_decoder->codec_context_ = &codec_context_;
- mock_decoder->OnDecode(buffer_);
+ mock_decoder->DoDecode(buffer_, done_cb.CreateTask());
}
-TEST_F(FFmpegVideoDecoderTest, OnDecode_FinishEnqueuesEmptyFrames) {
+TEST_F(FFmpegVideoDecoderTest, DoDecode_FinishEnqueuesEmptyFrames) {
+ MockVideoDecodeEngine* mock_engine = new StrictMock<MockVideoDecodeEngine>();
scoped_refptr<DecoderPrivateMock> mock_decoder =
- new StrictMock<DecoderPrivateMock>();
+ 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.
+ // Expect 2 calls, make two calls. If kDecodeFinished is set, the buffer is
+ // not even examined.
EXPECT_CALL(*mock_decoder, EnqueueEmptyFrame()).Times(3);
- mock_decoder->OnDecode(NULL);
- mock_decoder->OnDecode(buffer_);
- mock_decoder->OnDecode(end_of_stream_buffer_);
+
+ // Setup callbacks to be executed 3 times.
+ TaskMocker done_cb;
+ EXPECT_CALL(done_cb, Run()).Times(3);
+
+ mock_decoder->DoDecode(NULL, done_cb.CreateTask());
+ mock_decoder->DoDecode(buffer_, done_cb.CreateTask());
+ mock_decoder->DoDecode(end_of_stream_buffer_, done_cb.CreateTask());
+
EXPECT_EQ(FFmpegVideoDecoder::kDecodeFinished, mock_decoder->state_);
}
-TEST_F(FFmpegVideoDecoderTest, OnSeek) {
- // Simulates receiving a call to OnSeek() while in every possible state. In
+TEST_F(FFmpegVideoDecoderTest, DoSeek) {
+ // Simulates receiving a call to DoSeek() while in every possible state. In
// every case, it should clear the timestamp queue, flush the decoder and
// reset the state to kNormal.
- scoped_refptr<DecoderPrivateMock> mock_decoder =
- new StrictMock<DecoderPrivateMock>();
- mock_decoder->codec_context_ = &codec_context_;
-
const base::TimeDelta kZero;
const FFmpegVideoDecoder::DecoderState kStates[] = {
FFmpegVideoDecoder::kNormal,
@@ -528,6 +476,13 @@ TEST_F(FFmpegVideoDecoderTest, OnSeek) {
};
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);
@@ -535,10 +490,14 @@ TEST_F(FFmpegVideoDecoderTest, OnSeek) {
// Expect a flush.
mock_decoder->state_ = kStates[i];
- EXPECT_CALL(mock_ffmpeg_, AVCodecFlushBuffers(&codec_context_));
+ EXPECT_CALL(*mock_engine, Flush(_))
+ .WillOnce(WithArg<0>(InvokeRunnable()));
+
+ TaskMocker done_cb;
+ EXPECT_CALL(done_cb, Run()).Times(1);
// Seek and verify the results.
- mock_decoder->OnSeek(kZero);
+ mock_decoder->DoSeek(kZero, done_cb.CreateTask());
EXPECT_TRUE(mock_decoder->pts_heap_.IsEmpty());
EXPECT_EQ(FFmpegVideoDecoder::kNormal, mock_decoder->state_);
}
« no previous file with comments | « media/filters/ffmpeg_video_decoder.cc ('k') | media/filters/video_decode_engine.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698