decrypting_audio_decoder_unittest.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
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 // Initialize data now that the config is known. Since the code uses 98 // invalid values (that CreateEmptyBuffer() doesn't support), tweak them 99 // just for CreateEmptyBuffer(). 100 int channels = ChannelLayoutToChannelCount(config.channel_layout()); 101 if (channels < 0) 102 channels = 0; 103 decoded_frame_ = AudioBuffer::CreateEmptyBuffer(config.channel_layout(), 104 channels, 105 kSampleRate, 106 kFakeAudioFrameSize, 107 kNoTimestamp(), 108 kNoTimestamp()); 109 decoded_frame_list_.push_back(decoded_frame_); 110 111 decoder_->Initialize(config, NewExpectedStatusCB(status)); 112 message_loop_.RunUntilIdle(); 113 } 114 115 void Initialize() { 116 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _)) 117 .Times(AtMost(1)) 118 .WillOnce(RunCallback<1>(true)); 119 EXPECT_CALL(*this, RequestDecryptorNotification(_)) 120 .WillOnce(RunCallbackIfNotNull(decryptor_.get())); 121 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _)) 122 .WillOnce(SaveArg<1>(&key_added_cb_)); 123 124 config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32, 125 CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, true, true, 126 base::TimeDelta(), base::TimeDelta()); 127 InitializeAndExpectStatus(config_, PIPELINE_OK); 128 } 129 130 void Reinitialize() { 131 ReinitializeConfigChange(config_); 132 } 133 134 void ReinitializeConfigChange(AudioDecoderConfig& new_config) { 135 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio)); 136 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _)) 137 .WillOnce(RunCallback<1>(true)); 138 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _)) 139 .WillOnce(SaveArg<1>(&key_added_cb_)); 140 decoder_->Initialize(new_config, NewExpectedStatusCB(PIPELINE_OK)); 141 } 142 143 void ReadAndExpectFrameReadyWith( 144 scoped_refptr<DecoderBuffer> input, 145 AudioDecoder::Status status, 146 const scoped_refptr<AudioBuffer>& audio_frame) { 147 148 const scoped_refptr<AudioBuffer>& buffer = decoder_->GetDecodeOutput(); 149 150 if (buffer) { 151 EXPECT_EQ(audio_frame, buffer); 152 EXPECT_EQ(status, AudioDecoder::kOk); 153 return; 154 } 155 156 if (status == AudioDecoder::kNotEnoughData) 157 // Keep calling again to give it more data if we get kNotEnoughData. 158 EXPECT_CALL(*this, FrameReady(status, scoped_refptr<AudioBuffer>(NULL))). 159 WillRepeatedly(CallExpectFrameReadyMoreData(this, audio_frame)); 160 else if (status != AudioDecoder::kOk) 161 EXPECT_CALL(*this, FrameReady(status, IsNull())); 162 else if (audio_frame->end_of_stream()) 163 EXPECT_CALL(*this, FrameReady(status, IsEndOfStream())); 164 else 165 EXPECT_CALL(*this, FrameReady(status, audio_frame)); 166 167 decoder_->Decode(input, 168 base::Bind(&DecryptingAudioDecoderTest::FrameReady, 169 base::Unretained(this))); 170 message_loop_.RunUntilIdle(); 171 } 172 173 // Sets up expectations and actions to put DecryptingAudioDecoder in an 174 // active normal decoding state. 175 void EnterNormalDecodingState() { 176 Decryptor::AudioBuffers end_of_stream_frames_(1, end_of_stream_frame_); 177 178 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _)) 179 .WillOnce(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_)) 180 .WillRepeatedly(RunCallback<1>(Decryptor::kNeedMoreData, 181 Decryptor::AudioBuffers())); 182 183 ReadAndExpectFrameReadyWith( 184 encrypted_buffer_, AudioDecoder::kOk, decoded_frame_); 185 } 186 187 // Sets up expectations and actions to put DecryptingAudioDecoder in an end 188 // of stream state. This function must be called after 189 // EnterNormalDecodingState() to work. 190 void EnterEndOfStreamState() { 191 ReadAndExpectFrameReadyWith(DecoderBuffer::CreateEOSBuffer(), 192 AudioDecoder::kOk, 193 end_of_stream_frame_); 194 } 195 196 // Make the audio decode callback pending by saving and not firing it. 197 void EnterPendingDecodeState() { 198 EXPECT_TRUE(pending_audio_decode_cb_.is_null()); 199 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _)) 200 .WillOnce(SaveArg<1>(&pending_audio_decode_cb_)); 201 202 decoder_->Decode(encrypted_buffer_, 203 base::Bind(&DecryptingAudioDecoderTest::FrameReady, 204 base::Unretained(this))); 205 message_loop_.RunUntilIdle(); 206 // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on 207 // the decryptor. 208 EXPECT_FALSE(pending_audio_decode_cb_.is_null()); 209 } 210 211 void EnterWaitingForKeyState() { 212 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _)) 213 .WillRepeatedly(RunCallback<1>(Decryptor::kNoKey, 214 Decryptor::AudioBuffers())); 215 decoder_->Decode(encrypted_buffer_, 216 base::Bind(&DecryptingAudioDecoderTest::FrameReady, 217 base::Unretained(this))); 218 message_loop_.RunUntilIdle(); 219 } 220 221 void AbortPendingAudioDecodeCB() { 222 if (!pending_audio_decode_cb_.is_null()) { 223 base::ResetAndReturn(&pending_audio_decode_cb_).Run( 224 Decryptor::kSuccess, Decryptor::AudioBuffers()); 225 } 226 } 227 228 void AbortAllPendingCBs() { 229 if (!pending_init_cb_.is_null()) { 230 ASSERT_TRUE(pending_audio_decode_cb_.is_null()); 231 base::ResetAndReturn(&pending_init_cb_).Run(false); 232 return; 233 } 234 235 AbortPendingAudioDecodeCB(); 236 } 237 238 void Reset() { 239 EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio)) 240 .WillRepeatedly(InvokeWithoutArgs( 241 this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB)); 242 243 decoder_->Reset(NewExpectedClosure()); 244 message_loop_.RunUntilIdle(); 245 } 246 247 void Stop() { 248 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio)) 249 .WillRepeatedly(InvokeWithoutArgs( 250 this, &DecryptingAudioDecoderTest::AbortAllPendingCBs)); 251 252 decoder_->Stop(NewExpectedClosure()); 253 message_loop_.RunUntilIdle(); 254 } 255 256 MOCK_METHOD1(RequestDecryptorNotification, void(const DecryptorReadyCB&)); 257 258 MOCK_METHOD2(FrameReady, 259 void(AudioDecoder::Status, const scoped_refptr<AudioBuffer>&)); 260 261 base::MessageLoop message_loop_; 262 scoped_ptr<DecryptingAudioDecoder> decoder_; 263 scoped_ptr<StrictMock<MockDecryptor> > decryptor_; 264 AudioDecoderConfig config_; 265 266 Decryptor::DecoderInitCB pending_init_cb_; 267 Decryptor::NewKeyCB key_added_cb_; 268 Decryptor::AudioDecodeCB pending_audio_decode_cb_; 269 270 // Constant buffer/frames, to be used/returned by |decoder_| and |decryptor_|. 271 scoped_refptr<DecoderBuffer> encrypted_buffer_; 272 scoped_refptr<AudioBuffer> decoded_frame_; 273 scoped_refptr<AudioBuffer> end_of_stream_frame_; 274 Decryptor::AudioBuffers decoded_frame_list_; 275 276 private: 277 DISALLOW_COPY_AND_ASSIGN(DecryptingAudioDecoderTest); 278}; 279 280TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) { 281 Initialize(); 282} 283 284// Ensure that DecryptingAudioDecoder only accepts encrypted audio. 285TEST_F(DecryptingAudioDecoderTest, Initialize_UnencryptedAudioConfig) { 286 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32, 287 CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, false); 288 289 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED); 290} 291 292// Ensure decoder handles invalid audio configs without crashing. 293TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) { 294 AudioDecoderConfig config(kUnknownAudioCodec, kUnknownSampleFormat, 295 CHANNEL_LAYOUT_STEREO, 0, NULL, 0, true); 296 297 InitializeAndExpectStatus(config, PIPELINE_ERROR_DECODE); 298} 299 300// Ensure decoder handles unsupported audio configs without crashing. 301TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) { 302 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _)) 303 .WillOnce(RunCallback<1>(false)); 304 EXPECT_CALL(*this, RequestDecryptorNotification(_)) 305 .WillOnce(RunCallbackIfNotNull(decryptor_.get())); 306 307 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32, 308 CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, true); 309 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED); 310} 311 312TEST_F(DecryptingAudioDecoderTest, Initialize_NullDecryptor) { 313 EXPECT_CALL(*this, RequestDecryptorNotification(_)) 314 .WillRepeatedly(RunCallbackIfNotNull(static_cast<Decryptor*>(NULL))); 315 316 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32, 317 CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, true); 318 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED); 319} 320 321// Test normal decrypt and decode case. 322TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) { 323 Initialize(); 324 EnterNormalDecodingState(); 325} 326 327// Test the case where the decryptor returns error when doing decrypt and 328// decode. 329TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) { 330 Initialize(); 331 332 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _)) 333 .WillRepeatedly(RunCallback<1>(Decryptor::kError, 334 Decryptor::AudioBuffers())); 335 336 ReadAndExpectFrameReadyWith( 337 encrypted_buffer_, AudioDecoder::kDecodeError, NULL); 338} 339 340// Test the case where the decryptor returns kNeedMoreData to ask for more 341// buffers before it can produce a frame. 342TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_NeedMoreData) { 343 Initialize(); 344 345 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _)) 346 .WillOnce(RunCallback<1>(Decryptor::kNeedMoreData, 347 Decryptor::AudioBuffers())) 348 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_)); 349 350 // We expect it to eventually return kOk, with any number of returns of 351 // kNotEnoughData beforehand. 352 EXPECT_CALL(*this, FrameReady(AudioDecoder::kOk, decoded_frame_)); 353 ReadAndExpectFrameReadyWith( 354 encrypted_buffer_, AudioDecoder::kNotEnoughData, decoded_frame_); 355} 356 357// Test the case where the decryptor returns multiple decoded frames. 358TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) { 359 Initialize(); 360 361 scoped_refptr<AudioBuffer> frame_a = AudioBuffer::CreateEmptyBuffer( 362 config_.channel_layout(), 363 ChannelLayoutToChannelCount(config_.channel_layout()), 364 kSampleRate, 365 kFakeAudioFrameSize, 366 kNoTimestamp(), 367 kNoTimestamp()); 368 scoped_refptr<AudioBuffer> frame_b = AudioBuffer::CreateEmptyBuffer( 369 config_.channel_layout(), 370 ChannelLayoutToChannelCount(config_.channel_layout()), 371 kSampleRate, 372 kFakeAudioFrameSize, 373 kNoTimestamp(), 374 kNoTimestamp()); 375 decoded_frame_list_.push_back(frame_a); 376 decoded_frame_list_.push_back(frame_b); 377 378 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _)) 379 .WillOnce(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_)); 380 381 ReadAndExpectFrameReadyWith( 382 encrypted_buffer_, AudioDecoder::kOk, decoded_frame_); 383 ReadAndExpectFrameReadyWith(encrypted_buffer_, AudioDecoder::kOk, frame_a); 384 ReadAndExpectFrameReadyWith(encrypted_buffer_, AudioDecoder::kOk, frame_b); 385} 386 387// Test the case where the decryptor receives end-of-stream buffer. 388TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) { 389 Initialize(); 390 EnterNormalDecodingState(); 391 EnterEndOfStreamState(); 392} 393 394// Test reinitializing decode with a new config 395TEST_F(DecryptingAudioDecoderTest, Reinitialize_ConfigChange) { 396 Initialize(); 397 398 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _)) 399 .Times(AtMost(1)) 400 .WillOnce(RunCallback<1>(true)); 401 402 // The new config is different from the initial config in bits-per-channel, 403 // channel layout and samples_per_second. 404 AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16, 405 CHANNEL_LAYOUT_5_1, 88200, NULL, 0, true); 406 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel()); 407 EXPECT_NE(new_config.channel_layout(), config_.channel_layout()); 408 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second()); 409 410 ReinitializeConfigChange(new_config); 411 message_loop_.RunUntilIdle(); 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