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

Side by Side Diff: media/filters/ffmpeg_video_decoder_unittest.cc

Issue 1834303005: Refactor audio and video decoder status into common file. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments. Created 4 years, 8 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
« no previous file with comments | « media/filters/ffmpeg_video_decoder.cc ('k') | media/filters/gpu_video_decoder.cc » ('j') | 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <stdint.h> 5 #include <stdint.h>
6 6
7 #include <list> 7 #include <list>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 } 94 }
95 95
96 void Destroy() { 96 void Destroy() {
97 decoder_.reset(); 97 decoder_.reset();
98 message_loop_.RunUntilIdle(); 98 message_loop_.RunUntilIdle();
99 } 99 }
100 100
101 // Sets up expectations and actions to put FFmpegVideoDecoder in an active 101 // Sets up expectations and actions to put FFmpegVideoDecoder in an active
102 // decoding state. 102 // decoding state.
103 void EnterDecodingState() { 103 void EnterDecodingState() {
104 EXPECT_EQ(VideoDecoder::kOk, DecodeSingleFrame(i_frame_buffer_)); 104 EXPECT_EQ(DecodeStatus::OK, DecodeSingleFrame(i_frame_buffer_));
105 ASSERT_EQ(1U, output_frames_.size()); 105 ASSERT_EQ(1U, output_frames_.size());
106 } 106 }
107 107
108 // Sets up expectations and actions to put FFmpegVideoDecoder in an end 108 // Sets up expectations and actions to put FFmpegVideoDecoder in an end
109 // of stream state. 109 // of stream state.
110 void EnterEndOfStreamState() { 110 void EnterEndOfStreamState() {
111 EXPECT_EQ(VideoDecoder::kOk, DecodeSingleFrame(end_of_stream_buffer_)); 111 EXPECT_EQ(DecodeStatus::OK, DecodeSingleFrame(end_of_stream_buffer_));
112 ASSERT_FALSE(output_frames_.empty()); 112 ASSERT_FALSE(output_frames_.empty());
113 } 113 }
114 114
115 typedef std::vector<scoped_refptr<DecoderBuffer> > InputBuffers; 115 typedef std::vector<scoped_refptr<DecoderBuffer> > InputBuffers;
116 typedef std::vector<scoped_refptr<VideoFrame> > OutputFrames; 116 typedef std::vector<scoped_refptr<VideoFrame> > OutputFrames;
117 117
118 // Decodes all buffers in |input_buffers| and push all successfully decoded 118 // Decodes all buffers in |input_buffers| and push all successfully decoded
119 // output frames into |output_frames|. 119 // output frames into |output_frames|.
120 // Returns the last decode status returned by the decoder. 120 // Returns the last decode status returned by the decoder.
121 VideoDecoder::Status DecodeMultipleFrames(const InputBuffers& input_buffers) { 121 DecodeStatus DecodeMultipleFrames(const InputBuffers& input_buffers) {
122 for (InputBuffers::const_iterator iter = input_buffers.begin(); 122 for (InputBuffers::const_iterator iter = input_buffers.begin();
123 iter != input_buffers.end(); 123 iter != input_buffers.end();
124 ++iter) { 124 ++iter) {
125 VideoDecoder::Status status = Decode(*iter); 125 DecodeStatus status = Decode(*iter);
126 switch (status) { 126 switch (status) {
127 case VideoDecoder::kOk: 127 case DecodeStatus::OK:
128 break; 128 break;
129 case VideoDecoder::kAborted: 129 case DecodeStatus::ABORTED:
130 NOTREACHED(); 130 NOTREACHED();
131 case VideoDecoder::kDecodeError: 131 case DecodeStatus::DECODE_ERROR:
132 DCHECK(output_frames_.empty()); 132 DCHECK(output_frames_.empty());
133 return status; 133 return status;
134 } 134 }
135 } 135 }
136 return VideoDecoder::kOk; 136 return DecodeStatus::OK;
137 } 137 }
138 138
139 // Decodes the single compressed frame in |buffer| and writes the 139 // Decodes the single compressed frame in |buffer| and writes the
140 // uncompressed output to |video_frame|. This method works with single 140 // uncompressed output to |video_frame|. This method works with single
141 // and multithreaded decoders. End of stream buffers are used to trigger 141 // and multithreaded decoders. End of stream buffers are used to trigger
142 // the frame to be returned in the multithreaded decoder case. 142 // the frame to be returned in the multithreaded decoder case.
143 VideoDecoder::Status DecodeSingleFrame( 143 DecodeStatus DecodeSingleFrame(const scoped_refptr<DecoderBuffer>& buffer) {
144 const scoped_refptr<DecoderBuffer>& buffer) {
145 InputBuffers input_buffers; 144 InputBuffers input_buffers;
146 input_buffers.push_back(buffer); 145 input_buffers.push_back(buffer);
147 input_buffers.push_back(end_of_stream_buffer_); 146 input_buffers.push_back(end_of_stream_buffer_);
148 147
149 return DecodeMultipleFrames(input_buffers); 148 return DecodeMultipleFrames(input_buffers);
150 } 149 }
151 150
152 // Decodes |i_frame_buffer_| and then decodes the data contained in 151 // Decodes |i_frame_buffer_| and then decodes the data contained in
153 // the file named |test_file_name|. This function expects both buffers 152 // the file named |test_file_name|. This function expects both buffers
154 // to decode to frames that are the same size. 153 // to decode to frames that are the same size.
155 void DecodeIFrameThenTestFile(const std::string& test_file_name, 154 void DecodeIFrameThenTestFile(const std::string& test_file_name,
156 int expected_width, 155 int expected_width,
157 int expected_height) { 156 int expected_height) {
158 Initialize(); 157 Initialize();
159 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(test_file_name); 158 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(test_file_name);
160 159
161 InputBuffers input_buffers; 160 InputBuffers input_buffers;
162 input_buffers.push_back(i_frame_buffer_); 161 input_buffers.push_back(i_frame_buffer_);
163 input_buffers.push_back(buffer); 162 input_buffers.push_back(buffer);
164 input_buffers.push_back(end_of_stream_buffer_); 163 input_buffers.push_back(end_of_stream_buffer_);
165 164
166 VideoDecoder::Status status = 165 DecodeStatus status = DecodeMultipleFrames(input_buffers);
167 DecodeMultipleFrames(input_buffers);
168 166
169 EXPECT_EQ(VideoDecoder::kOk, status); 167 EXPECT_EQ(DecodeStatus::OK, status);
170 ASSERT_EQ(2U, output_frames_.size()); 168 ASSERT_EQ(2U, output_frames_.size());
171 169
172 gfx::Size original_size = kVisibleRect.size(); 170 gfx::Size original_size = kVisibleRect.size();
173 EXPECT_EQ(original_size.width(), 171 EXPECT_EQ(original_size.width(),
174 output_frames_[0]->visible_rect().size().width()); 172 output_frames_[0]->visible_rect().size().width());
175 EXPECT_EQ(original_size.height(), 173 EXPECT_EQ(original_size.height(),
176 output_frames_[0]->visible_rect().size().height()); 174 output_frames_[0]->visible_rect().size().height());
177 EXPECT_EQ(expected_width, 175 EXPECT_EQ(expected_width,
178 output_frames_[1]->visible_rect().size().width()); 176 output_frames_[1]->visible_rect().size().width());
179 EXPECT_EQ(expected_height, 177 EXPECT_EQ(expected_height,
180 output_frames_[1]->visible_rect().size().height()); 178 output_frames_[1]->visible_rect().size().height());
181 } 179 }
182 180
183 VideoDecoder::Status Decode(const scoped_refptr<DecoderBuffer>& buffer) { 181 DecodeStatus Decode(const scoped_refptr<DecoderBuffer>& buffer) {
184 VideoDecoder::Status status; 182 DecodeStatus status;
185 EXPECT_CALL(*this, DecodeDone(_)).WillOnce(SaveArg<0>(&status)); 183 EXPECT_CALL(*this, DecodeDone(_)).WillOnce(SaveArg<0>(&status));
186 184
187 decoder_->Decode(buffer, decode_cb_); 185 decoder_->Decode(buffer, decode_cb_);
188 186
189 message_loop_.RunUntilIdle(); 187 message_loop_.RunUntilIdle();
190 188
191 return status; 189 return status;
192 } 190 }
193 191
194 void FrameReady(const scoped_refptr<VideoFrame>& frame) { 192 void FrameReady(const scoped_refptr<VideoFrame>& frame) {
195 DCHECK(!frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)); 193 DCHECK(!frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM));
196 output_frames_.push_back(frame); 194 output_frames_.push_back(frame);
197 } 195 }
198 196
199 MOCK_METHOD1(DecodeDone, void(VideoDecoder::Status)); 197 MOCK_METHOD1(DecodeDone, void(DecodeStatus));
200 198
201 base::MessageLoop message_loop_; 199 base::MessageLoop message_loop_;
202 scoped_ptr<FFmpegVideoDecoder> decoder_; 200 scoped_ptr<FFmpegVideoDecoder> decoder_;
203 201
204 VideoDecoder::DecodeCB decode_cb_; 202 VideoDecoder::DecodeCB decode_cb_;
205 203
206 // Various buffers for testing. 204 // Various buffers for testing.
207 scoped_ptr<uint8_t[]> frame_buffer_; 205 scoped_ptr<uint8_t[]> frame_buffer_;
208 scoped_refptr<DecoderBuffer> end_of_stream_buffer_; 206 scoped_refptr<DecoderBuffer> end_of_stream_buffer_;
209 scoped_refptr<DecoderBuffer> i_frame_buffer_; 207 scoped_refptr<DecoderBuffer> i_frame_buffer_;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 Initialize(); 241 Initialize();
244 EnterDecodingState(); 242 EnterDecodingState();
245 Reset(); 243 Reset();
246 Reinitialize(); 244 Reinitialize();
247 } 245 }
248 246
249 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_Normal) { 247 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_Normal) {
250 Initialize(); 248 Initialize();
251 249
252 // Simulate decoding a single frame. 250 // Simulate decoding a single frame.
253 EXPECT_EQ(VideoDecoder::kOk, DecodeSingleFrame(i_frame_buffer_)); 251 EXPECT_EQ(DecodeStatus::OK, DecodeSingleFrame(i_frame_buffer_));
254 ASSERT_EQ(1U, output_frames_.size()); 252 ASSERT_EQ(1U, output_frames_.size());
255 } 253 }
256 254
257 // Verify current behavior for 0 byte frames. FFmpeg simply ignores 255 // Verify current behavior for 0 byte frames. FFmpeg simply ignores
258 // the 0 byte frames. 256 // the 0 byte frames.
259 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_0ByteFrame) { 257 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_0ByteFrame) {
260 Initialize(); 258 Initialize();
261 259
262 scoped_refptr<DecoderBuffer> zero_byte_buffer = new DecoderBuffer(0); 260 scoped_refptr<DecoderBuffer> zero_byte_buffer = new DecoderBuffer(0);
263 261
264 InputBuffers input_buffers; 262 InputBuffers input_buffers;
265 input_buffers.push_back(i_frame_buffer_); 263 input_buffers.push_back(i_frame_buffer_);
266 input_buffers.push_back(zero_byte_buffer); 264 input_buffers.push_back(zero_byte_buffer);
267 input_buffers.push_back(i_frame_buffer_); 265 input_buffers.push_back(i_frame_buffer_);
268 input_buffers.push_back(end_of_stream_buffer_); 266 input_buffers.push_back(end_of_stream_buffer_);
269 267
270 VideoDecoder::Status status = DecodeMultipleFrames(input_buffers); 268 DecodeStatus status = DecodeMultipleFrames(input_buffers);
271 269
272 EXPECT_EQ(VideoDecoder::kOk, status); 270 EXPECT_EQ(DecodeStatus::OK, status);
273 ASSERT_EQ(2U, output_frames_.size()); 271 ASSERT_EQ(2U, output_frames_.size());
274 } 272 }
275 273
276 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_DecodeError) { 274 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_DecodeError) {
277 Initialize(); 275 Initialize();
278 276
279 // The error is only raised on the second decode attempt, so we expect at 277 // The error is only raised on the second decode attempt, so we expect at
280 // least one successful decode but we don't expect valid frame to be decoded. 278 // least one successful decode but we don't expect valid frame to be decoded.
281 // During the second decode attempt an error is raised. 279 // During the second decode attempt an error is raised.
282 EXPECT_EQ(VideoDecoder::kOk, Decode(corrupt_i_frame_buffer_)); 280 EXPECT_EQ(DecodeStatus::OK, Decode(corrupt_i_frame_buffer_));
283 EXPECT_TRUE(output_frames_.empty()); 281 EXPECT_TRUE(output_frames_.empty());
284 EXPECT_EQ(VideoDecoder::kDecodeError, Decode(i_frame_buffer_)); 282 EXPECT_EQ(DecodeStatus::DECODE_ERROR, Decode(i_frame_buffer_));
285 EXPECT_TRUE(output_frames_.empty()); 283 EXPECT_TRUE(output_frames_.empty());
286 284
287 // After a decode error occurred, all following decodes will return 285 // After a decode error occurred, all following decodes will return
288 // kDecodeError. 286 // DecodeStatus::DECODE_ERROR.
289 EXPECT_EQ(VideoDecoder::kDecodeError, Decode(i_frame_buffer_)); 287 EXPECT_EQ(DecodeStatus::DECODE_ERROR, Decode(i_frame_buffer_));
290 EXPECT_TRUE(output_frames_.empty()); 288 EXPECT_TRUE(output_frames_.empty());
291 } 289 }
292 290
293 // A corrupt frame followed by an EOS buffer should raise a decode error. 291 // A corrupt frame followed by an EOS buffer should raise a decode error.
294 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_DecodeErrorAtEndOfStream) { 292 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_DecodeErrorAtEndOfStream) {
295 Initialize(); 293 Initialize();
296 294
297 EXPECT_EQ(VideoDecoder::kDecodeError, 295 EXPECT_EQ(DecodeStatus::DECODE_ERROR,
298 DecodeSingleFrame(corrupt_i_frame_buffer_)); 296 DecodeSingleFrame(corrupt_i_frame_buffer_));
299 } 297 }
300 298
301 // Decode |i_frame_buffer_| and then a frame with a larger width and verify 299 // Decode |i_frame_buffer_| and then a frame with a larger width and verify
302 // the output size was adjusted. 300 // the output size was adjusted.
303 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_LargerWidth) { 301 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_LargerWidth) {
304 DecodeIFrameThenTestFile("vp8-I-frame-640x240", 640, 240); 302 DecodeIFrameThenTestFile("vp8-I-frame-640x240", 640, 240);
305 } 303 }
306 304
307 // Decode |i_frame_buffer_| and then a frame with a smaller width and verify 305 // Decode |i_frame_buffer_| and then a frame with a smaller width and verify
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 356
359 // Test destruction when decoder has hit end of stream. 357 // Test destruction when decoder has hit end of stream.
360 TEST_F(FFmpegVideoDecoderTest, Destroy_EndOfStream) { 358 TEST_F(FFmpegVideoDecoderTest, Destroy_EndOfStream) {
361 Initialize(); 359 Initialize();
362 EnterDecodingState(); 360 EnterDecodingState();
363 EnterEndOfStreamState(); 361 EnterEndOfStreamState();
364 Destroy(); 362 Destroy();
365 } 363 }
366 364
367 } // namespace media 365 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/ffmpeg_video_decoder.cc ('k') | media/filters/gpu_video_decoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698