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

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

Issue 6104007: Merge 70703 - Handle changes in video frame size.... (Closed) Base URL: svn://svn.chromium.org/chrome/branches/552d/src/
Patch Set: Created 9 years, 11 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/scoped_ptr.h" 5 #include "base/scoped_ptr.h"
6 #include "media/base/data_buffer.h" 6 #include "media/base/data_buffer.h"
7 #include "media/base/mock_ffmpeg.h" 7 #include "media/base/mock_ffmpeg.h"
8 #include "media/base/mock_task.h" 8 #include "media/base/mock_task.h"
9 #include "media/video/ffmpeg_video_decode_engine.h" 9 #include "media/video/ffmpeg_video_decode_engine.h"
10 #include "testing/gmock/include/gmock/gmock.h" 10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h" 11 #include "testing/gtest/include/gtest/gtest.h"
12 12
13 using ::testing::_; 13 using ::testing::_;
14 using ::testing::DoAll; 14 using ::testing::DoAll;
15 using ::testing::Return; 15 using ::testing::Return;
16 using ::testing::ReturnNull; 16 using ::testing::ReturnNull;
17 using ::testing::SetArgumentPointee; 17 using ::testing::SetArgumentPointee;
18 using ::testing::StrictMock; 18 using ::testing::StrictMock;
19 19
20 namespace media { 20 namespace media {
21 21
22 static const int kWidth = 320; 22 static const int kWidth = 320;
23 static const int kHeight = 240; 23 static const int kHeight = 240;
24 static const AVRational kTimeBase = { 1, 100 }; 24 static const AVRational kTimeBase = { 1, 100 };
25 25
26 static void InitializeFrame(uint8_t* data, int width, AVFrame* frame) {
27 frame->data[0] = data;
28 frame->data[1] = data;
29 frame->data[2] = data;
30 frame->linesize[0] = width;
31 frame->linesize[1] = width / 2;
32 frame->linesize[2] = width / 2;
33 }
34
35 ACTION_P(DecodeComplete, decoder) {
36 decoder->video_frame_ = arg0;
37 }
38
39 ACTION_P2(DemuxComplete, engine, buffer) {
40 engine->ConsumeVideoSample(buffer);
41 }
42
26 ACTION_P(SaveInitializeResult, engine) { 43 ACTION_P(SaveInitializeResult, engine) {
27 engine->info_ = arg0; 44 engine->info_ = arg0;
28 } 45 }
29 46
30 class FFmpegVideoDecodeEngineTest : public testing::Test, 47 class FFmpegVideoDecodeEngineTest : public testing::Test,
31 public VideoDecodeEngine::EventHandler { 48 public VideoDecodeEngine::EventHandler {
32 protected: 49 protected:
33 FFmpegVideoDecodeEngineTest() { 50 FFmpegVideoDecodeEngineTest() {
34 // Setup FFmpeg structures. 51 // Setup FFmpeg structures.
35 frame_buffer_.reset(new uint8[kWidth * kHeight]); 52 frame_buffer_.reset(new uint8[kWidth * kHeight]);
36 memset(&yuv_frame_, 0, sizeof(yuv_frame_)); 53 memset(&yuv_frame_, 0, sizeof(yuv_frame_));
37 54 InitializeFrame(frame_buffer_.get(), kWidth, &yuv_frame_);
38 // DecodeFrame will check these pointers as non-NULL value.
39 yuv_frame_.data[0] = yuv_frame_.data[1] = yuv_frame_.data[2]
40 = frame_buffer_.get();
41 yuv_frame_.linesize[0] = kWidth;
42 yuv_frame_.linesize[1] = yuv_frame_.linesize[2] = kWidth >> 1;
43 55
44 memset(&codec_context_, 0, sizeof(codec_context_)); 56 memset(&codec_context_, 0, sizeof(codec_context_));
45 codec_context_.width = kWidth; 57 codec_context_.width = kWidth;
46 codec_context_.height = kHeight; 58 codec_context_.height = kHeight;
47 codec_context_.time_base = kTimeBase; 59 codec_context_.time_base = kTimeBase;
48 60
49 memset(&codec_, 0, sizeof(codec_)); 61 memset(&codec_, 0, sizeof(codec_));
50 memset(&stream_, 0, sizeof(stream_)); 62 memset(&stream_, 0, sizeof(stream_));
51 stream_.codec = &codec_context_; 63 stream_.codec = &codec_context_;
52 stream_.r_frame_rate.num = kTimeBase.den; 64 stream_.r_frame_rate.num = kTimeBase.den;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 config_.codec = kCodecH264; 100 config_.codec = kCodecH264;
89 config_.opaque_context = &stream_; 101 config_.opaque_context = &stream_;
90 config_.width = kWidth; 102 config_.width = kWidth;
91 config_.height = kHeight; 103 config_.height = kHeight;
92 EXPECT_CALL(*this, OnInitializeComplete(_)) 104 EXPECT_CALL(*this, OnInitializeComplete(_))
93 .WillOnce(SaveInitializeResult(this)); 105 .WillOnce(SaveInitializeResult(this));
94 test_engine_->Initialize(MessageLoop::current(), this, NULL, config_); 106 test_engine_->Initialize(MessageLoop::current(), this, NULL, config_);
95 EXPECT_TRUE(info_.success); 107 EXPECT_TRUE(info_.success);
96 } 108 }
97 109
110 void Decode() {
111 EXPECT_CALL(mock_ffmpeg_, AVInitPacket(_));
112 EXPECT_CALL(mock_ffmpeg_,
113 AVCodecDecodeVideo2(&codec_context_, &yuv_frame_, _, _))
114 .WillOnce(DoAll(SetArgumentPointee<2>(1), // Simulate 1 byte frame.
115 Return(0)));
116
117 EXPECT_CALL(*this, ProduceVideoSample(_))
118 .WillOnce(DemuxComplete(test_engine_.get(), buffer_));
119 EXPECT_CALL(*this, ConsumeVideoFrame(_))
120 .WillOnce(DecodeComplete(this));
121 test_engine_->ProduceVideoFrame(video_frame_);
122 }
123
124 void ChangeDimensions(int width, int height) {
125 frame_buffer_.reset(new uint8[width * height]);
126 InitializeFrame(frame_buffer_.get(), width, &yuv_frame_);
127 codec_context_.width = width;
128 codec_context_.height = height;
129 }
130
98 public: 131 public:
99 MOCK_METHOD1(ConsumeVideoFrame, 132 MOCK_METHOD1(ConsumeVideoFrame,
100 void(scoped_refptr<VideoFrame> video_frame)); 133 void(scoped_refptr<VideoFrame> video_frame));
101 MOCK_METHOD1(ProduceVideoSample, 134 MOCK_METHOD1(ProduceVideoSample,
102 void(scoped_refptr<Buffer> buffer)); 135 void(scoped_refptr<Buffer> buffer));
103 MOCK_METHOD1(OnInitializeComplete, 136 MOCK_METHOD1(OnInitializeComplete,
104 void(const VideoCodecInfo& info)); 137 void(const VideoCodecInfo& info));
105 MOCK_METHOD0(OnUninitializeComplete, void()); 138 MOCK_METHOD0(OnUninitializeComplete, void());
106 MOCK_METHOD0(OnFlushComplete, void()); 139 MOCK_METHOD0(OnFlushComplete, void());
107 MOCK_METHOD0(OnSeekComplete, void()); 140 MOCK_METHOD0(OnSeekComplete, void());
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 config_.codec = kCodecH264; 218 config_.codec = kCodecH264;
186 config_.opaque_context = &stream_; 219 config_.opaque_context = &stream_;
187 config_.width = kWidth; 220 config_.width = kWidth;
188 config_.height = kHeight; 221 config_.height = kHeight;
189 EXPECT_CALL(*this, OnInitializeComplete(_)) 222 EXPECT_CALL(*this, OnInitializeComplete(_))
190 .WillOnce(SaveInitializeResult(this)); 223 .WillOnce(SaveInitializeResult(this));
191 test_engine_->Initialize(MessageLoop::current(), this, NULL, config_); 224 test_engine_->Initialize(MessageLoop::current(), this, NULL, config_);
192 EXPECT_FALSE(info_.success); 225 EXPECT_FALSE(info_.success);
193 } 226 }
194 227
195 ACTION_P2(DemuxComplete, engine, buffer) {
196 engine->ConsumeVideoSample(buffer);
197 }
198
199 ACTION_P(DecodeComplete, decoder) {
200 decoder->video_frame_ = arg0;
201 }
202
203 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_Normal) { 228 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_Normal) {
204 Initialize(); 229 Initialize();
205 230
206 // We rely on FFmpeg for timestamp and duration reporting. The one tricky 231 // We rely on FFmpeg for timestamp and duration reporting. The one tricky
207 // bit is calculating the duration when |repeat_pict| > 0. 232 // bit is calculating the duration when |repeat_pict| > 0.
208 const base::TimeDelta kTimestamp = base::TimeDelta::FromMicroseconds(123); 233 const base::TimeDelta kTimestamp = base::TimeDelta::FromMicroseconds(123);
209 const base::TimeDelta kDuration = base::TimeDelta::FromMicroseconds(15000); 234 const base::TimeDelta kDuration = base::TimeDelta::FromMicroseconds(15000);
210 yuv_frame_.repeat_pict = 1; 235 yuv_frame_.repeat_pict = 1;
211 yuv_frame_.reordered_opaque = kTimestamp.InMicroseconds(); 236 yuv_frame_.reordered_opaque = kTimestamp.InMicroseconds();
212 237
213 // Expect a bunch of avcodec calls. 238 // Simulate decoding a single frame.
214 EXPECT_CALL(mock_ffmpeg_, AVInitPacket(_)); 239 Decode();
215 EXPECT_CALL(mock_ffmpeg_,
216 AVCodecDecodeVideo2(&codec_context_, &yuv_frame_, _, _))
217 .WillOnce(DoAll(SetArgumentPointee<2>(1), // Simulate 1 byte frame.
218 Return(0)));
219
220 EXPECT_CALL(*this, ProduceVideoSample(_))
221 .WillOnce(DemuxComplete(test_engine_.get(), buffer_));
222 EXPECT_CALL(*this, ConsumeVideoFrame(_))
223 .WillOnce(DecodeComplete(this));
224 test_engine_->ProduceVideoFrame(video_frame_);
225 240
226 // |video_frame_| timestamp is 0 because we set the timestamp based off 241 // |video_frame_| timestamp is 0 because we set the timestamp based off
227 // the buffer timestamp. 242 // the buffer timestamp.
228 EXPECT_EQ(0, video_frame_->GetTimestamp().ToInternalValue()); 243 EXPECT_EQ(0, video_frame_->GetTimestamp().ToInternalValue());
229 EXPECT_EQ(kDuration.ToInternalValue(), 244 EXPECT_EQ(kDuration.ToInternalValue(),
230 video_frame_->GetDuration().ToInternalValue()); 245 video_frame_->GetDuration().ToInternalValue());
231 } 246 }
232 247
233 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_0ByteFrame) { 248 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_0ByteFrame) {
234 Initialize(); 249 Initialize();
(...skipping 29 matching lines...) Expand all
264 279
265 EXPECT_CALL(*this, ProduceVideoSample(_)) 280 EXPECT_CALL(*this, ProduceVideoSample(_))
266 .WillOnce(DemuxComplete(test_engine_.get(), buffer_)); 281 .WillOnce(DemuxComplete(test_engine_.get(), buffer_));
267 EXPECT_CALL(*this, ConsumeVideoFrame(_)) 282 EXPECT_CALL(*this, ConsumeVideoFrame(_))
268 .WillOnce(DecodeComplete(this)); 283 .WillOnce(DecodeComplete(this));
269 test_engine_->ProduceVideoFrame(video_frame_); 284 test_engine_->ProduceVideoFrame(video_frame_);
270 285
271 EXPECT_FALSE(video_frame_.get()); 286 EXPECT_FALSE(video_frame_.get());
272 } 287 }
273 288
289 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_LargerWidth) {
290 Initialize();
291 ChangeDimensions(kWidth * 2, kHeight);
292 Decode();
293 }
294
295 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_SmallerWidth) {
296 Initialize();
297 ChangeDimensions(kWidth / 2, kHeight);
298 Decode();
299 }
300
301 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_LargerHeight) {
302 Initialize();
303 ChangeDimensions(kWidth, kHeight * 2);
304 Decode();
305 }
306
307 TEST_F(FFmpegVideoDecodeEngineTest, DecodeFrame_SmallerHeight) {
308 Initialize();
309 ChangeDimensions(kWidth, kHeight / 2);
310 Decode();
311 }
312
274 TEST_F(FFmpegVideoDecodeEngineTest, GetSurfaceFormat) { 313 TEST_F(FFmpegVideoDecodeEngineTest, GetSurfaceFormat) {
275 // YV12 formats. 314 // YV12 formats.
276 codec_context_.pix_fmt = PIX_FMT_YUV420P; 315 codec_context_.pix_fmt = PIX_FMT_YUV420P;
277 EXPECT_EQ(VideoFrame::YV12, test_engine_->GetSurfaceFormat()); 316 EXPECT_EQ(VideoFrame::YV12, test_engine_->GetSurfaceFormat());
278 codec_context_.pix_fmt = PIX_FMT_YUVJ420P; 317 codec_context_.pix_fmt = PIX_FMT_YUVJ420P;
279 EXPECT_EQ(VideoFrame::YV12, test_engine_->GetSurfaceFormat()); 318 EXPECT_EQ(VideoFrame::YV12, test_engine_->GetSurfaceFormat());
280 319
281 // YV16 formats. 320 // YV16 formats.
282 codec_context_.pix_fmt = PIX_FMT_YUV422P; 321 codec_context_.pix_fmt = PIX_FMT_YUV422P;
283 EXPECT_EQ(VideoFrame::YV16, test_engine_->GetSurfaceFormat()); 322 EXPECT_EQ(VideoFrame::YV16, test_engine_->GetSurfaceFormat());
284 codec_context_.pix_fmt = PIX_FMT_YUVJ422P; 323 codec_context_.pix_fmt = PIX_FMT_YUVJ422P;
285 EXPECT_EQ(VideoFrame::YV16, test_engine_->GetSurfaceFormat()); 324 EXPECT_EQ(VideoFrame::YV16, test_engine_->GetSurfaceFormat());
286 325
287 // Invalid value. 326 // Invalid value.
288 codec_context_.pix_fmt = PIX_FMT_NONE; 327 codec_context_.pix_fmt = PIX_FMT_NONE;
289 EXPECT_EQ(VideoFrame::INVALID, test_engine_->GetSurfaceFormat()); 328 EXPECT_EQ(VideoFrame::INVALID, test_engine_->GetSurfaceFormat());
290 } 329 }
291 330
292 } // namespace media 331 } // 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