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