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

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

Issue 18414008: Reland r210741 "Separate DemuxerStream and VideoDecoder." (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase only Created 7 years, 5 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/fake_video_decoder.cc ('k') | media/filters/ffmpeg_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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/basictypes.h" 5 #include "base/basictypes.h"
6 #include "base/bind.h" 6 #include "base/bind.h"
7 #include "base/message_loop.h" 7 #include "base/message_loop.h"
8 #include "media/base/decoder_buffer.h" 8 #include "media/base/decoder_buffer.h"
9 #include "media/base/mock_filters.h" 9 #include "media/base/mock_filters.h"
10 #include "media/base/test_helpers.h" 10 #include "media/base/test_helpers.h"
11 #include "media/base/video_frame.h" 11 #include "media/base/video_frame.h"
12 #include "media/filters/fake_demuxer_stream.h"
13 #include "media/filters/fake_video_decoder.h" 12 #include "media/filters/fake_video_decoder.h"
14 #include "testing/gtest/include/gtest/gtest.h" 13 #include "testing/gtest/include/gtest/gtest.h"
15 14
16 namespace media { 15 namespace media {
17 16
18 static const int kDecodingDelay = 9; 17 static const int kDecodingDelay = 9;
19 static const int kNumConfigs = 3; 18 static const int kTotalBuffers = 12;
20 static const int kNumBuffersInOneConfig = 9; 19 static const int kDurationMs = 30;
21 static const int kNumInputBuffers = kNumConfigs * kNumBuffersInOneConfig;
22 20
23 class FakeVideoDecoderTest : public testing::Test { 21 class FakeVideoDecoderTest : public testing::Test {
24 public: 22 public:
25 FakeVideoDecoderTest() 23 FakeVideoDecoderTest()
26 : decoder_(new FakeVideoDecoder(kDecodingDelay)), 24 : decoder_(new FakeVideoDecoder(kDecodingDelay)),
27 demuxer_stream_( 25 num_input_buffers_(0),
28 new FakeDemuxerStream(kNumConfigs, kNumBuffersInOneConfig, false)),
29 num_decoded_frames_(0), 26 num_decoded_frames_(0),
30 is_read_pending_(false), 27 decode_status_(VideoDecoder::kNotEnoughData),
28 is_decode_pending_(false),
31 is_reset_pending_(false), 29 is_reset_pending_(false),
32 is_stop_pending_(false) {} 30 is_stop_pending_(false) {}
33 31
34 virtual ~FakeVideoDecoderTest() { 32 virtual ~FakeVideoDecoderTest() {
35 StopAndExpect(OK); 33 StopAndExpect(OK);
36 } 34 }
37 35
38 void Initialize() { 36 void InitializeWithConfig(const VideoDecoderConfig& config) {
39 decoder_->Initialize(demuxer_stream_.get(), 37 decoder_->Initialize(config,
40 NewExpectedStatusCB(PIPELINE_OK), 38 NewExpectedStatusCB(PIPELINE_OK),
41 base::Bind(&MockStatisticsCB::OnStatistics, 39 base::Bind(&MockStatisticsCB::OnStatistics,
42 base::Unretained(&statistics_cb_))); 40 base::Unretained(&statistics_cb_)));
43 message_loop_.RunUntilIdle(); 41 message_loop_.RunUntilIdle();
42 current_config_ = config;
43 }
44
45 void Initialize() {
46 InitializeWithConfig(TestVideoConfig::Normal());
44 } 47 }
45 48
46 void EnterPendingInitState() { 49 void EnterPendingInitState() {
47 decoder_->HoldNextInit(); 50 decoder_->HoldNextInit();
48 Initialize(); 51 Initialize();
49 } 52 }
50 53
51 void SatisfyInit() { 54 void SatisfyInit() {
52 decoder_->SatisfyInit(); 55 decoder_->SatisfyInit();
53 message_loop_.RunUntilIdle(); 56 message_loop_.RunUntilIdle();
54 } 57 }
55 58
56 // Callback for VideoDecoder::Read(). 59 // Callback for VideoDecoder::Read().
57 void FrameReady(VideoDecoder::Status status, 60 void FrameReady(VideoDecoder::Status status,
58 const scoped_refptr<VideoFrame>& frame) { 61 const scoped_refptr<VideoFrame>& frame) {
59 DCHECK(is_read_pending_); 62 DCHECK(is_decode_pending_);
60 ASSERT_EQ(VideoDecoder::kOk, status); 63 ASSERT_TRUE(status == VideoDecoder::kOk ||
64 status == VideoDecoder::kNotEnoughData);
65 is_decode_pending_ = false;
66 decode_status_ = status;
67 frame_decoded_ = frame;
61 68
62 is_read_pending_ = false; 69 if (frame && !frame->IsEndOfStream())
63 frame_read_ = frame;
64
65 if (frame.get() && !frame->IsEndOfStream())
66 num_decoded_frames_++; 70 num_decoded_frames_++;
67 } 71 }
68 72
69 enum CallbackResult { 73 enum CallbackResult {
70 PENDING, 74 PENDING,
71 OK, 75 OK,
76 NOT_ENOUGH_DATA,
72 ABROTED, 77 ABROTED,
73 EOS 78 EOS
74 }; 79 };
75 80
76 void ExpectReadResult(CallbackResult result) { 81 void ExpectReadResult(CallbackResult result) {
77 switch (result) { 82 switch (result) {
78 case PENDING: 83 case PENDING:
79 EXPECT_TRUE(is_read_pending_); 84 EXPECT_TRUE(is_decode_pending_);
80 ASSERT_FALSE(frame_read_.get()); 85 ASSERT_FALSE(frame_decoded_);
81 break; 86 break;
82 case OK: 87 case OK:
83 EXPECT_FALSE(is_read_pending_); 88 EXPECT_FALSE(is_decode_pending_);
84 ASSERT_TRUE(frame_read_.get()); 89 ASSERT_EQ(VideoDecoder::kOk, decode_status_);
85 EXPECT_FALSE(frame_read_->IsEndOfStream()); 90 ASSERT_TRUE(frame_decoded_);
91 EXPECT_FALSE(frame_decoded_->IsEndOfStream());
92 break;
93 case NOT_ENOUGH_DATA:
94 EXPECT_FALSE(is_decode_pending_);
95 ASSERT_EQ(VideoDecoder::kNotEnoughData, decode_status_);
96 ASSERT_FALSE(frame_decoded_);
86 break; 97 break;
87 case ABROTED: 98 case ABROTED:
88 EXPECT_FALSE(is_read_pending_); 99 EXPECT_FALSE(is_decode_pending_);
89 EXPECT_FALSE(frame_read_.get()); 100 ASSERT_EQ(VideoDecoder::kOk, decode_status_);
101 EXPECT_FALSE(frame_decoded_);
90 break; 102 break;
91 case EOS: 103 case EOS:
92 EXPECT_FALSE(is_read_pending_); 104 EXPECT_FALSE(is_decode_pending_);
93 ASSERT_TRUE(frame_read_.get()); 105 ASSERT_EQ(VideoDecoder::kOk, decode_status_);
94 EXPECT_TRUE(frame_read_->IsEndOfStream()); 106 ASSERT_TRUE(frame_decoded_);
107 EXPECT_TRUE(frame_decoded_->IsEndOfStream());
95 break; 108 break;
96 } 109 }
97 } 110 }
98 111
99 void ReadOneFrame() { 112 void Decode() {
100 frame_read_ = NULL; 113 scoped_refptr<DecoderBuffer> buffer;
101 is_read_pending_ = true; 114
102 decoder_->Read( 115 if (num_input_buffers_ < kTotalBuffers) {
116 buffer = CreateFakeVideoBufferForTest(
117 current_config_,
118 base::TimeDelta::FromMilliseconds(kDurationMs * num_input_buffers_),
119 base::TimeDelta::FromMilliseconds(kDurationMs));
120 num_input_buffers_++;
121 } else {
122 buffer = DecoderBuffer::CreateEOSBuffer();
123 }
124
125 decode_status_ = VideoDecoder::kDecodeError;
126 frame_decoded_ = NULL;
127 is_decode_pending_ = true;
128
129 decoder_->Decode(
130 buffer,
103 base::Bind(&FakeVideoDecoderTest::FrameReady, base::Unretained(this))); 131 base::Bind(&FakeVideoDecoderTest::FrameReady, base::Unretained(this)));
104 message_loop_.RunUntilIdle(); 132 message_loop_.RunUntilIdle();
105 } 133 }
106 134
135 void ReadOneFrame() {
136 do {
137 Decode();
138 } while (decode_status_ == VideoDecoder::kNotEnoughData &&
139 !is_decode_pending_);
140 }
141
107 void ReadUntilEOS() { 142 void ReadUntilEOS() {
108 do { 143 do {
109 ReadOneFrame(); 144 ReadOneFrame();
110 } while (frame_read_.get() && !frame_read_->IsEndOfStream()); 145 } while (frame_decoded_ && !frame_decoded_->IsEndOfStream());
111 } 146 }
112 147
113 void EnterPendingReadState() { 148 void EnterPendingReadState() {
149 // Pass the initial NOT_ENOUGH_DATA stage.
150 ReadOneFrame();
114 decoder_->HoldNextRead(); 151 decoder_->HoldNextRead();
115 ReadOneFrame(); 152 ReadOneFrame();
116 ExpectReadResult(PENDING); 153 ExpectReadResult(PENDING);
117 } 154 }
118 155
119 void SatisfyRead() { 156 void SatisfyReadAndExpect(CallbackResult result) {
120 decoder_->SatisfyRead(); 157 decoder_->SatisfyRead();
121 message_loop_.RunUntilIdle(); 158 message_loop_.RunUntilIdle();
122 ExpectReadResult(OK); 159 ExpectReadResult(result);
160 }
161
162 void SatisfyRead() {
163 SatisfyReadAndExpect(OK);
123 } 164 }
124 165
125 // Callback for VideoDecoder::Reset(). 166 // Callback for VideoDecoder::Reset().
126 void OnDecoderReset() { 167 void OnDecoderReset() {
127 DCHECK(is_reset_pending_); 168 DCHECK(is_reset_pending_);
128 is_reset_pending_ = false; 169 is_reset_pending_ = false;
129 } 170 }
130 171
131 void ExpectResetResult(CallbackResult result) { 172 void ExpectResetResult(CallbackResult result) {
132 switch (result) { 173 switch (result) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 decoder_->HoldNextStop(); 232 decoder_->HoldNextStop();
192 StopAndExpect(PENDING); 233 StopAndExpect(PENDING);
193 } 234 }
194 235
195 void SatisfyStop() { 236 void SatisfyStop() {
196 decoder_->SatisfyStop(); 237 decoder_->SatisfyStop();
197 message_loop_.RunUntilIdle(); 238 message_loop_.RunUntilIdle();
198 ExpectStopResult(OK); 239 ExpectStopResult(OK);
199 } 240 }
200 241
201 // Callback for DemuxerStream::Read so that we can skip frames to trigger a 242 base::MessageLoop message_loop_;
202 // config change. 243 VideoDecoderConfig current_config_;
203 void BufferReady(bool* config_changed,
204 DemuxerStream::Status status,
205 const scoped_refptr<DecoderBuffer>& buffer) {
206 if (status == DemuxerStream::kConfigChanged)
207 *config_changed = true;
208 }
209 244
210 void ChangeConfig() { 245 scoped_ptr<FakeVideoDecoder> decoder_;
211 bool config_changed = false; 246 MockStatisticsCB statistics_cb_;
212 while (!config_changed) {
213 demuxer_stream_->Read(base::Bind(&FakeVideoDecoderTest::BufferReady,
214 base::Unretained(this),
215 &config_changed));
216 message_loop_.RunUntilIdle();
217 }
218 }
219 247
220 void EnterPendingDemuxerReadState() { 248 int num_input_buffers_;
221 demuxer_stream_->HoldNextRead();
222 ReadOneFrame();
223 }
224
225 void SatisfyDemuxerRead() {
226 demuxer_stream_->SatisfyRead();
227 message_loop_.RunUntilIdle();
228 }
229
230 void AbortDemuxerRead() {
231 demuxer_stream_->Reset();
232 message_loop_.RunUntilIdle();
233 }
234
235 base::MessageLoop message_loop_;
236 scoped_ptr<FakeVideoDecoder> decoder_;
237 scoped_ptr<FakeDemuxerStream> demuxer_stream_;
238 MockStatisticsCB statistics_cb_;
239 int num_decoded_frames_; 249 int num_decoded_frames_;
240 250
241 // Callback result/status. 251 // Callback result/status.
242 scoped_refptr<VideoFrame> frame_read_; 252 VideoDecoder::Status decode_status_;
243 bool is_read_pending_; 253 scoped_refptr<VideoFrame> frame_decoded_;
254 bool is_decode_pending_;
244 bool is_reset_pending_; 255 bool is_reset_pending_;
245 bool is_stop_pending_; 256 bool is_stop_pending_;
246 257
247 private: 258 private:
248 DISALLOW_COPY_AND_ASSIGN(FakeVideoDecoderTest); 259 DISALLOW_COPY_AND_ASSIGN(FakeVideoDecoderTest);
249 }; 260 };
250 261
251 TEST_F(FakeVideoDecoderTest, Initialize) { 262 TEST_F(FakeVideoDecoderTest, Initialize) {
252 Initialize(); 263 Initialize();
253 } 264 }
254 265
255 TEST_F(FakeVideoDecoderTest, Read_AllFrames) { 266 TEST_F(FakeVideoDecoderTest, Read_AllFrames) {
256 Initialize(); 267 Initialize();
257 ReadUntilEOS(); 268 ReadUntilEOS();
258 EXPECT_EQ(kNumInputBuffers, num_decoded_frames_); 269 EXPECT_EQ(kTotalBuffers, num_decoded_frames_);
259 }
260
261 TEST_F(FakeVideoDecoderTest, Read_AbortedDemuxerRead) {
262 Initialize();
263 demuxer_stream_->HoldNextRead();
264 ReadOneFrame();
265 AbortDemuxerRead();
266 ExpectReadResult(ABROTED);
267 } 270 }
268 271
269 TEST_F(FakeVideoDecoderTest, Read_DecodingDelay) { 272 TEST_F(FakeVideoDecoderTest, Read_DecodingDelay) {
270 Initialize(); 273 Initialize();
271 274
272 while (demuxer_stream_->num_buffers_returned() < kNumInputBuffers) { 275 while (num_input_buffers_ < kTotalBuffers) {
273 ReadOneFrame(); 276 ReadOneFrame();
274 EXPECT_EQ(demuxer_stream_->num_buffers_returned(), 277 EXPECT_EQ(num_input_buffers_, num_decoded_frames_ + kDecodingDelay);
275 num_decoded_frames_ + kDecodingDelay);
276 } 278 }
277 } 279 }
278 280
279 TEST_F(FakeVideoDecoderTest, Read_ZeroDelay) { 281 TEST_F(FakeVideoDecoderTest, Read_ZeroDelay) {
280 decoder_.reset(new FakeVideoDecoder(0)); 282 decoder_.reset(new FakeVideoDecoder(0));
281 Initialize(); 283 Initialize();
282 284
283 while (demuxer_stream_->num_buffers_returned() < kNumInputBuffers) { 285 while (num_input_buffers_ < kTotalBuffers) {
284 ReadOneFrame(); 286 ReadOneFrame();
285 EXPECT_EQ(demuxer_stream_->num_buffers_returned(), num_decoded_frames_); 287 EXPECT_EQ(num_input_buffers_, num_decoded_frames_);
286 } 288 }
287 } 289 }
288 290
289 TEST_F(FakeVideoDecoderTest, Read_Pending) { 291 TEST_F(FakeVideoDecoderTest, Read_Pending_NotEnoughData) {
290 Initialize(); 292 Initialize();
293 decoder_->HoldNextRead();
294 ReadOneFrame();
295 ExpectReadResult(PENDING);
296 SatisfyReadAndExpect(NOT_ENOUGH_DATA);
297 }
298
299 TEST_F(FakeVideoDecoderTest, Read_Pending_OK) {
300 Initialize();
301 ReadOneFrame();
291 EnterPendingReadState(); 302 EnterPendingReadState();
292 SatisfyRead(); 303 SatisfyReadAndExpect(OK);
293 } 304 }
294 305
295 TEST_F(FakeVideoDecoderTest, Reinitialize) { 306 TEST_F(FakeVideoDecoderTest, Reinitialize) {
296 Initialize(); 307 Initialize();
297 VideoDecoderConfig old_config = demuxer_stream_->video_decoder_config(); 308 ReadOneFrame();
298 ChangeConfig(); 309 InitializeWithConfig(TestVideoConfig::Large());
299 VideoDecoderConfig new_config = demuxer_stream_->video_decoder_config(); 310 ReadOneFrame();
300 EXPECT_FALSE(new_config.Matches(old_config));
301 Initialize();
302 } 311 }
303 312
304 // Reinitializing the decoder during the middle of the decoding process can 313 // Reinitializing the decoder during the middle of the decoding process can
305 // cause dropped frames. 314 // cause dropped frames.
306 TEST_F(FakeVideoDecoderTest, Reinitialize_FrameDropped) { 315 TEST_F(FakeVideoDecoderTest, Reinitialize_FrameDropped) {
307 Initialize(); 316 Initialize();
308 ReadOneFrame(); 317 ReadOneFrame();
309 Initialize(); 318 Initialize();
310 ReadUntilEOS(); 319 ReadUntilEOS();
311 EXPECT_LT(num_decoded_frames_, kNumInputBuffers); 320 EXPECT_LT(num_decoded_frames_, kTotalBuffers);
312 } 321 }
313 322
314 TEST_F(FakeVideoDecoderTest, Reset) { 323 TEST_F(FakeVideoDecoderTest, Reset) {
315 Initialize(); 324 Initialize();
316 ReadOneFrame(); 325 ReadOneFrame();
317 ResetAndExpect(OK); 326 ResetAndExpect(OK);
318 } 327 }
319 328
320 TEST_F(FakeVideoDecoderTest, Reset_DuringPendingDemuxerRead) {
321 Initialize();
322 EnterPendingDemuxerReadState();
323 ResetAndExpect(PENDING);
324 SatisfyDemuxerRead();
325 ExpectReadResult(ABROTED);
326 }
327
328 TEST_F(FakeVideoDecoderTest, Reset_DuringPendingDemuxerRead_Aborted) {
329 Initialize();
330 EnterPendingDemuxerReadState();
331 ResetAndExpect(PENDING);
332 AbortDemuxerRead();
333 ExpectReadResult(ABROTED);
334 }
335
336 TEST_F(FakeVideoDecoderTest, Reset_DuringPendingRead) { 329 TEST_F(FakeVideoDecoderTest, Reset_DuringPendingRead) {
337 Initialize(); 330 Initialize();
338 EnterPendingReadState(); 331 EnterPendingReadState();
339 ResetAndExpect(PENDING); 332 ResetAndExpect(PENDING);
340 SatisfyRead(); 333 SatisfyRead();
341 } 334 }
342 335
343 TEST_F(FakeVideoDecoderTest, Reset_Pending) { 336 TEST_F(FakeVideoDecoderTest, Reset_Pending) {
344 Initialize(); 337 Initialize();
345 EnterPendingResetState(); 338 EnterPendingResetState();
(...skipping 15 matching lines...) Expand all
361 StopAndExpect(OK); 354 StopAndExpect(OK);
362 } 355 }
363 356
364 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingInitialization) { 357 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingInitialization) {
365 EnterPendingInitState(); 358 EnterPendingInitState();
366 EnterPendingStopState(); 359 EnterPendingStopState();
367 SatisfyInit(); 360 SatisfyInit();
368 SatisfyStop(); 361 SatisfyStop();
369 } 362 }
370 363
371 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingDemuxerRead) {
372 Initialize();
373 EnterPendingDemuxerReadState();
374 StopAndExpect(PENDING);
375 SatisfyDemuxerRead();
376 ExpectReadResult(ABROTED);
377 }
378
379 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingDemuxerRead_Aborted) {
380 Initialize();
381 EnterPendingDemuxerReadState();
382 ResetAndExpect(PENDING);
383 StopAndExpect(PENDING);
384 SatisfyDemuxerRead();
385 ExpectReadResult(ABROTED);
386 ExpectResetResult(OK);
387 ExpectStopResult(OK);
388 }
389
390 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingRead) { 364 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingRead) {
391 Initialize(); 365 Initialize();
392 EnterPendingReadState(); 366 EnterPendingReadState();
393 StopAndExpect(PENDING); 367 StopAndExpect(PENDING);
394 SatisfyRead(); 368 SatisfyRead();
395 ExpectStopResult(OK); 369 ExpectStopResult(OK);
396 } 370 }
397 371
398 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingReset) { 372 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingReset) {
399 Initialize(); 373 Initialize();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 Initialize(); 416 Initialize();
443 EnterPendingReadState(); 417 EnterPendingReadState();
444 EnterPendingResetState(); 418 EnterPendingResetState();
445 EnterPendingStopState(); 419 EnterPendingStopState();
446 SatisfyRead(); 420 SatisfyRead();
447 SatisfyReset(); 421 SatisfyReset();
448 SatisfyStop(); 422 SatisfyStop();
449 } 423 }
450 424
451 } // namespace media 425 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/fake_video_decoder.cc ('k') | media/filters/ffmpeg_video_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698