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