Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / media / filters / fake_video_decoder_unittest.cc
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.
4
5 #include "base/basictypes.h"
6 #include "base/bind.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"
14
15 namespace media {
16
17 static const int kDecodingDelay = 9;
18 static const int kTotalBuffers = 12;
19 static const int kDurationMs = 30;
20
21 class FakeVideoDecoderTest : public testing::Test,
22                              public testing::WithParamInterface<int> {
23  public:
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) {}
31
32   virtual ~FakeVideoDecoderTest() {
33     Stop();
34   }
35
36   void InitializeWithConfig(const VideoDecoderConfig& config) {
37     decoder_->Initialize(config, false, NewExpectedStatusCB(PIPELINE_OK));
38     message_loop_.RunUntilIdle();
39     current_config_ = config;
40   }
41
42   void Initialize() {
43     InitializeWithConfig(TestVideoConfig::Normal());
44   }
45
46   void EnterPendingInitState() {
47     decoder_->HoldNextInit();
48     Initialize();
49   }
50
51   void SatisfyInit() {
52     decoder_->SatisfyInit();
53     message_loop_.RunUntilIdle();
54   }
55
56   // Callback for VideoDecoder::Read().
57   void FrameReady(VideoDecoder::Status status,
58                   const scoped_refptr<VideoFrame>& frame) {
59     DCHECK_GT(pending_decode_requests_, 0);
60
61     --pending_decode_requests_;
62     last_decode_status_ = status;
63     last_decoded_frame_ = frame;
64
65     if (frame && !frame->end_of_stream())
66       num_decoded_frames_++;
67   }
68
69   enum CallbackResult {
70     PENDING,
71     OK,
72     NOT_ENOUGH_DATA,
73     ABORTED,
74     EOS
75   };
76
77   void ExpectReadResult(CallbackResult result) {
78     switch (result) {
79       case PENDING:
80         EXPECT_GT(pending_decode_requests_, 0);
81         break;
82       case OK:
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());
87         break;
88       case NOT_ENOUGH_DATA:
89         EXPECT_EQ(0, pending_decode_requests_);
90         ASSERT_EQ(VideoDecoder::kNotEnoughData, last_decode_status_);
91         ASSERT_FALSE(last_decoded_frame_);
92         break;
93       case ABORTED:
94         EXPECT_EQ(0, pending_decode_requests_);
95         ASSERT_EQ(VideoDecoder::kAborted, last_decode_status_);
96         EXPECT_FALSE(last_decoded_frame_);
97         break;
98       case EOS:
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());
103         break;
104     }
105   }
106
107   void Decode() {
108     scoped_refptr<DecoderBuffer> buffer;
109
110     if (num_input_buffers_ < kTotalBuffers) {
111       buffer = CreateFakeVideoBufferForTest(
112           current_config_,
113           base::TimeDelta::FromMilliseconds(kDurationMs * num_input_buffers_),
114           base::TimeDelta::FromMilliseconds(kDurationMs));
115       num_input_buffers_++;
116     } else {
117       buffer = DecoderBuffer::CreateEOSBuffer();
118     }
119
120     ++pending_decode_requests_;
121
122     decoder_->Decode(
123         buffer,
124         base::Bind(&FakeVideoDecoderTest::FrameReady, base::Unretained(this)));
125     message_loop_.RunUntilIdle();
126   }
127
128   void ReadOneFrame() {
129     do {
130       Decode();
131     } while (last_decode_status_ == VideoDecoder::kNotEnoughData &&
132              pending_decode_requests_ == 0);
133   }
134
135   void ReadUntilEOS() {
136     do {
137       ReadOneFrame();
138     } while (last_decoded_frame_ && !last_decoded_frame_->end_of_stream());
139   }
140
141   void EnterPendingReadState() {
142     // Pass the initial NOT_ENOUGH_DATA stage.
143     ReadOneFrame();
144     decoder_->HoldDecode();
145     ReadOneFrame();
146     ExpectReadResult(PENDING);
147   }
148
149   void SatisfyReadAndExpect(CallbackResult result) {
150     decoder_->SatisfyDecode();
151     message_loop_.RunUntilIdle();
152     ExpectReadResult(result);
153   }
154
155   void SatisfyRead() {
156     SatisfyReadAndExpect(OK);
157   }
158
159   // Callback for VideoDecoder::Reset().
160   void OnDecoderReset() {
161     DCHECK(is_reset_pending_);
162     is_reset_pending_ = false;
163   }
164
165   void ExpectResetResult(CallbackResult result) {
166     switch (result) {
167       case PENDING:
168         EXPECT_TRUE(is_reset_pending_);
169         break;
170       case OK:
171         EXPECT_FALSE(is_reset_pending_);
172         break;
173       default:
174         NOTREACHED();
175     }
176   }
177
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);
184   }
185
186   void EnterPendingResetState() {
187     decoder_->HoldNextReset();
188     ResetAndExpect(PENDING);
189   }
190
191   void SatisfyReset() {
192     decoder_->SatisfyReset();
193     message_loop_.RunUntilIdle();
194     ExpectResetResult(OK);
195   }
196
197   void Stop() {
198     decoder_->Stop();
199     message_loop_.RunUntilIdle();
200
201     // All pending callbacks must have been fired.
202     DCHECK_EQ(pending_decode_requests_, 0);
203     DCHECK(!is_reset_pending_);
204   }
205
206   base::MessageLoop message_loop_;
207   VideoDecoderConfig current_config_;
208
209   scoped_ptr<FakeVideoDecoder> decoder_;
210
211   int num_input_buffers_;
212   int num_decoded_frames_;
213
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_;
219
220  private:
221   DISALLOW_COPY_AND_ASSIGN(FakeVideoDecoderTest);
222 };
223
224 INSTANTIATE_TEST_CASE_P(NoParallelDecode,
225                         FakeVideoDecoderTest,
226                         ::testing::Values(1));
227 INSTANTIATE_TEST_CASE_P(ParallelDecode,
228                         FakeVideoDecoderTest,
229                         ::testing::Values(3));
230
231 TEST_P(FakeVideoDecoderTest, Initialize) {
232   Initialize();
233 }
234
235 TEST_P(FakeVideoDecoderTest, Read_AllFrames) {
236   Initialize();
237   ReadUntilEOS();
238   EXPECT_EQ(kTotalBuffers, num_decoded_frames_);
239 }
240
241 TEST_P(FakeVideoDecoderTest, Read_DecodingDelay) {
242   Initialize();
243
244   while (num_input_buffers_ < kTotalBuffers) {
245     ReadOneFrame();
246     EXPECT_EQ(num_input_buffers_, num_decoded_frames_ + kDecodingDelay);
247   }
248 }
249
250 TEST_P(FakeVideoDecoderTest, Read_ZeroDelay) {
251   decoder_.reset(new FakeVideoDecoder(0, false, 1));
252   Initialize();
253
254   while (num_input_buffers_ < kTotalBuffers) {
255     ReadOneFrame();
256     EXPECT_EQ(num_input_buffers_, num_decoded_frames_);
257   }
258 }
259
260 TEST_P(FakeVideoDecoderTest, Read_Pending_NotEnoughData) {
261   Initialize();
262   decoder_->HoldDecode();
263   ReadOneFrame();
264   ExpectReadResult(PENDING);
265   SatisfyReadAndExpect(NOT_ENOUGH_DATA);
266 }
267
268 TEST_P(FakeVideoDecoderTest, Read_Pending_OK) {
269   Initialize();
270   ReadOneFrame();
271   EnterPendingReadState();
272   SatisfyReadAndExpect(OK);
273 }
274
275 TEST_P(FakeVideoDecoderTest, Read_Parallel) {
276   int max_decode_requests = GetParam();
277   if (max_decode_requests < 2)
278     return;
279
280   Initialize();
281   ReadOneFrame();
282   decoder_->HoldDecode();
283   for (int i = 0; i < max_decode_requests; ++i) {
284     ReadOneFrame();
285     ExpectReadResult(PENDING);
286   }
287   EXPECT_EQ(max_decode_requests, pending_decode_requests_);
288   SatisfyReadAndExpect(OK);
289 }
290
291 TEST_P(FakeVideoDecoderTest, ReadWithHold_DecodingDelay) {
292   Initialize();
293
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())
299       Decode();
300     decoder_->SatisfySingleDecode();
301     ++num_decodes_satisfied;
302     message_loop_.RunUntilIdle();
303   }
304
305   DCHECK_EQ(num_decoded_frames_, 1);
306   DCHECK_EQ(num_decodes_satisfied, kDecodingDelay + 1);
307 }
308
309 TEST_P(FakeVideoDecoderTest, Reinitialize) {
310   Initialize();
311   ReadOneFrame();
312   InitializeWithConfig(TestVideoConfig::Large());
313   ReadOneFrame();
314 }
315
316 // Reinitializing the decoder during the middle of the decoding process can
317 // cause dropped frames.
318 TEST_P(FakeVideoDecoderTest, Reinitialize_FrameDropped) {
319   Initialize();
320   ReadOneFrame();
321   Initialize();
322   ReadUntilEOS();
323   EXPECT_LT(num_decoded_frames_, kTotalBuffers);
324 }
325
326 TEST_P(FakeVideoDecoderTest, Reset) {
327   Initialize();
328   ReadOneFrame();
329   ResetAndExpect(OK);
330 }
331
332 TEST_P(FakeVideoDecoderTest, Reset_DuringPendingRead) {
333   Initialize();
334   EnterPendingReadState();
335   ResetAndExpect(PENDING);
336   SatisfyReadAndExpect(ABORTED);
337 }
338
339 TEST_P(FakeVideoDecoderTest, Reset_Pending) {
340   Initialize();
341   EnterPendingResetState();
342   SatisfyReset();
343 }
344
345 TEST_P(FakeVideoDecoderTest, Reset_PendingDuringPendingRead) {
346   Initialize();
347   EnterPendingReadState();
348   EnterPendingResetState();
349   SatisfyReadAndExpect(ABORTED);
350   SatisfyReset();
351 }
352
353 TEST_P(FakeVideoDecoderTest, Stop) {
354   Initialize();
355   ReadOneFrame();
356   ExpectReadResult(OK);
357   Stop();
358 }
359
360 TEST_P(FakeVideoDecoderTest, Stop_DuringPendingInitialization) {
361   EnterPendingInitState();
362   Stop();
363 }
364
365 TEST_P(FakeVideoDecoderTest, Stop_DuringPendingRead) {
366   Initialize();
367   EnterPendingReadState();
368   Stop();
369 }
370
371 TEST_P(FakeVideoDecoderTest, Stop_DuringPendingReset) {
372   Initialize();
373   EnterPendingResetState();
374   Stop();
375 }
376
377 TEST_P(FakeVideoDecoderTest, Stop_DuringPendingReadAndPendingReset) {
378   Initialize();
379   EnterPendingReadState();
380   EnterPendingResetState();
381   Stop();
382 }
383
384 TEST_P(FakeVideoDecoderTest, GetDecodeOutput) {
385   decoder_.reset(new FakeVideoDecoder(kDecodingDelay, true, 1));
386   Initialize();
387
388   while (num_input_buffers_ < kTotalBuffers) {
389     ReadOneFrame();
390     while (decoder_->GetDecodeOutput())
391       ++num_decoded_frames_;
392     EXPECT_EQ(num_input_buffers_, num_decoded_frames_);
393   }
394 }
395
396 }  // namespace media