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