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