diff options
author | acolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-16 17:46:16 +0000 |
---|---|---|
committer | acolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-16 17:46:16 +0000 |
commit | d143750beccc3ac206857afb2950e25b7175654d (patch) | |
tree | 648b56c7772f05e6cb0c0628a5bb8a5aee91ac5e /media/video | |
parent | 2c0a4317e8190a04f20dc8377567ca429efe664d (diff) | |
download | chromium_src-d143750beccc3ac206857afb2950e25b7175654d.zip chromium_src-d143750beccc3ac206857afb2950e25b7175654d.tar.gz chromium_src-d143750beccc3ac206857afb2950e25b7175654d.tar.bz2 |
Remove mock_ffmpeg and update media unittests.
BUG=92429
TEST=BitstreamConverterTest.*, ChunkDemuxerTest.*, FFmpegDemuxerTest.*, FFmpegGlueTest.*, FFmpegVideoDecoderTest.*, FFmpegH264BitstreamConverterTest.*, FFmpegVideoDecodeEngineTest.*
Review URL: http://codereview.chromium.org/7587012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96974 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/video')
-rw-r--r-- | media/video/ffmpeg_video_decode_engine.cc | 20 | ||||
-rw-r--r-- | media/video/ffmpeg_video_decode_engine.h | 2 | ||||
-rw-r--r-- | media/video/ffmpeg_video_decode_engine_unittest.cc | 228 |
3 files changed, 91 insertions, 159 deletions
diff --git a/media/video/ffmpeg_video_decode_engine.cc b/media/video/ffmpeg_video_decode_engine.cc index 4af73a1..0958516 100644 --- a/media/video/ffmpeg_video_decode_engine.cc +++ b/media/video/ffmpeg_video_decode_engine.cc @@ -120,6 +120,7 @@ void FFmpegVideoDecodeEngine::Initialize( kNoTimestamp); frame_queue_available_.push_back(video_frame); } + codec_context_->thread_count = decode_threads; if (codec && avcodec_open(codec_context_, codec) >= 0 && @@ -186,7 +187,6 @@ void FFmpegVideoDecodeEngine::DecodeFrame(scoped_refptr<Buffer> buffer) { av_frame_.get(), &frame_decoded, &packet); - // Log the problem if we can't decode a video frame and exit early. if (result < 0) { LOG(ERROR) << "Error decoding a video frame with timestamp: " @@ -303,24 +303,6 @@ void FFmpegVideoDecodeEngine::ReadInput() { event_handler_->ProduceVideoSample(NULL); } -VideoFrame::Format FFmpegVideoDecodeEngine::GetSurfaceFormat() const { - // J (Motion JPEG) versions of YUV are full range 0..255. - // Regular (MPEG) YUV is 16..240. - // For now we will ignore the distinction and treat them the same. - switch (codec_context_->pix_fmt) { - case PIX_FMT_YUV420P: - case PIX_FMT_YUVJ420P: - return VideoFrame::YV12; - case PIX_FMT_YUV422P: - case PIX_FMT_YUVJ422P: - return VideoFrame::YV16; - default: - // TODO(scherkus): More formats here? - break; - } - return VideoFrame::INVALID; -} - } // namespace media // Disable refcounting for this object because this object only lives diff --git a/media/video/ffmpeg_video_decode_engine.h b/media/video/ffmpeg_video_decode_engine.h index 32eac45..b7d7661 100644 --- a/media/video/ffmpeg_video_decode_engine.h +++ b/media/video/ffmpeg_video_decode_engine.h @@ -33,8 +33,6 @@ class FFmpegVideoDecodeEngine : public VideoDecodeEngine { virtual void Flush(); virtual void Seek(); - VideoFrame::Format GetSurfaceFormat() const; - private: void DecodeFrame(scoped_refptr<Buffer> buffer); void ReadInput(); diff --git a/media/video/ffmpeg_video_decode_engine_unittest.cc b/media/video/ffmpeg_video_decode_engine_unittest.cc index 261ca45..665fb86 100644 --- a/media/video/ffmpeg_video_decode_engine_unittest.cc +++ b/media/video/ffmpeg_video_decode_engine_unittest.cc @@ -5,9 +5,10 @@ #include "base/memory/scoped_ptr.h" #include "base/message_loop.h" #include "media/base/data_buffer.h" -#include "media/base/mock_ffmpeg.h" #include "media/base/mock_task.h" #include "media/base/pipeline.h" +#include "media/base/test_data_util.h" +#include "media/filters/ffmpeg_glue.h" #include "media/video/ffmpeg_video_decode_engine.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -21,21 +22,12 @@ using ::testing::StrictMock; namespace media { -static const int kWidth = 320; -static const int kHeight = 240; +static const size_t kWidth = 320; +static const size_t kHeight = 240; static const int kSurfaceWidth = 522; static const int kSurfaceHeight = 288; static const AVRational kFrameRate = { 100, 1 }; -static void InitializeFrame(uint8_t* data, int width, AVFrame* frame) { - frame->data[0] = data; - frame->data[1] = data; - frame->data[2] = data; - frame->linesize[0] = width; - frame->linesize[1] = width / 2; - frame->linesize[2] = width / 2; -} - ACTION_P(DecodeComplete, decoder) { decoder->set_video_frame(arg0); } @@ -53,18 +45,12 @@ class FFmpegVideoDecodeEngineTest public VideoDecodeEngine::EventHandler { public: FFmpegVideoDecodeEngineTest() - : config_(kCodecH264, kWidth, kHeight, kSurfaceWidth, kSurfaceHeight, + : config_(kCodecVP8, kWidth, kHeight, kSurfaceWidth, kSurfaceHeight, kFrameRate.num, kFrameRate.den, NULL, 0) { + CHECK(FFmpegGlue::GetInstance()); // Setup FFmpeg structures. frame_buffer_.reset(new uint8[kWidth * kHeight]); - memset(&yuv_frame_, 0, sizeof(yuv_frame_)); - InitializeFrame(frame_buffer_.get(), kWidth, &yuv_frame_); - - memset(&codec_context_, 0, sizeof(codec_context_)); - memset(&codec_, 0, sizeof(codec_)); - - buffer_ = new DataBuffer(1); test_engine_.reset(new FFmpegVideoDecodeEngine()); @@ -73,6 +59,8 @@ class FFmpegVideoDecodeEngineTest kHeight, kNoTimestamp, kNoTimestamp); + + ReadTestDataFile("vp8-I-frame-320x240", &i_frame_buffer_); } ~FFmpegVideoDecodeEngineTest() { @@ -80,48 +68,20 @@ class FFmpegVideoDecodeEngineTest } void Initialize() { - EXPECT_CALL(mock_ffmpeg_, AVCodecAllocContext()) - .WillOnce(Return(&codec_context_)); - EXPECT_CALL(mock_ffmpeg_, AVCodecFindDecoder(CODEC_ID_H264)) - .WillOnce(Return(&codec_)); - EXPECT_CALL(mock_ffmpeg_, AVCodecAllocFrame()) - .WillOnce(Return(&yuv_frame_)); - EXPECT_CALL(mock_ffmpeg_, AVCodecOpen(&codec_context_, &codec_)) - .WillOnce(Return(0)); - EXPECT_CALL(mock_ffmpeg_, AVCodecClose(&codec_context_)) - .WillOnce(Return(0)); - EXPECT_CALL(mock_ffmpeg_, AVFree(&yuv_frame_)) - .Times(1); - EXPECT_CALL(mock_ffmpeg_, AVFree(&codec_context_)) - .Times(1); - EXPECT_CALL(*this, OnInitializeComplete(_)) .WillOnce(SaveInitializeResult(this)); test_engine_->Initialize(MessageLoop::current(), this, NULL, config_); EXPECT_TRUE(info_.success); } - void Decode() { - 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))); - + void Decode(const scoped_refptr<Buffer>& buffer) { EXPECT_CALL(*this, ProduceVideoSample(_)) - .WillOnce(DemuxComplete(test_engine_.get(), buffer_)); + .WillOnce(DemuxComplete(test_engine_.get(), buffer)); EXPECT_CALL(*this, ConsumeVideoFrame(_, _)) .WillOnce(DecodeComplete(this)); test_engine_->ProduceVideoFrame(video_frame_); } - void ChangeDimensions(int width, int height) { - frame_buffer_.reset(new uint8[width * height]); - InitializeFrame(frame_buffer_.get(), width, &yuv_frame_); - codec_context_.width = width; - codec_context_.height = height; - } - // VideoDecodeEngine::EventHandler implementation. MOCK_METHOD2(ConsumeVideoFrame, void(scoped_refptr<VideoFrame> video_frame, @@ -150,12 +110,7 @@ class FFmpegVideoDecodeEngineTest scoped_refptr<VideoFrame> video_frame_; scoped_ptr<FFmpegVideoDecodeEngine> test_engine_; scoped_array<uint8_t> frame_buffer_; - StrictMock<MockFFmpeg> mock_ffmpeg_; - - AVFrame yuv_frame_; - AVCodecContext codec_context_; - AVCodec codec_; - scoped_refptr<DataBuffer> buffer_; + scoped_refptr<Buffer> i_frame_buffer_; private: DISALLOW_COPY_AND_ASSIGN(FFmpegVideoDecodeEngineTest); @@ -166,61 +121,36 @@ TEST_F(FFmpegVideoDecodeEngineTest, Initialize_Normal) { } TEST_F(FFmpegVideoDecodeEngineTest, Initialize_FindDecoderFails) { + VideoDecoderConfig config(kUnknown, kWidth, kHeight, kSurfaceWidth, + kSurfaceHeight, kFrameRate.num, kFrameRate.den, + NULL, 0); // Test avcodec_find_decoder() returning NULL. - EXPECT_CALL(mock_ffmpeg_, AVCodecAllocContext()) - .WillOnce(Return(&codec_context_)); - EXPECT_CALL(mock_ffmpeg_, AVCodecFindDecoder(CODEC_ID_H264)) - .WillOnce(ReturnNull()); - EXPECT_CALL(mock_ffmpeg_, AVCodecAllocFrame()) - .WillOnce(Return(&yuv_frame_)); - EXPECT_CALL(mock_ffmpeg_, AVCodecClose(&codec_context_)) - .WillOnce(Return(0)); - EXPECT_CALL(mock_ffmpeg_, AVFree(&yuv_frame_)) - .Times(1); - EXPECT_CALL(mock_ffmpeg_, AVFree(&codec_context_)) - .Times(1); - EXPECT_CALL(*this, OnInitializeComplete(_)) .WillOnce(SaveInitializeResult(this)); - test_engine_->Initialize(MessageLoop::current(), this, NULL, config_); + test_engine_->Initialize(MessageLoop::current(), this, NULL, config); EXPECT_FALSE(info_.success); } TEST_F(FFmpegVideoDecodeEngineTest, Initialize_OpenDecoderFails) { - // Test avcodec_open() failing. - EXPECT_CALL(mock_ffmpeg_, AVCodecAllocContext()) - .WillOnce(Return(&codec_context_)); - EXPECT_CALL(mock_ffmpeg_, AVCodecFindDecoder(CODEC_ID_H264)) - .WillOnce(Return(&codec_)); - EXPECT_CALL(mock_ffmpeg_, AVCodecAllocFrame()) - .WillOnce(Return(&yuv_frame_)); - EXPECT_CALL(mock_ffmpeg_, AVCodecOpen(&codec_context_, &codec_)) - .WillOnce(Return(-1)); - EXPECT_CALL(mock_ffmpeg_, AVCodecClose(&codec_context_)) - .WillOnce(Return(0)); - EXPECT_CALL(mock_ffmpeg_, AVFree(&yuv_frame_)) - .Times(1); - EXPECT_CALL(mock_ffmpeg_, AVFree(&codec_context_)) - .Times(1); - + // Specify Theora w/o extra data so that avcodec_open() fails. + VideoDecoderConfig config(kCodecTheora, kWidth, kHeight, kSurfaceWidth, + kSurfaceHeight, kFrameRate.num, kFrameRate.den, + NULL, 0); EXPECT_CALL(*this, OnInitializeComplete(_)) .WillOnce(SaveInitializeResult(this)); - test_engine_->Initialize(MessageLoop::current(), this, NULL, config_); + test_engine_->Initialize(MessageLoop::current(), this, NULL, config); EXPECT_FALSE(info_.success); } TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_Normal) { Initialize(); - // We rely on FFmpeg for timestamp and duration reporting. The one tricky - // bit is calculating the duration when |repeat_pict| > 0. - const base::TimeDelta kTimestamp = base::TimeDelta::FromMicroseconds(123); - const base::TimeDelta kDuration = base::TimeDelta::FromMicroseconds(15000); - yuv_frame_.repeat_pict = 1; - yuv_frame_.reordered_opaque = kTimestamp.InMicroseconds(); + // We rely on FFmpeg for timestamp and duration reporting. + const base::TimeDelta kTimestamp = base::TimeDelta::FromMicroseconds(0); + const base::TimeDelta kDuration = base::TimeDelta::FromMicroseconds(10000); // Simulate decoding a single frame. - Decode(); + Decode(i_frame_buffer_); // |video_frame_| timestamp is 0 because we set the timestamp based off // the buffer timestamp. @@ -232,19 +162,11 @@ TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_Normal) { TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_0ByteFrame) { Initialize(); - // Expect a bunch of avcodec calls. - EXPECT_CALL(mock_ffmpeg_, AVInitPacket(_)) - .Times(2); - EXPECT_CALL(mock_ffmpeg_, - AVCodecDecodeVideo2(&codec_context_, &yuv_frame_, _, _)) - .WillOnce(DoAll(SetArgumentPointee<2>(0), // Simulate 0 byte frame. - Return(0))) - .WillOnce(DoAll(SetArgumentPointee<2>(1), // Simulate 1 byte frame. - Return(0))); + scoped_refptr<Buffer> buffer_a = new DataBuffer(1); EXPECT_CALL(*this, ProduceVideoSample(_)) - .WillOnce(DemuxComplete(test_engine_.get(), buffer_)) - .WillOnce(DemuxComplete(test_engine_.get(), buffer_)); + .WillOnce(DemuxComplete(test_engine_.get(), buffer_a)) + .WillOnce(DemuxComplete(test_engine_.get(), i_frame_buffer_)); EXPECT_CALL(*this, ConsumeVideoFrame(_, _)) .WillOnce(DecodeComplete(this)); test_engine_->ProduceVideoFrame(video_frame_); @@ -255,14 +177,19 @@ TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_0ByteFrame) { TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_DecodeError) { Initialize(); - // 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<DataBuffer> buffer = + new DataBuffer(i_frame_buffer_->GetDataSize()); + buffer->SetDataSize(i_frame_buffer_->GetDataSize()); + + uint8* buf = buffer->GetWritableData(); + memcpy(buf, i_frame_buffer_->GetData(), buffer->GetDataSize()); + + // Corrupt bytes by flipping bits w/ xor. + for (size_t i = 0; i < buffer->GetDataSize(); i++) + buf[i] ^= 0xA5; EXPECT_CALL(*this, ProduceVideoSample(_)) - .WillOnce(DemuxComplete(test_engine_.get(), buffer_)); + .WillOnce(DemuxComplete(test_engine_.get(), buffer)); EXPECT_CALL(*this, OnError()); test_engine_->ProduceVideoFrame(video_frame_); @@ -270,46 +197,71 @@ TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_DecodeError) { TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_LargerWidth) { Initialize(); - ChangeDimensions(kWidth * 2, kHeight); - Decode(); + + // Decode a frame and verify the width. + Decode(i_frame_buffer_); + EXPECT_EQ(video_frame_->width(), kWidth); + EXPECT_EQ(video_frame_->height(), kHeight); + + // Now decode a frame with a larger width and verify the output size didn't + // change. + scoped_refptr<Buffer> buffer; + ReadTestDataFile("vp8-I-frame-640x240", &buffer); + Decode(buffer); + + EXPECT_EQ(kWidth, video_frame_->width()); + EXPECT_EQ(kHeight, video_frame_->height()); } TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_SmallerWidth) { Initialize(); - ChangeDimensions(kWidth / 2, kHeight); - Decode(); + + // Decode a frame and verify the width. + Decode(i_frame_buffer_); + EXPECT_EQ(video_frame_->width(), kWidth); + EXPECT_EQ(video_frame_->height(), kHeight); + + // Now decode a frame with a smaller width and verify the output size didn't + // change. + scoped_refptr<Buffer> buffer; + ReadTestDataFile("vp8-I-frame-160x240", &buffer); + Decode(buffer); + EXPECT_EQ(video_frame_->width(), kWidth); + EXPECT_EQ(video_frame_->height(), kHeight); } TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_LargerHeight) { Initialize(); - ChangeDimensions(kWidth, kHeight * 2); - Decode(); -} -TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_SmallerHeight) { - Initialize(); - ChangeDimensions(kWidth, kHeight / 2); - Decode(); + // Decode a frame and verify the width. + Decode(i_frame_buffer_); + EXPECT_EQ(video_frame_->width(), kWidth); + EXPECT_EQ(video_frame_->height(), kHeight); + + // Now decode a frame with a larger height and verify the output + // size didn't change. + scoped_refptr<Buffer> buffer; + ReadTestDataFile("vp8-I-frame-320x480", &buffer); + Decode(buffer); + EXPECT_EQ(kWidth, video_frame_->width()); + EXPECT_EQ(kHeight, video_frame_->height()); } -TEST_F(FFmpegVideoDecodeEngineTest, GetSurfaceFormat) { +TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_SmallerHeight) { Initialize(); - // YV12 formats. - codec_context_.pix_fmt = PIX_FMT_YUV420P; - EXPECT_EQ(VideoFrame::YV12, test_engine_->GetSurfaceFormat()); - codec_context_.pix_fmt = PIX_FMT_YUVJ420P; - EXPECT_EQ(VideoFrame::YV12, test_engine_->GetSurfaceFormat()); - - // YV16 formats. - codec_context_.pix_fmt = PIX_FMT_YUV422P; - EXPECT_EQ(VideoFrame::YV16, test_engine_->GetSurfaceFormat()); - codec_context_.pix_fmt = PIX_FMT_YUVJ422P; - EXPECT_EQ(VideoFrame::YV16, test_engine_->GetSurfaceFormat()); - - // Invalid value. - codec_context_.pix_fmt = PIX_FMT_NONE; - EXPECT_EQ(VideoFrame::INVALID, test_engine_->GetSurfaceFormat()); + // Decode a frame and verify the width. + Decode(i_frame_buffer_); + EXPECT_EQ(video_frame_->width(), kWidth); + EXPECT_EQ(video_frame_->height(), kHeight); + + // Now decode a frame with a smaller height and verify the output size + // didn't change. + scoped_refptr<Buffer> buffer; + ReadTestDataFile("vp8-I-frame-320x120", &buffer); + Decode(buffer); + EXPECT_EQ(kWidth, video_frame_->width()); + EXPECT_EQ(kHeight, video_frame_->height()); } } // namespace media |