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.
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"
22 using ::testing::AtMost
;
23 using ::testing::SaveArg
;
24 using ::testing::StrictMock
;
28 const int kSampleRate
= 44100;
30 // Make sure the kFakeAudioFrameSize is a valid frame size for all audio decoder
31 // configs used in this test.
32 const int kFakeAudioFrameSize
= 48;
33 const uint8 kFakeKeyId
[] = { 0x4b, 0x65, 0x79, 0x20, 0x49, 0x44 };
34 const uint8 kFakeIv
[DecryptConfig::kDecryptionKeySize
] = { 0 };
35 const int kDecodingDelay
= 3;
37 // Create a fake non-empty encrypted buffer.
38 static 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
>())));
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.
53 ACTION_P(ReturnBuffer
, buffer
) {
59 class DecryptingAudioDecoderTest
: public testing::Test
{
61 DecryptingAudioDecoderTest()
62 : decoder_(new DecryptingAudioDecoder(
63 message_loop_
.message_loop_proxy(),
65 &DecryptingAudioDecoderTest::RequestDecryptorNotification
,
66 base::Unretained(this)))),
67 decryptor_(new StrictMock
<MockDecryptor
>()),
68 num_decrypt_and_decode_calls_(0),
69 num_frames_in_decryptor_(0),
70 encrypted_buffer_(CreateFakeEncryptedBuffer()),
72 decoded_frame_list_() {}
74 virtual ~DecryptingAudioDecoderTest() {
75 EXPECT_CALL(*this, RequestDecryptorNotification(_
))
76 .Times(testing::AnyNumber());
80 void InitializeAndExpectStatus(const AudioDecoderConfig
& config
,
81 PipelineStatus status
) {
82 // Initialize data now that the config is known. Since the code uses
83 // invalid values (that CreateEmptyBuffer() doesn't support), tweak them
84 // just for CreateEmptyBuffer().
85 int channels
= ChannelLayoutToChannelCount(config
.channel_layout());
88 decoded_frame_
= AudioBuffer::CreateEmptyBuffer(config
.channel_layout(),
93 decoded_frame_list_
.push_back(decoded_frame_
);
95 decoder_
->Initialize(config
, NewExpectedStatusCB(status
),
96 base::Bind(&DecryptingAudioDecoderTest::FrameReady
,
97 base::Unretained(this)));
98 message_loop_
.RunUntilIdle();
101 void ExpectDecryptorNotification(Decryptor
* decryptor
, bool expected_result
) {
102 EXPECT_CALL(*this, RequestDecryptorNotification(_
)).WillOnce(
103 RunCallback
<0>(decryptor
,
104 base::Bind(&DecryptingAudioDecoderTest::DecryptorSet
,
105 base::Unretained(this))));
106 EXPECT_CALL(*this, DecryptorSet(expected_result
));
110 EXPECT_CALL(*decryptor_
, InitializeAudioDecoder(_
, _
))
112 .WillOnce(RunCallback
<1>(true));
113 ExpectDecryptorNotification(decryptor_
.get(), true);
114 EXPECT_CALL(*decryptor_
, RegisterNewKeyCB(Decryptor::kAudio
, _
))
115 .WillOnce(SaveArg
<1>(&key_added_cb_
));
117 config_
.Initialize(kCodecVorbis
, kSampleFormatPlanarF32
,
118 CHANNEL_LAYOUT_STEREO
, kSampleRate
, NULL
, 0, true, true,
119 base::TimeDelta(), 0);
120 InitializeAndExpectStatus(config_
, PIPELINE_OK
);
123 void Reinitialize() {
124 ReinitializeConfigChange(config_
);
127 void ReinitializeConfigChange(const AudioDecoderConfig
& new_config
) {
128 EXPECT_CALL(*decryptor_
, DeinitializeDecoder(Decryptor::kAudio
));
129 EXPECT_CALL(*decryptor_
, InitializeAudioDecoder(_
, _
))
130 .WillOnce(RunCallback
<1>(true));
131 EXPECT_CALL(*decryptor_
, RegisterNewKeyCB(Decryptor::kAudio
, _
))
132 .WillOnce(SaveArg
<1>(&key_added_cb_
));
133 decoder_
->Initialize(new_config
, NewExpectedStatusCB(PIPELINE_OK
),
134 base::Bind(&DecryptingAudioDecoderTest::FrameReady
,
135 base::Unretained(this)));
138 // Decode |buffer| and expect DecodeDone to get called with |status|.
139 void DecodeAndExpect(const scoped_refptr
<DecoderBuffer
>& buffer
,
140 AudioDecoder::Status status
) {
141 EXPECT_CALL(*this, DecodeDone(status
));
142 decoder_
->Decode(buffer
,
143 base::Bind(&DecryptingAudioDecoderTest::DecodeDone
,
144 base::Unretained(this)));
145 message_loop_
.RunUntilIdle();
148 // Helper function to simulate the decrypting and decoding process in the
149 // |decryptor_| with a decoding delay of kDecodingDelay buffers.
150 void DecryptAndDecodeAudio(const scoped_refptr
<DecoderBuffer
>& encrypted
,
151 const Decryptor::AudioDecodeCB
& audio_decode_cb
) {
152 num_decrypt_and_decode_calls_
++;
153 if (!encrypted
->end_of_stream())
154 num_frames_in_decryptor_
++;
156 if (num_decrypt_and_decode_calls_
<= kDecodingDelay
||
157 num_frames_in_decryptor_
== 0) {
158 audio_decode_cb
.Run(Decryptor::kNeedMoreData
, Decryptor::AudioBuffers());
162 num_frames_in_decryptor_
--;
163 audio_decode_cb
.Run(Decryptor::kSuccess
,
164 Decryptor::AudioBuffers(1, decoded_frame_
));
167 // Sets up expectations and actions to put DecryptingAudioDecoder in an
168 // active normal decoding state.
169 void EnterNormalDecodingState() {
170 EXPECT_CALL(*decryptor_
, DecryptAndDecodeAudio(_
, _
)).WillRepeatedly(
171 Invoke(this, &DecryptingAudioDecoderTest::DecryptAndDecodeAudio
));
172 EXPECT_CALL(*this, FrameReady(decoded_frame_
));
173 for (int i
= 0; i
< kDecodingDelay
+ 1; ++i
)
174 DecodeAndExpect(encrypted_buffer_
, AudioDecoder::kOk
);
177 // Sets up expectations and actions to put DecryptingAudioDecoder in an end
178 // of stream state. This function must be called after
179 // EnterNormalDecodingState() to work.
180 void EnterEndOfStreamState() {
181 // The codec in the |decryptor_| will be flushed.
182 EXPECT_CALL(*this, FrameReady(decoded_frame_
))
183 .Times(kDecodingDelay
);
184 DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(), AudioDecoder::kOk
);
185 EXPECT_EQ(0, num_frames_in_decryptor_
);
188 // Make the audio decode callback pending by saving and not firing it.
189 void EnterPendingDecodeState() {
190 EXPECT_TRUE(pending_audio_decode_cb_
.is_null());
191 EXPECT_CALL(*decryptor_
, DecryptAndDecodeAudio(encrypted_buffer_
, _
))
192 .WillOnce(SaveArg
<1>(&pending_audio_decode_cb_
));
194 decoder_
->Decode(encrypted_buffer_
,
195 base::Bind(&DecryptingAudioDecoderTest::DecodeDone
,
196 base::Unretained(this)));
197 message_loop_
.RunUntilIdle();
198 // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
200 EXPECT_FALSE(pending_audio_decode_cb_
.is_null());
203 void EnterWaitingForKeyState() {
204 EXPECT_CALL(*decryptor_
, DecryptAndDecodeAudio(encrypted_buffer_
, _
))
205 .WillRepeatedly(RunCallback
<1>(Decryptor::kNoKey
,
206 Decryptor::AudioBuffers()));
207 decoder_
->Decode(encrypted_buffer_
,
208 base::Bind(&DecryptingAudioDecoderTest::DecodeDone
,
209 base::Unretained(this)));
210 message_loop_
.RunUntilIdle();
213 void AbortPendingAudioDecodeCB() {
214 if (!pending_audio_decode_cb_
.is_null()) {
215 base::ResetAndReturn(&pending_audio_decode_cb_
).Run(
216 Decryptor::kSuccess
, Decryptor::AudioBuffers());
220 void AbortAllPendingCBs() {
221 if (!pending_init_cb_
.is_null()) {
222 ASSERT_TRUE(pending_audio_decode_cb_
.is_null());
223 base::ResetAndReturn(&pending_init_cb_
).Run(false);
227 AbortPendingAudioDecodeCB();
231 EXPECT_CALL(*decryptor_
, ResetDecoder(Decryptor::kAudio
))
232 .WillRepeatedly(InvokeWithoutArgs(
233 this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB
));
235 decoder_
->Reset(NewExpectedClosure());
236 message_loop_
.RunUntilIdle();
240 EXPECT_CALL(*decryptor_
, DeinitializeDecoder(Decryptor::kAudio
))
241 .WillRepeatedly(InvokeWithoutArgs(
242 this, &DecryptingAudioDecoderTest::AbortAllPendingCBs
));
245 message_loop_
.RunUntilIdle();
248 MOCK_METHOD1(RequestDecryptorNotification
, void(const DecryptorReadyCB
&));
250 MOCK_METHOD1(FrameReady
, void(const scoped_refptr
<AudioBuffer
>&));
251 MOCK_METHOD1(DecodeDone
, void(AudioDecoder::Status
));
253 MOCK_METHOD1(DecryptorSet
, void(bool));
255 base::MessageLoop message_loop_
;
256 scoped_ptr
<DecryptingAudioDecoder
> decoder_
;
257 scoped_ptr
<StrictMock
<MockDecryptor
> > decryptor_
;
258 AudioDecoderConfig config_
;
260 // Variables to help the |decryptor_| to simulate decoding delay and flushing.
261 int num_decrypt_and_decode_calls_
;
262 int num_frames_in_decryptor_
;
264 Decryptor::DecoderInitCB pending_init_cb_
;
265 Decryptor::NewKeyCB key_added_cb_
;
266 Decryptor::AudioDecodeCB pending_audio_decode_cb_
;
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 Decryptor::AudioBuffers decoded_frame_list_
;
274 DISALLOW_COPY_AND_ASSIGN(DecryptingAudioDecoderTest
);
277 TEST_F(DecryptingAudioDecoderTest
, Initialize_Normal
) {
281 // Ensure that DecryptingAudioDecoder only accepts encrypted audio.
282 TEST_F(DecryptingAudioDecoderTest
, Initialize_UnencryptedAudioConfig
) {
283 AudioDecoderConfig
config(kCodecVorbis
, kSampleFormatPlanarF32
,
284 CHANNEL_LAYOUT_STEREO
, kSampleRate
, NULL
, 0, false);
286 InitializeAndExpectStatus(config
, DECODER_ERROR_NOT_SUPPORTED
);
289 // Ensure decoder handles invalid audio configs without crashing.
290 TEST_F(DecryptingAudioDecoderTest
, Initialize_InvalidAudioConfig
) {
291 AudioDecoderConfig
config(kUnknownAudioCodec
, kUnknownSampleFormat
,
292 CHANNEL_LAYOUT_STEREO
, 0, NULL
, 0, true);
294 InitializeAndExpectStatus(config
, PIPELINE_ERROR_DECODE
);
297 // Ensure decoder handles unsupported audio configs without crashing.
298 TEST_F(DecryptingAudioDecoderTest
, Initialize_UnsupportedAudioConfig
) {
299 EXPECT_CALL(*decryptor_
, InitializeAudioDecoder(_
, _
))
300 .WillOnce(RunCallback
<1>(false));
301 ExpectDecryptorNotification(decryptor_
.get(), true);
303 AudioDecoderConfig
config(kCodecVorbis
, kSampleFormatPlanarF32
,
304 CHANNEL_LAYOUT_STEREO
, kSampleRate
, NULL
, 0, true);
305 InitializeAndExpectStatus(config
, DECODER_ERROR_NOT_SUPPORTED
);
308 TEST_F(DecryptingAudioDecoderTest
, Initialize_NullDecryptor
) {
309 ExpectDecryptorNotification(NULL
, false);
310 AudioDecoderConfig
config(kCodecVorbis
, kSampleFormatPlanarF32
,
311 CHANNEL_LAYOUT_STEREO
, kSampleRate
, NULL
, 0, true);
312 InitializeAndExpectStatus(config
, DECODER_ERROR_NOT_SUPPORTED
);
315 // Test normal decrypt and decode case.
316 TEST_F(DecryptingAudioDecoderTest
, DecryptAndDecode_Normal
) {
318 EnterNormalDecodingState();
321 // Test the case where the decryptor returns error when doing decrypt and
323 TEST_F(DecryptingAudioDecoderTest
, DecryptAndDecode_DecodeError
) {
326 EXPECT_CALL(*decryptor_
, DecryptAndDecodeAudio(_
, _
))
327 .WillRepeatedly(RunCallback
<1>(Decryptor::kError
,
328 Decryptor::AudioBuffers()));
330 DecodeAndExpect(encrypted_buffer_
, AudioDecoder::kDecodeError
);
333 // Test the case where the decryptor returns multiple decoded frames.
334 TEST_F(DecryptingAudioDecoderTest
, DecryptAndDecode_MultipleFrames
) {
337 scoped_refptr
<AudioBuffer
> frame_a
= AudioBuffer::CreateEmptyBuffer(
338 config_
.channel_layout(),
339 ChannelLayoutToChannelCount(config_
.channel_layout()),
343 scoped_refptr
<AudioBuffer
> frame_b
= AudioBuffer::CreateEmptyBuffer(
344 config_
.channel_layout(),
345 ChannelLayoutToChannelCount(config_
.channel_layout()),
349 decoded_frame_list_
.push_back(frame_a
);
350 decoded_frame_list_
.push_back(frame_b
);
352 EXPECT_CALL(*decryptor_
, DecryptAndDecodeAudio(_
, _
))
353 .WillOnce(RunCallback
<1>(Decryptor::kSuccess
, decoded_frame_list_
));
355 EXPECT_CALL(*this, FrameReady(decoded_frame_
));
356 EXPECT_CALL(*this, FrameReady(frame_a
));
357 EXPECT_CALL(*this, FrameReady(frame_b
));
358 DecodeAndExpect(encrypted_buffer_
, AudioDecoder::kOk
);
361 // Test the case where the decryptor receives end-of-stream buffer.
362 TEST_F(DecryptingAudioDecoderTest
, DecryptAndDecode_EndOfStream
) {
364 EnterNormalDecodingState();
365 EnterEndOfStreamState();
368 // Test reinitializing decode with a new config
369 TEST_F(DecryptingAudioDecoderTest
, Reinitialize_ConfigChange
) {
372 EXPECT_CALL(*decryptor_
, InitializeAudioDecoder(_
, _
))
374 .WillOnce(RunCallback
<1>(true));
376 // The new config is different from the initial config in bits-per-channel,
377 // channel layout and samples_per_second.
378 AudioDecoderConfig
new_config(kCodecVorbis
, kSampleFormatPlanarS16
,
379 CHANNEL_LAYOUT_5_1
, 88200, NULL
, 0, true);
380 EXPECT_NE(new_config
.bits_per_channel(), config_
.bits_per_channel());
381 EXPECT_NE(new_config
.channel_layout(), config_
.channel_layout());
382 EXPECT_NE(new_config
.samples_per_second(), config_
.samples_per_second());
384 ReinitializeConfigChange(new_config
);
385 message_loop_
.RunUntilIdle();
388 // Test the case where the a key is added when the decryptor is in
389 // kWaitingForKey state.
390 TEST_F(DecryptingAudioDecoderTest
, KeyAdded_DuringWaitingForKey
) {
392 EnterWaitingForKeyState();
394 EXPECT_CALL(*decryptor_
, DecryptAndDecodeAudio(_
, _
))
395 .WillRepeatedly(RunCallback
<1>(Decryptor::kSuccess
, decoded_frame_list_
));
396 EXPECT_CALL(*this, FrameReady(decoded_frame_
));
397 EXPECT_CALL(*this, DecodeDone(AudioDecoder::kOk
));
399 message_loop_
.RunUntilIdle();
402 // Test the case where the a key is added when the decryptor is in
403 // kPendingDecode state.
404 TEST_F(DecryptingAudioDecoderTest
, KeyAdded_DruingPendingDecode
) {
406 EnterPendingDecodeState();
408 EXPECT_CALL(*decryptor_
, DecryptAndDecodeAudio(_
, _
))
409 .WillRepeatedly(RunCallback
<1>(Decryptor::kSuccess
, decoded_frame_list_
));
410 EXPECT_CALL(*this, FrameReady(decoded_frame_
));
411 EXPECT_CALL(*this, DecodeDone(AudioDecoder::kOk
));
412 // The audio decode callback is returned after the correct decryption key is
415 base::ResetAndReturn(&pending_audio_decode_cb_
).Run(
416 Decryptor::kNoKey
, Decryptor::AudioBuffers());
417 message_loop_
.RunUntilIdle();
420 // Test resetting when the decoder is in kIdle state but has not decoded any
422 TEST_F(DecryptingAudioDecoderTest
, Reset_DuringIdleAfterInitialization
) {
427 // Test resetting when the decoder is in kIdle state after it has decoded one
429 TEST_F(DecryptingAudioDecoderTest
, Reset_DuringIdleAfterDecodedOneFrame
) {
431 EnterNormalDecodingState();
435 // Test resetting when the decoder is in kPendingDecode state.
436 TEST_F(DecryptingAudioDecoderTest
, Reset_DuringPendingDecode
) {
438 EnterPendingDecodeState();
440 EXPECT_CALL(*this, DecodeDone(AudioDecoder::kAborted
));
445 // Test resetting when the decoder is in kWaitingForKey state.
446 TEST_F(DecryptingAudioDecoderTest
, Reset_DuringWaitingForKey
) {
448 EnterWaitingForKeyState();
450 EXPECT_CALL(*this, DecodeDone(AudioDecoder::kAborted
));
455 // Test resetting when the decoder has hit end of stream and is in
456 // kDecodeFinished state.
457 TEST_F(DecryptingAudioDecoderTest
, Reset_AfterDecodeFinished
) {
459 EnterNormalDecodingState();
460 EnterEndOfStreamState();
464 // Test resetting after the decoder has been reset.
465 TEST_F(DecryptingAudioDecoderTest
, Reset_AfterReset
) {
467 EnterNormalDecodingState();