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(DecryptConfig::CreateCencConfig(
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 ~DecryptingAudioDecoderTest() override { Destroy(); }
70 void InitializeAndExpectResult(const AudioDecoderConfig& config,
72 // Initialize data now that the config is known. Since the code uses
73 // invalid values (that CreateEmptyBuffer() doesn't support), tweak them
74 // just for CreateEmptyBuffer().
75 int channels = ChannelLayoutToChannelCount(config.channel_layout());
78 decoded_frame_ = AudioBuffer::CreateEmptyBuffer(
79 config.channel_layout(), channels, kSampleRate, kFakeAudioFrameSize,
81 decoded_frame_list_.push_back(decoded_frame_);
84 config, cdm_context_.get(), NewExpectedBoolCB(success),
85 base::Bind(&DecryptingAudioDecoderTest::FrameReady,
86 base::Unretained(this)),
87 base::Bind(&DecryptingAudioDecoderTest::OnWaitingForDecryptionKey,
88 base::Unretained(this)));
89 base::RunLoop().RunUntilIdle();
92 enum CdmType { CDM_WITHOUT_DECRYPTOR, CDM_WITH_DECRYPTOR };
94 void SetCdmType(CdmType cdm_type) {
95 const bool has_decryptor = cdm_type == CDM_WITH_DECRYPTOR;
96 EXPECT_CALL(*cdm_context_, GetDecryptor())
97 .WillRepeatedly(Return(has_decryptor ? decryptor_.get() : nullptr));
101 SetCdmType(CDM_WITH_DECRYPTOR);
102 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
104 .WillOnce(RunCallback<1>(true));
105 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
106 .WillOnce(SaveArg<1>(&key_added_cb_));
108 config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32,
109 CHANNEL_LAYOUT_STEREO, kSampleRate, EmptyExtraData(),
110 AesCtrEncryptionScheme(), base::TimeDelta(), 0);
111 InitializeAndExpectResult(config_, true);
114 void Reinitialize() { ReinitializeConfigChange(config_); }
116 void ReinitializeConfigChange(const AudioDecoderConfig& new_config) {
117 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
118 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
119 .WillOnce(RunCallback<1>(true));
120 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
121 .WillOnce(SaveArg<1>(&key_added_cb_));
122 decoder_->Initialize(
123 new_config, cdm_context_.get(), NewExpectedBoolCB(true),
124 base::Bind(&DecryptingAudioDecoderTest::FrameReady,
125 base::Unretained(this)),
126 base::Bind(&DecryptingAudioDecoderTest::OnWaitingForDecryptionKey,
127 base::Unretained(this)));
130 // Decode |buffer| and expect DecodeDone to get called with |status|.
131 void DecodeAndExpect(scoped_refptr<DecoderBuffer> buffer,
132 DecodeStatus status) {
133 EXPECT_CALL(*this, DecodeDone(status));
134 decoder_->Decode(buffer, base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
135 base::Unretained(this)));
136 base::RunLoop().RunUntilIdle();
139 // Helper function to simulate the decrypting and decoding process in the
140 // |decryptor_| with a decoding delay of kDecodingDelay buffers.
141 void DecryptAndDecodeAudio(scoped_refptr<DecoderBuffer> encrypted,
142 const Decryptor::AudioDecodeCB& audio_decode_cb) {
143 num_decrypt_and_decode_calls_++;
144 if (!encrypted->end_of_stream())
145 num_frames_in_decryptor_++;
147 if (num_decrypt_and_decode_calls_ <= kDecodingDelay ||
148 num_frames_in_decryptor_ == 0) {
149 audio_decode_cb.Run(Decryptor::kNeedMoreData, Decryptor::AudioFrames());
153 num_frames_in_decryptor_--;
154 audio_decode_cb.Run(Decryptor::kSuccess,
155 Decryptor::AudioFrames(1, decoded_frame_));
158 // Sets up expectations and actions to put DecryptingAudioDecoder in an
159 // active normal decoding state.
160 void EnterNormalDecodingState() {
161 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
163 Invoke(this, &DecryptingAudioDecoderTest::DecryptAndDecodeAudio));
164 EXPECT_CALL(*this, FrameReady(decoded_frame_));
165 for (int i = 0; i < kDecodingDelay + 1; ++i)
166 DecodeAndExpect(encrypted_buffer_, DecodeStatus::OK);
169 // Sets up expectations and actions to put DecryptingAudioDecoder in an end
170 // of stream state. This function must be called after
171 // EnterNormalDecodingState() to work.
172 void EnterEndOfStreamState() {
173 // The codec in the |decryptor_| will be flushed.
174 EXPECT_CALL(*this, FrameReady(decoded_frame_)).Times(kDecodingDelay);
175 DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(), DecodeStatus::OK);
176 EXPECT_EQ(0, num_frames_in_decryptor_);
179 // Make the audio decode callback pending by saving and not firing it.
180 void EnterPendingDecodeState() {
181 EXPECT_TRUE(pending_audio_decode_cb_.is_null());
182 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
183 .WillOnce(SaveArg<1>(&pending_audio_decode_cb_));
185 decoder_->Decode(encrypted_buffer_,
186 base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
187 base::Unretained(this)));
188 base::RunLoop().RunUntilIdle();
189 // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
191 EXPECT_FALSE(pending_audio_decode_cb_.is_null());
194 void EnterWaitingForKeyState() {
195 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
197 RunCallback<1>(Decryptor::kNoKey, Decryptor::AudioFrames()));
198 EXPECT_CALL(*this, OnWaitingForDecryptionKey());
199 decoder_->Decode(encrypted_buffer_,
200 base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
201 base::Unretained(this)));
203 base::RunLoop().RunUntilIdle();
206 void AbortPendingAudioDecodeCB() {
207 if (!pending_audio_decode_cb_.is_null()) {
208 base::ResetAndReturn(&pending_audio_decode_cb_)
209 .Run(Decryptor::kSuccess, Decryptor::AudioFrames());
213 void AbortAllPendingCBs() {
214 if (!pending_init_cb_.is_null()) {
215 ASSERT_TRUE(pending_audio_decode_cb_.is_null());
216 base::ResetAndReturn(&pending_init_cb_).Run(false);
220 AbortPendingAudioDecodeCB();
224 EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio))
225 .WillRepeatedly(InvokeWithoutArgs(
226 this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB));
228 decoder_->Reset(NewExpectedClosure());
229 base::RunLoop().RunUntilIdle();
233 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio))
234 .WillRepeatedly(InvokeWithoutArgs(
235 this, &DecryptingAudioDecoderTest::AbortAllPendingCBs));
238 base::RunLoop().RunUntilIdle();
241 MOCK_METHOD1(FrameReady, void(const scoped_refptr<AudioBuffer>&));
242 MOCK_METHOD1(DecodeDone, void(DecodeStatus));
244 MOCK_METHOD0(OnWaitingForDecryptionKey, void(void));
246 base::MessageLoop message_loop_;
248 std::unique_ptr<DecryptingAudioDecoder> decoder_;
249 std::unique_ptr<StrictMock<MockCdmContext>> cdm_context_;
250 std::unique_ptr<StrictMock<MockDecryptor>> decryptor_;
251 AudioDecoderConfig config_;
253 // Variables to help the |decryptor_| to simulate decoding delay and flushing.
254 int num_decrypt_and_decode_calls_;
255 int num_frames_in_decryptor_;
257 Decryptor::DecoderInitCB pending_init_cb_;
258 Decryptor::NewKeyCB key_added_cb_;
259 Decryptor::AudioDecodeCB pending_audio_decode_cb_;
261 // Constant buffer/frames, to be used/returned by |decoder_| and |decryptor_|.
262 scoped_refptr<DecoderBuffer> encrypted_buffer_;
263 scoped_refptr<AudioBuffer> decoded_frame_;
264 Decryptor::AudioFrames decoded_frame_list_;
267 DISALLOW_COPY_AND_ASSIGN(DecryptingAudioDecoderTest);
270 TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) {
274 // Ensure decoder handles invalid audio configs without crashing.
275 TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) {
276 AudioDecoderConfig config(kUnknownAudioCodec, kUnknownSampleFormat,
277 CHANNEL_LAYOUT_STEREO, 0, EmptyExtraData(),
278 AesCtrEncryptionScheme());
280 InitializeAndExpectResult(config, false);
283 // Ensure decoder handles unsupported audio configs without crashing.
284 TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) {
285 SetCdmType(CDM_WITH_DECRYPTOR);
286 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
287 .WillOnce(RunCallback<1>(false));
289 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
290 CHANNEL_LAYOUT_STEREO, kSampleRate,
291 EmptyExtraData(), AesCtrEncryptionScheme());
292 InitializeAndExpectResult(config, false);
295 TEST_F(DecryptingAudioDecoderTest, Initialize_CdmWithoutDecryptor) {
296 SetCdmType(CDM_WITHOUT_DECRYPTOR);
297 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
298 CHANNEL_LAYOUT_STEREO, kSampleRate,
299 EmptyExtraData(), AesCtrEncryptionScheme());
300 InitializeAndExpectResult(config, false);
303 // Test normal decrypt and decode case.
304 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) {
306 EnterNormalDecodingState();
309 // Test the case where the decryptor returns error when doing decrypt and
311 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) {
314 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
316 RunCallback<1>(Decryptor::kError, Decryptor::AudioFrames()));
318 DecodeAndExpect(encrypted_buffer_, DecodeStatus::DECODE_ERROR);
321 // Test the case where the decryptor returns multiple decoded frames.
322 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) {
325 scoped_refptr<AudioBuffer> frame_a = AudioBuffer::CreateEmptyBuffer(
326 config_.channel_layout(),
327 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
328 kFakeAudioFrameSize, kNoTimestamp);
329 scoped_refptr<AudioBuffer> frame_b = AudioBuffer::CreateEmptyBuffer(
330 config_.channel_layout(),
331 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
332 kFakeAudioFrameSize, kNoTimestamp);
333 decoded_frame_list_.push_back(frame_a);
334 decoded_frame_list_.push_back(frame_b);
336 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
337 .WillOnce(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
339 EXPECT_CALL(*this, FrameReady(decoded_frame_));
340 EXPECT_CALL(*this, FrameReady(frame_a));
341 EXPECT_CALL(*this, FrameReady(frame_b));
342 DecodeAndExpect(encrypted_buffer_, DecodeStatus::OK);
345 // Test the case where the decryptor receives end-of-stream buffer.
346 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) {
348 EnterNormalDecodingState();
349 EnterEndOfStreamState();
352 // Test reinitializing decode with a new encrypted config.
353 TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToEncrypted) {
356 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
358 .WillOnce(RunCallback<1>(true));
360 // The new config is different from the initial config in bits-per-channel,
361 // channel layout and samples_per_second.
362 AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16,
363 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
364 AesCtrEncryptionScheme());
365 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
366 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
367 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
368 ASSERT_TRUE(new_config.is_encrypted());
370 ReinitializeConfigChange(new_config);
371 base::RunLoop().RunUntilIdle();
374 // Test reinitializing decode with a new clear config.
375 TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToClear) {
378 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
380 .WillOnce(RunCallback<1>(true));
382 // The new config is different from the initial config in bits-per-channel,
383 // channel layout and samples_per_second.
384 AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16,
385 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
387 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
388 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
389 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
390 ASSERT_FALSE(new_config.is_encrypted());
392 ReinitializeConfigChange(new_config);
393 base::RunLoop().RunUntilIdle();
396 // Test the case where the a key is added when the decryptor is in
397 // kWaitingForKey state.
398 TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) {
400 EnterWaitingForKeyState();
402 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
403 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
404 EXPECT_CALL(*this, FrameReady(decoded_frame_));
405 EXPECT_CALL(*this, DecodeDone(DecodeStatus::OK));
407 base::RunLoop().RunUntilIdle();
410 // Test the case where the a key is added when the decryptor is in
411 // kPendingDecode state.
412 TEST_F(DecryptingAudioDecoderTest, KeyAdded_DruingPendingDecode) {
414 EnterPendingDecodeState();
416 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
417 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
418 EXPECT_CALL(*this, FrameReady(decoded_frame_));
419 EXPECT_CALL(*this, DecodeDone(DecodeStatus::OK));
420 // The audio decode callback is returned after the correct decryption key is
423 base::ResetAndReturn(&pending_audio_decode_cb_)
424 .Run(Decryptor::kNoKey, Decryptor::AudioFrames());
425 base::RunLoop().RunUntilIdle();
428 // Test resetting when the decoder is in kIdle state but has not decoded any
430 TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) {
435 // Test resetting when the decoder is in kIdle state after it has decoded one
437 TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
439 EnterNormalDecodingState();
443 // Test resetting when the decoder is in kPendingDecode state.
444 TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) {
446 EnterPendingDecodeState();
448 EXPECT_CALL(*this, DecodeDone(DecodeStatus::ABORTED));
453 // Test resetting when the decoder is in kWaitingForKey state.
454 TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) {
456 EnterWaitingForKeyState();
458 EXPECT_CALL(*this, DecodeDone(DecodeStatus::ABORTED));
463 // Test resetting when the decoder has hit end of stream and is in
464 // kDecodeFinished state.
465 TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) {
467 EnterNormalDecodingState();
468 EnterEndOfStreamState();
472 // Test resetting after the decoder has been reset.
473 TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) {
475 EnterNormalDecodingState();