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.
10 #include "base/bind.h"
11 #include "base/callback_helpers.h"
12 #include "base/macros.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/run_loop.h"
15 #include "media/base/audio_buffer.h"
16 #include "media/base/decoder_buffer.h"
17 #include "media/base/decrypt_config.h"
18 #include "media/base/gmock_callback_support.h"
19 #include "media/base/media_util.h"
20 #include "media/base/mock_filters.h"
21 #include "media/base/test_helpers.h"
22 #include "media/base/timestamp_constants.h"
23 #include "media/filters/decrypting_audio_decoder.h"
24 #include "testing/gmock/include/gmock/gmock.h"
27 using ::testing::AtMost;
28 using ::testing::Return;
29 using ::testing::SaveArg;
30 using ::testing::StrictMock;
34 const int kSampleRate = 44100;
36 // Make sure the kFakeAudioFrameSize is a valid frame size for all audio decoder
37 // configs used in this test.
38 const int kFakeAudioFrameSize = 48;
39 const uint8_t kFakeKeyId[] = {0x4b, 0x65, 0x79, 0x20, 0x49, 0x44};
40 const uint8_t kFakeIv[DecryptConfig::kDecryptionKeySize] = {0};
41 const int kDecodingDelay = 3;
43 // Create a fake non-empty encrypted buffer.
44 static scoped_refptr<DecoderBuffer> CreateFakeEncryptedBuffer() {
45 const int buffer_size = 16; // Need a non-empty buffer;
46 scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(buffer_size));
47 buffer->set_decrypt_config(std::unique_ptr<DecryptConfig>(new DecryptConfig(
48 std::string(reinterpret_cast<const char*>(kFakeKeyId),
49 arraysize(kFakeKeyId)),
50 std::string(reinterpret_cast<const char*>(kFakeIv), arraysize(kFakeIv)),
51 std::vector<SubsampleEntry>())));
55 class DecryptingAudioDecoderTest : public testing::Test {
57 DecryptingAudioDecoderTest()
58 : decoder_(new DecryptingAudioDecoder(message_loop_.task_runner(),
60 cdm_context_(new StrictMock<MockCdmContext>()),
61 decryptor_(new StrictMock<MockDecryptor>()),
62 num_decrypt_and_decode_calls_(0),
63 num_frames_in_decryptor_(0),
64 encrypted_buffer_(CreateFakeEncryptedBuffer()),
66 decoded_frame_list_() {}
68 virtual ~DecryptingAudioDecoderTest() {
72 void InitializeAndExpectResult(const AudioDecoderConfig& config,
74 // Initialize data now that the config is known. Since the code uses
75 // invalid values (that CreateEmptyBuffer() doesn't support), tweak them
76 // just for CreateEmptyBuffer().
77 int channels = ChannelLayoutToChannelCount(config.channel_layout());
80 decoded_frame_ = AudioBuffer::CreateEmptyBuffer(
81 config.channel_layout(), channels, kSampleRate, kFakeAudioFrameSize,
83 decoded_frame_list_.push_back(decoded_frame_);
86 config, cdm_context_.get(), NewExpectedBoolCB(success),
87 base::Bind(&DecryptingAudioDecoderTest::FrameReady,
88 base::Unretained(this)),
89 base::Bind(&DecryptingAudioDecoderTest::OnWaitingForDecryptionKey,
90 base::Unretained(this)));
91 base::RunLoop().RunUntilIdle();
94 enum CdmType { CDM_WITHOUT_DECRYPTOR, CDM_WITH_DECRYPTOR };
96 void SetCdmType(CdmType cdm_type) {
97 const bool has_decryptor = cdm_type == CDM_WITH_DECRYPTOR;
98 EXPECT_CALL(*cdm_context_, GetDecryptor())
99 .WillRepeatedly(Return(has_decryptor ? decryptor_.get() : nullptr));
103 SetCdmType(CDM_WITH_DECRYPTOR);
104 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
106 .WillOnce(RunCallback<1>(true));
107 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
108 .WillOnce(SaveArg<1>(&key_added_cb_));
110 config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32,
111 CHANNEL_LAYOUT_STEREO, kSampleRate, EmptyExtraData(),
112 AesCtrEncryptionScheme(), base::TimeDelta(), 0);
113 InitializeAndExpectResult(config_, true);
116 void Reinitialize() {
117 ReinitializeConfigChange(config_);
120 void ReinitializeConfigChange(const AudioDecoderConfig& new_config) {
121 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
122 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
123 .WillOnce(RunCallback<1>(true));
124 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
125 .WillOnce(SaveArg<1>(&key_added_cb_));
126 decoder_->Initialize(
127 new_config, cdm_context_.get(), NewExpectedBoolCB(true),
128 base::Bind(&DecryptingAudioDecoderTest::FrameReady,
129 base::Unretained(this)),
130 base::Bind(&DecryptingAudioDecoderTest::OnWaitingForDecryptionKey,
131 base::Unretained(this)));
134 // Decode |buffer| and expect DecodeDone to get called with |status|.
135 void DecodeAndExpect(scoped_refptr<DecoderBuffer> buffer,
136 DecodeStatus status) {
137 EXPECT_CALL(*this, DecodeDone(status));
138 decoder_->Decode(buffer,
139 base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
140 base::Unretained(this)));
141 base::RunLoop().RunUntilIdle();
144 // Helper function to simulate the decrypting and decoding process in the
145 // |decryptor_| with a decoding delay of kDecodingDelay buffers.
146 void DecryptAndDecodeAudio(scoped_refptr<DecoderBuffer> encrypted,
147 const Decryptor::AudioDecodeCB& audio_decode_cb) {
148 num_decrypt_and_decode_calls_++;
149 if (!encrypted->end_of_stream())
150 num_frames_in_decryptor_++;
152 if (num_decrypt_and_decode_calls_ <= kDecodingDelay ||
153 num_frames_in_decryptor_ == 0) {
154 audio_decode_cb.Run(Decryptor::kNeedMoreData, Decryptor::AudioFrames());
158 num_frames_in_decryptor_--;
159 audio_decode_cb.Run(Decryptor::kSuccess,
160 Decryptor::AudioFrames(1, decoded_frame_));
163 // Sets up expectations and actions to put DecryptingAudioDecoder in an
164 // active normal decoding state.
165 void EnterNormalDecodingState() {
166 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _)).WillRepeatedly(
167 Invoke(this, &DecryptingAudioDecoderTest::DecryptAndDecodeAudio));
168 EXPECT_CALL(*this, FrameReady(decoded_frame_));
169 for (int i = 0; i < kDecodingDelay + 1; ++i)
170 DecodeAndExpect(encrypted_buffer_, DecodeStatus::OK);
173 // Sets up expectations and actions to put DecryptingAudioDecoder in an end
174 // of stream state. This function must be called after
175 // EnterNormalDecodingState() to work.
176 void EnterEndOfStreamState() {
177 // The codec in the |decryptor_| will be flushed.
178 EXPECT_CALL(*this, FrameReady(decoded_frame_))
179 .Times(kDecodingDelay);
180 DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(), DecodeStatus::OK);
181 EXPECT_EQ(0, num_frames_in_decryptor_);
184 // Make the audio decode callback pending by saving and not firing it.
185 void EnterPendingDecodeState() {
186 EXPECT_TRUE(pending_audio_decode_cb_.is_null());
187 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
188 .WillOnce(SaveArg<1>(&pending_audio_decode_cb_));
190 decoder_->Decode(encrypted_buffer_,
191 base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
192 base::Unretained(this)));
193 base::RunLoop().RunUntilIdle();
194 // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
196 EXPECT_FALSE(pending_audio_decode_cb_.is_null());
199 void EnterWaitingForKeyState() {
200 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
201 .WillRepeatedly(RunCallback<1>(Decryptor::kNoKey,
202 Decryptor::AudioFrames()));
203 EXPECT_CALL(*this, OnWaitingForDecryptionKey());
204 decoder_->Decode(encrypted_buffer_,
205 base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
206 base::Unretained(this)));
208 base::RunLoop().RunUntilIdle();
211 void AbortPendingAudioDecodeCB() {
212 if (!pending_audio_decode_cb_.is_null()) {
213 base::ResetAndReturn(&pending_audio_decode_cb_).Run(
214 Decryptor::kSuccess, Decryptor::AudioFrames());
218 void AbortAllPendingCBs() {
219 if (!pending_init_cb_.is_null()) {
220 ASSERT_TRUE(pending_audio_decode_cb_.is_null());
221 base::ResetAndReturn(&pending_init_cb_).Run(false);
225 AbortPendingAudioDecodeCB();
229 EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio))
230 .WillRepeatedly(InvokeWithoutArgs(
231 this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB));
233 decoder_->Reset(NewExpectedClosure());
234 base::RunLoop().RunUntilIdle();
238 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio))
239 .WillRepeatedly(InvokeWithoutArgs(
240 this, &DecryptingAudioDecoderTest::AbortAllPendingCBs));
243 base::RunLoop().RunUntilIdle();
246 MOCK_METHOD1(FrameReady, void(const scoped_refptr<AudioBuffer>&));
247 MOCK_METHOD1(DecodeDone, void(DecodeStatus));
249 MOCK_METHOD0(OnWaitingForDecryptionKey, void(void));
251 base::MessageLoop message_loop_;
253 std::unique_ptr<DecryptingAudioDecoder> decoder_;
254 std::unique_ptr<StrictMock<MockCdmContext>> cdm_context_;
255 std::unique_ptr<StrictMock<MockDecryptor>> decryptor_;
256 AudioDecoderConfig config_;
258 // Variables to help the |decryptor_| to simulate decoding delay and flushing.
259 int num_decrypt_and_decode_calls_;
260 int num_frames_in_decryptor_;
262 Decryptor::DecoderInitCB pending_init_cb_;
263 Decryptor::NewKeyCB key_added_cb_;
264 Decryptor::AudioDecodeCB pending_audio_decode_cb_;
266 // Constant buffer/frames, to be used/returned by |decoder_| and |decryptor_|.
267 scoped_refptr<DecoderBuffer> encrypted_buffer_;
268 scoped_refptr<AudioBuffer> decoded_frame_;
269 Decryptor::AudioFrames decoded_frame_list_;
272 DISALLOW_COPY_AND_ASSIGN(DecryptingAudioDecoderTest);
275 TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) {
279 // Ensure decoder handles invalid audio configs without crashing.
280 TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) {
281 AudioDecoderConfig config(kUnknownAudioCodec, kUnknownSampleFormat,
282 CHANNEL_LAYOUT_STEREO, 0, EmptyExtraData(),
283 AesCtrEncryptionScheme());
285 InitializeAndExpectResult(config, false);
288 // Ensure decoder handles unsupported audio configs without crashing.
289 TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) {
290 SetCdmType(CDM_WITH_DECRYPTOR);
291 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
292 .WillOnce(RunCallback<1>(false));
294 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
295 CHANNEL_LAYOUT_STEREO, kSampleRate,
296 EmptyExtraData(), AesCtrEncryptionScheme());
297 InitializeAndExpectResult(config, false);
300 TEST_F(DecryptingAudioDecoderTest, Initialize_CdmWithoutDecryptor) {
301 SetCdmType(CDM_WITHOUT_DECRYPTOR);
302 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
303 CHANNEL_LAYOUT_STEREO, kSampleRate,
304 EmptyExtraData(), AesCtrEncryptionScheme());
305 InitializeAndExpectResult(config, false);
308 // Test normal decrypt and decode case.
309 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) {
311 EnterNormalDecodingState();
314 // Test the case where the decryptor returns error when doing decrypt and
316 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) {
319 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
320 .WillRepeatedly(RunCallback<1>(Decryptor::kError,
321 Decryptor::AudioFrames()));
323 DecodeAndExpect(encrypted_buffer_, DecodeStatus::DECODE_ERROR);
326 // Test the case where the decryptor returns multiple decoded frames.
327 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) {
330 scoped_refptr<AudioBuffer> frame_a = AudioBuffer::CreateEmptyBuffer(
331 config_.channel_layout(),
332 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
333 kFakeAudioFrameSize, kNoTimestamp);
334 scoped_refptr<AudioBuffer> frame_b = AudioBuffer::CreateEmptyBuffer(
335 config_.channel_layout(),
336 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
337 kFakeAudioFrameSize, kNoTimestamp);
338 decoded_frame_list_.push_back(frame_a);
339 decoded_frame_list_.push_back(frame_b);
341 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
342 .WillOnce(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
344 EXPECT_CALL(*this, FrameReady(decoded_frame_));
345 EXPECT_CALL(*this, FrameReady(frame_a));
346 EXPECT_CALL(*this, FrameReady(frame_b));
347 DecodeAndExpect(encrypted_buffer_, DecodeStatus::OK);
350 // Test the case where the decryptor receives end-of-stream buffer.
351 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) {
353 EnterNormalDecodingState();
354 EnterEndOfStreamState();
357 // Test reinitializing decode with a new encrypted config.
358 TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToEncrypted) {
361 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
363 .WillOnce(RunCallback<1>(true));
365 // The new config is different from the initial config in bits-per-channel,
366 // channel layout and samples_per_second.
367 AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16,
368 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
369 AesCtrEncryptionScheme());
370 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
371 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
372 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
373 ASSERT_TRUE(new_config.is_encrypted());
375 ReinitializeConfigChange(new_config);
376 base::RunLoop().RunUntilIdle();
379 // Test reinitializing decode with a new clear config.
380 TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToClear) {
383 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
385 .WillOnce(RunCallback<1>(true));
387 // The new config is different from the initial config in bits-per-channel,
388 // channel layout and samples_per_second.
389 AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16,
390 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
392 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
393 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
394 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
395 ASSERT_FALSE(new_config.is_encrypted());
397 ReinitializeConfigChange(new_config);
398 base::RunLoop().RunUntilIdle();
401 // Test the case where the a key is added when the decryptor is in
402 // kWaitingForKey state.
403 TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) {
405 EnterWaitingForKeyState();
407 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
408 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
409 EXPECT_CALL(*this, FrameReady(decoded_frame_));
410 EXPECT_CALL(*this, DecodeDone(DecodeStatus::OK));
412 base::RunLoop().RunUntilIdle();
415 // Test the case where the a key is added when the decryptor is in
416 // kPendingDecode state.
417 TEST_F(DecryptingAudioDecoderTest, KeyAdded_DruingPendingDecode) {
419 EnterPendingDecodeState();
421 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
422 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
423 EXPECT_CALL(*this, FrameReady(decoded_frame_));
424 EXPECT_CALL(*this, DecodeDone(DecodeStatus::OK));
425 // The audio decode callback is returned after the correct decryption key is
428 base::ResetAndReturn(&pending_audio_decode_cb_).Run(
429 Decryptor::kNoKey, Decryptor::AudioFrames());
430 base::RunLoop().RunUntilIdle();
433 // Test resetting when the decoder is in kIdle state but has not decoded any
435 TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) {
440 // Test resetting when the decoder is in kIdle state after it has decoded one
442 TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
444 EnterNormalDecodingState();
448 // Test resetting when the decoder is in kPendingDecode state.
449 TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) {
451 EnterPendingDecodeState();
453 EXPECT_CALL(*this, DecodeDone(DecodeStatus::ABORTED));
458 // Test resetting when the decoder is in kWaitingForKey state.
459 TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) {
461 EnterWaitingForKeyState();
463 EXPECT_CALL(*this, DecodeDone(DecodeStatus::ABORTED));
468 // Test resetting when the decoder has hit end of stream and is in
469 // kDecodeFinished state.
470 TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) {
472 EnterNormalDecodingState();
473 EnterEndOfStreamState();
477 // Test resetting after the decoder has been reset.
478 TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) {
480 EnterNormalDecodingState();