1// Copyright (c) 2012 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/bind.h"
6#include "base/callback_helpers.h"
7#include "base/message_loop/message_loop.h"
8#include "media/base/gmock_callback_support.h"
9#include "media/base/mock_filters.h"
10#include "media/base/test_helpers.h"
11#include "media/filters/fake_demuxer_stream.h"
12#include "media/filters/fake_video_decoder.h"
13#include "media/filters/video_frame_stream.h"
14#include "testing/gtest/include/gtest/gtest.h"
15
16using ::testing::_;
17using ::testing::Assign;
18using ::testing::Invoke;
19using ::testing::NiceMock;
20using ::testing::Return;
21using ::testing::SaveArg;
22
23static const int kNumConfigs = 3;
24static const int kNumBuffersInOneConfig = 5;
25static const int kDecodingDelay = 7;
26
27namespace media {
28
29class VideoFrameStreamTest : public testing::TestWithParam<bool> {
30 public:
31  VideoFrameStreamTest()
32      : demuxer_stream_(new FakeDemuxerStream(kNumConfigs,
33                                              kNumBuffersInOneConfig,
34                                              GetParam())),
35        decryptor_(new NiceMock<MockDecryptor>()),
36        decoder_(new FakeVideoDecoder(kDecodingDelay)),
37        is_initialized_(false),
38        num_decoded_frames_(0),
39        pending_read_(false),
40        pending_reset_(false),
41        pending_stop_(false),
42        total_bytes_decoded_(0) {
43    ScopedVector<VideoDecoder> decoders;
44    decoders.push_back(decoder_);
45
46    video_frame_stream_.reset(new VideoFrameStream(
47        message_loop_.message_loop_proxy(),
48        decoders.Pass(),
49        base::Bind(&VideoFrameStreamTest::SetDecryptorReadyCallback,
50                   base::Unretained(this))));
51
52    EXPECT_CALL(*this, SetDecryptorReadyCallback(_))
53        .WillRepeatedly(RunCallback<0>(decryptor_.get()));
54
55    // Decryptor can only decrypt (not decrypt-and-decode) so that
56    // DecryptingDemuxerStream will be used.
57    EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _))
58        .WillRepeatedly(RunCallback<1>(false));
59    EXPECT_CALL(*decryptor_, Decrypt(_, _, _))
60        .WillRepeatedly(Invoke(this, &VideoFrameStreamTest::Decrypt));
61  }
62
63  ~VideoFrameStreamTest() {
64    DCHECK(!pending_read_);
65    DCHECK(!pending_reset_);
66    DCHECK(!pending_stop_);
67
68    // Check that the pipeline statistics callback was fired correctly.
69    if (decoder_)
70      EXPECT_EQ(decoder_->total_bytes_decoded(), total_bytes_decoded_);
71
72    if (is_initialized_)
73      Stop();
74    EXPECT_FALSE(is_initialized_);
75  }
76
77  MOCK_METHOD1(SetDecryptorReadyCallback, void(const media::DecryptorReadyCB&));
78  MOCK_METHOD2(OnInitialized, void(bool, bool));
79
80  void OnStatistics(const PipelineStatistics& statistics) {
81    total_bytes_decoded_ += statistics.video_bytes_decoded;
82  }
83
84  // Fake Decrypt() function used by DecryptingDemuxerStream. It does nothing
85  // but removes the DecryptConfig to make the buffer unencrypted.
86  void Decrypt(Decryptor::StreamType stream_type,
87               const scoped_refptr<DecoderBuffer>& encrypted,
88               const Decryptor::DecryptCB& decrypt_cb) {
89    DCHECK_EQ(stream_type, Decryptor::kVideo);
90    scoped_refptr<DecoderBuffer> decrypted = DecoderBuffer::CopyFrom(
91        encrypted->data(), encrypted->data_size());
92    decrypted->set_timestamp(encrypted->timestamp());
93    decrypted->set_duration(encrypted->duration());
94    decrypt_cb.Run(Decryptor::kSuccess, decrypted);
95  }
96
97  // Callback for VideoFrameStream::Read().
98  void FrameReady(VideoFrameStream::Status status,
99                  const scoped_refptr<VideoFrame>& frame) {
100    DCHECK(pending_read_);
101    // TODO(xhwang): Add test cases where the fake decoder returns error or
102    // the fake demuxer aborts demuxer read.
103    ASSERT_TRUE(status == VideoFrameStream::OK ||
104                status == VideoFrameStream::ABORTED);
105    frame_read_ = frame;
106    if (frame.get() && !frame->IsEndOfStream())
107      num_decoded_frames_++;
108    pending_read_ = false;
109  }
110
111  void OnReset() {
112    DCHECK(!pending_read_);
113    DCHECK(pending_reset_);
114    pending_reset_ = false;
115  }
116
117  void OnStopped() {
118    DCHECK(!pending_read_);
119    DCHECK(!pending_reset_);
120    DCHECK(pending_stop_);
121    pending_stop_ = false;
122    is_initialized_ = false;
123  }
124
125  void ReadUntilPending() {
126    do {
127      frame_read_ = NULL;
128      pending_read_ = true;
129      video_frame_stream_->Read(base::Bind(
130          &VideoFrameStreamTest::FrameReady, base::Unretained(this)));
131      message_loop_.RunUntilIdle();
132    } while (!pending_read_);
133  }
134
135  enum PendingState {
136    NOT_PENDING,
137    DEMUXER_READ_NORMAL,
138    DEMUXER_READ_CONFIG_CHANGE,
139    DECODER_INIT,
140    DECODER_REINIT,
141    DECODER_READ,
142    DECODER_RESET,
143    DECODER_STOP
144  };
145
146  void EnterPendingState(PendingState state) {
147    DCHECK_NE(state, NOT_PENDING);
148    switch (state) {
149      case DEMUXER_READ_NORMAL:
150        demuxer_stream_->HoldNextRead();
151        ReadUntilPending();
152        break;
153
154      case DEMUXER_READ_CONFIG_CHANGE:
155        demuxer_stream_->HoldNextConfigChangeRead();
156        ReadUntilPending();
157        break;
158
159      case DECODER_INIT:
160        decoder_->HoldNextInit();
161        video_frame_stream_->Initialize(
162            demuxer_stream_.get(),
163            base::Bind(&VideoFrameStreamTest::OnStatistics,
164                       base::Unretained(this)),
165            base::Bind(&VideoFrameStreamTest::OnInitialized,
166                       base::Unretained(this)));
167        message_loop_.RunUntilIdle();
168        break;
169
170      case DECODER_REINIT:
171        decoder_->HoldNextInit();
172        ReadUntilPending();
173        break;
174
175      case DECODER_READ:
176        decoder_->HoldNextRead();
177        ReadUntilPending();
178        break;
179
180      case DECODER_RESET:
181        decoder_->HoldNextReset();
182        pending_reset_ = true;
183        video_frame_stream_->Reset(base::Bind(&VideoFrameStreamTest::OnReset,
184                                              base::Unretained(this)));
185        message_loop_.RunUntilIdle();
186        break;
187
188      case DECODER_STOP:
189        decoder_->HoldNextStop();
190        pending_stop_ = true;
191        video_frame_stream_->Stop(base::Bind(&VideoFrameStreamTest::OnStopped,
192                                             base::Unretained(this)));
193        message_loop_.RunUntilIdle();
194        break;
195
196      case NOT_PENDING:
197        NOTREACHED();
198        break;
199    }
200  }
201
202  void SatisfyPendingCallback(PendingState state) {
203    DCHECK_NE(state, NOT_PENDING);
204    switch (state) {
205      case DEMUXER_READ_NORMAL:
206      case DEMUXER_READ_CONFIG_CHANGE:
207        demuxer_stream_->SatisfyRead();
208        break;
209
210      case DECODER_INIT:
211        EXPECT_CALL(*this, OnInitialized(true, false))
212            .WillOnce(SaveArg<0>(&is_initialized_));
213        decoder_->SatisfyInit();
214        break;
215
216      case DECODER_REINIT:
217        decoder_->SatisfyInit();
218        break;
219
220      case DECODER_READ:
221        DCHECK(pending_read_);
222        decoder_->SatisfyRead();
223        break;
224
225      case DECODER_RESET:
226        DCHECK(pending_reset_);
227        decoder_->SatisfyReset();
228        break;
229
230      case DECODER_STOP:
231        DCHECK(pending_stop_);
232        decoder_->SatisfyStop();
233        break;
234
235      case NOT_PENDING:
236        NOTREACHED();
237        break;
238    }
239
240    message_loop_.RunUntilIdle();
241    if (!is_initialized_)
242      decoder_ = NULL;
243  }
244
245  void Initialize() {
246    EnterPendingState(DECODER_INIT);
247    SatisfyPendingCallback(DECODER_INIT);
248  }
249
250  void Read() {
251    EnterPendingState(DECODER_READ);
252    SatisfyPendingCallback(DECODER_READ);
253  }
254
255  void Reset() {
256    EnterPendingState(DECODER_RESET);
257    SatisfyPendingCallback(DECODER_RESET);
258  }
259
260  void Stop() {
261    EnterPendingState(DECODER_STOP);
262    SatisfyPendingCallback(DECODER_STOP);
263  }
264
265  base::MessageLoop message_loop_;
266
267  scoped_ptr<VideoFrameStream> video_frame_stream_;
268  scoped_ptr<FakeDemuxerStream> demuxer_stream_;
269  // Use NiceMock since we don't care about most of calls on the decryptor,
270  // e.g. RegisterNewKeyCB().
271  scoped_ptr<NiceMock<MockDecryptor> > decryptor_;
272  FakeVideoDecoder* decoder_;  // Owned by |video_frame_stream_|.
273
274  bool is_initialized_;
275  int num_decoded_frames_;
276  bool pending_read_;
277  bool pending_reset_;
278  bool pending_stop_;
279  int total_bytes_decoded_;
280  scoped_refptr<VideoFrame> frame_read_;
281
282 private:
283  DISALLOW_COPY_AND_ASSIGN(VideoFrameStreamTest);
284};
285
286INSTANTIATE_TEST_CASE_P(Clear, VideoFrameStreamTest, testing::Values(false));
287INSTANTIATE_TEST_CASE_P(Encrypted, VideoFrameStreamTest, testing::Values(true));
288
289TEST_P(VideoFrameStreamTest, Initialization) {
290  Initialize();
291}
292
293TEST_P(VideoFrameStreamTest, ReadOneFrame) {
294  Initialize();
295  Read();
296}
297
298TEST_P(VideoFrameStreamTest, ReadAllFrames) {
299  Initialize();
300  do {
301    Read();
302  } while (frame_read_.get() && !frame_read_->IsEndOfStream());
303
304  const int total_num_frames = kNumConfigs * kNumBuffersInOneConfig;
305  DCHECK_EQ(num_decoded_frames_, total_num_frames);
306}
307
308TEST_P(VideoFrameStreamTest, Read_AfterReset) {
309  Initialize();
310  Reset();
311  Read();
312  Reset();
313  Read();
314}
315
316// No Reset() before initialization is successfully completed.
317
318TEST_P(VideoFrameStreamTest, Reset_AfterInitialization) {
319  Initialize();
320  Reset();
321  Read();
322}
323
324TEST_P(VideoFrameStreamTest, Reset_DuringReinitialization) {
325  Initialize();
326  EnterPendingState(DECODER_REINIT);
327  // VideoDecoder::Reset() is not called when we reset during reinitialization.
328  pending_reset_ = true;
329  video_frame_stream_->Reset(
330      base::Bind(&VideoFrameStreamTest::OnReset, base::Unretained(this)));
331  SatisfyPendingCallback(DECODER_REINIT);
332  Read();
333}
334
335TEST_P(VideoFrameStreamTest, Reset_AfterReinitialization) {
336  Initialize();
337  EnterPendingState(DECODER_REINIT);
338  SatisfyPendingCallback(DECODER_REINIT);
339  Reset();
340  Read();
341}
342
343TEST_P(VideoFrameStreamTest, Reset_DuringDemuxerRead_Normal) {
344  Initialize();
345  EnterPendingState(DEMUXER_READ_NORMAL);
346  EnterPendingState(DECODER_RESET);
347  SatisfyPendingCallback(DEMUXER_READ_NORMAL);
348  SatisfyPendingCallback(DECODER_RESET);
349  Read();
350}
351
352TEST_P(VideoFrameStreamTest, Reset_DuringDemuxerRead_ConfigChange) {
353  Initialize();
354  EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
355  EnterPendingState(DECODER_RESET);
356  SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
357  SatisfyPendingCallback(DECODER_RESET);
358  Read();
359}
360
361TEST_P(VideoFrameStreamTest, Reset_DuringNormalDecoderRead) {
362  Initialize();
363  EnterPendingState(DECODER_READ);
364  EnterPendingState(DECODER_RESET);
365  SatisfyPendingCallback(DECODER_READ);
366  SatisfyPendingCallback(DECODER_RESET);
367  Read();
368}
369
370TEST_P(VideoFrameStreamTest, Reset_AfterNormalRead) {
371  Initialize();
372  Read();
373  Reset();
374  Read();
375}
376
377TEST_P(VideoFrameStreamTest, Reset_AfterDemuxerRead_ConfigChange) {
378  Initialize();
379  EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
380  SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
381  Reset();
382  Read();
383}
384
385TEST_P(VideoFrameStreamTest, Stop_BeforeInitialization) {
386  pending_stop_ = true;
387  video_frame_stream_->Stop(
388      base::Bind(&VideoFrameStreamTest::OnStopped, base::Unretained(this)));
389  message_loop_.RunUntilIdle();
390}
391
392TEST_P(VideoFrameStreamTest, Stop_DuringInitialization) {
393  EnterPendingState(DECODER_INIT);
394  EnterPendingState(DECODER_STOP);
395  SatisfyPendingCallback(DECODER_INIT);
396  SatisfyPendingCallback(DECODER_STOP);
397}
398
399TEST_P(VideoFrameStreamTest, Stop_AfterInitialization) {
400  Initialize();
401  Stop();
402}
403
404TEST_P(VideoFrameStreamTest, Stop_DuringReinitialization) {
405  Initialize();
406  EnterPendingState(DECODER_REINIT);
407  EnterPendingState(DECODER_STOP);
408  SatisfyPendingCallback(DECODER_REINIT);
409  SatisfyPendingCallback(DECODER_STOP);
410}
411
412TEST_P(VideoFrameStreamTest, Stop_AfterReinitialization) {
413  Initialize();
414  EnterPendingState(DECODER_REINIT);
415  SatisfyPendingCallback(DECODER_REINIT);
416  Stop();
417}
418
419TEST_P(VideoFrameStreamTest, Stop_DuringDemuxerRead_Normal) {
420  Initialize();
421  EnterPendingState(DEMUXER_READ_NORMAL);
422  EnterPendingState(DECODER_STOP);
423  SatisfyPendingCallback(DEMUXER_READ_NORMAL);
424  SatisfyPendingCallback(DECODER_STOP);
425}
426
427TEST_P(VideoFrameStreamTest, Stop_DuringDemuxerRead_ConfigChange) {
428  Initialize();
429  EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
430  EnterPendingState(DECODER_STOP);
431  SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
432  SatisfyPendingCallback(DECODER_STOP);
433}
434
435TEST_P(VideoFrameStreamTest, Stop_DuringNormalDecoderRead) {
436  Initialize();
437  EnterPendingState(DECODER_READ);
438  EnterPendingState(DECODER_STOP);
439  SatisfyPendingCallback(DECODER_READ);
440  SatisfyPendingCallback(DECODER_STOP);
441}
442
443TEST_P(VideoFrameStreamTest, Stop_AfterNormalRead) {
444  Initialize();
445  Read();
446  Stop();
447}
448
449TEST_P(VideoFrameStreamTest, Stop_AfterConfigChangeRead) {
450  Initialize();
451  EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
452  SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
453  Stop();
454}
455
456TEST_P(VideoFrameStreamTest, Stop_DuringReset) {
457  Initialize();
458  EnterPendingState(DECODER_RESET);
459  EnterPendingState(DECODER_STOP);
460  SatisfyPendingCallback(DECODER_RESET);
461  SatisfyPendingCallback(DECODER_STOP);
462}
463
464TEST_P(VideoFrameStreamTest, Stop_AfterReset) {
465  Initialize();
466  Reset();
467  Stop();
468}
469
470TEST_P(VideoFrameStreamTest, Stop_DuringRead_DuringReset) {
471  Initialize();
472  EnterPendingState(DECODER_READ);
473  EnterPendingState(DECODER_RESET);
474  EnterPendingState(DECODER_STOP);
475  SatisfyPendingCallback(DECODER_READ);
476  SatisfyPendingCallback(DECODER_RESET);
477  SatisfyPendingCallback(DECODER_STOP);
478}
479
480TEST_P(VideoFrameStreamTest, Stop_AfterRead_DuringReset) {
481  Initialize();
482  EnterPendingState(DECODER_READ);
483  EnterPendingState(DECODER_RESET);
484  SatisfyPendingCallback(DECODER_READ);
485  EnterPendingState(DECODER_STOP);
486  SatisfyPendingCallback(DECODER_RESET);
487  SatisfyPendingCallback(DECODER_STOP);
488}
489
490TEST_P(VideoFrameStreamTest, Stop_AfterRead_AfterReset) {
491  Initialize();
492  Read();
493  Reset();
494  Stop();
495}
496
497}  // namespace media
498