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/cxx17_backports.h"
13 #include "base/run_loop.h"
14 #include "base/test/gmock_callback_support.h"
15 #include "base/test/gmock_move_support.h"
16 #include "base/test/task_environment.h"
17 #include "media/base/audio_buffer.h"
18 #include "media/base/decoder_buffer.h"
19 #include "media/base/decrypt_config.h"
20 #include "media/base/media_util.h"
21 #include "media/base/mock_filters.h"
22 #include "media/base/test_helpers.h"
23 #include "media/base/timestamp_constants.h"
24 #include "media/filters/decrypting_audio_decoder.h"
25 #include "testing/gmock/include/gmock/gmock.h"
27 using ::base::test::RunOnceCallback;
29 using ::testing::AtMost;
30 using ::testing::Return;
31 using ::testing::StrictMock;
35 const int kSampleRate = 44100;
37 // Make sure the kFakeAudioFrameSize is a valid frame size for all audio decoder
38 // configs used in this test.
39 const int kFakeAudioFrameSize = 48;
40 const uint8_t kFakeKeyId[] = {0x4b, 0x65, 0x79, 0x20, 0x49, 0x44};
41 const uint8_t kFakeIv[DecryptConfig::kDecryptionKeySize] = {0};
42 const int kDecodingDelay = 3;
44 // Create a fake non-empty encrypted buffer.
45 static scoped_refptr<DecoderBuffer> CreateFakeEncryptedBuffer() {
46 const int buffer_size = 16; // Need a non-empty buffer;
47 scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(buffer_size));
48 buffer->set_decrypt_config(DecryptConfig::CreateCencConfig(
49 std::string(reinterpret_cast<const char*>(kFakeKeyId),
50 base::size(kFakeKeyId)),
51 std::string(reinterpret_cast<const char*>(kFakeIv), base::size(kFakeIv)),
52 std::vector<SubsampleEntry>()));
56 class DecryptingAudioDecoderTest : public testing::Test {
58 DecryptingAudioDecoderTest()
59 : decoder_(new DecryptingAudioDecoder(
60 task_environment_.GetMainThreadTaskRunner(),
62 cdm_context_(new StrictMock<MockCdmContext>()),
63 decryptor_(new StrictMock<MockDecryptor>()),
64 num_decrypt_and_decode_calls_(0),
65 num_frames_in_decryptor_(0),
66 encrypted_buffer_(CreateFakeEncryptedBuffer()),
67 decoded_frame_(nullptr),
68 decoded_frame_list_() {}
70 ~DecryptingAudioDecoderTest() override { Destroy(); }
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(),
88 [](bool success, Status status) {
89 EXPECT_EQ(status.is_ok(), success);
92 base::BindRepeating(&DecryptingAudioDecoderTest::FrameReady,
93 base::Unretained(this)),
94 base::BindRepeating(&DecryptingAudioDecoderTest::OnWaiting,
95 base::Unretained(this)));
96 base::RunLoop().RunUntilIdle();
99 enum CdmType { CDM_WITHOUT_DECRYPTOR, CDM_WITH_DECRYPTOR };
101 void SetCdmType(CdmType cdm_type) {
102 const bool has_decryptor = cdm_type == CDM_WITH_DECRYPTOR;
103 EXPECT_CALL(*cdm_context_, GetDecryptor())
104 .WillRepeatedly(Return(has_decryptor ? decryptor_.get() : nullptr));
108 SetCdmType(CDM_WITH_DECRYPTOR);
109 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
111 .WillOnce(RunOnceCallback<1>(true));
112 EXPECT_CALL(*cdm_context_, RegisterEventCB(_)).WillOnce([&](auto cb) {
114 return std::make_unique<CallbackRegistration>();
117 config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32,
118 CHANNEL_LAYOUT_STEREO, kSampleRate, EmptyExtraData(),
119 EncryptionScheme::kCenc, base::TimeDelta(), 0);
120 InitializeAndExpectResult(config_, true);
123 void Reinitialize() { ReinitializeConfigChange(config_); }
125 void ReinitializeConfigChange(const AudioDecoderConfig& new_config) {
126 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
127 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
128 .WillOnce(RunOnceCallback<1>(true));
129 decoder_->Initialize(
130 new_config, cdm_context_.get(),
131 base::BindOnce([](Status status) { EXPECT_TRUE(status.is_ok()); }),
132 base::BindRepeating(&DecryptingAudioDecoderTest::FrameReady,
133 base::Unretained(this)),
134 base::BindRepeating(&DecryptingAudioDecoderTest::OnWaiting,
135 base::Unretained(this)));
138 // Decode |buffer| and expect DecodeDone to get called with |status|.
139 void DecodeAndExpect(scoped_refptr<DecoderBuffer> buffer, StatusCode status) {
140 EXPECT_CALL(*this, DecodeDone(HasStatusCode(status)));
141 decoder_->Decode(buffer,
142 base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
143 base::Unretained(this)));
144 base::RunLoop().RunUntilIdle();
147 // Helper function to simulate the decrypting and decoding process in the
148 // |decryptor_| with a decoding delay of kDecodingDelay buffers.
149 void DecryptAndDecodeAudio(scoped_refptr<DecoderBuffer> encrypted,
150 Decryptor::AudioDecodeCB audio_decode_cb) {
151 num_decrypt_and_decode_calls_++;
152 if (!encrypted->end_of_stream())
153 num_frames_in_decryptor_++;
155 if (num_decrypt_and_decode_calls_ <= kDecodingDelay ||
156 num_frames_in_decryptor_ == 0) {
157 std::move(audio_decode_cb)
158 .Run(Decryptor::kNeedMoreData, Decryptor::AudioFrames());
162 num_frames_in_decryptor_--;
163 std::move(audio_decode_cb)
164 .Run(Decryptor::kSuccess, Decryptor::AudioFrames(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(_, _))
172 Invoke(this, &DecryptingAudioDecoderTest::DecryptAndDecodeAudio));
173 EXPECT_CALL(*this, FrameReady(decoded_frame_));
174 for (int i = 0; i < kDecodingDelay + 1; ++i)
175 DecodeAndExpect(encrypted_buffer_, DecodeStatus::OK);
178 // Sets up expectations and actions to put DecryptingAudioDecoder in an end
179 // of stream state. This function must be called after
180 // EnterNormalDecodingState() to work.
181 void EnterEndOfStreamState() {
182 // The codec in the |decryptor_| will be flushed.
183 EXPECT_CALL(*this, FrameReady(decoded_frame_)).Times(kDecodingDelay);
184 DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(), DecodeStatus::OK);
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_);
191 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
192 .WillOnce(MoveArg<1>(&pending_audio_decode_cb_));
194 decoder_->Decode(encrypted_buffer_,
195 base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
196 base::Unretained(this)));
197 base::RunLoop().RunUntilIdle();
198 // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
200 EXPECT_FALSE(!pending_audio_decode_cb_);
203 void EnterWaitingForKeyState() {
204 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
206 RunOnceCallback<1>(Decryptor::kNoKey, Decryptor::AudioFrames()));
207 EXPECT_CALL(*this, OnWaiting(WaitingReason::kNoDecryptionKey));
208 decoder_->Decode(encrypted_buffer_,
209 base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
210 base::Unretained(this)));
212 base::RunLoop().RunUntilIdle();
215 void AbortPendingAudioDecodeCB() {
216 if (pending_audio_decode_cb_) {
217 std::move(pending_audio_decode_cb_)
218 .Run(Decryptor::kSuccess, Decryptor::AudioFrames());
222 void AbortAllPendingCBs() {
223 if (pending_init_cb_) {
224 ASSERT_TRUE(!pending_audio_decode_cb_);
225 std::move(pending_init_cb_).Run(false);
229 AbortPendingAudioDecodeCB();
233 EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio))
234 .WillRepeatedly(InvokeWithoutArgs(
235 this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB));
237 decoder_->Reset(NewExpectedClosure());
238 base::RunLoop().RunUntilIdle();
242 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio))
243 .WillRepeatedly(InvokeWithoutArgs(
244 this, &DecryptingAudioDecoderTest::AbortAllPendingCBs));
247 base::RunLoop().RunUntilIdle();
250 MOCK_METHOD1(FrameReady, void(scoped_refptr<AudioBuffer>));
251 MOCK_METHOD1(DecodeDone, void(Status));
253 MOCK_METHOD1(OnWaiting, void(WaitingReason));
255 base::test::SingleThreadTaskEnvironment task_environment_;
256 NullMediaLog media_log_;
257 std::unique_ptr<DecryptingAudioDecoder> decoder_;
258 std::unique_ptr<StrictMock<MockCdmContext>> cdm_context_;
259 std::unique_ptr<StrictMock<MockDecryptor>> decryptor_;
260 AudioDecoderConfig config_;
262 // Variables to help the |decryptor_| to simulate decoding delay and flushing.
263 int num_decrypt_and_decode_calls_;
264 int num_frames_in_decryptor_;
266 Decryptor::DecoderInitCB pending_init_cb_;
267 CdmContext::EventCB event_cb_;
268 Decryptor::AudioDecodeCB pending_audio_decode_cb_;
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 Decryptor::AudioFrames decoded_frame_list_;
276 DISALLOW_COPY_AND_ASSIGN(DecryptingAudioDecoderTest);
279 TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) {
283 // Ensure decoder handles invalid audio configs without crashing.
284 TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) {
285 AudioDecoderConfig config(kUnknownAudioCodec, kUnknownSampleFormat,
286 CHANNEL_LAYOUT_STEREO, 0, EmptyExtraData(),
287 EncryptionScheme::kCenc);
289 InitializeAndExpectResult(config, false);
292 // Ensure decoder handles unsupported audio configs without crashing.
293 TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) {
294 SetCdmType(CDM_WITH_DECRYPTOR);
295 EXPECT_CALL(*cdm_context_, RegisterEventCB(_)).WillOnce([&](auto cb) {
297 return std::make_unique<CallbackRegistration>();
299 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
300 .WillOnce(RunOnceCallback<1>(false));
302 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
303 CHANNEL_LAYOUT_STEREO, kSampleRate,
304 EmptyExtraData(), EncryptionScheme::kCenc);
305 InitializeAndExpectResult(config, false);
308 TEST_F(DecryptingAudioDecoderTest, Initialize_CdmWithoutDecryptor) {
309 SetCdmType(CDM_WITHOUT_DECRYPTOR);
310 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
311 CHANNEL_LAYOUT_STEREO, kSampleRate,
312 EmptyExtraData(), EncryptionScheme::kCenc);
313 InitializeAndExpectResult(config, false);
316 // Test normal decrypt and decode case.
317 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) {
319 EnterNormalDecodingState();
322 // Test the case where the decryptor returns error when doing decrypt and
324 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) {
327 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
329 RunOnceCallback<1>(Decryptor::kError, Decryptor::AudioFrames()));
331 DecodeAndExpect(encrypted_buffer_, DecodeStatus::DECODE_ERROR);
334 // Test the case where the decryptor returns multiple decoded frames.
335 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) {
338 scoped_refptr<AudioBuffer> frame_a = AudioBuffer::CreateEmptyBuffer(
339 config_.channel_layout(),
340 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
341 kFakeAudioFrameSize, kNoTimestamp);
342 scoped_refptr<AudioBuffer> frame_b = AudioBuffer::CreateEmptyBuffer(
343 config_.channel_layout(),
344 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
345 kFakeAudioFrameSize, kNoTimestamp);
346 decoded_frame_list_.push_back(frame_a);
347 decoded_frame_list_.push_back(frame_b);
349 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
350 .WillOnce(RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
352 EXPECT_CALL(*this, FrameReady(decoded_frame_));
353 EXPECT_CALL(*this, FrameReady(frame_a));
354 EXPECT_CALL(*this, FrameReady(frame_b));
355 DecodeAndExpect(encrypted_buffer_, DecodeStatus::OK);
358 // Test the case where the decryptor receives end-of-stream buffer.
359 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) {
361 EnterNormalDecodingState();
362 EnterEndOfStreamState();
365 // Test reinitializing decode with a new encrypted config.
366 TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToEncrypted) {
369 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
371 .WillOnce(RunOnceCallback<1>(true));
373 // The new config is different from the initial config in bits-per-channel,
374 // channel layout and samples_per_second.
375 AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16,
376 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
377 EncryptionScheme::kCenc);
378 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
379 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
380 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
381 ASSERT_TRUE(new_config.is_encrypted());
383 ReinitializeConfigChange(new_config);
384 base::RunLoop().RunUntilIdle();
387 // Test reinitializing decode with a new clear config.
388 TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToClear) {
391 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
393 .WillOnce(RunOnceCallback<1>(true));
395 // The new config is different from the initial config in bits-per-channel,
396 // channel layout and samples_per_second.
397 AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16,
398 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
399 EncryptionScheme::kUnencrypted);
400 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
401 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
402 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
403 ASSERT_FALSE(new_config.is_encrypted());
405 ReinitializeConfigChange(new_config);
406 base::RunLoop().RunUntilIdle();
409 // Test the case where the a key is added when the decryptor is in
410 // kWaitingForKey state.
411 TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) {
413 EnterWaitingForKeyState();
415 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
417 RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
418 EXPECT_CALL(*this, FrameReady(decoded_frame_));
419 EXPECT_CALL(*this, DecodeDone(IsOkStatus()));
420 event_cb_.Run(CdmContext::Event::kHasAdditionalUsableKey);
421 base::RunLoop().RunUntilIdle();
424 // Test the case where the a key is added when the decryptor is in
425 // kPendingDecode state.
426 TEST_F(DecryptingAudioDecoderTest, KeyAdded_DruingPendingDecode) {
428 EnterPendingDecodeState();
430 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
432 RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
433 EXPECT_CALL(*this, FrameReady(decoded_frame_));
434 EXPECT_CALL(*this, DecodeDone(IsOkStatus()));
435 // The audio decode callback is returned after the correct decryption key is
437 event_cb_.Run(CdmContext::Event::kHasAdditionalUsableKey);
438 std::move(pending_audio_decode_cb_)
439 .Run(Decryptor::kNoKey, Decryptor::AudioFrames());
440 base::RunLoop().RunUntilIdle();
443 // Test resetting when the decoder is in kIdle state but has not decoded any
445 TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) {
450 // Test resetting when the decoder is in kIdle state after it has decoded one
452 TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
454 EnterNormalDecodingState();
458 // Test resetting when the decoder is in kPendingDecode state.
459 TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) {
461 EnterPendingDecodeState();
463 EXPECT_CALL(*this, DecodeDone(HasStatusCode(StatusCode::kAborted)));
468 // Test resetting when the decoder is in kWaitingForKey state.
469 TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) {
471 EnterWaitingForKeyState();
473 EXPECT_CALL(*this, DecodeDone(HasStatusCode(StatusCode::kAborted)));
478 // Test resetting when the decoder has hit end of stream and is in
479 // kDecodeFinished state.
480 TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) {
482 EnterNormalDecodingState();
483 EnterEndOfStreamState();
487 // Test resetting after the decoder has been reset.
488 TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) {
490 EnterNormalDecodingState();