Fix some potential after free errors on TestCompletionCallback
[chromium-blink-merge.git] / media / filters / fake_video_decoder_unittest.cc
blobfc1cb14adc668df9a71d9084b5a42b46f40788fb
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
3 // found in the LICENSE file.
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"
16 namespace media {
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;
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) {}
34 virtual ~FakeVideoDecoderTest() {
35 StopAndExpect(OK);
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();
46 void EnterPendingInitState() {
47 decoder_->HoldNextInit();
48 Initialize();
51 void SatisfyInit() {
52 decoder_->SatisfyInit();
53 message_loop_.RunUntilIdle();
56 // Callback for VideoDecoder::Read().
57 void FrameReady(VideoDecoder::Status status,
58 const scoped_refptr<VideoFrame>& frame) {
59 DCHECK(is_read_pending_);
60 ASSERT_EQ(VideoDecoder::kOk, status);
62 is_read_pending_ = false;
63 frame_read_ = frame;
65 if (frame.get() && !frame->IsEndOfStream())
66 num_decoded_frames_++;
69 enum CallbackResult {
70 PENDING,
71 OK,
72 ABROTED,
73 EOS
76 void ExpectReadResult(CallbackResult result) {
77 switch (result) {
78 case PENDING:
79 EXPECT_TRUE(is_read_pending_);
80 ASSERT_FALSE(frame_read_.get());
81 break;
82 case OK:
83 EXPECT_FALSE(is_read_pending_);
84 ASSERT_TRUE(frame_read_.get());
85 EXPECT_FALSE(frame_read_->IsEndOfStream());
86 break;
87 case ABROTED:
88 EXPECT_FALSE(is_read_pending_);
89 EXPECT_FALSE(frame_read_.get());
90 break;
91 case EOS:
92 EXPECT_FALSE(is_read_pending_);
93 ASSERT_TRUE(frame_read_.get());
94 EXPECT_TRUE(frame_read_->IsEndOfStream());
95 break;
99 void ReadOneFrame() {
100 frame_read_ = NULL;
101 is_read_pending_ = true;
102 decoder_->Read(
103 base::Bind(&FakeVideoDecoderTest::FrameReady, base::Unretained(this)));
104 message_loop_.RunUntilIdle();
107 void ReadUntilEOS() {
108 do {
109 ReadOneFrame();
110 } while (frame_read_.get() && !frame_read_->IsEndOfStream());
113 void EnterPendingReadState() {
114 decoder_->HoldNextRead();
115 ReadOneFrame();
116 ExpectReadResult(PENDING);
119 void SatisfyRead() {
120 decoder_->SatisfyRead();
121 message_loop_.RunUntilIdle();
122 ExpectReadResult(OK);
125 // Callback for VideoDecoder::Reset().
126 void OnDecoderReset() {
127 DCHECK(is_reset_pending_);
128 is_reset_pending_ = false;
131 void ExpectResetResult(CallbackResult result) {
132 switch (result) {
133 case PENDING:
134 EXPECT_TRUE(is_reset_pending_);
135 break;
136 case OK:
137 EXPECT_FALSE(is_reset_pending_);
138 break;
139 default:
140 NOTREACHED();
144 void ResetAndExpect(CallbackResult result) {
145 is_reset_pending_ = true;
146 decoder_->Reset(base::Bind(&FakeVideoDecoderTest::OnDecoderReset,
147 base::Unretained(this)));
148 message_loop_.RunUntilIdle();
149 ExpectResetResult(result);
152 void EnterPendingResetState() {
153 decoder_->HoldNextReset();
154 ResetAndExpect(PENDING);
157 void SatisfyReset() {
158 decoder_->SatisfyReset();
159 message_loop_.RunUntilIdle();
160 ExpectResetResult(OK);
163 // Callback for VideoDecoder::Stop().
164 void OnDecoderStopped() {
165 DCHECK(is_stop_pending_);
166 is_stop_pending_ = false;
169 void ExpectStopResult(CallbackResult result) {
170 switch (result) {
171 case PENDING:
172 EXPECT_TRUE(is_stop_pending_);
173 break;
174 case OK:
175 EXPECT_FALSE(is_stop_pending_);
176 break;
177 default:
178 NOTREACHED();
182 void StopAndExpect(CallbackResult result) {
183 is_stop_pending_ = true;
184 decoder_->Stop(base::Bind(&FakeVideoDecoderTest::OnDecoderStopped,
185 base::Unretained(this)));
186 message_loop_.RunUntilIdle();
187 ExpectStopResult(result);
190 void EnterPendingStopState() {
191 decoder_->HoldNextStop();
192 StopAndExpect(PENDING);
195 void SatisfyStop() {
196 decoder_->SatisfyStop();
197 message_loop_.RunUntilIdle();
198 ExpectStopResult(OK);
201 // Callback for DemuxerStream::Read so that we can skip frames to trigger a
202 // config change.
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;
210 void ChangeConfig() {
211 bool config_changed = false;
212 while (!config_changed) {
213 demuxer_stream_->Read(base::Bind(&FakeVideoDecoderTest::BufferReady,
214 base::Unretained(this),
215 &config_changed));
216 message_loop_.RunUntilIdle();
220 void EnterPendingDemuxerReadState() {
221 demuxer_stream_->HoldNextRead();
222 ReadOneFrame();
225 void SatisfyDemuxerRead() {
226 demuxer_stream_->SatisfyRead();
227 message_loop_.RunUntilIdle();
230 void AbortDemuxerRead() {
231 demuxer_stream_->Reset();
232 message_loop_.RunUntilIdle();
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_;
241 // Callback result/status.
242 scoped_refptr<VideoFrame> frame_read_;
243 bool is_read_pending_;
244 bool is_reset_pending_;
245 bool is_stop_pending_;
247 private:
248 DISALLOW_COPY_AND_ASSIGN(FakeVideoDecoderTest);
251 TEST_F(FakeVideoDecoderTest, Initialize) {
252 Initialize();
255 TEST_F(FakeVideoDecoderTest, Read_AllFrames) {
256 Initialize();
257 ReadUntilEOS();
258 EXPECT_EQ(kNumInputBuffers, num_decoded_frames_);
261 TEST_F(FakeVideoDecoderTest, Read_AbortedDemuxerRead) {
262 Initialize();
263 demuxer_stream_->HoldNextRead();
264 ReadOneFrame();
265 AbortDemuxerRead();
266 ExpectReadResult(ABROTED);
269 TEST_F(FakeVideoDecoderTest, Read_DecodingDelay) {
270 Initialize();
272 while (demuxer_stream_->num_buffers_returned() < kNumInputBuffers) {
273 ReadOneFrame();
274 EXPECT_EQ(demuxer_stream_->num_buffers_returned(),
275 num_decoded_frames_ + kDecodingDelay);
279 TEST_F(FakeVideoDecoderTest, Read_ZeroDelay) {
280 decoder_.reset(new FakeVideoDecoder(0));
281 Initialize();
283 while (demuxer_stream_->num_buffers_returned() < kNumInputBuffers) {
284 ReadOneFrame();
285 EXPECT_EQ(demuxer_stream_->num_buffers_returned(), num_decoded_frames_);
289 TEST_F(FakeVideoDecoderTest, Read_Pending) {
290 Initialize();
291 EnterPendingReadState();
292 SatisfyRead();
295 TEST_F(FakeVideoDecoderTest, Reinitialize) {
296 Initialize();
297 VideoDecoderConfig old_config = demuxer_stream_->video_decoder_config();
298 ChangeConfig();
299 VideoDecoderConfig new_config = demuxer_stream_->video_decoder_config();
300 EXPECT_FALSE(new_config.Matches(old_config));
301 Initialize();
304 // Reinitializing the decoder during the middle of the decoding process can
305 // cause dropped frames.
306 TEST_F(FakeVideoDecoderTest, Reinitialize_FrameDropped) {
307 Initialize();
308 ReadOneFrame();
309 Initialize();
310 ReadUntilEOS();
311 EXPECT_LT(num_decoded_frames_, kNumInputBuffers);
314 TEST_F(FakeVideoDecoderTest, Reset) {
315 Initialize();
316 ReadOneFrame();
317 ResetAndExpect(OK);
320 TEST_F(FakeVideoDecoderTest, Reset_DuringPendingDemuxerRead) {
321 Initialize();
322 EnterPendingDemuxerReadState();
323 ResetAndExpect(PENDING);
324 SatisfyDemuxerRead();
325 ExpectReadResult(ABROTED);
328 TEST_F(FakeVideoDecoderTest, Reset_DuringPendingDemuxerRead_Aborted) {
329 Initialize();
330 EnterPendingDemuxerReadState();
331 ResetAndExpect(PENDING);
332 AbortDemuxerRead();
333 ExpectReadResult(ABROTED);
336 TEST_F(FakeVideoDecoderTest, Reset_DuringPendingRead) {
337 Initialize();
338 EnterPendingReadState();
339 ResetAndExpect(PENDING);
340 SatisfyRead();
343 TEST_F(FakeVideoDecoderTest, Reset_Pending) {
344 Initialize();
345 EnterPendingResetState();
346 SatisfyReset();
349 TEST_F(FakeVideoDecoderTest, Reset_PendingDuringPendingRead) {
350 Initialize();
351 EnterPendingReadState();
352 EnterPendingResetState();
353 SatisfyRead();
354 SatisfyReset();
357 TEST_F(FakeVideoDecoderTest, Stop) {
358 Initialize();
359 ReadOneFrame();
360 ExpectReadResult(OK);
361 StopAndExpect(OK);
364 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingInitialization) {
365 EnterPendingInitState();
366 EnterPendingStopState();
367 SatisfyInit();
368 SatisfyStop();
371 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingDemuxerRead) {
372 Initialize();
373 EnterPendingDemuxerReadState();
374 StopAndExpect(PENDING);
375 SatisfyDemuxerRead();
376 ExpectReadResult(ABROTED);
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);
390 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingRead) {
391 Initialize();
392 EnterPendingReadState();
393 StopAndExpect(PENDING);
394 SatisfyRead();
395 ExpectStopResult(OK);
398 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingReset) {
399 Initialize();
400 EnterPendingResetState();
401 StopAndExpect(PENDING);
402 SatisfyReset();
403 ExpectStopResult(OK);
406 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingReadAndPendingReset) {
407 Initialize();
408 EnterPendingReadState();
409 EnterPendingResetState();
410 StopAndExpect(PENDING);
411 SatisfyRead();
412 SatisfyReset();
413 ExpectStopResult(OK);
416 TEST_F(FakeVideoDecoderTest, Stop_Pending) {
417 Initialize();
418 decoder_->HoldNextStop();
419 StopAndExpect(PENDING);
420 decoder_->SatisfyStop();
421 message_loop_.RunUntilIdle();
422 ExpectStopResult(OK);
425 TEST_F(FakeVideoDecoderTest, Stop_PendingDuringPendingRead) {
426 Initialize();
427 EnterPendingReadState();
428 EnterPendingStopState();
429 SatisfyRead();
430 SatisfyStop();
433 TEST_F(FakeVideoDecoderTest, Stop_PendingDuringPendingReset) {
434 Initialize();
435 EnterPendingResetState();
436 EnterPendingStopState();
437 SatisfyReset();
438 SatisfyStop();
441 TEST_F(FakeVideoDecoderTest, Stop_PendingDuringPendingReadAndPendingReset) {
442 Initialize();
443 EnterPendingReadState();
444 EnterPendingResetState();
445 EnterPendingStopState();
446 SatisfyRead();
447 SatisfyReset();
448 SatisfyStop();
451 } // namespace media