video_frame_stream_unittest.cc revision ca12bfac764ba476d6cd062bf1dde12cc64c3f40
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(VideoDecoder::Status status,
99                  const scoped_refptr<VideoFrame>& frame) {
100    DCHECK(pending_read_);
101    ASSERT_EQ(VideoDecoder::kOk, status);
102    frame_read_ = frame;
103    if (frame.get() && !frame->IsEndOfStream())
104      num_decoded_frames_++;
105    pending_read_ = false;
106  }
107
108  void OnReset() {
109    DCHECK(!pending_read_);
110    DCHECK(pending_reset_);
111    pending_reset_ = false;
112  }
113
114  void OnStopped() {
115    DCHECK(!pending_read_);
116    DCHECK(!pending_reset_);
117    DCHECK(pending_stop_);
118    pending_stop_ = false;
119    is_initialized_ = false;
120  }
121
122  void ReadUntilPending() {
123    do {
124      frame_read_ = NULL;
125      pending_read_ = true;
126      video_frame_stream_->Read(base::Bind(
127          &VideoFrameStreamTest::FrameReady, base::Unretained(this)));
128      message_loop_.RunUntilIdle();
129    } while (!pending_read_);
130  }
131
132  enum PendingState {
133    NOT_PENDING,
134    DEMUXER_READ_NORMAL,
135    DEMUXER_READ_CONFIG_CHANGE,
136    DECODER_INIT,
137    DECODER_REINIT,
138    DECODER_READ,
139    DECODER_RESET,
140    DECODER_STOP
141  };
142
143  void EnterPendingState(PendingState state) {
144    DCHECK_NE(state, NOT_PENDING);
145    switch (state) {
146      case DEMUXER_READ_NORMAL:
147        demuxer_stream_->HoldNextRead();
148        ReadUntilPending();
149        break;
150
151      case DEMUXER_READ_CONFIG_CHANGE:
152        demuxer_stream_->HoldNextConfigChangeRead();
153        ReadUntilPending();
154        break;
155
156      case DECODER_INIT:
157        decoder_->HoldNextInit();
158        video_frame_stream_->Initialize(
159            demuxer_stream_.get(),
160            base::Bind(&VideoFrameStreamTest::OnStatistics,
161                       base::Unretained(this)),
162            base::Bind(&VideoFrameStreamTest::OnInitialized,
163                       base::Unretained(this)));
164        message_loop_.RunUntilIdle();
165        break;
166
167      case DECODER_REINIT:
168        decoder_->HoldNextInit();
169        ReadUntilPending();
170        break;
171
172      case DECODER_READ:
173        decoder_->HoldNextRead();
174        ReadUntilPending();
175        break;
176
177      case DECODER_RESET:
178        decoder_->HoldNextReset();
179        pending_reset_ = true;
180        video_frame_stream_->Reset(base::Bind(&VideoFrameStreamTest::OnReset,
181                                              base::Unretained(this)));
182        message_loop_.RunUntilIdle();
183        break;
184
185      case DECODER_STOP:
186        decoder_->HoldNextStop();
187        pending_stop_ = true;
188        video_frame_stream_->Stop(base::Bind(&VideoFrameStreamTest::OnStopped,
189                                             base::Unretained(this)));
190        message_loop_.RunUntilIdle();
191        break;
192
193      case NOT_PENDING:
194        NOTREACHED();
195        break;
196    }
197  }
198
199  void SatisfyPendingCallback(PendingState state) {
200    DCHECK_NE(state, NOT_PENDING);
201    switch (state) {
202      case DEMUXER_READ_NORMAL:
203      case DEMUXER_READ_CONFIG_CHANGE:
204        demuxer_stream_->SatisfyRead();
205        break;
206
207      case DECODER_INIT:
208        EXPECT_CALL(*this, OnInitialized(true, false))
209            .WillOnce(SaveArg<0>(&is_initialized_));
210        decoder_->SatisfyInit();
211        break;
212
213      case DECODER_REINIT:
214        decoder_->SatisfyInit();
215        break;
216
217      case DECODER_READ:
218        DCHECK(pending_read_);
219        decoder_->SatisfyRead();
220        break;
221
222      case DECODER_RESET:
223        DCHECK(pending_reset_);
224        decoder_->SatisfyReset();
225        break;
226
227      case DECODER_STOP:
228        DCHECK(pending_stop_);
229        decoder_->SatisfyStop();
230        break;
231
232      case NOT_PENDING:
233        NOTREACHED();
234        break;
235    }
236
237    message_loop_.RunUntilIdle();
238    if (!is_initialized_)
239      decoder_ = NULL;
240  }
241
242  void Initialize() {
243    EnterPendingState(DECODER_INIT);
244    SatisfyPendingCallback(DECODER_INIT);
245  }
246
247  void Read() {
248    EnterPendingState(DECODER_READ);
249    SatisfyPendingCallback(DECODER_READ);
250  }
251
252  void Reset() {
253    EnterPendingState(DECODER_RESET);
254    SatisfyPendingCallback(DECODER_RESET);
255  }
256
257  void Stop() {
258    EnterPendingState(DECODER_STOP);
259    SatisfyPendingCallback(DECODER_STOP);
260  }
261
262  base::MessageLoop message_loop_;
263
264  scoped_ptr<VideoFrameStream> video_frame_stream_;
265  scoped_ptr<FakeDemuxerStream> demuxer_stream_;
266  // Use NiceMock since we don't care about most of calls on the decryptor,
267  // e.g. RegisterNewKeyCB().
268  scoped_ptr<NiceMock<MockDecryptor> > decryptor_;
269  FakeVideoDecoder* decoder_;  // Owned by |video_frame_stream_|.
270
271  bool is_initialized_;
272  int num_decoded_frames_;
273  bool pending_read_;
274  bool pending_reset_;
275  bool pending_stop_;
276  int total_bytes_decoded_;
277  scoped_refptr<VideoFrame> frame_read_;
278
279 private:
280  DISALLOW_COPY_AND_ASSIGN(VideoFrameStreamTest);
281};
282
283INSTANTIATE_TEST_CASE_P(Clear, VideoFrameStreamTest, testing::Values(false));
284INSTANTIATE_TEST_CASE_P(Encrypted, VideoFrameStreamTest, testing::Values(true));
285
286TEST_P(VideoFrameStreamTest, Initialization) {
287  Initialize();
288}
289
290TEST_P(VideoFrameStreamTest, ReadOneFrame) {
291  Initialize();
292  Read();
293}
294
295TEST_P(VideoFrameStreamTest, ReadAllFrames) {
296  Initialize();
297  do {
298    Read();
299  } while (frame_read_.get() && !frame_read_->IsEndOfStream());
300
301  const int total_num_frames = kNumConfigs * kNumBuffersInOneConfig;
302  DCHECK_EQ(num_decoded_frames_, total_num_frames);
303}
304
305TEST_P(VideoFrameStreamTest, Read_AfterReset) {
306  Initialize();
307  Reset();
308  Read();
309  Reset();
310  Read();
311}
312
313// No Reset() before initialization is successfully completed.
314
315TEST_P(VideoFrameStreamTest, Reset_AfterInitialization) {
316  Initialize();
317  Reset();
318  Read();
319}
320
321TEST_P(VideoFrameStreamTest, Reset_DuringReinitialization) {
322  Initialize();
323  EnterPendingState(DECODER_REINIT);
324  // VideoDecoder::Reset() is not called when we reset during reinitialization.
325  pending_reset_ = true;
326  video_frame_stream_->Reset(
327      base::Bind(&VideoFrameStreamTest::OnReset, base::Unretained(this)));
328  SatisfyPendingCallback(DECODER_REINIT);
329  Read();
330}
331
332TEST_P(VideoFrameStreamTest, Reset_AfterReinitialization) {
333  Initialize();
334  EnterPendingState(DECODER_REINIT);
335  SatisfyPendingCallback(DECODER_REINIT);
336  Reset();
337  Read();
338}
339
340TEST_P(VideoFrameStreamTest, Reset_DuringDemuxerRead_Normal) {
341  Initialize();
342  EnterPendingState(DEMUXER_READ_NORMAL);
343  EnterPendingState(DECODER_RESET);
344  SatisfyPendingCallback(DEMUXER_READ_NORMAL);
345  SatisfyPendingCallback(DECODER_RESET);
346  Read();
347}
348
349TEST_P(VideoFrameStreamTest, Reset_DuringDemuxerRead_ConfigChange) {
350  Initialize();
351  EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
352  EnterPendingState(DECODER_RESET);
353  SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
354  SatisfyPendingCallback(DECODER_RESET);
355  Read();
356}
357
358TEST_P(VideoFrameStreamTest, Reset_DuringNormalDecoderRead) {
359  Initialize();
360  EnterPendingState(DECODER_READ);
361  EnterPendingState(DECODER_RESET);
362  SatisfyPendingCallback(DECODER_READ);
363  SatisfyPendingCallback(DECODER_RESET);
364  Read();
365}
366
367TEST_P(VideoFrameStreamTest, Reset_AfterNormalRead) {
368  Initialize();
369  Read();
370  Reset();
371  Read();
372}
373
374TEST_P(VideoFrameStreamTest, Reset_AfterDemuxerRead_ConfigChange) {
375  Initialize();
376  EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
377  SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
378  Reset();
379  Read();
380}
381
382TEST_P(VideoFrameStreamTest, Stop_BeforeInitialization) {
383  pending_stop_ = true;
384  video_frame_stream_->Stop(
385      base::Bind(&VideoFrameStreamTest::OnStopped, base::Unretained(this)));
386  message_loop_.RunUntilIdle();
387}
388
389TEST_P(VideoFrameStreamTest, Stop_DuringInitialization) {
390  EnterPendingState(DECODER_INIT);
391  EnterPendingState(DECODER_STOP);
392  SatisfyPendingCallback(DECODER_INIT);
393  SatisfyPendingCallback(DECODER_STOP);
394}
395
396TEST_P(VideoFrameStreamTest, Stop_AfterInitialization) {
397  Initialize();
398  Stop();
399}
400
401TEST_P(VideoFrameStreamTest, Stop_DuringReinitialization) {
402  Initialize();
403  EnterPendingState(DECODER_REINIT);
404  EnterPendingState(DECODER_STOP);
405  SatisfyPendingCallback(DECODER_REINIT);
406  SatisfyPendingCallback(DECODER_STOP);
407}
408
409TEST_P(VideoFrameStreamTest, Stop_AfterReinitialization) {
410  Initialize();
411  EnterPendingState(DECODER_REINIT);
412  SatisfyPendingCallback(DECODER_REINIT);
413  Stop();
414}
415
416TEST_P(VideoFrameStreamTest, Stop_DuringDemuxerRead_Normal) {
417  Initialize();
418  EnterPendingState(DEMUXER_READ_NORMAL);
419  EnterPendingState(DECODER_STOP);
420  SatisfyPendingCallback(DEMUXER_READ_NORMAL);
421  SatisfyPendingCallback(DECODER_STOP);
422}
423
424TEST_P(VideoFrameStreamTest, Stop_DuringDemuxerRead_ConfigChange) {
425  Initialize();
426  EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
427  EnterPendingState(DECODER_STOP);
428  SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
429  SatisfyPendingCallback(DECODER_STOP);
430}
431
432TEST_P(VideoFrameStreamTest, Stop_DuringNormalDecoderRead) {
433  Initialize();
434  EnterPendingState(DECODER_READ);
435  EnterPendingState(DECODER_STOP);
436  SatisfyPendingCallback(DECODER_READ);
437  SatisfyPendingCallback(DECODER_STOP);
438}
439
440TEST_P(VideoFrameStreamTest, Stop_AfterNormalRead) {
441  Initialize();
442  Read();
443  Stop();
444}
445
446TEST_P(VideoFrameStreamTest, Stop_AfterConfigChangeRead) {
447  Initialize();
448  EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
449  SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
450  Stop();
451}
452
453TEST_P(VideoFrameStreamTest, Stop_DuringReset) {
454  Initialize();
455  EnterPendingState(DECODER_RESET);
456  EnterPendingState(DECODER_STOP);
457  SatisfyPendingCallback(DECODER_RESET);
458  SatisfyPendingCallback(DECODER_STOP);
459}
460
461TEST_P(VideoFrameStreamTest, Stop_AfterReset) {
462  Initialize();
463  Reset();
464  Stop();
465}
466
467TEST_P(VideoFrameStreamTest, Stop_DuringRead_DuringReset) {
468  Initialize();
469  EnterPendingState(DECODER_READ);
470  EnterPendingState(DECODER_RESET);
471  EnterPendingState(DECODER_STOP);
472  SatisfyPendingCallback(DECODER_READ);
473  SatisfyPendingCallback(DECODER_RESET);
474  SatisfyPendingCallback(DECODER_STOP);
475}
476
477TEST_P(VideoFrameStreamTest, Stop_AfterRead_DuringReset) {
478  Initialize();
479  EnterPendingState(DECODER_READ);
480  EnterPendingState(DECODER_RESET);
481  SatisfyPendingCallback(DECODER_READ);
482  EnterPendingState(DECODER_STOP);
483  SatisfyPendingCallback(DECODER_RESET);
484  SatisfyPendingCallback(DECODER_STOP);
485}
486
487TEST_P(VideoFrameStreamTest, Stop_AfterRead_AfterReset) {
488  Initialize();
489  Read();
490  Reset();
491  Stop();
492}
493
494}  // namespace media
495