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

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

Issue 297553002: Add callback in VideoDecoder and AudioDecoder to return decoded frames. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 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/filters/ffmpeg_video_decoder.cc ('k') | media/filters/gpu_video_decoder.h » ('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 <list>
5 #include <string> 6 #include <string>
6 #include <vector> 7 #include <vector>
7 8
8 #include "base/bind.h" 9 #include "base/bind.h"
9 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
10 #include "base/memory/singleton.h" 11 #include "base/memory/singleton.h"
11 #include "base/message_loop/message_loop.h" 12 #include "base/message_loop/message_loop.h"
12 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
13 #include "media/base/decoder_buffer.h" 14 #include "media/base/decoder_buffer.h"
14 #include "media/base/gmock_callback_support.h" 15 #include "media/base/gmock_callback_support.h"
15 #include "media/base/limits.h" 16 #include "media/base/limits.h"
16 #include "media/base/mock_filters.h" 17 #include "media/base/mock_filters.h"
17 #include "media/base/test_data_util.h" 18 #include "media/base/test_data_util.h"
18 #include "media/base/test_helpers.h" 19 #include "media/base/test_helpers.h"
19 #include "media/base/video_decoder.h" 20 #include "media/base/video_decoder.h"
20 #include "media/base/video_frame.h" 21 #include "media/base/video_frame.h"
21 #include "media/base/video_util.h" 22 #include "media/base/video_util.h"
22 #include "media/ffmpeg/ffmpeg_common.h" 23 #include "media/ffmpeg/ffmpeg_common.h"
23 #include "media/filters/ffmpeg_glue.h" 24 #include "media/filters/ffmpeg_glue.h"
24 #include "media/filters/ffmpeg_video_decoder.h" 25 #include "media/filters/ffmpeg_video_decoder.h"
25 #include "testing/gmock/include/gmock/gmock.h" 26 #include "testing/gmock/include/gmock/gmock.h"
26 27
27 using ::testing::_; 28 using ::testing::_;
28 using ::testing::AtLeast; 29 using ::testing::AtLeast;
30 using ::testing::AtMost;
29 using ::testing::InSequence; 31 using ::testing::InSequence;
30 using ::testing::IsNull; 32 using ::testing::IsNull;
31 using ::testing::Return; 33 using ::testing::Return;
32 using ::testing::SaveArg; 34 using ::testing::SaveArg;
33 using ::testing::StrictMock; 35 using ::testing::StrictMock;
34 36
35 namespace media { 37 namespace media {
36 38
37 static const VideoFrame::Format kVideoFormat = VideoFrame::YV12; 39 static const VideoFrame::Format kVideoFormat = VideoFrame::YV12;
38 static const gfx::Size kCodedSize(320, 240); 40 static const gfx::Size kCodedSize(320, 240);
39 static const gfx::Rect kVisibleRect(320, 240); 41 static const gfx::Rect kVisibleRect(320, 240);
40 static const gfx::Size kNaturalSize(320, 240); 42 static const gfx::Size kNaturalSize(320, 240);
41 43
42 ACTION_P(ReturnBuffer, buffer) { 44 ACTION_P(ReturnBuffer, buffer) {
43 arg0.Run(buffer.get() ? DemuxerStream::kOk : DemuxerStream::kAborted, buffer); 45 arg0.Run(buffer.get() ? DemuxerStream::kOk : DemuxerStream::kAborted, buffer);
44 } 46 }
45 47
46 class FFmpegVideoDecoderTest : public testing::Test { 48 class FFmpegVideoDecoderTest : public testing::Test {
47 public: 49 public:
48 FFmpegVideoDecoderTest() 50 FFmpegVideoDecoderTest()
49 : decoder_(new FFmpegVideoDecoder(message_loop_.message_loop_proxy())), 51 : decoder_(new FFmpegVideoDecoder(message_loop_.message_loop_proxy())),
50 decode_cb_(base::Bind(&FFmpegVideoDecoderTest::FrameReady, 52 decode_cb_(base::Bind(&FFmpegVideoDecoderTest::DecodeDone,
51 base::Unretained(this))) { 53 base::Unretained(this))) {
52 FFmpegGlue::InitializeFFmpeg(); 54 FFmpegGlue::InitializeFFmpeg();
53 55
54 // Initialize various test buffers. 56 // Initialize various test buffers.
55 frame_buffer_.reset(new uint8[kCodedSize.GetArea()]); 57 frame_buffer_.reset(new uint8[kCodedSize.GetArea()]);
56 end_of_stream_buffer_ = DecoderBuffer::CreateEOSBuffer(); 58 end_of_stream_buffer_ = DecoderBuffer::CreateEOSBuffer();
57 i_frame_buffer_ = ReadTestDataFile("vp8-I-frame-320x240"); 59 i_frame_buffer_ = ReadTestDataFile("vp8-I-frame-320x240");
58 corrupt_i_frame_buffer_ = ReadTestDataFile("vp8-corrupt-I-frame"); 60 corrupt_i_frame_buffer_ = ReadTestDataFile("vp8-corrupt-I-frame");
59 } 61 }
60 62
61 virtual ~FFmpegVideoDecoderTest() { 63 virtual ~FFmpegVideoDecoderTest() {
62 Stop(); 64 Stop();
63 } 65 }
64 66
65 void Initialize() { 67 void Initialize() {
66 InitializeWithConfig(TestVideoConfig::Normal()); 68 InitializeWithConfig(TestVideoConfig::Normal());
67 } 69 }
68 70
69 void InitializeWithConfigAndStatus(const VideoDecoderConfig& config, 71 void InitializeWithConfigAndStatus(const VideoDecoderConfig& config,
70 PipelineStatus status) { 72 PipelineStatus status) {
71 decoder_->Initialize(config, false, NewExpectedStatusCB(status)); 73 decoder_->Initialize(config, false, NewExpectedStatusCB(status),
74 base::Bind(&FFmpegVideoDecoderTest::FrameReady,
75 base::Unretained(this)));
72 message_loop_.RunUntilIdle(); 76 message_loop_.RunUntilIdle();
73 } 77 }
74 78
75 void InitializeWithConfig(const VideoDecoderConfig& config) { 79 void InitializeWithConfig(const VideoDecoderConfig& config) {
76 InitializeWithConfigAndStatus(config, PIPELINE_OK); 80 InitializeWithConfigAndStatus(config, PIPELINE_OK);
77 } 81 }
78 82
79 void Reinitialize() { 83 void Reinitialize() {
80 InitializeWithConfig(TestVideoConfig::Large()); 84 InitializeWithConfig(TestVideoConfig::Large());
81 } 85 }
82 86
83 void Reset() { 87 void Reset() {
84 decoder_->Reset(NewExpectedClosure()); 88 decoder_->Reset(NewExpectedClosure());
85 message_loop_.RunUntilIdle(); 89 message_loop_.RunUntilIdle();
86 } 90 }
87 91
88 void Stop() { 92 void Stop() {
89 decoder_->Stop(); 93 decoder_->Stop();
90 message_loop_.RunUntilIdle(); 94 message_loop_.RunUntilIdle();
91 } 95 }
92 96
93 // Sets up expectations and actions to put FFmpegVideoDecoder in an active 97 // Sets up expectations and actions to put FFmpegVideoDecoder in an active
94 // decoding state. 98 // decoding state.
95 void EnterDecodingState() { 99 void EnterDecodingState() {
96 VideoDecoder::Status status; 100 EXPECT_EQ(VideoDecoder::kOk, DecodeSingleFrame(i_frame_buffer_));
97 scoped_refptr<VideoFrame> video_frame; 101 ASSERT_EQ(2U, output_frames_.size());
98 DecodeSingleFrame(i_frame_buffer_, &status, &video_frame); 102 EXPECT_FALSE(output_frames_[0]->end_of_stream());
99 103 EXPECT_TRUE(output_frames_[1]->end_of_stream());
100 EXPECT_EQ(VideoDecoder::kOk, status);
101 ASSERT_TRUE(video_frame.get());
102 EXPECT_FALSE(video_frame->end_of_stream());
103 } 104 }
104 105
105 // Sets up expectations and actions to put FFmpegVideoDecoder in an end 106 // Sets up expectations and actions to put FFmpegVideoDecoder in an end
106 // of stream state. 107 // of stream state.
107 void EnterEndOfStreamState() { 108 void EnterEndOfStreamState() {
108 VideoDecoder::Status status; 109 EXPECT_EQ(VideoDecoder::kOk, DecodeSingleFrame(end_of_stream_buffer_));
109 scoped_refptr<VideoFrame> video_frame; 110 ASSERT_FALSE(output_frames_.empty());
110 DecodeSingleFrame(end_of_stream_buffer_, &status, &video_frame); 111 EXPECT_TRUE(output_frames_.back()->end_of_stream());
111 EXPECT_EQ(VideoDecoder::kOk, status);
112 ASSERT_TRUE(video_frame.get());
113 EXPECT_TRUE(video_frame->end_of_stream());
114 } 112 }
115 113
116 typedef std::vector<scoped_refptr<DecoderBuffer> > InputBuffers; 114 typedef std::vector<scoped_refptr<DecoderBuffer> > InputBuffers;
117 typedef std::vector<scoped_refptr<VideoFrame> > OutputFrames; 115 typedef std::vector<scoped_refptr<VideoFrame> > OutputFrames;
118 116
119 // Decodes all buffers in |input_buffers| and push all successfully decoded 117 // Decodes all buffers in |input_buffers| and push all successfully decoded
120 // output frames (excluding EOS frames) into |output_frames|. 118 // output frames (excluding EOS frames) into |output_frames|.
121 // Returns the last decode status returned by the decoder. 119 // Returns the last decode status returned by the decoder.
122 VideoDecoder::Status DecodeMultipleFrames(const InputBuffers& input_buffers, 120 VideoDecoder::Status DecodeMultipleFrames(const InputBuffers& input_buffers) {
123 OutputFrames* output_frames) {
124 InputBuffers::const_iterator input_iter = input_buffers.begin(); 121 InputBuffers::const_iterator input_iter = input_buffers.begin();
125 122
126 for (;;) { 123 while (output_frames_.empty() || !output_frames_.back()->end_of_stream()) {
127 // Prepare input buffer. 124 // Prepare input buffer.
128 scoped_refptr<DecoderBuffer> buffer; 125 scoped_refptr<DecoderBuffer> buffer;
129 if (input_iter != input_buffers.end()) { 126 if (input_iter != input_buffers.end()) {
130 buffer = *input_iter; 127 buffer = *input_iter;
131 ++input_iter; 128 ++input_iter;
132 } else { 129 } else {
133 buffer = end_of_stream_buffer_; 130 buffer = end_of_stream_buffer_;
134 } 131 }
135 132
136 VideoDecoder::Status status; 133 VideoDecoder::Status status = Decode(buffer);
137 scoped_refptr<VideoFrame> frame;
138 Decode(buffer, &status, &frame);
139 134
140 switch (status) { 135 switch (status) {
141 case VideoDecoder::kOk: 136 case VideoDecoder::kOk:
142 DCHECK(frame); 137 break;
143 if (!frame->end_of_stream()) {
144 output_frames->push_back(frame);
145 continue;
146 } else { // EOS
147 return status;
148 }
149 case VideoDecoder::kNotEnoughData:
150 DCHECK(!frame);
151 continue;
152 case VideoDecoder::kAborted: 138 case VideoDecoder::kAborted:
153 NOTREACHED(); 139 NOTREACHED();
154 case VideoDecoder::kDecodeError: 140 case VideoDecoder::kDecodeError:
155 case VideoDecoder::kDecryptError: 141 case VideoDecoder::kDecryptError:
156 DCHECK(!frame); 142 DCHECK(output_frames_.empty());
157 return status; 143 return status;
158 } 144 }
159 } 145 }
146
147 return VideoDecoder::kOk;
160 } 148 }
161 149
162 // Decodes the single compressed frame in |buffer| and writes the 150 // Decodes the single compressed frame in |buffer| and writes the
163 // uncompressed output to |video_frame|. This method works with single 151 // uncompressed output to |video_frame|. This method works with single
164 // and multithreaded decoders. End of stream buffers are used to trigger 152 // and multithreaded decoders. End of stream buffers are used to trigger
165 // the frame to be returned in the multithreaded decoder case. 153 // the frame to be returned in the multithreaded decoder case.
166 void DecodeSingleFrame(const scoped_refptr<DecoderBuffer>& buffer, 154 VideoDecoder::Status DecodeSingleFrame(
167 VideoDecoder::Status* status, 155 const scoped_refptr<DecoderBuffer>& buffer) {
168 scoped_refptr<VideoFrame>* video_frame) {
169 InputBuffers input_buffers; 156 InputBuffers input_buffers;
170 input_buffers.push_back(buffer); 157 input_buffers.push_back(buffer);
171 158
172 OutputFrames output_frames; 159 return DecodeMultipleFrames(input_buffers);
173 *status = DecodeMultipleFrames(input_buffers, &output_frames);
174
175 if (*status != VideoDecoder::kOk)
176 return;
177
178 ASSERT_LE(output_frames.size(), 1U);
179 if (output_frames.size() == 1U)
180 *video_frame = output_frames[0];
181 else
182 *video_frame = VideoFrame::CreateEOSFrame();
183 } 160 }
184 161
185 // Decodes |i_frame_buffer_| and then decodes the data contained in 162 // Decodes |i_frame_buffer_| and then decodes the data contained in
186 // the file named |test_file_name|. This function expects both buffers 163 // the file named |test_file_name|. This function expects both buffers
187 // to decode to frames that are the same size. 164 // to decode to frames that are the same size.
188 void DecodeIFrameThenTestFile(const std::string& test_file_name, 165 void DecodeIFrameThenTestFile(const std::string& test_file_name,
189 int expected_width, 166 int expected_width,
190 int expected_height) { 167 int expected_height) {
191 Initialize(); 168 Initialize();
192 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(test_file_name); 169 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(test_file_name);
193 170
194 InputBuffers input_buffers; 171 InputBuffers input_buffers;
195 input_buffers.push_back(i_frame_buffer_); 172 input_buffers.push_back(i_frame_buffer_);
196 input_buffers.push_back(buffer); 173 input_buffers.push_back(buffer);
197 174
198 OutputFrames output_frames;
199 VideoDecoder::Status status = 175 VideoDecoder::Status status =
200 DecodeMultipleFrames(input_buffers, &output_frames); 176 DecodeMultipleFrames(input_buffers);
201 177
202 EXPECT_EQ(VideoDecoder::kOk, status); 178 EXPECT_EQ(VideoDecoder::kOk, status);
203 ASSERT_EQ(2U, output_frames.size()); 179 ASSERT_EQ(3U, output_frames_.size());
204 180
205 gfx::Size original_size = kVisibleRect.size(); 181 gfx::Size original_size = kVisibleRect.size();
206 EXPECT_EQ(original_size.width(), 182 EXPECT_EQ(original_size.width(),
207 output_frames[0]->visible_rect().size().width()); 183 output_frames_[0]->visible_rect().size().width());
208 EXPECT_EQ(original_size.height(), 184 EXPECT_EQ(original_size.height(),
209 output_frames[0]->visible_rect().size().height()); 185 output_frames_[0]->visible_rect().size().height());
210 EXPECT_EQ(expected_width, 186 EXPECT_EQ(expected_width,
211 output_frames[1]->visible_rect().size().width()); 187 output_frames_[1]->visible_rect().size().width());
212 EXPECT_EQ(expected_height, 188 EXPECT_EQ(expected_height,
213 output_frames[1]->visible_rect().size().height()); 189 output_frames_[1]->visible_rect().size().height());
190 EXPECT_TRUE(output_frames_[2]->end_of_stream());
214 } 191 }
215 192
216 void Decode(const scoped_refptr<DecoderBuffer>& buffer, 193 VideoDecoder::Status Decode(const scoped_refptr<DecoderBuffer>& buffer) {
217 VideoDecoder::Status* status, 194 VideoDecoder::Status status;
218 scoped_refptr<VideoFrame>* video_frame) { 195 EXPECT_CALL(*this, DecodeDone(_)).WillOnce(SaveArg<0>(&status));
219 EXPECT_CALL(*this, FrameReady(_, _))
220 .WillOnce(DoAll(SaveArg<0>(status), SaveArg<1>(video_frame)));
221 196
222 decoder_->Decode(buffer, decode_cb_); 197 decoder_->Decode(buffer, decode_cb_);
223 198
224 message_loop_.RunUntilIdle(); 199 message_loop_.RunUntilIdle();
200
201 return status;
225 } 202 }
226 203
227 MOCK_METHOD2(FrameReady, void(VideoDecoder::Status, 204 void FrameReady(const scoped_refptr<VideoFrame>& frame) {
228 const scoped_refptr<VideoFrame>&)); 205 output_frames_.push_back(frame);
206 }
207
208 MOCK_METHOD1(DecodeDone, void(VideoDecoder::Status));
229 209
230 base::MessageLoop message_loop_; 210 base::MessageLoop message_loop_;
231 scoped_ptr<FFmpegVideoDecoder> decoder_; 211 scoped_ptr<FFmpegVideoDecoder> decoder_;
232 212
233 VideoDecoder::DecodeCB decode_cb_; 213 VideoDecoder::DecodeCB decode_cb_;
234 214
235 // Various buffers for testing. 215 // Various buffers for testing.
236 scoped_ptr<uint8_t[]> frame_buffer_; 216 scoped_ptr<uint8_t[]> frame_buffer_;
237 scoped_refptr<DecoderBuffer> end_of_stream_buffer_; 217 scoped_refptr<DecoderBuffer> end_of_stream_buffer_;
238 scoped_refptr<DecoderBuffer> i_frame_buffer_; 218 scoped_refptr<DecoderBuffer> i_frame_buffer_;
239 scoped_refptr<DecoderBuffer> corrupt_i_frame_buffer_; 219 scoped_refptr<DecoderBuffer> corrupt_i_frame_buffer_;
240 220
221 OutputFrames output_frames_;
222
241 private: 223 private:
242 DISALLOW_COPY_AND_ASSIGN(FFmpegVideoDecoderTest); 224 DISALLOW_COPY_AND_ASSIGN(FFmpegVideoDecoderTest);
243 }; 225 };
244 226
245 TEST_F(FFmpegVideoDecoderTest, Initialize_Normal) { 227 TEST_F(FFmpegVideoDecoderTest, Initialize_Normal) {
246 Initialize(); 228 Initialize();
247 } 229 }
248 230
249 TEST_F(FFmpegVideoDecoderTest, Initialize_UnsupportedDecoder) { 231 TEST_F(FFmpegVideoDecoderTest, Initialize_UnsupportedDecoder) {
250 // Test avcodec_find_decoder() returning NULL. 232 // Test avcodec_find_decoder() returning NULL.
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 Initialize(); 330 Initialize();
349 EnterDecodingState(); 331 EnterDecodingState();
350 Reset(); 332 Reset();
351 Reinitialize(); 333 Reinitialize();
352 } 334 }
353 335
354 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_Normal) { 336 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_Normal) {
355 Initialize(); 337 Initialize();
356 338
357 // Simulate decoding a single frame. 339 // Simulate decoding a single frame.
358 VideoDecoder::Status status; 340 EXPECT_EQ(VideoDecoder::kOk, DecodeSingleFrame(i_frame_buffer_));
359 scoped_refptr<VideoFrame> video_frame; 341 ASSERT_EQ(2U, output_frames_.size());
360 DecodeSingleFrame(i_frame_buffer_, &status, &video_frame); 342 EXPECT_FALSE(output_frames_[0]->end_of_stream());
361 343 EXPECT_TRUE(output_frames_[1]->end_of_stream());
362 EXPECT_EQ(VideoDecoder::kOk, status);
363 ASSERT_TRUE(video_frame.get());
364 EXPECT_FALSE(video_frame->end_of_stream());
365 } 344 }
366 345
367 // Verify current behavior for 0 byte frames. FFmpeg simply ignores 346 // Verify current behavior for 0 byte frames. FFmpeg simply ignores
368 // the 0 byte frames. 347 // the 0 byte frames.
369 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_0ByteFrame) { 348 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_0ByteFrame) {
370 Initialize(); 349 Initialize();
371 350
372 scoped_refptr<DecoderBuffer> zero_byte_buffer = new DecoderBuffer(0); 351 scoped_refptr<DecoderBuffer> zero_byte_buffer = new DecoderBuffer(0);
373 352
374 InputBuffers input_buffers; 353 InputBuffers input_buffers;
375 input_buffers.push_back(i_frame_buffer_); 354 input_buffers.push_back(i_frame_buffer_);
376 input_buffers.push_back(zero_byte_buffer); 355 input_buffers.push_back(zero_byte_buffer);
377 input_buffers.push_back(i_frame_buffer_); 356 input_buffers.push_back(i_frame_buffer_);
378 357
379 OutputFrames output_frames; 358 VideoDecoder::Status status = DecodeMultipleFrames(input_buffers);
380 VideoDecoder::Status status =
381 DecodeMultipleFrames(input_buffers, &output_frames);
382 359
383 EXPECT_EQ(VideoDecoder::kOk, status); 360 EXPECT_EQ(VideoDecoder::kOk, status);
384 ASSERT_EQ(2U, output_frames.size()); 361 ASSERT_EQ(3U, output_frames_.size());
385 362
386 EXPECT_FALSE(output_frames[0]->end_of_stream()); 363 EXPECT_FALSE(output_frames_[0]->end_of_stream());
387 EXPECT_FALSE(output_frames[1]->end_of_stream()); 364 EXPECT_FALSE(output_frames_[1]->end_of_stream());
365 EXPECT_TRUE(output_frames_[2]->end_of_stream());
388 } 366 }
389 367
390 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_DecodeError) { 368 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_DecodeError) {
391 Initialize(); 369 Initialize();
392 370
393 VideoDecoder::Status status;
394 scoped_refptr<VideoFrame> frame;
395
396 // The error is only raised on the second decode attempt, so we expect at 371 // The error is only raised on the second decode attempt, so we expect at
397 // least one successful decode but we don't expect valid frame to be decoded. 372 // least one successful decode but we don't expect valid frame to be decoded.
398 // During the second decode attempt an error is raised. 373 // During the second decode attempt an error is raised.
399 Decode(corrupt_i_frame_buffer_, &status, &frame); 374 EXPECT_EQ(VideoDecoder::kOk, Decode(corrupt_i_frame_buffer_));
400 DCHECK(!frame); 375 EXPECT_TRUE(output_frames_.empty());
401 DCHECK_EQ(VideoDecoder::kNotEnoughData, status); 376 EXPECT_EQ(VideoDecoder::kDecodeError, Decode(i_frame_buffer_));
402 Decode(i_frame_buffer_, &status, &frame); 377 EXPECT_TRUE(output_frames_.empty());
403 DCHECK(!frame);
404 DCHECK_EQ(VideoDecoder::kDecodeError, status);
405 378
406 // After a decode error occurred, all following decodes will return 379 // After a decode error occurred, all following decodes will return
407 // kDecodeError. 380 // kDecodeError.
408 Decode(i_frame_buffer_, &status, &frame); 381 EXPECT_EQ(VideoDecoder::kDecodeError, Decode(i_frame_buffer_));
409 DCHECK(!frame); 382 EXPECT_TRUE(output_frames_.empty());
410 DCHECK_EQ(VideoDecoder::kDecodeError, status);
411 } 383 }
412 384
413 // Multi-threaded decoders have different behavior than single-threaded 385 // Multi-threaded decoders have different behavior than single-threaded
414 // decoders at the end of the stream. Multithreaded decoders hide errors 386 // decoders at the end of the stream. Multithreaded decoders hide errors
415 // that happen on the last |codec_context_->thread_count| frames to avoid 387 // that happen on the last |codec_context_->thread_count| frames to avoid
416 // prematurely signalling EOS. This test just exposes that behavior so we can 388 // prematurely signalling EOS. This test just exposes that behavior so we can
417 // detect if it changes. 389 // detect if it changes.
418 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_DecodeErrorAtEndOfStream) { 390 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_DecodeErrorAtEndOfStream) {
419 Initialize(); 391 Initialize();
420 392
421 VideoDecoder::Status status; 393 EXPECT_EQ(VideoDecoder::kOk, DecodeSingleFrame(corrupt_i_frame_buffer_));
422 scoped_refptr<VideoFrame> video_frame; 394 ASSERT_FALSE(output_frames_.empty());
423 DecodeSingleFrame(corrupt_i_frame_buffer_, &status, &video_frame); 395 EXPECT_TRUE(output_frames_.back()->end_of_stream());
424
425 EXPECT_EQ(VideoDecoder::kOk, status);
426 ASSERT_TRUE(video_frame.get());
427 EXPECT_TRUE(video_frame->end_of_stream());
428 } 396 }
429 397
430 // Decode |i_frame_buffer_| and then a frame with a larger width and verify 398 // Decode |i_frame_buffer_| and then a frame with a larger width and verify
431 // the output size was adjusted. 399 // the output size was adjusted.
432 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_LargerWidth) { 400 TEST_F(FFmpegVideoDecoderTest, DecodeFrame_LargerWidth) {
433 DecodeIFrameThenTestFile("vp8-I-frame-640x240", 640, 240); 401 DecodeIFrameThenTestFile("vp8-I-frame-640x240", 640, 240);
434 } 402 }
435 403
436 // Decode |i_frame_buffer_| and then a frame with a smaller width and verify 404 // Decode |i_frame_buffer_| and then a frame with a smaller width and verify
437 // the output size was adjusted. 405 // the output size was adjusted.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 455
488 // Test stopping when decoder has hit end of stream. 456 // Test stopping when decoder has hit end of stream.
489 TEST_F(FFmpegVideoDecoderTest, Stop_EndOfStream) { 457 TEST_F(FFmpegVideoDecoderTest, Stop_EndOfStream) {
490 Initialize(); 458 Initialize();
491 EnterDecodingState(); 459 EnterDecodingState();
492 EnterEndOfStreamState(); 460 EnterEndOfStreamState();
493 Stop(); 461 Stop();
494 } 462 }
495 463
496 } // namespace media 464 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/ffmpeg_video_decoder.cc ('k') | media/filters/gpu_video_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698