| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/memory/scoped_ptr.h" | 5 #include "base/memory/scoped_ptr.h" |
| 6 #include "base/message_loop.h" | 6 #include "base/message_loop.h" |
| 7 #include "media/base/data_buffer.h" | 7 #include "media/base/data_buffer.h" |
| 8 #include "media/base/mock_ffmpeg.h" | |
| 9 #include "media/base/mock_task.h" | 8 #include "media/base/mock_task.h" |
| 10 #include "media/base/pipeline.h" | 9 #include "media/base/pipeline.h" |
| 10 #include "media/base/test_data_util.h" |
| 11 #include "media/filters/ffmpeg_glue.h" |
| 11 #include "media/video/ffmpeg_video_decode_engine.h" | 12 #include "media/video/ffmpeg_video_decode_engine.h" |
| 12 #include "testing/gmock/include/gmock/gmock.h" | 13 #include "testing/gmock/include/gmock/gmock.h" |
| 13 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
| 14 | 15 |
| 15 using ::testing::_; | 16 using ::testing::_; |
| 16 using ::testing::DoAll; | 17 using ::testing::DoAll; |
| 17 using ::testing::Return; | 18 using ::testing::Return; |
| 18 using ::testing::ReturnNull; | 19 using ::testing::ReturnNull; |
| 19 using ::testing::SetArgumentPointee; | 20 using ::testing::SetArgumentPointee; |
| 20 using ::testing::StrictMock; | 21 using ::testing::StrictMock; |
| 21 | 22 |
| 22 namespace media { | 23 namespace media { |
| 23 | 24 |
| 24 static const int kWidth = 320; | 25 static const size_t kWidth = 320; |
| 25 static const int kHeight = 240; | 26 static const size_t kHeight = 240; |
| 26 static const int kSurfaceWidth = 522; | 27 static const int kSurfaceWidth = 522; |
| 27 static const int kSurfaceHeight = 288; | 28 static const int kSurfaceHeight = 288; |
| 28 static const AVRational kFrameRate = { 100, 1 }; | 29 static const AVRational kFrameRate = { 100, 1 }; |
| 29 | 30 |
| 30 static void InitializeFrame(uint8_t* data, int width, AVFrame* frame) { | |
| 31 frame->data[0] = data; | |
| 32 frame->data[1] = data; | |
| 33 frame->data[2] = data; | |
| 34 frame->linesize[0] = width; | |
| 35 frame->linesize[1] = width / 2; | |
| 36 frame->linesize[2] = width / 2; | |
| 37 } | |
| 38 | |
| 39 ACTION_P(DecodeComplete, decoder) { | 31 ACTION_P(DecodeComplete, decoder) { |
| 40 decoder->set_video_frame(arg0); | 32 decoder->set_video_frame(arg0); |
| 41 } | 33 } |
| 42 | 34 |
| 43 ACTION_P2(DemuxComplete, engine, buffer) { | 35 ACTION_P2(DemuxComplete, engine, buffer) { |
| 44 engine->ConsumeVideoSample(buffer); | 36 engine->ConsumeVideoSample(buffer); |
| 45 } | 37 } |
| 46 | 38 |
| 47 ACTION_P(SaveInitializeResult, engine) { | 39 ACTION_P(SaveInitializeResult, engine) { |
| 48 engine->set_video_codec_info(arg0); | 40 engine->set_video_codec_info(arg0); |
| 49 } | 41 } |
| 50 | 42 |
| 51 class FFmpegVideoDecodeEngineTest | 43 class FFmpegVideoDecodeEngineTest |
| 52 : public testing::Test, | 44 : public testing::Test, |
| 53 public VideoDecodeEngine::EventHandler { | 45 public VideoDecodeEngine::EventHandler { |
| 54 public: | 46 public: |
| 55 FFmpegVideoDecodeEngineTest() | 47 FFmpegVideoDecodeEngineTest() |
| 56 : config_(kCodecH264, kWidth, kHeight, kSurfaceWidth, kSurfaceHeight, | 48 : config_(kCodecVP8, kWidth, kHeight, kSurfaceWidth, kSurfaceHeight, |
| 57 kFrameRate.num, kFrameRate.den, NULL, 0) { | 49 kFrameRate.num, kFrameRate.den, NULL, 0) { |
| 50 CHECK(FFmpegGlue::GetInstance()); |
| 58 | 51 |
| 59 // Setup FFmpeg structures. | 52 // Setup FFmpeg structures. |
| 60 frame_buffer_.reset(new uint8[kWidth * kHeight]); | 53 frame_buffer_.reset(new uint8[kWidth * kHeight]); |
| 61 memset(&yuv_frame_, 0, sizeof(yuv_frame_)); | |
| 62 InitializeFrame(frame_buffer_.get(), kWidth, &yuv_frame_); | |
| 63 | |
| 64 memset(&codec_context_, 0, sizeof(codec_context_)); | |
| 65 memset(&codec_, 0, sizeof(codec_)); | |
| 66 | |
| 67 buffer_ = new DataBuffer(1); | |
| 68 | 54 |
| 69 test_engine_.reset(new FFmpegVideoDecodeEngine()); | 55 test_engine_.reset(new FFmpegVideoDecodeEngine()); |
| 70 | 56 |
| 71 video_frame_ = VideoFrame::CreateFrame(VideoFrame::YV12, | 57 video_frame_ = VideoFrame::CreateFrame(VideoFrame::YV12, |
| 72 kWidth, | 58 kWidth, |
| 73 kHeight, | 59 kHeight, |
| 74 kNoTimestamp, | 60 kNoTimestamp, |
| 75 kNoTimestamp); | 61 kNoTimestamp); |
| 62 |
| 63 ReadTestDataFile("vp8-I-frame-320x240", &i_frame_buffer_); |
| 76 } | 64 } |
| 77 | 65 |
| 78 ~FFmpegVideoDecodeEngineTest() { | 66 ~FFmpegVideoDecodeEngineTest() { |
| 79 test_engine_.reset(); | 67 test_engine_.reset(); |
| 80 } | 68 } |
| 81 | 69 |
| 82 void Initialize() { | 70 void Initialize() { |
| 83 EXPECT_CALL(mock_ffmpeg_, AVCodecAllocContext()) | |
| 84 .WillOnce(Return(&codec_context_)); | |
| 85 EXPECT_CALL(mock_ffmpeg_, AVCodecFindDecoder(CODEC_ID_H264)) | |
| 86 .WillOnce(Return(&codec_)); | |
| 87 EXPECT_CALL(mock_ffmpeg_, AVCodecAllocFrame()) | |
| 88 .WillOnce(Return(&yuv_frame_)); | |
| 89 EXPECT_CALL(mock_ffmpeg_, AVCodecOpen(&codec_context_, &codec_)) | |
| 90 .WillOnce(Return(0)); | |
| 91 EXPECT_CALL(mock_ffmpeg_, AVCodecClose(&codec_context_)) | |
| 92 .WillOnce(Return(0)); | |
| 93 EXPECT_CALL(mock_ffmpeg_, AVFree(&yuv_frame_)) | |
| 94 .Times(1); | |
| 95 EXPECT_CALL(mock_ffmpeg_, AVFree(&codec_context_)) | |
| 96 .Times(1); | |
| 97 | |
| 98 EXPECT_CALL(*this, OnInitializeComplete(_)) | 71 EXPECT_CALL(*this, OnInitializeComplete(_)) |
| 99 .WillOnce(SaveInitializeResult(this)); | 72 .WillOnce(SaveInitializeResult(this)); |
| 100 test_engine_->Initialize(MessageLoop::current(), this, NULL, config_); | 73 test_engine_->Initialize(MessageLoop::current(), this, NULL, config_); |
| 101 EXPECT_TRUE(info_.success); | 74 EXPECT_TRUE(info_.success); |
| 102 } | 75 } |
| 103 | 76 |
| 104 void Decode() { | 77 void Decode(const scoped_refptr<Buffer>& buffer) { |
| 105 EXPECT_CALL(mock_ffmpeg_, AVInitPacket(_)); | |
| 106 EXPECT_CALL(mock_ffmpeg_, | |
| 107 AVCodecDecodeVideo2(&codec_context_, &yuv_frame_, _, _)) | |
| 108 .WillOnce(DoAll(SetArgumentPointee<2>(1), // Simulate 1 byte frame. | |
| 109 Return(0))); | |
| 110 | |
| 111 EXPECT_CALL(*this, ProduceVideoSample(_)) | 78 EXPECT_CALL(*this, ProduceVideoSample(_)) |
| 112 .WillOnce(DemuxComplete(test_engine_.get(), buffer_)); | 79 .WillOnce(DemuxComplete(test_engine_.get(), buffer)); |
| 113 EXPECT_CALL(*this, ConsumeVideoFrame(_, _)) | 80 EXPECT_CALL(*this, ConsumeVideoFrame(_, _)) |
| 114 .WillOnce(DecodeComplete(this)); | 81 .WillOnce(DecodeComplete(this)); |
| 115 test_engine_->ProduceVideoFrame(video_frame_); | 82 test_engine_->ProduceVideoFrame(video_frame_); |
| 116 } | 83 } |
| 117 | 84 |
| 118 void ChangeDimensions(int width, int height) { | |
| 119 frame_buffer_.reset(new uint8[width * height]); | |
| 120 InitializeFrame(frame_buffer_.get(), width, &yuv_frame_); | |
| 121 codec_context_.width = width; | |
| 122 codec_context_.height = height; | |
| 123 } | |
| 124 | |
| 125 // VideoDecodeEngine::EventHandler implementation. | 85 // VideoDecodeEngine::EventHandler implementation. |
| 126 MOCK_METHOD2(ConsumeVideoFrame, | 86 MOCK_METHOD2(ConsumeVideoFrame, |
| 127 void(scoped_refptr<VideoFrame> video_frame, | 87 void(scoped_refptr<VideoFrame> video_frame, |
| 128 const PipelineStatistics& statistics)); | 88 const PipelineStatistics& statistics)); |
| 129 MOCK_METHOD1(ProduceVideoSample, | 89 MOCK_METHOD1(ProduceVideoSample, |
| 130 void(scoped_refptr<Buffer> buffer)); | 90 void(scoped_refptr<Buffer> buffer)); |
| 131 MOCK_METHOD1(OnInitializeComplete, | 91 MOCK_METHOD1(OnInitializeComplete, |
| 132 void(const VideoCodecInfo& info)); | 92 void(const VideoCodecInfo& info)); |
| 133 MOCK_METHOD0(OnUninitializeComplete, void()); | 93 MOCK_METHOD0(OnUninitializeComplete, void()); |
| 134 MOCK_METHOD0(OnFlushComplete, void()); | 94 MOCK_METHOD0(OnFlushComplete, void()); |
| 135 MOCK_METHOD0(OnSeekComplete, void()); | 95 MOCK_METHOD0(OnSeekComplete, void()); |
| 136 MOCK_METHOD0(OnError, void()); | 96 MOCK_METHOD0(OnError, void()); |
| 137 | 97 |
| 138 // Used by gmock actions. | 98 // Used by gmock actions. |
| 139 void set_video_frame(scoped_refptr<VideoFrame> video_frame) { | 99 void set_video_frame(scoped_refptr<VideoFrame> video_frame) { |
| 140 video_frame_ = video_frame; | 100 video_frame_ = video_frame; |
| 141 } | 101 } |
| 142 | 102 |
| 143 void set_video_codec_info(const VideoCodecInfo& info) { | 103 void set_video_codec_info(const VideoCodecInfo& info) { |
| 144 info_ = info; | 104 info_ = info; |
| 145 } | 105 } |
| 146 | 106 |
| 147 protected: | 107 protected: |
| 148 VideoDecoderConfig config_; | 108 VideoDecoderConfig config_; |
| 149 VideoCodecInfo info_; | 109 VideoCodecInfo info_; |
| 150 scoped_refptr<VideoFrame> video_frame_; | 110 scoped_refptr<VideoFrame> video_frame_; |
| 151 scoped_ptr<FFmpegVideoDecodeEngine> test_engine_; | 111 scoped_ptr<FFmpegVideoDecodeEngine> test_engine_; |
| 152 scoped_array<uint8_t> frame_buffer_; | 112 scoped_array<uint8_t> frame_buffer_; |
| 153 StrictMock<MockFFmpeg> mock_ffmpeg_; | 113 scoped_refptr<Buffer> i_frame_buffer_; |
| 154 | |
| 155 AVFrame yuv_frame_; | |
| 156 AVCodecContext codec_context_; | |
| 157 AVCodec codec_; | |
| 158 scoped_refptr<DataBuffer> buffer_; | |
| 159 | 114 |
| 160 private: | 115 private: |
| 161 DISALLOW_COPY_AND_ASSIGN(FFmpegVideoDecodeEngineTest); | 116 DISALLOW_COPY_AND_ASSIGN(FFmpegVideoDecodeEngineTest); |
| 162 }; | 117 }; |
| 163 | 118 |
| 164 TEST_F(FFmpegVideoDecodeEngineTest, Initialize_Normal) { | 119 TEST_F(FFmpegVideoDecodeEngineTest, Initialize_Normal) { |
| 165 Initialize(); | 120 Initialize(); |
| 166 } | 121 } |
| 167 | 122 |
| 168 TEST_F(FFmpegVideoDecodeEngineTest, Initialize_FindDecoderFails) { | 123 TEST_F(FFmpegVideoDecodeEngineTest, Initialize_FindDecoderFails) { |
| 124 VideoDecoderConfig config(kUnknown, kWidth, kHeight, kSurfaceWidth, |
| 125 kSurfaceHeight, kFrameRate.num, kFrameRate.den, |
| 126 NULL, 0); |
| 169 // Test avcodec_find_decoder() returning NULL. | 127 // Test avcodec_find_decoder() returning NULL. |
| 170 EXPECT_CALL(mock_ffmpeg_, AVCodecAllocContext()) | |
| 171 .WillOnce(Return(&codec_context_)); | |
| 172 EXPECT_CALL(mock_ffmpeg_, AVCodecFindDecoder(CODEC_ID_H264)) | |
| 173 .WillOnce(ReturnNull()); | |
| 174 EXPECT_CALL(mock_ffmpeg_, AVCodecAllocFrame()) | |
| 175 .WillOnce(Return(&yuv_frame_)); | |
| 176 EXPECT_CALL(mock_ffmpeg_, AVCodecClose(&codec_context_)) | |
| 177 .WillOnce(Return(0)); | |
| 178 EXPECT_CALL(mock_ffmpeg_, AVFree(&yuv_frame_)) | |
| 179 .Times(1); | |
| 180 EXPECT_CALL(mock_ffmpeg_, AVFree(&codec_context_)) | |
| 181 .Times(1); | |
| 182 | |
| 183 EXPECT_CALL(*this, OnInitializeComplete(_)) | 128 EXPECT_CALL(*this, OnInitializeComplete(_)) |
| 184 .WillOnce(SaveInitializeResult(this)); | 129 .WillOnce(SaveInitializeResult(this)); |
| 185 test_engine_->Initialize(MessageLoop::current(), this, NULL, config_); | 130 test_engine_->Initialize(MessageLoop::current(), this, NULL, config); |
| 186 EXPECT_FALSE(info_.success); | 131 EXPECT_FALSE(info_.success); |
| 187 } | 132 } |
| 188 | 133 |
| 189 TEST_F(FFmpegVideoDecodeEngineTest, Initialize_OpenDecoderFails) { | 134 TEST_F(FFmpegVideoDecodeEngineTest, Initialize_OpenDecoderFails) { |
| 190 // Test avcodec_open() failing. | 135 // Specify Theora w/o extra data so that avcodec_open() fails. |
| 191 EXPECT_CALL(mock_ffmpeg_, AVCodecAllocContext()) | 136 VideoDecoderConfig config(kCodecTheora, kWidth, kHeight, kSurfaceWidth, |
| 192 .WillOnce(Return(&codec_context_)); | 137 kSurfaceHeight, kFrameRate.num, kFrameRate.den, |
| 193 EXPECT_CALL(mock_ffmpeg_, AVCodecFindDecoder(CODEC_ID_H264)) | 138 NULL, 0); |
| 194 .WillOnce(Return(&codec_)); | |
| 195 EXPECT_CALL(mock_ffmpeg_, AVCodecAllocFrame()) | |
| 196 .WillOnce(Return(&yuv_frame_)); | |
| 197 EXPECT_CALL(mock_ffmpeg_, AVCodecOpen(&codec_context_, &codec_)) | |
| 198 .WillOnce(Return(-1)); | |
| 199 EXPECT_CALL(mock_ffmpeg_, AVCodecClose(&codec_context_)) | |
| 200 .WillOnce(Return(0)); | |
| 201 EXPECT_CALL(mock_ffmpeg_, AVFree(&yuv_frame_)) | |
| 202 .Times(1); | |
| 203 EXPECT_CALL(mock_ffmpeg_, AVFree(&codec_context_)) | |
| 204 .Times(1); | |
| 205 | |
| 206 EXPECT_CALL(*this, OnInitializeComplete(_)) | 139 EXPECT_CALL(*this, OnInitializeComplete(_)) |
| 207 .WillOnce(SaveInitializeResult(this)); | 140 .WillOnce(SaveInitializeResult(this)); |
| 208 test_engine_->Initialize(MessageLoop::current(), this, NULL, config_); | 141 test_engine_->Initialize(MessageLoop::current(), this, NULL, config); |
| 209 EXPECT_FALSE(info_.success); | 142 EXPECT_FALSE(info_.success); |
| 210 } | 143 } |
| 211 | 144 |
| 212 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_Normal) { | 145 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_Normal) { |
| 213 Initialize(); | 146 Initialize(); |
| 214 | 147 |
| 215 // We rely on FFmpeg for timestamp and duration reporting. The one tricky | 148 // We rely on FFmpeg for timestamp and duration reporting. |
| 216 // bit is calculating the duration when |repeat_pict| > 0. | 149 const base::TimeDelta kTimestamp = base::TimeDelta::FromMicroseconds(0); |
| 217 const base::TimeDelta kTimestamp = base::TimeDelta::FromMicroseconds(123); | 150 const base::TimeDelta kDuration = base::TimeDelta::FromMicroseconds(10000); |
| 218 const base::TimeDelta kDuration = base::TimeDelta::FromMicroseconds(15000); | |
| 219 yuv_frame_.repeat_pict = 1; | |
| 220 yuv_frame_.reordered_opaque = kTimestamp.InMicroseconds(); | |
| 221 | 151 |
| 222 // Simulate decoding a single frame. | 152 // Simulate decoding a single frame. |
| 223 Decode(); | 153 Decode(i_frame_buffer_); |
| 224 | 154 |
| 225 // |video_frame_| timestamp is 0 because we set the timestamp based off | 155 // |video_frame_| timestamp is 0 because we set the timestamp based off |
| 226 // the buffer timestamp. | 156 // the buffer timestamp. |
| 227 EXPECT_EQ(0, video_frame_->GetTimestamp().ToInternalValue()); | 157 EXPECT_EQ(0, video_frame_->GetTimestamp().ToInternalValue()); |
| 228 EXPECT_EQ(kDuration.ToInternalValue(), | 158 EXPECT_EQ(kDuration.ToInternalValue(), |
| 229 video_frame_->GetDuration().ToInternalValue()); | 159 video_frame_->GetDuration().ToInternalValue()); |
| 230 } | 160 } |
| 231 | 161 |
| 232 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_0ByteFrame) { | 162 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_0ByteFrame) { |
| 233 Initialize(); | 163 Initialize(); |
| 234 | 164 |
| 235 // Expect a bunch of avcodec calls. | 165 scoped_refptr<Buffer> buffer_a = new DataBuffer(1); |
| 236 EXPECT_CALL(mock_ffmpeg_, AVInitPacket(_)) | |
| 237 .Times(2); | |
| 238 EXPECT_CALL(mock_ffmpeg_, | |
| 239 AVCodecDecodeVideo2(&codec_context_, &yuv_frame_, _, _)) | |
| 240 .WillOnce(DoAll(SetArgumentPointee<2>(0), // Simulate 0 byte frame. | |
| 241 Return(0))) | |
| 242 .WillOnce(DoAll(SetArgumentPointee<2>(1), // Simulate 1 byte frame. | |
| 243 Return(0))); | |
| 244 | 166 |
| 245 EXPECT_CALL(*this, ProduceVideoSample(_)) | 167 EXPECT_CALL(*this, ProduceVideoSample(_)) |
| 246 .WillOnce(DemuxComplete(test_engine_.get(), buffer_)) | 168 .WillOnce(DemuxComplete(test_engine_.get(), buffer_a)) |
| 247 .WillOnce(DemuxComplete(test_engine_.get(), buffer_)); | 169 .WillOnce(DemuxComplete(test_engine_.get(), i_frame_buffer_)); |
| 248 EXPECT_CALL(*this, ConsumeVideoFrame(_, _)) | 170 EXPECT_CALL(*this, ConsumeVideoFrame(_, _)) |
| 249 .WillOnce(DecodeComplete(this)); | 171 .WillOnce(DecodeComplete(this)); |
| 250 test_engine_->ProduceVideoFrame(video_frame_); | 172 test_engine_->ProduceVideoFrame(video_frame_); |
| 251 | 173 |
| 252 EXPECT_TRUE(video_frame_.get()); | 174 EXPECT_TRUE(video_frame_.get()); |
| 253 } | 175 } |
| 254 | 176 |
| 255 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_DecodeError) { | 177 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_DecodeError) { |
| 256 Initialize(); | 178 Initialize(); |
| 257 | 179 |
| 258 // Expect a bunch of avcodec calls. | 180 scoped_refptr<DataBuffer> buffer = |
| 259 EXPECT_CALL(mock_ffmpeg_, AVInitPacket(_)); | 181 new DataBuffer(i_frame_buffer_->GetDataSize()); |
| 260 EXPECT_CALL(mock_ffmpeg_, | 182 buffer->SetDataSize(i_frame_buffer_->GetDataSize()); |
| 261 AVCodecDecodeVideo2(&codec_context_, &yuv_frame_, _, _)) | 183 |
| 262 .WillOnce(Return(-1)); | 184 uint8* buf = buffer->GetWritableData(); |
| 185 memcpy(buf, i_frame_buffer_->GetData(), buffer->GetDataSize()); |
| 186 |
| 187 // Corrupt bytes by flipping bits w/ xor. |
| 188 for (size_t i = 0; i < buffer->GetDataSize(); i++) |
| 189 buf[i] ^= 0xA5; |
| 263 | 190 |
| 264 EXPECT_CALL(*this, ProduceVideoSample(_)) | 191 EXPECT_CALL(*this, ProduceVideoSample(_)) |
| 265 .WillOnce(DemuxComplete(test_engine_.get(), buffer_)); | 192 .WillOnce(DemuxComplete(test_engine_.get(), buffer)); |
| 266 EXPECT_CALL(*this, OnError()); | 193 EXPECT_CALL(*this, OnError()); |
| 267 | 194 |
| 268 test_engine_->ProduceVideoFrame(video_frame_); | 195 test_engine_->ProduceVideoFrame(video_frame_); |
| 269 } | 196 } |
| 270 | 197 |
| 271 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_LargerWidth) { | 198 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_LargerWidth) { |
| 272 Initialize(); | 199 Initialize(); |
| 273 ChangeDimensions(kWidth * 2, kHeight); | 200 |
| 274 Decode(); | 201 // Decode a frame and verify the width. |
| 202 Decode(i_frame_buffer_); |
| 203 EXPECT_EQ(video_frame_->width(), kWidth); |
| 204 EXPECT_EQ(video_frame_->height(), kHeight); |
| 205 |
| 206 // Now decode a frame with a larger width and verify the output size didn't |
| 207 // change. |
| 208 scoped_refptr<Buffer> buffer; |
| 209 ReadTestDataFile("vp8-I-frame-640x240", &buffer); |
| 210 Decode(buffer); |
| 211 |
| 212 EXPECT_EQ(kWidth, video_frame_->width()); |
| 213 EXPECT_EQ(kHeight, video_frame_->height()); |
| 275 } | 214 } |
| 276 | 215 |
| 277 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_SmallerWidth) { | 216 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_SmallerWidth) { |
| 278 Initialize(); | 217 Initialize(); |
| 279 ChangeDimensions(kWidth / 2, kHeight); | 218 |
| 280 Decode(); | 219 // Decode a frame and verify the width. |
| 220 Decode(i_frame_buffer_); |
| 221 EXPECT_EQ(video_frame_->width(), kWidth); |
| 222 EXPECT_EQ(video_frame_->height(), kHeight); |
| 223 |
| 224 // Now decode a frame with a smaller width and verify the output size didn't |
| 225 // change. |
| 226 scoped_refptr<Buffer> buffer; |
| 227 ReadTestDataFile("vp8-I-frame-160x240", &buffer); |
| 228 Decode(buffer); |
| 229 EXPECT_EQ(video_frame_->width(), kWidth); |
| 230 EXPECT_EQ(video_frame_->height(), kHeight); |
| 281 } | 231 } |
| 282 | 232 |
| 283 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_LargerHeight) { | 233 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_LargerHeight) { |
| 284 Initialize(); | 234 Initialize(); |
| 285 ChangeDimensions(kWidth, kHeight * 2); | 235 |
| 286 Decode(); | 236 // Decode a frame and verify the width. |
| 237 Decode(i_frame_buffer_); |
| 238 EXPECT_EQ(video_frame_->width(), kWidth); |
| 239 EXPECT_EQ(video_frame_->height(), kHeight); |
| 240 |
| 241 // Now decode a frame with a larger height and verify the output |
| 242 // size didn't change. |
| 243 scoped_refptr<Buffer> buffer; |
| 244 ReadTestDataFile("vp8-I-frame-320x480", &buffer); |
| 245 Decode(buffer); |
| 246 EXPECT_EQ(kWidth, video_frame_->width()); |
| 247 EXPECT_EQ(kHeight, video_frame_->height()); |
| 287 } | 248 } |
| 288 | 249 |
| 289 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_SmallerHeight) { | 250 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_SmallerHeight) { |
| 290 Initialize(); | 251 Initialize(); |
| 291 ChangeDimensions(kWidth, kHeight / 2); | |
| 292 Decode(); | |
| 293 } | |
| 294 | 252 |
| 295 TEST_F(FFmpegVideoDecodeEngineTest, GetSurfaceFormat) { | 253 // Decode a frame and verify the width. |
| 296 Initialize(); | 254 Decode(i_frame_buffer_); |
| 255 EXPECT_EQ(video_frame_->width(), kWidth); |
| 256 EXPECT_EQ(video_frame_->height(), kHeight); |
| 297 | 257 |
| 298 // YV12 formats. | 258 // Now decode a frame with a smaller height and verify the output size |
| 299 codec_context_.pix_fmt = PIX_FMT_YUV420P; | 259 // didn't change. |
| 300 EXPECT_EQ(VideoFrame::YV12, test_engine_->GetSurfaceFormat()); | 260 scoped_refptr<Buffer> buffer; |
| 301 codec_context_.pix_fmt = PIX_FMT_YUVJ420P; | 261 ReadTestDataFile("vp8-I-frame-320x120", &buffer); |
| 302 EXPECT_EQ(VideoFrame::YV12, test_engine_->GetSurfaceFormat()); | 262 Decode(buffer); |
| 303 | 263 EXPECT_EQ(kWidth, video_frame_->width()); |
| 304 // YV16 formats. | 264 EXPECT_EQ(kHeight, video_frame_->height()); |
| 305 codec_context_.pix_fmt = PIX_FMT_YUV422P; | |
| 306 EXPECT_EQ(VideoFrame::YV16, test_engine_->GetSurfaceFormat()); | |
| 307 codec_context_.pix_fmt = PIX_FMT_YUVJ422P; | |
| 308 EXPECT_EQ(VideoFrame::YV16, test_engine_->GetSurfaceFormat()); | |
| 309 | |
| 310 // Invalid value. | |
| 311 codec_context_.pix_fmt = PIX_FMT_NONE; | |
| 312 EXPECT_EQ(VideoFrame::INVALID, test_engine_->GetSurfaceFormat()); | |
| 313 } | 265 } |
| 314 | 266 |
| 315 } // namespace media | 267 } // namespace media |
| OLD | NEW |