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/message_loop/message_loop.h"
13 #include "base/run_loop.h"
14 #include "base/stl_util.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 base::size(kFakeKeyId)),
50 std::string(reinterpret_cast<const char*>(kFakeIv), base::size(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_);
83 decoder_->Initialize(config, cdm_context_.get(), NewExpectedBoolCB(success),
84 base::Bind(&DecryptingAudioDecoderTest::FrameReady,
85 base::Unretained(this)),
86 base::Bind(&DecryptingAudioDecoderTest::OnWaiting,
87 base::Unretained(this)));
88 base::RunLoop().RunUntilIdle();
91 enum CdmType { CDM_WITHOUT_DECRYPTOR, CDM_WITH_DECRYPTOR };
93 void SetCdmType(CdmType cdm_type) {
94 const bool has_decryptor = cdm_type == CDM_WITH_DECRYPTOR;
95 EXPECT_CALL(*cdm_context_, GetDecryptor())
96 .WillRepeatedly(Return(has_decryptor ? decryptor_.get() : nullptr));
100 SetCdmType(CDM_WITH_DECRYPTOR);
101 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
103 .WillOnce(RunCallback<1>(true));
104 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
105 .WillOnce(SaveArg<1>(&key_added_cb_));
107 config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32,
108 CHANNEL_LAYOUT_STEREO, kSampleRate, EmptyExtraData(),
109 AesCtrEncryptionScheme(), base::TimeDelta(), 0);
110 InitializeAndExpectResult(config_, true);
113 void Reinitialize() { ReinitializeConfigChange(config_); }
115 void ReinitializeConfigChange(const AudioDecoderConfig& new_config) {
116 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
117 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
118 .WillOnce(RunCallback<1>(true));
119 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
120 .WillOnce(SaveArg<1>(&key_added_cb_));
121 decoder_->Initialize(new_config, cdm_context_.get(),
122 NewExpectedBoolCB(true),
123 base::Bind(&DecryptingAudioDecoderTest::FrameReady,
124 base::Unretained(this)),
125 base::Bind(&DecryptingAudioDecoderTest::OnWaiting,
126 base::Unretained(this)));
129 // Decode |buffer| and expect DecodeDone to get called with |status|.
130 void DecodeAndExpect(scoped_refptr<DecoderBuffer> buffer,
131 DecodeStatus status) {
132 EXPECT_CALL(*this, DecodeDone(status));
133 decoder_->Decode(buffer, base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
134 base::Unretained(this)));
135 base::RunLoop().RunUntilIdle();
138 // Helper function to simulate the decrypting and decoding process in the
139 // |decryptor_| with a decoding delay of kDecodingDelay buffers.
140 void DecryptAndDecodeAudio(scoped_refptr<DecoderBuffer> encrypted,
141 const Decryptor::AudioDecodeCB& audio_decode_cb) {
142 num_decrypt_and_decode_calls_++;
143 if (!encrypted->end_of_stream())
144 num_frames_in_decryptor_++;
146 if (num_decrypt_and_decode_calls_ <= kDecodingDelay ||
147 num_frames_in_decryptor_ == 0) {
148 audio_decode_cb.Run(Decryptor::kNeedMoreData, Decryptor::AudioFrames());
152 num_frames_in_decryptor_--;
153 audio_decode_cb.Run(Decryptor::kSuccess,
154 Decryptor::AudioFrames(1, decoded_frame_));
157 // Sets up expectations and actions to put DecryptingAudioDecoder in an
158 // active normal decoding state.
159 void EnterNormalDecodingState() {
160 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
162 Invoke(this, &DecryptingAudioDecoderTest::DecryptAndDecodeAudio));
163 EXPECT_CALL(*this, FrameReady(decoded_frame_));
164 for (int i = 0; i < kDecodingDelay + 1; ++i)
165 DecodeAndExpect(encrypted_buffer_, DecodeStatus::OK);
168 // Sets up expectations and actions to put DecryptingAudioDecoder in an end
169 // of stream state. This function must be called after
170 // EnterNormalDecodingState() to work.
171 void EnterEndOfStreamState() {
172 // The codec in the |decryptor_| will be flushed.
173 EXPECT_CALL(*this, FrameReady(decoded_frame_)).Times(kDecodingDelay);
174 DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(), DecodeStatus::OK);
175 EXPECT_EQ(0, num_frames_in_decryptor_);
178 // Make the audio decode callback pending by saving and not firing it.
179 void EnterPendingDecodeState() {
180 EXPECT_TRUE(!pending_audio_decode_cb_);
181 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
182 .WillOnce(SaveArg<1>(&pending_audio_decode_cb_));
184 decoder_->Decode(encrypted_buffer_,
185 base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
186 base::Unretained(this)));
187 base::RunLoop().RunUntilIdle();
188 // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
190 EXPECT_FALSE(!pending_audio_decode_cb_);
193 void EnterWaitingForKeyState() {
194 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
196 RunCallback<1>(Decryptor::kNoKey, Decryptor::AudioFrames()));
197 EXPECT_CALL(*this, OnWaiting(WaitingReason::kNoDecryptionKey));
198 decoder_->Decode(encrypted_buffer_,
199 base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
200 base::Unretained(this)));
202 base::RunLoop().RunUntilIdle();
205 void AbortPendingAudioDecodeCB() {
206 if (pending_audio_decode_cb_) {
207 std::move(pending_audio_decode_cb_)
208 .Run(Decryptor::kSuccess, Decryptor::AudioFrames());
212 void AbortAllPendingCBs() {
213 if (pending_init_cb_) {
214 ASSERT_TRUE(!pending_audio_decode_cb_);
215 std::move(pending_init_cb_).Run(false);
219 AbortPendingAudioDecodeCB();
223 EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio))
224 .WillRepeatedly(InvokeWithoutArgs(
225 this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB));
227 decoder_->Reset(NewExpectedClosure());
228 base::RunLoop().RunUntilIdle();
232 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio))
233 .WillRepeatedly(InvokeWithoutArgs(
234 this, &DecryptingAudioDecoderTest::AbortAllPendingCBs));
237 base::RunLoop().RunUntilIdle();
240 MOCK_METHOD1(FrameReady, void(const scoped_refptr<AudioBuffer>&));
241 MOCK_METHOD1(DecodeDone, void(DecodeStatus));
243 MOCK_METHOD1(OnWaiting, void(WaitingReason));
245 base::MessageLoop message_loop_;
246 NullMediaLog media_log_;
247 std::unique_ptr<DecryptingAudioDecoder> decoder_;
248 std::unique_ptr<StrictMock<MockCdmContext>> cdm_context_;
249 std::unique_ptr<StrictMock<MockDecryptor>> decryptor_;
250 AudioDecoderConfig config_;
252 // Variables to help the |decryptor_| to simulate decoding delay and flushing.
253 int num_decrypt_and_decode_calls_;
254 int num_frames_in_decryptor_;
256 Decryptor::DecoderInitCB pending_init_cb_;
257 Decryptor::NewKeyCB key_added_cb_;
258 Decryptor::AudioDecodeCB pending_audio_decode_cb_;
260 // Constant buffer/frames, to be used/returned by |decoder_| and |decryptor_|.
261 scoped_refptr<DecoderBuffer> encrypted_buffer_;
262 scoped_refptr<AudioBuffer> decoded_frame_;
263 Decryptor::AudioFrames decoded_frame_list_;
266 DISALLOW_COPY_AND_ASSIGN(DecryptingAudioDecoderTest);
269 TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) {
273 // Ensure decoder handles invalid audio configs without crashing.
274 TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) {
275 AudioDecoderConfig config(kUnknownAudioCodec, kUnknownSampleFormat,
276 CHANNEL_LAYOUT_STEREO, 0, EmptyExtraData(),
277 AesCtrEncryptionScheme());
279 InitializeAndExpectResult(config, false);
282 // Ensure decoder handles unsupported audio configs without crashing.
283 TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) {
284 SetCdmType(CDM_WITH_DECRYPTOR);
285 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
286 .WillOnce(RunCallback<1>(false));
288 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
289 CHANNEL_LAYOUT_STEREO, kSampleRate,
290 EmptyExtraData(), AesCtrEncryptionScheme());
291 InitializeAndExpectResult(config, false);
294 TEST_F(DecryptingAudioDecoderTest, Initialize_CdmWithoutDecryptor) {
295 SetCdmType(CDM_WITHOUT_DECRYPTOR);
296 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
297 CHANNEL_LAYOUT_STEREO, kSampleRate,
298 EmptyExtraData(), AesCtrEncryptionScheme());
299 InitializeAndExpectResult(config, false);
302 // Test normal decrypt and decode case.
303 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) {
305 EnterNormalDecodingState();
308 // Test the case where the decryptor returns error when doing decrypt and
310 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) {
313 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
315 RunCallback<1>(Decryptor::kError, Decryptor::AudioFrames()));
317 DecodeAndExpect(encrypted_buffer_, DecodeStatus::DECODE_ERROR);
320 // Test the case where the decryptor returns multiple decoded frames.
321 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) {
324 scoped_refptr<AudioBuffer> frame_a = AudioBuffer::CreateEmptyBuffer(
325 config_.channel_layout(),
326 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
327 kFakeAudioFrameSize, kNoTimestamp);
328 scoped_refptr<AudioBuffer> frame_b = AudioBuffer::CreateEmptyBuffer(
329 config_.channel_layout(),
330 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
331 kFakeAudioFrameSize, kNoTimestamp);
332 decoded_frame_list_.push_back(frame_a);
333 decoded_frame_list_.push_back(frame_b);
335 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
336 .WillOnce(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
338 EXPECT_CALL(*this, FrameReady(decoded_frame_));
339 EXPECT_CALL(*this, FrameReady(frame_a));
340 EXPECT_CALL(*this, FrameReady(frame_b));
341 DecodeAndExpect(encrypted_buffer_, DecodeStatus::OK);
344 // Test the case where the decryptor receives end-of-stream buffer.
345 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) {
347 EnterNormalDecodingState();
348 EnterEndOfStreamState();
351 // Test reinitializing decode with a new encrypted config.
352 TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToEncrypted) {
355 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
357 .WillOnce(RunCallback<1>(true));
359 // The new config is different from the initial config in bits-per-channel,
360 // channel layout and samples_per_second.
361 AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16,
362 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
363 AesCtrEncryptionScheme());
364 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
365 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
366 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
367 ASSERT_TRUE(new_config.is_encrypted());
369 ReinitializeConfigChange(new_config);
370 base::RunLoop().RunUntilIdle();
373 // Test reinitializing decode with a new clear config.
374 TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToClear) {
377 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
379 .WillOnce(RunCallback<1>(true));
381 // The new config is different from the initial config in bits-per-channel,
382 // channel layout and samples_per_second.
383 AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16,
384 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
386 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
387 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
388 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
389 ASSERT_FALSE(new_config.is_encrypted());
391 ReinitializeConfigChange(new_config);
392 base::RunLoop().RunUntilIdle();
395 // Test the case where the a key is added when the decryptor is in
396 // kWaitingForKey state.
397 TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) {
399 EnterWaitingForKeyState();
401 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
402 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
403 EXPECT_CALL(*this, FrameReady(decoded_frame_));
404 EXPECT_CALL(*this, DecodeDone(DecodeStatus::OK));
406 base::RunLoop().RunUntilIdle();
409 // Test the case where the a key is added when the decryptor is in
410 // kPendingDecode state.
411 TEST_F(DecryptingAudioDecoderTest, KeyAdded_DruingPendingDecode) {
413 EnterPendingDecodeState();
415 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
416 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
417 EXPECT_CALL(*this, FrameReady(decoded_frame_));
418 EXPECT_CALL(*this, DecodeDone(DecodeStatus::OK));
419 // The audio decode callback is returned after the correct decryption key is
422 std::move(pending_audio_decode_cb_)
423 .Run(Decryptor::kNoKey, Decryptor::AudioFrames());
424 base::RunLoop().RunUntilIdle();
427 // Test resetting when the decoder is in kIdle state but has not decoded any
429 TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) {
434 // Test resetting when the decoder is in kIdle state after it has decoded one
436 TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
438 EnterNormalDecodingState();
442 // Test resetting when the decoder is in kPendingDecode state.
443 TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) {
445 EnterPendingDecodeState();
447 EXPECT_CALL(*this, DecodeDone(DecodeStatus::ABORTED));
452 // Test resetting when the decoder is in kWaitingForKey state.
453 TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) {
455 EnterWaitingForKeyState();
457 EXPECT_CALL(*this, DecodeDone(DecodeStatus::ABORTED));
462 // Test resetting when the decoder has hit end of stream and is in
463 // kDecodeFinished state.
464 TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) {
466 EnterNormalDecodingState();
467 EnterEndOfStreamState();
471 // Test resetting after the decoder has been reset.
472 TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) {
474 EnterNormalDecodingState();