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

Side by Side Diff: media/video/ffmpeg_video_decode_engine_unittest.cc

Issue 7587012: Remove mock_ffmpeg and update media unittests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix FFmpegVideoDecodeEngineTest to work with multithreaded decoders Created 9 years, 4 months 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/video/ffmpeg_video_decode_engine.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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;
20 using ::testing::SaveArg;
19 using ::testing::SetArgumentPointee; 21 using ::testing::SetArgumentPointee;
20 using ::testing::StrictMock; 22 using ::testing::StrictMock;
21 23
22 namespace media { 24 namespace media {
23 25
24 static const int kWidth = 320; 26 static const size_t kWidth = 320;
25 static const int kHeight = 240; 27 static const size_t kHeight = 240;
26 static const int kSurfaceWidth = 522; 28 static const int kSurfaceWidth = 522;
27 static const int kSurfaceHeight = 288; 29 static const int kSurfaceHeight = 288;
28 static const AVRational kFrameRate = { 100, 1 }; 30 static const AVRational kFrameRate = { 100, 1 };
29 31
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) {
40 decoder->set_video_frame(arg0);
41 }
42
43 ACTION_P2(DemuxComplete, engine, buffer) { 32 ACTION_P2(DemuxComplete, engine, buffer) {
44 engine->ConsumeVideoSample(buffer); 33 engine->ConsumeVideoSample(buffer);
45 } 34 }
46 35
47 ACTION_P(SaveInitializeResult, engine) {
48 engine->set_video_codec_info(arg0);
49 }
50
51 class FFmpegVideoDecodeEngineTest 36 class FFmpegVideoDecodeEngineTest
52 : public testing::Test, 37 : public testing::Test,
53 public VideoDecodeEngine::EventHandler { 38 public VideoDecodeEngine::EventHandler {
54 public: 39 public:
55 FFmpegVideoDecodeEngineTest() 40 FFmpegVideoDecodeEngineTest()
56 : config_(kCodecH264, kWidth, kHeight, kSurfaceWidth, kSurfaceHeight, 41 : config_(kCodecVP8, kWidth, kHeight, kSurfaceWidth, kSurfaceHeight,
57 kFrameRate.num, kFrameRate.den, NULL, 0) { 42 kFrameRate.num, kFrameRate.den, NULL, 0) {
43 CHECK(FFmpegGlue::GetInstance());
58 44
59 // Setup FFmpeg structures. 45 // Setup FFmpeg structures.
60 frame_buffer_.reset(new uint8[kWidth * kHeight]); 46 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 47
69 test_engine_.reset(new FFmpegVideoDecodeEngine()); 48 test_engine_.reset(new FFmpegVideoDecodeEngine());
70 49
71 video_frame_ = VideoFrame::CreateFrame(VideoFrame::YV12, 50 ReadTestDataFile("vp8-I-frame-320x240", &i_frame_buffer_);
72 kWidth, 51
73 kHeight, 52 // Create a corrupt version of |i_frame_buffer_|.
scherkus (not reviewing) 2011/08/23 14:42:08 couldn't this be a file?
74 kNoTimestamp, 53 corrupt_i_frame_buffer_ = new DataBuffer(i_frame_buffer_->GetDataSize());
75 kNoTimestamp); 54 corrupt_i_frame_buffer_->SetDataSize(i_frame_buffer_->GetDataSize());
55
56 uint8* buf = corrupt_i_frame_buffer_->GetWritableData();
57 memcpy(buf, i_frame_buffer_->GetData(),
58 corrupt_i_frame_buffer_->GetDataSize());
59
60 // Corrupt bytes by flipping bits w/ xor.
61 for (size_t i = 0; i < corrupt_i_frame_buffer_->GetDataSize(); i++)
62 buf[i] ^= 0xA5;
63
64 end_of_stream_buffer_ = new DataBuffer(0);
76 } 65 }
77 66
78 ~FFmpegVideoDecodeEngineTest() { 67 ~FFmpegVideoDecodeEngineTest() {
79 test_engine_.reset(); 68 test_engine_.reset();
80 } 69 }
81 70
82 void Initialize() { 71 void Initialize() {
83 EXPECT_CALL(mock_ffmpeg_, AVCodecAllocContext()) 72 VideoCodecInfo info;
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(_)) 73 EXPECT_CALL(*this, OnInitializeComplete(_))
99 .WillOnce(SaveInitializeResult(this)); 74 .WillOnce(SaveArg<0>(&info));
100 test_engine_->Initialize(MessageLoop::current(), this, NULL, config_); 75 test_engine_->Initialize(MessageLoop::current(), this, NULL, config_);
101 EXPECT_TRUE(info_.success); 76 EXPECT_TRUE(info.success);
102 } 77 }
103 78
104 void Decode() { 79 // Decodes the single compressed frame in |buffer| and writes the
105 EXPECT_CALL(mock_ffmpeg_, AVInitPacket(_)); 80 // uncompressed output to |video_frame|. This method works with single
106 EXPECT_CALL(mock_ffmpeg_, 81 // and multithreaded decoders. End of stream buffers are used to trigger
107 AVCodecDecodeVideo2(&codec_context_, &yuv_frame_, _, _)) 82 // the frame to be returned in the multithreaded decoder case.
108 .WillOnce(DoAll(SetArgumentPointee<2>(1), // Simulate 1 byte frame. 83 void DecodeASingleFrame(const scoped_refptr<Buffer>& buffer,
109 Return(0))); 84 scoped_refptr<VideoFrame>* video_frame) {
85 EXPECT_CALL(*this, ProduceVideoSample(_))
86 .WillOnce(DemuxComplete(test_engine_.get(), buffer))
87 .WillRepeatedly(DemuxComplete(test_engine_.get(),
88 end_of_stream_buffer_));
89
90 EXPECT_CALL(*this, ConsumeVideoFrame(_, _))
91 .WillOnce(SaveArg<0>(video_frame));
92 CallProduceVideoFrame();
93 }
94
95 // Decodes |i_frame_buffer_| and then decodes the data contained in
96 // the file named |test_file_name|. This function expects both buffers
97 // to decode to frames that are the same size.
98 void DecodeIFrameThenTestFile(const std::string& test_file_name) {
99 Initialize();
100
101 scoped_refptr<VideoFrame> video_frame_a;
102 scoped_refptr<VideoFrame> video_frame_b;
103
104 scoped_refptr<Buffer> buffer;
105 ReadTestDataFile(test_file_name, &buffer);
110 106
111 EXPECT_CALL(*this, ProduceVideoSample(_)) 107 EXPECT_CALL(*this, ProduceVideoSample(_))
112 .WillOnce(DemuxComplete(test_engine_.get(), buffer_)); 108 .WillOnce(DemuxComplete(test_engine_.get(), i_frame_buffer_))
109 .WillOnce(DemuxComplete(test_engine_.get(), buffer))
110 .WillRepeatedly(DemuxComplete(test_engine_.get(),
111 end_of_stream_buffer_));
112
113 EXPECT_CALL(*this, ConsumeVideoFrame(_, _)) 113 EXPECT_CALL(*this, ConsumeVideoFrame(_, _))
114 .WillOnce(DecodeComplete(this)); 114 .WillOnce(SaveArg<0>(&video_frame_a))
115 test_engine_->ProduceVideoFrame(video_frame_); 115 .WillOnce(SaveArg<0>(&video_frame_b));
116 } 116 CallProduceVideoFrame();
117 CallProduceVideoFrame();
117 118
118 void ChangeDimensions(int width, int height) { 119 EXPECT_EQ(kWidth, video_frame_a->width());
119 frame_buffer_.reset(new uint8[width * height]); 120 EXPECT_EQ(kHeight, video_frame_a->height());
120 InitializeFrame(frame_buffer_.get(), width, &yuv_frame_); 121 EXPECT_EQ(kWidth, video_frame_b->width());
121 codec_context_.width = width; 122 EXPECT_EQ(kHeight, video_frame_b->height());
122 codec_context_.height = height;
123 } 123 }
124 124
125 // VideoDecodeEngine::EventHandler implementation. 125 // VideoDecodeEngine::EventHandler implementation.
126 MOCK_METHOD2(ConsumeVideoFrame, 126 MOCK_METHOD2(ConsumeVideoFrame,
127 void(scoped_refptr<VideoFrame> video_frame, 127 void(scoped_refptr<VideoFrame> video_frame,
128 const PipelineStatistics& statistics)); 128 const PipelineStatistics& statistics));
129 MOCK_METHOD1(ProduceVideoSample, 129 MOCK_METHOD1(ProduceVideoSample,
130 void(scoped_refptr<Buffer> buffer)); 130 void(scoped_refptr<Buffer> buffer));
131 MOCK_METHOD1(OnInitializeComplete, 131 MOCK_METHOD1(OnInitializeComplete,
132 void(const VideoCodecInfo& info)); 132 void(const VideoCodecInfo& info));
133 MOCK_METHOD0(OnUninitializeComplete, void()); 133 MOCK_METHOD0(OnUninitializeComplete, void());
134 MOCK_METHOD0(OnFlushComplete, void()); 134 MOCK_METHOD0(OnFlushComplete, void());
135 MOCK_METHOD0(OnSeekComplete, void()); 135 MOCK_METHOD0(OnSeekComplete, void());
136 MOCK_METHOD0(OnError, void()); 136 MOCK_METHOD0(OnError, void());
137 137
138 // Used by gmock actions. 138 void CallProduceVideoFrame() {
139 void set_video_frame(scoped_refptr<VideoFrame> video_frame) { 139 test_engine_->ProduceVideoFrame(VideoFrame::CreateFrame(VideoFrame::YV12,
140 video_frame_ = video_frame; 140 kWidth,
141 } 141 kHeight,
142 142 kNoTimestamp,
143 void set_video_codec_info(const VideoCodecInfo& info) { 143 kNoTimestamp));
144 info_ = info;
145 } 144 }
146 145
147 protected: 146 protected:
148 VideoDecoderConfig config_; 147 VideoDecoderConfig config_;
149 VideoCodecInfo info_;
150 scoped_refptr<VideoFrame> video_frame_;
151 scoped_ptr<FFmpegVideoDecodeEngine> test_engine_; 148 scoped_ptr<FFmpegVideoDecodeEngine> test_engine_;
152 scoped_array<uint8_t> frame_buffer_; 149 scoped_array<uint8_t> frame_buffer_;
153 StrictMock<MockFFmpeg> mock_ffmpeg_; 150 scoped_refptr<Buffer> i_frame_buffer_;
154 151 scoped_refptr<DataBuffer> corrupt_i_frame_buffer_;
155 AVFrame yuv_frame_; 152 scoped_refptr<Buffer> end_of_stream_buffer_;
156 AVCodecContext codec_context_;
157 AVCodec codec_;
158 scoped_refptr<DataBuffer> buffer_;
159 153
160 private: 154 private:
161 DISALLOW_COPY_AND_ASSIGN(FFmpegVideoDecodeEngineTest); 155 DISALLOW_COPY_AND_ASSIGN(FFmpegVideoDecodeEngineTest);
162 }; 156 };
163 157
164 TEST_F(FFmpegVideoDecodeEngineTest, Initialize_Normal) { 158 TEST_F(FFmpegVideoDecodeEngineTest, Initialize_Normal) {
165 Initialize(); 159 Initialize();
166 } 160 }
167 161
168 TEST_F(FFmpegVideoDecodeEngineTest, Initialize_FindDecoderFails) { 162 TEST_F(FFmpegVideoDecodeEngineTest, Initialize_FindDecoderFails) {
163 VideoDecoderConfig config(kUnknown, kWidth, kHeight, kSurfaceWidth,
164 kSurfaceHeight, kFrameRate.num, kFrameRate.den,
165 NULL, 0);
169 // Test avcodec_find_decoder() returning NULL. 166 // Test avcodec_find_decoder() returning NULL.
170 EXPECT_CALL(mock_ffmpeg_, AVCodecAllocContext()) 167 VideoCodecInfo info;
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(_)) 168 EXPECT_CALL(*this, OnInitializeComplete(_))
184 .WillOnce(SaveInitializeResult(this)); 169 .WillOnce(SaveArg<0>(&info));
185 test_engine_->Initialize(MessageLoop::current(), this, NULL, config_); 170 test_engine_->Initialize(MessageLoop::current(), this, NULL, config);
186 EXPECT_FALSE(info_.success); 171 EXPECT_FALSE(info.success);
187 } 172 }
188 173
189 TEST_F(FFmpegVideoDecodeEngineTest, Initialize_OpenDecoderFails) { 174 TEST_F(FFmpegVideoDecodeEngineTest, Initialize_OpenDecoderFails) {
190 // Test avcodec_open() failing. 175 // Specify Theora w/o extra data so that avcodec_open() fails.
191 EXPECT_CALL(mock_ffmpeg_, AVCodecAllocContext()) 176 VideoDecoderConfig config(kCodecTheora, kWidth, kHeight, kSurfaceWidth,
192 .WillOnce(Return(&codec_context_)); 177 kSurfaceHeight, kFrameRate.num, kFrameRate.den,
193 EXPECT_CALL(mock_ffmpeg_, AVCodecFindDecoder(CODEC_ID_H264)) 178 NULL, 0);
194 .WillOnce(Return(&codec_)); 179 VideoCodecInfo info;
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(_)) 180 EXPECT_CALL(*this, OnInitializeComplete(_))
207 .WillOnce(SaveInitializeResult(this)); 181 .WillOnce(SaveArg<0>(&info));
208 test_engine_->Initialize(MessageLoop::current(), this, NULL, config_); 182 test_engine_->Initialize(MessageLoop::current(), this, NULL, config);
209 EXPECT_FALSE(info_.success); 183 EXPECT_FALSE(info.success);
210 } 184 }
211 185
212 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_Normal) { 186 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_Normal) {
213 Initialize(); 187 Initialize();
214 188
215 // We rely on FFmpeg for timestamp and duration reporting. The one tricky 189 // We rely on FFmpeg for timestamp and duration reporting.
216 // bit is calculating the duration when |repeat_pict| > 0. 190 const base::TimeDelta kTimestamp = base::TimeDelta::FromMicroseconds(0);
217 const base::TimeDelta kTimestamp = base::TimeDelta::FromMicroseconds(123); 191 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 192
222 // Simulate decoding a single frame. 193 // Simulate decoding a single frame.
223 Decode(); 194 scoped_refptr<VideoFrame> video_frame;
195 DecodeASingleFrame(i_frame_buffer_, &video_frame);
224 196
225 // |video_frame_| timestamp is 0 because we set the timestamp based off 197 // |video_frame| timestamp is 0 because we set the timestamp based off
226 // the buffer timestamp. 198 // the buffer timestamp.
227 EXPECT_EQ(0, video_frame_->GetTimestamp().ToInternalValue()); 199 ASSERT_TRUE(video_frame);
200 EXPECT_EQ(0, video_frame->GetTimestamp().ToInternalValue());
228 EXPECT_EQ(kDuration.ToInternalValue(), 201 EXPECT_EQ(kDuration.ToInternalValue(),
229 video_frame_->GetDuration().ToInternalValue()); 202 video_frame->GetDuration().ToInternalValue());
230 } 203 }
231 204
205
206 // Verify current behavior for 0 byte frames. FFmpeg simply ignores
207 // the 0 byte frames.
232 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_0ByteFrame) { 208 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_0ByteFrame) {
233 Initialize(); 209 Initialize();
234 210
235 // Expect a bunch of avcodec calls. 211 scoped_refptr<DataBuffer> zero_byte_buffer = new DataBuffer(1);
236 EXPECT_CALL(mock_ffmpeg_, AVInitPacket(_)) 212
237 .Times(2); 213 scoped_refptr<VideoFrame> video_frame_a;
238 EXPECT_CALL(mock_ffmpeg_, 214 scoped_refptr<VideoFrame> video_frame_b;
239 AVCodecDecodeVideo2(&codec_context_, &yuv_frame_, _, _)) 215 scoped_refptr<VideoFrame> video_frame_c;
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 216
245 EXPECT_CALL(*this, ProduceVideoSample(_)) 217 EXPECT_CALL(*this, ProduceVideoSample(_))
246 .WillOnce(DemuxComplete(test_engine_.get(), buffer_)) 218 .WillOnce(DemuxComplete(test_engine_.get(), i_frame_buffer_))
247 .WillOnce(DemuxComplete(test_engine_.get(), buffer_)); 219 .WillOnce(DemuxComplete(test_engine_.get(), zero_byte_buffer))
220 .WillOnce(DemuxComplete(test_engine_.get(), i_frame_buffer_))
221 .WillRepeatedly(DemuxComplete(test_engine_.get(),
222 end_of_stream_buffer_));
223
248 EXPECT_CALL(*this, ConsumeVideoFrame(_, _)) 224 EXPECT_CALL(*this, ConsumeVideoFrame(_, _))
249 .WillOnce(DecodeComplete(this)); 225 .WillOnce(SaveArg<0>(&video_frame_a))
250 test_engine_->ProduceVideoFrame(video_frame_); 226 .WillOnce(SaveArg<0>(&video_frame_b))
227 .WillOnce(SaveArg<0>(&video_frame_c));
228 CallProduceVideoFrame();
229 CallProduceVideoFrame();
230 CallProduceVideoFrame();
251 231
252 EXPECT_TRUE(video_frame_.get()); 232 EXPECT_TRUE(video_frame_a);
233 EXPECT_TRUE(video_frame_b);
234 EXPECT_FALSE(video_frame_c);
253 } 235 }
254 236
237
255 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_DecodeError) { 238 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_DecodeError) {
256 Initialize(); 239 Initialize();
257 240
258 // Expect a bunch of avcodec calls. 241 EXPECT_CALL(*this, ProduceVideoSample(_))
259 EXPECT_CALL(mock_ffmpeg_, AVInitPacket(_)); 242 .WillOnce(DemuxComplete(test_engine_.get(), corrupt_i_frame_buffer_))
260 EXPECT_CALL(mock_ffmpeg_, 243 .WillRepeatedly(DemuxComplete(test_engine_.get(), i_frame_buffer_));
261 AVCodecDecodeVideo2(&codec_context_, &yuv_frame_, _, _)) 244 EXPECT_CALL(*this, OnError());
262 .WillOnce(Return(-1)); 245
246 CallProduceVideoFrame();
247 }
248
249 // Multi-threaded decoders have different behavior than single-threaded
250 // decoders at the end of the stream. Multithreaded decoders hide errors
251 // that happen on the last |codec_context_->thread_count| frames to avoid
252 // prematurely signalling EOS. This test just exposes that behavior so we can
253 // detect if it changes.
254 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_DecodeErrorAtEndOfStream) {
255 Initialize();
263 256
264 EXPECT_CALL(*this, ProduceVideoSample(_)) 257 EXPECT_CALL(*this, ProduceVideoSample(_))
265 .WillOnce(DemuxComplete(test_engine_.get(), buffer_)); 258 .WillOnce(DemuxComplete(test_engine_.get(), corrupt_i_frame_buffer_))
266 EXPECT_CALL(*this, OnError()); 259 .WillRepeatedly(DemuxComplete(test_engine_.get(), end_of_stream_buffer_));
267 260
268 test_engine_->ProduceVideoFrame(video_frame_); 261 scoped_refptr<VideoFrame> video_frame;
262 EXPECT_CALL(*this, ConsumeVideoFrame(_, _))
263 .WillOnce(SaveArg<0>(&video_frame));
264 CallProduceVideoFrame();
265
266 EXPECT_FALSE(video_frame);
269 } 267 }
270 268
269 // Decode |i_frame_buffer_| and then a frame with a larger width and verify
270 // the output size didn't change.
271 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_LargerWidth) { 271 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_LargerWidth) {
272 Initialize(); 272 DecodeIFrameThenTestFile("vp8-I-frame-640x240");
273 ChangeDimensions(kWidth * 2, kHeight);
274 Decode();
275 } 273 }
276 274
275 // Decode |i_frame_buffer_| and then a frame with a smaller width and verify
276 // the output size didn't change.
277 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_SmallerWidth) { 277 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_SmallerWidth) {
278 Initialize(); 278 DecodeIFrameThenTestFile("vp8-I-frame-160x240");
279 ChangeDimensions(kWidth / 2, kHeight);
280 Decode();
281 } 279 }
282 280
281 // Decode |i_frame_buffer_| and then a frame with a larger height and verify
282 // the output size didn't change.
283 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_LargerHeight) { 283 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_LargerHeight) {
284 Initialize(); 284 DecodeIFrameThenTestFile("vp8-I-frame-320x480");
285 ChangeDimensions(kWidth, kHeight * 2);
286 Decode();
287 } 285 }
288 286
287 // Decode |i_frame_buffer_| and then a frame with a smaller height and verify
288 // the output size didn't change.
289 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_SmallerHeight) { 289 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_SmallerHeight) {
290 Initialize(); 290 DecodeIFrameThenTestFile("vp8-I-frame-320x120");
291 ChangeDimensions(kWidth, kHeight / 2);
292 Decode();
293 }
294
295 TEST_F(FFmpegVideoDecodeEngineTest, GetSurfaceFormat) {
296 Initialize();
297
298 // YV12 formats.
299 codec_context_.pix_fmt = PIX_FMT_YUV420P;
300 EXPECT_EQ(VideoFrame::YV12, test_engine_->GetSurfaceFormat());
301 codec_context_.pix_fmt = PIX_FMT_YUVJ420P;
302 EXPECT_EQ(VideoFrame::YV12, test_engine_->GetSurfaceFormat());
303
304 // YV16 formats.
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 } 291 }
314 292
315 } // namespace media 293 } // namespace media
OLDNEW
« no previous file with comments | « media/video/ffmpeg_video_decode_engine.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698