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"
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"
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
{
25 FakeVideoDecoderTest()
26 : decoder_(new FakeVideoDecoder(kDecodingDelay
)),
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() {
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();
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;
65 if (frame
.get() && !frame
->IsEndOfStream())
66 num_decoded_frames_
++;
76 void ExpectReadResult(CallbackResult result
) {
79 EXPECT_TRUE(is_read_pending_
);
80 ASSERT_FALSE(frame_read_
.get());
83 EXPECT_FALSE(is_read_pending_
);
84 ASSERT_TRUE(frame_read_
.get());
85 EXPECT_FALSE(frame_read_
->IsEndOfStream());
88 EXPECT_FALSE(is_read_pending_
);
89 EXPECT_FALSE(frame_read_
.get());
92 EXPECT_FALSE(is_read_pending_
);
93 ASSERT_TRUE(frame_read_
.get());
94 EXPECT_TRUE(frame_read_
->IsEndOfStream());
101 is_read_pending_
= true;
103 base::Bind(&FakeVideoDecoderTest::FrameReady
, base::Unretained(this)));
104 message_loop_
.RunUntilIdle();
107 void ReadUntilEOS() {
110 } while (frame_read_
.get() && !frame_read_
->IsEndOfStream());
113 void EnterPendingReadState() {
114 decoder_
->HoldNextRead();
116 ExpectReadResult(PENDING
);
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
) {
134 EXPECT_TRUE(is_reset_pending_
);
137 EXPECT_FALSE(is_reset_pending_
);
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
) {
172 EXPECT_TRUE(is_stop_pending_
);
175 EXPECT_FALSE(is_stop_pending_
);
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
);
196 decoder_
->SatisfyStop();
197 message_loop_
.RunUntilIdle();
198 ExpectStopResult(OK
);
201 // Callback for DemuxerStream::Read so that we can skip frames to trigger a
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),
216 message_loop_
.RunUntilIdle();
220 void EnterPendingDemuxerReadState() {
221 demuxer_stream_
->HoldNextRead();
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_
;
248 DISALLOW_COPY_AND_ASSIGN(FakeVideoDecoderTest
);
251 TEST_F(FakeVideoDecoderTest
, Initialize
) {
255 TEST_F(FakeVideoDecoderTest
, Read_AllFrames
) {
258 EXPECT_EQ(kNumInputBuffers
, num_decoded_frames_
);
261 TEST_F(FakeVideoDecoderTest
, Read_AbortedDemuxerRead
) {
263 demuxer_stream_
->HoldNextRead();
266 ExpectReadResult(ABROTED
);
269 TEST_F(FakeVideoDecoderTest
, Read_DecodingDelay
) {
272 while (demuxer_stream_
->num_buffers_returned() < kNumInputBuffers
) {
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));
283 while (demuxer_stream_
->num_buffers_returned() < kNumInputBuffers
) {
285 EXPECT_EQ(demuxer_stream_
->num_buffers_returned(), num_decoded_frames_
);
289 TEST_F(FakeVideoDecoderTest
, Read_Pending
) {
291 EnterPendingReadState();
295 TEST_F(FakeVideoDecoderTest
, Reinitialize
) {
297 VideoDecoderConfig old_config
= demuxer_stream_
->video_decoder_config();
299 VideoDecoderConfig new_config
= demuxer_stream_
->video_decoder_config();
300 EXPECT_FALSE(new_config
.Matches(old_config
));
304 // Reinitializing the decoder during the middle of the decoding process can
305 // cause dropped frames.
306 TEST_F(FakeVideoDecoderTest
, Reinitialize_FrameDropped
) {
311 EXPECT_LT(num_decoded_frames_
, kNumInputBuffers
);
314 TEST_F(FakeVideoDecoderTest
, Reset
) {
320 TEST_F(FakeVideoDecoderTest
, Reset_DuringPendingDemuxerRead
) {
322 EnterPendingDemuxerReadState();
323 ResetAndExpect(PENDING
);
324 SatisfyDemuxerRead();
325 ExpectReadResult(ABROTED
);
328 TEST_F(FakeVideoDecoderTest
, Reset_DuringPendingDemuxerRead_Aborted
) {
330 EnterPendingDemuxerReadState();
331 ResetAndExpect(PENDING
);
333 ExpectReadResult(ABROTED
);
336 TEST_F(FakeVideoDecoderTest
, Reset_DuringPendingRead
) {
338 EnterPendingReadState();
339 ResetAndExpect(PENDING
);
343 TEST_F(FakeVideoDecoderTest
, Reset_Pending
) {
345 EnterPendingResetState();
349 TEST_F(FakeVideoDecoderTest
, Reset_PendingDuringPendingRead
) {
351 EnterPendingReadState();
352 EnterPendingResetState();
357 TEST_F(FakeVideoDecoderTest
, Stop
) {
360 ExpectReadResult(OK
);
364 TEST_F(FakeVideoDecoderTest
, Stop_DuringPendingInitialization
) {
365 EnterPendingInitState();
366 EnterPendingStopState();
371 TEST_F(FakeVideoDecoderTest
, Stop_DuringPendingDemuxerRead
) {
373 EnterPendingDemuxerReadState();
374 StopAndExpect(PENDING
);
375 SatisfyDemuxerRead();
376 ExpectReadResult(ABROTED
);
379 TEST_F(FakeVideoDecoderTest
, Stop_DuringPendingDemuxerRead_Aborted
) {
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
) {
392 EnterPendingReadState();
393 StopAndExpect(PENDING
);
395 ExpectStopResult(OK
);
398 TEST_F(FakeVideoDecoderTest
, Stop_DuringPendingReset
) {
400 EnterPendingResetState();
401 StopAndExpect(PENDING
);
403 ExpectStopResult(OK
);
406 TEST_F(FakeVideoDecoderTest
, Stop_DuringPendingReadAndPendingReset
) {
408 EnterPendingReadState();
409 EnterPendingResetState();
410 StopAndExpect(PENDING
);
413 ExpectStopResult(OK
);
416 TEST_F(FakeVideoDecoderTest
, Stop_Pending
) {
418 decoder_
->HoldNextStop();
419 StopAndExpect(PENDING
);
420 decoder_
->SatisfyStop();
421 message_loop_
.RunUntilIdle();
422 ExpectStopResult(OK
);
425 TEST_F(FakeVideoDecoderTest
, Stop_PendingDuringPendingRead
) {
427 EnterPendingReadState();
428 EnterPendingStopState();
433 TEST_F(FakeVideoDecoderTest
, Stop_PendingDuringPendingReset
) {
435 EnterPendingResetState();
436 EnterPendingStopState();
441 TEST_F(FakeVideoDecoderTest
, Stop_PendingDuringPendingReadAndPendingReset
) {
443 EnterPendingReadState();
444 EnterPendingResetState();
445 EnterPendingStopState();