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 <string>
6#include <vector>
7
8#include "base/bind.h"
9#include "base/callback_helpers.h"
10#include "base/message_loop/message_loop.h"
11#include "media/base/decoder_buffer.h"
12#include "media/base/decrypt_config.h"
13#include "media/base/gmock_callback_support.h"
14#include "media/base/mock_filters.h"
15#include "media/base/test_helpers.h"
16#include "media/base/video_frame.h"
17#include "media/filters/decrypting_video_decoder.h"
18#include "testing/gmock/include/gmock/gmock.h"
19
20using ::testing::_;
21using ::testing::Invoke;
22using ::testing::SaveArg;
23using ::testing::StrictMock;
24
25namespace media {
26
27const uint8 kFakeKeyId[] = { 0x4b, 0x65, 0x79, 0x20, 0x49, 0x44 };
28const uint8 kFakeIv[DecryptConfig::kDecryptionKeySize] = { 0 };
29const int kDecodingDelay = 3;
30
31// Create a fake non-empty encrypted buffer.
32static scoped_refptr<DecoderBuffer> CreateFakeEncryptedBuffer() {
33  const int buffer_size = 16;  // Need a non-empty buffer;
34  scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(buffer_size));
35  buffer->set_decrypt_config(scoped_ptr<DecryptConfig>(new DecryptConfig(
36      std::string(reinterpret_cast<const char*>(kFakeKeyId),
37                  arraysize(kFakeKeyId)),
38      std::string(reinterpret_cast<const char*>(kFakeIv), arraysize(kFakeIv)),
39      std::vector<SubsampleEntry>())));
40  return buffer;
41}
42
43// Use anonymous namespace here to prevent the actions to be defined multiple
44// times across multiple test files. Sadly we can't use static for them.
45namespace {
46
47ACTION_P3(ResetAndRunCallback, callback, p1, p2) {
48  base::ResetAndReturn(callback).Run(p1, p2);
49}
50
51}  // namespace
52
53class DecryptingVideoDecoderTest : public testing::Test {
54 public:
55  DecryptingVideoDecoderTest()
56      : decoder_(new DecryptingVideoDecoder(
57            message_loop_.message_loop_proxy(),
58            base::Bind(
59                &DecryptingVideoDecoderTest::RequestDecryptorNotification,
60                base::Unretained(this)))),
61        decryptor_(new StrictMock<MockDecryptor>()),
62        num_decrypt_and_decode_calls_(0),
63        num_frames_in_decryptor_(0),
64        encrypted_buffer_(CreateFakeEncryptedBuffer()),
65        decoded_video_frame_(VideoFrame::CreateBlackFrame(
66            TestVideoConfig::NormalCodedSize())),
67        null_video_frame_(scoped_refptr<VideoFrame>()) {
68  }
69
70  virtual ~DecryptingVideoDecoderTest() {
71    Destroy();
72  }
73
74  void ExpectDecryptorNotification(Decryptor* decryptor, bool expected_result) {
75    EXPECT_CALL(*this, RequestDecryptorNotification(_)).WillOnce(
76        RunCallback<0>(decryptor,
77                       base::Bind(&DecryptingVideoDecoderTest::DecryptorSet,
78                                  base::Unretained(this))));
79    EXPECT_CALL(*this, DecryptorSet(expected_result));
80  }
81
82  // Initializes the |decoder_| and expects |status|. Note the initialization
83  // can succeed or fail.
84  void InitializeAndExpectStatus(const VideoDecoderConfig& config,
85                                 PipelineStatus status) {
86    decoder_->Initialize(config, false, NewExpectedStatusCB(status),
87                         base::Bind(&DecryptingVideoDecoderTest::FrameReady,
88                                    base::Unretained(this)));
89    message_loop_.RunUntilIdle();
90  }
91
92  // Initialize the |decoder_| and expects it to succeed.
93  void Initialize() {
94    ExpectDecryptorNotification(decryptor_.get(), true);
95    EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _))
96        .WillOnce(RunCallback<1>(true));
97    EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kVideo, _))
98        .WillOnce(SaveArg<1>(&key_added_cb_));
99
100    InitializeAndExpectStatus(TestVideoConfig::NormalEncrypted(), PIPELINE_OK);
101  }
102
103  // Reinitialize the |decoder_| and expects it to succeed.
104  void Reinitialize() {
105    EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kVideo));
106    EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _))
107        .WillOnce(RunCallback<1>(true));
108    EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kVideo, _))
109        .WillOnce(SaveArg<1>(&key_added_cb_));
110
111    InitializeAndExpectStatus(TestVideoConfig::LargeEncrypted(), PIPELINE_OK);
112  }
113
114  // Decode |buffer| and expect DecodeDone to get called with |status|.
115  void DecodeAndExpect(const scoped_refptr<DecoderBuffer>& buffer,
116                       VideoDecoder::Status status) {
117    EXPECT_CALL(*this, DecodeDone(status));
118    decoder_->Decode(buffer,
119                     base::Bind(&DecryptingVideoDecoderTest::DecodeDone,
120                                base::Unretained(this)));
121    message_loop_.RunUntilIdle();
122  }
123
124  // Helper function to simulate the decrypting and decoding process in the
125  // |decryptor_| with a decoding delay of kDecodingDelay buffers.
126  void DecryptAndDecodeVideo(const scoped_refptr<DecoderBuffer>& encrypted,
127                             const Decryptor::VideoDecodeCB& video_decode_cb) {
128    num_decrypt_and_decode_calls_++;
129    if (!encrypted->end_of_stream())
130      num_frames_in_decryptor_++;
131
132    if (num_decrypt_and_decode_calls_ <= kDecodingDelay ||
133        num_frames_in_decryptor_ == 0) {
134      video_decode_cb.Run(Decryptor::kNeedMoreData,
135                          scoped_refptr<VideoFrame>());
136      return;
137    }
138
139    num_frames_in_decryptor_--;
140    video_decode_cb.Run(Decryptor::kSuccess, decoded_video_frame_);
141  }
142
143  // Sets up expectations and actions to put DecryptingVideoDecoder in an
144  // active normal decoding state.
145  void EnterNormalDecodingState() {
146    EXPECT_CALL(*decryptor_, DecryptAndDecodeVideo(_, _)).WillRepeatedly(
147        Invoke(this, &DecryptingVideoDecoderTest::DecryptAndDecodeVideo));
148    EXPECT_CALL(*this, FrameReady(decoded_video_frame_));
149    for (int i = 0; i < kDecodingDelay + 1; ++i)
150      DecodeAndExpect(encrypted_buffer_, VideoDecoder::kOk);
151  }
152
153  // Sets up expectations and actions to put DecryptingVideoDecoder in an end
154  // of stream state. This function must be called after
155  // EnterNormalDecodingState() to work.
156  void EnterEndOfStreamState() {
157    // The codec in the |decryptor_| will be flushed.
158    EXPECT_CALL(*this, FrameReady(decoded_video_frame_))
159        .Times(kDecodingDelay);
160    DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(), VideoDecoder::kOk);
161    EXPECT_EQ(0, num_frames_in_decryptor_);
162  }
163
164  // Make the video decode callback pending by saving and not firing it.
165  void EnterPendingDecodeState() {
166    EXPECT_TRUE(pending_video_decode_cb_.is_null());
167    EXPECT_CALL(*decryptor_, DecryptAndDecodeVideo(encrypted_buffer_, _))
168        .WillOnce(SaveArg<1>(&pending_video_decode_cb_));
169
170    decoder_->Decode(encrypted_buffer_,
171                     base::Bind(&DecryptingVideoDecoderTest::DecodeDone,
172                                base::Unretained(this)));
173    message_loop_.RunUntilIdle();
174    // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
175    // the decryptor.
176    EXPECT_FALSE(pending_video_decode_cb_.is_null());
177  }
178
179  void EnterWaitingForKeyState() {
180    EXPECT_CALL(*decryptor_, DecryptAndDecodeVideo(_, _))
181        .WillRepeatedly(RunCallback<1>(Decryptor::kNoKey, null_video_frame_));
182    decoder_->Decode(encrypted_buffer_,
183                     base::Bind(&DecryptingVideoDecoderTest::DecodeDone,
184                                base::Unretained(this)));
185    message_loop_.RunUntilIdle();
186  }
187
188  void AbortPendingVideoDecodeCB() {
189    if (!pending_video_decode_cb_.is_null()) {
190      base::ResetAndReturn(&pending_video_decode_cb_).Run(
191          Decryptor::kSuccess, scoped_refptr<VideoFrame>(NULL));
192    }
193  }
194
195  void AbortAllPendingCBs() {
196    if (!pending_init_cb_.is_null()) {
197      ASSERT_TRUE(pending_video_decode_cb_.is_null());
198      base::ResetAndReturn(&pending_init_cb_).Run(false);
199      return;
200    }
201
202    AbortPendingVideoDecodeCB();
203  }
204
205  void Reset() {
206    EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kVideo))
207        .WillRepeatedly(InvokeWithoutArgs(
208            this, &DecryptingVideoDecoderTest::AbortPendingVideoDecodeCB));
209
210    decoder_->Reset(NewExpectedClosure());
211    message_loop_.RunUntilIdle();
212  }
213
214  void Destroy() {
215    EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kVideo))
216        .WillRepeatedly(InvokeWithoutArgs(
217            this, &DecryptingVideoDecoderTest::AbortAllPendingCBs));
218
219    decoder_.reset();
220    message_loop_.RunUntilIdle();
221  }
222
223  MOCK_METHOD1(RequestDecryptorNotification, void(const DecryptorReadyCB&));
224
225  MOCK_METHOD1(FrameReady, void(const scoped_refptr<VideoFrame>&));
226  MOCK_METHOD1(DecodeDone, void(VideoDecoder::Status));
227
228  MOCK_METHOD1(DecryptorSet, void(bool));
229
230  base::MessageLoop message_loop_;
231  scoped_ptr<DecryptingVideoDecoder> decoder_;
232  scoped_ptr<StrictMock<MockDecryptor> > decryptor_;
233
234  // Variables to help the |decryptor_| to simulate decoding delay and flushing.
235  int num_decrypt_and_decode_calls_;
236  int num_frames_in_decryptor_;
237
238  Decryptor::DecoderInitCB pending_init_cb_;
239  Decryptor::NewKeyCB key_added_cb_;
240  Decryptor::VideoDecodeCB pending_video_decode_cb_;
241
242  // Constant buffer/frames.
243  scoped_refptr<DecoderBuffer> encrypted_buffer_;
244  scoped_refptr<VideoFrame> decoded_video_frame_;
245  scoped_refptr<VideoFrame> null_video_frame_;
246
247 private:
248  DISALLOW_COPY_AND_ASSIGN(DecryptingVideoDecoderTest);
249};
250
251TEST_F(DecryptingVideoDecoderTest, Initialize_Normal) {
252  Initialize();
253}
254
255TEST_F(DecryptingVideoDecoderTest, Initialize_NullDecryptor) {
256  ExpectDecryptorNotification(NULL, false);
257  InitializeAndExpectStatus(TestVideoConfig::NormalEncrypted(),
258                            DECODER_ERROR_NOT_SUPPORTED);
259}
260
261TEST_F(DecryptingVideoDecoderTest, Initialize_Failure) {
262  EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _))
263      .WillRepeatedly(RunCallback<1>(false));
264  EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kVideo, _))
265      .WillRepeatedly(SaveArg<1>(&key_added_cb_));
266
267  InitializeAndExpectStatus(TestVideoConfig::NormalEncrypted(),
268                            DECODER_ERROR_NOT_SUPPORTED);
269}
270
271TEST_F(DecryptingVideoDecoderTest, Reinitialize_Normal) {
272  Initialize();
273  EnterNormalDecodingState();
274  Reinitialize();
275}
276
277TEST_F(DecryptingVideoDecoderTest, Reinitialize_Failure) {
278  Initialize();
279  EnterNormalDecodingState();
280
281  EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kVideo));
282  EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _))
283      .WillOnce(RunCallback<1>(false));
284
285  // Reinitialize() expects the reinitialization to succeed. Call
286  // InitializeAndExpectStatus() directly to test the reinitialization failure.
287  InitializeAndExpectStatus(TestVideoConfig::NormalEncrypted(),
288                            DECODER_ERROR_NOT_SUPPORTED);
289}
290
291// Test normal decrypt and decode case.
292TEST_F(DecryptingVideoDecoderTest, DecryptAndDecode_Normal) {
293  Initialize();
294  EnterNormalDecodingState();
295}
296
297// Test the case where the decryptor returns error when doing decrypt and
298// decode.
299TEST_F(DecryptingVideoDecoderTest, DecryptAndDecode_DecodeError) {
300  Initialize();
301
302  EXPECT_CALL(*decryptor_, DecryptAndDecodeVideo(_, _))
303      .WillRepeatedly(RunCallback<1>(Decryptor::kError,
304                                     scoped_refptr<VideoFrame>(NULL)));
305
306  DecodeAndExpect(encrypted_buffer_, VideoDecoder::kDecodeError);
307
308  // After a decode error occurred, all following decode returns kDecodeError.
309  DecodeAndExpect(encrypted_buffer_, VideoDecoder::kDecodeError);
310}
311
312// Test the case where the decryptor receives end-of-stream buffer.
313TEST_F(DecryptingVideoDecoderTest, DecryptAndDecode_EndOfStream) {
314  Initialize();
315  EnterNormalDecodingState();
316  EnterEndOfStreamState();
317}
318
319// Test the case where the a key is added when the decryptor is in
320// kWaitingForKey state.
321TEST_F(DecryptingVideoDecoderTest, KeyAdded_DuringWaitingForKey) {
322  Initialize();
323  EnterWaitingForKeyState();
324
325  EXPECT_CALL(*decryptor_, DecryptAndDecodeVideo(_, _))
326      .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess,
327                                     decoded_video_frame_));
328  EXPECT_CALL(*this, FrameReady(decoded_video_frame_));
329  EXPECT_CALL(*this, DecodeDone(VideoDecoder::kOk));
330  key_added_cb_.Run();
331  message_loop_.RunUntilIdle();
332}
333
334// Test the case where the a key is added when the decryptor is in
335// kPendingDecode state.
336TEST_F(DecryptingVideoDecoderTest, KeyAdded_DruingPendingDecode) {
337  Initialize();
338  EnterPendingDecodeState();
339
340  EXPECT_CALL(*decryptor_, DecryptAndDecodeVideo(_, _))
341      .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess,
342                                     decoded_video_frame_));
343  EXPECT_CALL(*this, FrameReady(decoded_video_frame_));
344  EXPECT_CALL(*this, DecodeDone(VideoDecoder::kOk));
345  // The video decode callback is returned after the correct decryption key is
346  // added.
347  key_added_cb_.Run();
348  base::ResetAndReturn(&pending_video_decode_cb_).Run(Decryptor::kNoKey,
349                                                      null_video_frame_);
350  message_loop_.RunUntilIdle();
351}
352
353// Test resetting when the decoder is in kIdle state but has not decoded any
354// frame.
355TEST_F(DecryptingVideoDecoderTest, Reset_DuringIdleAfterInitialization) {
356  Initialize();
357  Reset();
358}
359
360// Test resetting when the decoder is in kIdle state after it has decoded one
361// frame.
362TEST_F(DecryptingVideoDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
363  Initialize();
364  EnterNormalDecodingState();
365  Reset();
366}
367
368// Test resetting when the decoder is in kPendingDecode state.
369TEST_F(DecryptingVideoDecoderTest, Reset_DuringPendingDecode) {
370  Initialize();
371  EnterPendingDecodeState();
372
373  EXPECT_CALL(*this, DecodeDone(VideoDecoder::kAborted));
374
375  Reset();
376}
377
378// Test resetting when the decoder is in kWaitingForKey state.
379TEST_F(DecryptingVideoDecoderTest, Reset_DuringWaitingForKey) {
380  Initialize();
381  EnterWaitingForKeyState();
382
383  EXPECT_CALL(*this, DecodeDone(VideoDecoder::kAborted));
384
385  Reset();
386}
387
388// Test resetting when the decoder has hit end of stream and is in
389// kDecodeFinished state.
390TEST_F(DecryptingVideoDecoderTest, Reset_AfterDecodeFinished) {
391  Initialize();
392  EnterNormalDecodingState();
393  EnterEndOfStreamState();
394  Reset();
395}
396
397// Test resetting after the decoder has been reset.
398TEST_F(DecryptingVideoDecoderTest, Reset_AfterReset) {
399  Initialize();
400  EnterNormalDecodingState();
401  Reset();
402  Reset();
403}
404
405// Test destruction when the decoder is in kDecryptorRequested state.
406TEST_F(DecryptingVideoDecoderTest, Destroy_DuringDecryptorRequested) {
407  DecryptorReadyCB decryptor_ready_cb;
408  EXPECT_CALL(*this, RequestDecryptorNotification(_))
409      .WillOnce(SaveArg<0>(&decryptor_ready_cb));
410  decoder_->Initialize(TestVideoConfig::NormalEncrypted(),
411                       false,
412                       NewExpectedStatusCB(DECODER_ERROR_NOT_SUPPORTED),
413                       base::Bind(&DecryptingVideoDecoderTest::FrameReady,
414                                  base::Unretained(this)));
415  message_loop_.RunUntilIdle();
416  // |decryptor_ready_cb| is saved but not called here.
417  EXPECT_FALSE(decryptor_ready_cb.is_null());
418
419  // During destruction, RequestDecryptorNotification() should be called with a
420  // NULL callback to cancel the |decryptor_ready_cb|.
421  EXPECT_CALL(*this, RequestDecryptorNotification(IsNullCallback())).WillOnce(
422      ResetAndRunCallback(&decryptor_ready_cb,
423                          reinterpret_cast<Decryptor*>(NULL),
424                          base::Bind(&DecryptingVideoDecoderTest::DecryptorSet,
425                                     base::Unretained(this))));
426  EXPECT_CALL(*this, DecryptorSet(_)).Times(0);
427  Destroy();
428}
429
430// Test destruction when the decoder is in kPendingDecoderInit state.
431TEST_F(DecryptingVideoDecoderTest, Destroy_DuringPendingDecoderInit) {
432  ExpectDecryptorNotification(decryptor_.get(), true);
433  EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _))
434      .WillOnce(SaveArg<1>(&pending_init_cb_));
435
436  InitializeAndExpectStatus(TestVideoConfig::NormalEncrypted(),
437                            DECODER_ERROR_NOT_SUPPORTED);
438  EXPECT_FALSE(pending_init_cb_.is_null());
439
440  Destroy();
441}
442
443// Test destruction when the decoder is in kIdle state but has not decoded any
444// frame.
445TEST_F(DecryptingVideoDecoderTest, Destroy_DuringIdleAfterInitialization) {
446  Initialize();
447  Destroy();
448}
449
450// Test destruction when the decoder is in kIdle state after it has decoded one
451// frame.
452TEST_F(DecryptingVideoDecoderTest, Destroy_DuringIdleAfterDecodedOneFrame) {
453  Initialize();
454  EnterNormalDecodingState();
455  Destroy();
456}
457
458// Test destruction when the decoder is in kPendingDecode state.
459TEST_F(DecryptingVideoDecoderTest, Destroy_DuringPendingDecode) {
460  Initialize();
461  EnterPendingDecodeState();
462
463  EXPECT_CALL(*this, DecodeDone(VideoDecoder::kAborted));
464
465  Destroy();
466}
467
468// Test destruction when the decoder is in kWaitingForKey state.
469TEST_F(DecryptingVideoDecoderTest, Destroy_DuringWaitingForKey) {
470  Initialize();
471  EnterWaitingForKeyState();
472
473  EXPECT_CALL(*this, DecodeDone(VideoDecoder::kAborted));
474
475  Destroy();
476}
477
478// Test destruction when the decoder has hit end of stream and is in
479// kDecodeFinished state.
480TEST_F(DecryptingVideoDecoderTest, Destroy_AfterDecodeFinished) {
481  Initialize();
482  EnterNormalDecodingState();
483  EnterEndOfStreamState();
484  Destroy();
485}
486
487// Test destruction when there is a pending reset on the decoder.
488// Reset is pending because it cannot complete when the video decode callback
489// is pending.
490TEST_F(DecryptingVideoDecoderTest, Destroy_DuringPendingReset) {
491  Initialize();
492  EnterPendingDecodeState();
493
494  EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kVideo));
495  EXPECT_CALL(*this, DecodeDone(VideoDecoder::kAborted));
496
497  decoder_->Reset(NewExpectedClosure());
498  Destroy();
499}
500
501// Test destruction after the decoder has been reset.
502TEST_F(DecryptingVideoDecoderTest, Destroy_AfterReset) {
503  Initialize();
504  EnterNormalDecodingState();
505  Reset();
506  Destroy();
507}
508
509}  // namespace media
510