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

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

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

Powered by Google App Engine
This is Rietveld 408576698