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/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_video_decoder.h"
13 #include "testing/gtest/include/gtest/gtest.h"
17 static const int kDecodingDelay = 9;
18 static const int kTotalBuffers = 12;
19 static const int kDurationMs = 30;
21 class FakeVideoDecoderTest : public testing::Test,
22 public testing::WithParamInterface<int> {
24 FakeVideoDecoderTest()
25 : decoder_(new FakeVideoDecoder(kDecodingDelay, false, GetParam())),
26 num_input_buffers_(0),
27 num_decoded_frames_(0),
28 last_decode_status_(VideoDecoder::kNotEnoughData),
29 pending_decode_requests_(0),
30 is_reset_pending_(false) {}
32 virtual ~FakeVideoDecoderTest() {
36 void InitializeWithConfig(const VideoDecoderConfig& config) {
37 decoder_->Initialize(config, false, NewExpectedStatusCB(PIPELINE_OK));
38 message_loop_.RunUntilIdle();
39 current_config_ = config;
43 InitializeWithConfig(TestVideoConfig::Normal());
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_GT(pending_decode_requests_, 0);
61 --pending_decode_requests_;
62 last_decode_status_ = status;
63 last_decoded_frame_ = frame;
65 if (frame && !frame->end_of_stream())
66 num_decoded_frames_++;
77 void ExpectReadResult(CallbackResult result) {
80 EXPECT_GT(pending_decode_requests_, 0);
83 EXPECT_EQ(0, pending_decode_requests_);
84 ASSERT_EQ(VideoDecoder::kOk, last_decode_status_);
85 ASSERT_TRUE(last_decoded_frame_);
86 EXPECT_FALSE(last_decoded_frame_->end_of_stream());
89 EXPECT_EQ(0, pending_decode_requests_);
90 ASSERT_EQ(VideoDecoder::kNotEnoughData, last_decode_status_);
91 ASSERT_FALSE(last_decoded_frame_);
94 EXPECT_EQ(0, pending_decode_requests_);
95 ASSERT_EQ(VideoDecoder::kAborted, last_decode_status_);
96 EXPECT_FALSE(last_decoded_frame_);
99 EXPECT_EQ(0, pending_decode_requests_);
100 ASSERT_EQ(VideoDecoder::kOk, last_decode_status_);
101 ASSERT_TRUE(last_decoded_frame_);
102 EXPECT_TRUE(last_decoded_frame_->end_of_stream());
108 scoped_refptr<DecoderBuffer> buffer;
110 if (num_input_buffers_ < kTotalBuffers) {
111 buffer = CreateFakeVideoBufferForTest(
113 base::TimeDelta::FromMilliseconds(kDurationMs * num_input_buffers_),
114 base::TimeDelta::FromMilliseconds(kDurationMs));
115 num_input_buffers_++;
117 buffer = DecoderBuffer::CreateEOSBuffer();
120 ++pending_decode_requests_;
124 base::Bind(&FakeVideoDecoderTest::FrameReady, base::Unretained(this)));
125 message_loop_.RunUntilIdle();
128 void ReadOneFrame() {
131 } while (last_decode_status_ == VideoDecoder::kNotEnoughData &&
132 pending_decode_requests_ == 0);
135 void ReadUntilEOS() {
138 } while (last_decoded_frame_ && !last_decoded_frame_->end_of_stream());
141 void EnterPendingReadState() {
142 // Pass the initial NOT_ENOUGH_DATA stage.
144 decoder_->HoldDecode();
146 ExpectReadResult(PENDING);
149 void SatisfyReadAndExpect(CallbackResult result) {
150 decoder_->SatisfyDecode();
151 message_loop_.RunUntilIdle();
152 ExpectReadResult(result);
156 SatisfyReadAndExpect(OK);
159 // Callback for VideoDecoder::Reset().
160 void OnDecoderReset() {
161 DCHECK(is_reset_pending_);
162 is_reset_pending_ = false;
165 void ExpectResetResult(CallbackResult result) {
168 EXPECT_TRUE(is_reset_pending_);
171 EXPECT_FALSE(is_reset_pending_);
178 void ResetAndExpect(CallbackResult result) {
179 is_reset_pending_ = true;
180 decoder_->Reset(base::Bind(&FakeVideoDecoderTest::OnDecoderReset,
181 base::Unretained(this)));
182 message_loop_.RunUntilIdle();
183 ExpectResetResult(result);
186 void EnterPendingResetState() {
187 decoder_->HoldNextReset();
188 ResetAndExpect(PENDING);
191 void SatisfyReset() {
192 decoder_->SatisfyReset();
193 message_loop_.RunUntilIdle();
194 ExpectResetResult(OK);
199 message_loop_.RunUntilIdle();
201 // All pending callbacks must have been fired.
202 DCHECK_EQ(pending_decode_requests_, 0);
203 DCHECK(!is_reset_pending_);
206 base::MessageLoop message_loop_;
207 VideoDecoderConfig current_config_;
209 scoped_ptr<FakeVideoDecoder> decoder_;
211 int num_input_buffers_;
212 int num_decoded_frames_;
214 // Callback result/status.
215 VideoDecoder::Status last_decode_status_;
216 scoped_refptr<VideoFrame> last_decoded_frame_;
217 int pending_decode_requests_;
218 bool is_reset_pending_;
221 DISALLOW_COPY_AND_ASSIGN(FakeVideoDecoderTest);
224 INSTANTIATE_TEST_CASE_P(NoParallelDecode,
225 FakeVideoDecoderTest,
226 ::testing::Values(1));
227 INSTANTIATE_TEST_CASE_P(ParallelDecode,
228 FakeVideoDecoderTest,
229 ::testing::Values(3));
231 TEST_P(FakeVideoDecoderTest, Initialize) {
235 TEST_P(FakeVideoDecoderTest, Read_AllFrames) {
238 EXPECT_EQ(kTotalBuffers, num_decoded_frames_);
241 TEST_P(FakeVideoDecoderTest, Read_DecodingDelay) {
244 while (num_input_buffers_ < kTotalBuffers) {
246 EXPECT_EQ(num_input_buffers_, num_decoded_frames_ + kDecodingDelay);
250 TEST_P(FakeVideoDecoderTest, Read_ZeroDelay) {
251 decoder_.reset(new FakeVideoDecoder(0, false, 1));
254 while (num_input_buffers_ < kTotalBuffers) {
256 EXPECT_EQ(num_input_buffers_, num_decoded_frames_);
260 TEST_P(FakeVideoDecoderTest, Read_Pending_NotEnoughData) {
262 decoder_->HoldDecode();
264 ExpectReadResult(PENDING);
265 SatisfyReadAndExpect(NOT_ENOUGH_DATA);
268 TEST_P(FakeVideoDecoderTest, Read_Pending_OK) {
271 EnterPendingReadState();
272 SatisfyReadAndExpect(OK);
275 TEST_P(FakeVideoDecoderTest, Read_Parallel) {
276 int max_decode_requests = GetParam();
277 if (max_decode_requests < 2)
282 decoder_->HoldDecode();
283 for (int i = 0; i < max_decode_requests; ++i) {
285 ExpectReadResult(PENDING);
287 EXPECT_EQ(max_decode_requests, pending_decode_requests_);
288 SatisfyReadAndExpect(OK);
291 TEST_P(FakeVideoDecoderTest, ReadWithHold_DecodingDelay) {
294 // Hold all decodes and satisfy one decode at a time.
295 decoder_->HoldDecode();
296 int num_decodes_satisfied = 0;
297 while (num_decoded_frames_ == 0) {
298 while (pending_decode_requests_ < decoder_->GetMaxDecodeRequests())
300 decoder_->SatisfySingleDecode();
301 ++num_decodes_satisfied;
302 message_loop_.RunUntilIdle();
305 DCHECK_EQ(num_decoded_frames_, 1);
306 DCHECK_EQ(num_decodes_satisfied, kDecodingDelay + 1);
309 TEST_P(FakeVideoDecoderTest, Reinitialize) {
312 InitializeWithConfig(TestVideoConfig::Large());
316 // Reinitializing the decoder during the middle of the decoding process can
317 // cause dropped frames.
318 TEST_P(FakeVideoDecoderTest, Reinitialize_FrameDropped) {
323 EXPECT_LT(num_decoded_frames_, kTotalBuffers);
326 TEST_P(FakeVideoDecoderTest, Reset) {
332 TEST_P(FakeVideoDecoderTest, Reset_DuringPendingRead) {
334 EnterPendingReadState();
335 ResetAndExpect(PENDING);
336 SatisfyReadAndExpect(ABORTED);
339 TEST_P(FakeVideoDecoderTest, Reset_Pending) {
341 EnterPendingResetState();
345 TEST_P(FakeVideoDecoderTest, Reset_PendingDuringPendingRead) {
347 EnterPendingReadState();
348 EnterPendingResetState();
349 SatisfyReadAndExpect(ABORTED);
353 TEST_P(FakeVideoDecoderTest, Stop) {
356 ExpectReadResult(OK);
360 TEST_P(FakeVideoDecoderTest, Stop_DuringPendingInitialization) {
361 EnterPendingInitState();
365 TEST_P(FakeVideoDecoderTest, Stop_DuringPendingRead) {
367 EnterPendingReadState();
371 TEST_P(FakeVideoDecoderTest, Stop_DuringPendingReset) {
373 EnterPendingResetState();
377 TEST_P(FakeVideoDecoderTest, Stop_DuringPendingReadAndPendingReset) {
379 EnterPendingReadState();
380 EnterPendingResetState();
384 TEST_P(FakeVideoDecoderTest, GetDecodeOutput) {
385 decoder_.reset(new FakeVideoDecoder(kDecodingDelay, true, 1));
388 while (num_input_buffers_ < kTotalBuffers) {
390 while (decoder_->GetDecodeOutput())
391 ++num_decoded_frames_;
392 EXPECT_EQ(num_input_buffers_, num_decoded_frames_);