1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/filters/decrypting_audio_decoder.h"
12 #include "base/bind.h"
13 #include "base/callback_helpers.h"
14 #include "base/run_loop.h"
15 #include "base/test/gmock_callback_support.h"
16 #include "base/test/gmock_move_support.h"
17 #include "base/test/task_environment.h"
18 #include "media/base/audio_buffer.h"
19 #include "media/base/decoder_buffer.h"
20 #include "media/base/decrypt_config.h"
21 #include "media/base/media_util.h"
22 #include "media/base/mock_filters.h"
23 #include "media/base/test_helpers.h"
24 #include "media/base/timestamp_constants.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 std::size(kFakeKeyId)),
51 std::string(reinterpret_cast<const char*>(kFakeIv), std::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(const DecryptingAudioDecoderTest&) = delete;
71 DecryptingAudioDecoderTest& operator=(const DecryptingAudioDecoderTest&) =
74 ~DecryptingAudioDecoderTest() override { Destroy(); }
76 void InitializeAndExpectResult(const AudioDecoderConfig& config,
78 // Initialize data now that the config is known. Since the code uses
79 // invalid values (that CreateEmptyBuffer() doesn't support), tweak them
80 // just for CreateEmptyBuffer().
81 int channels = ChannelLayoutToChannelCount(config.channel_layout());
84 decoded_frame_ = AudioBuffer::CreateEmptyBuffer(
85 config.channel_layout(), channels, kSampleRate, kFakeAudioFrameSize,
87 decoded_frame_list_.push_back(decoded_frame_);
90 config, cdm_context_.get(),
92 [](bool success, DecoderStatus status) {
93 EXPECT_EQ(status.is_ok(), success);
96 base::BindRepeating(&DecryptingAudioDecoderTest::FrameReady,
97 base::Unretained(this)),
98 base::BindRepeating(&DecryptingAudioDecoderTest::OnWaiting,
99 base::Unretained(this)));
100 base::RunLoop().RunUntilIdle();
103 enum CdmType { CDM_WITHOUT_DECRYPTOR, CDM_WITH_DECRYPTOR };
105 void SetCdmType(CdmType cdm_type) {
106 const bool has_decryptor = cdm_type == CDM_WITH_DECRYPTOR;
107 EXPECT_CALL(*cdm_context_, GetDecryptor())
108 .WillRepeatedly(Return(has_decryptor ? decryptor_.get() : nullptr));
112 SetCdmType(CDM_WITH_DECRYPTOR);
113 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
115 .WillOnce(RunOnceCallback<1>(true));
116 EXPECT_CALL(*cdm_context_, RegisterEventCB(_)).WillOnce([&](auto cb) {
118 return std::make_unique<CallbackRegistration>();
121 config_.Initialize(AudioCodec::kVorbis, kSampleFormatPlanarF32,
122 CHANNEL_LAYOUT_STEREO, kSampleRate, EmptyExtraData(),
123 EncryptionScheme::kCenc, base::TimeDelta(), 0);
124 InitializeAndExpectResult(config_, true);
127 void Reinitialize() { ReinitializeConfigChange(config_); }
129 void ReinitializeConfigChange(const AudioDecoderConfig& new_config) {
130 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
131 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
132 .WillOnce(RunOnceCallback<1>(true));
133 decoder_->Initialize(
134 new_config, cdm_context_.get(),
136 [](DecoderStatus status) { EXPECT_TRUE(status.is_ok()); }),
137 base::BindRepeating(&DecryptingAudioDecoderTest::FrameReady,
138 base::Unretained(this)),
139 base::BindRepeating(&DecryptingAudioDecoderTest::OnWaiting,
140 base::Unretained(this)));
143 // Decode |buffer| and expect DecodeDone to get called with |status|.
144 void DecodeAndExpect(scoped_refptr<DecoderBuffer> buffer,
145 DecoderStatus status) {
146 EXPECT_CALL(*this, DecodeDone(HasStatusCode(status)));
147 decoder_->Decode(buffer,
148 base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
149 base::Unretained(this)));
150 base::RunLoop().RunUntilIdle();
153 // Helper function to simulate the decrypting and decoding process in the
154 // |decryptor_| with a decoding delay of kDecodingDelay buffers.
155 void DecryptAndDecodeAudio(scoped_refptr<DecoderBuffer> encrypted,
156 Decryptor::AudioDecodeCB audio_decode_cb) {
157 num_decrypt_and_decode_calls_++;
158 if (!encrypted->end_of_stream())
159 num_frames_in_decryptor_++;
161 if (num_decrypt_and_decode_calls_ <= kDecodingDelay ||
162 num_frames_in_decryptor_ == 0) {
163 std::move(audio_decode_cb)
164 .Run(Decryptor::kNeedMoreData, Decryptor::AudioFrames());
168 num_frames_in_decryptor_--;
169 std::move(audio_decode_cb)
170 .Run(Decryptor::kSuccess, Decryptor::AudioFrames(1, decoded_frame_));
173 // Sets up expectations and actions to put DecryptingAudioDecoder in an
174 // active normal decoding state.
175 void EnterNormalDecodingState() {
176 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
178 Invoke(this, &DecryptingAudioDecoderTest::DecryptAndDecodeAudio));
179 EXPECT_CALL(*this, FrameReady(decoded_frame_));
180 for (int i = 0; i < kDecodingDelay + 1; ++i)
181 DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kOk);
184 // Sets up expectations and actions to put DecryptingAudioDecoder in an end
185 // of stream state. This function must be called after
186 // EnterNormalDecodingState() to work.
187 void EnterEndOfStreamState() {
188 // The codec in the |decryptor_| will be flushed.
189 EXPECT_CALL(*this, FrameReady(decoded_frame_)).Times(kDecodingDelay);
190 DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(),
191 DecoderStatus::Codes::kOk);
192 EXPECT_EQ(0, num_frames_in_decryptor_);
195 // Make the audio decode callback pending by saving and not firing it.
196 void EnterPendingDecodeState() {
197 EXPECT_TRUE(!pending_audio_decode_cb_);
198 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
199 .WillOnce(MoveArg<1>(&pending_audio_decode_cb_));
201 decoder_->Decode(encrypted_buffer_,
202 base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
203 base::Unretained(this)));
204 base::RunLoop().RunUntilIdle();
205 // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
207 EXPECT_FALSE(!pending_audio_decode_cb_);
210 void EnterWaitingForKeyState() {
211 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
213 RunOnceCallback<1>(Decryptor::kNoKey, Decryptor::AudioFrames()));
214 EXPECT_CALL(*this, OnWaiting(WaitingReason::kNoDecryptionKey));
215 decoder_->Decode(encrypted_buffer_,
216 base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
217 base::Unretained(this)));
219 base::RunLoop().RunUntilIdle();
222 void AbortPendingAudioDecodeCB() {
223 if (pending_audio_decode_cb_) {
224 std::move(pending_audio_decode_cb_)
225 .Run(Decryptor::kSuccess, Decryptor::AudioFrames());
229 void AbortAllPendingCBs() {
230 if (pending_init_cb_) {
231 ASSERT_TRUE(!pending_audio_decode_cb_);
232 std::move(pending_init_cb_).Run(false);
236 AbortPendingAudioDecodeCB();
240 EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio))
241 .WillRepeatedly(InvokeWithoutArgs(
242 this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB));
244 decoder_->Reset(NewExpectedClosure());
245 base::RunLoop().RunUntilIdle();
249 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio))
250 .WillRepeatedly(InvokeWithoutArgs(
251 this, &DecryptingAudioDecoderTest::AbortAllPendingCBs));
254 base::RunLoop().RunUntilIdle();
257 MOCK_METHOD1(FrameReady, void(scoped_refptr<AudioBuffer>));
258 MOCK_METHOD1(DecodeDone, void(DecoderStatus));
260 MOCK_METHOD1(OnWaiting, void(WaitingReason));
262 base::test::SingleThreadTaskEnvironment task_environment_;
263 NullMediaLog media_log_;
264 std::unique_ptr<DecryptingAudioDecoder> decoder_;
265 std::unique_ptr<StrictMock<MockCdmContext>> cdm_context_;
266 std::unique_ptr<StrictMock<MockDecryptor>> decryptor_;
267 AudioDecoderConfig config_;
269 // Variables to help the |decryptor_| to simulate decoding delay and flushing.
270 int num_decrypt_and_decode_calls_;
271 int num_frames_in_decryptor_;
273 Decryptor::DecoderInitCB pending_init_cb_;
274 CdmContext::EventCB event_cb_;
275 Decryptor::AudioDecodeCB pending_audio_decode_cb_;
277 // Constant buffer/frames, to be used/returned by |decoder_| and |decryptor_|.
278 scoped_refptr<DecoderBuffer> encrypted_buffer_;
279 scoped_refptr<AudioBuffer> decoded_frame_;
280 Decryptor::AudioFrames decoded_frame_list_;
283 TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) {
287 // Ensure decoder handles invalid audio configs without crashing.
288 TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) {
289 AudioDecoderConfig config(AudioCodec::kUnknown, kUnknownSampleFormat,
290 CHANNEL_LAYOUT_STEREO, 0, EmptyExtraData(),
291 EncryptionScheme::kCenc);
293 InitializeAndExpectResult(config, false);
296 // Ensure decoder handles unsupported audio configs without crashing.
297 TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) {
298 SetCdmType(CDM_WITH_DECRYPTOR);
299 EXPECT_CALL(*cdm_context_, RegisterEventCB(_)).WillOnce([&](auto cb) {
301 return std::make_unique<CallbackRegistration>();
303 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
304 .WillOnce(RunOnceCallback<1>(false));
306 AudioDecoderConfig config(AudioCodec::kVorbis, kSampleFormatPlanarF32,
307 CHANNEL_LAYOUT_STEREO, kSampleRate,
308 EmptyExtraData(), EncryptionScheme::kCenc);
309 InitializeAndExpectResult(config, false);
312 TEST_F(DecryptingAudioDecoderTest, Initialize_CdmWithoutDecryptor) {
313 SetCdmType(CDM_WITHOUT_DECRYPTOR);
314 AudioDecoderConfig config(AudioCodec::kVorbis, kSampleFormatPlanarF32,
315 CHANNEL_LAYOUT_STEREO, kSampleRate,
316 EmptyExtraData(), EncryptionScheme::kCenc);
317 InitializeAndExpectResult(config, false);
320 // Test normal decrypt and decode case.
321 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) {
323 EnterNormalDecodingState();
326 // Test the case where the decryptor returns error when doing decrypt and
328 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) {
331 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
333 RunOnceCallback<1>(Decryptor::kError, Decryptor::AudioFrames()));
335 DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kFailed);
338 // Test the case where the decryptor returns multiple decoded frames.
339 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) {
342 scoped_refptr<AudioBuffer> frame_a = AudioBuffer::CreateEmptyBuffer(
343 config_.channel_layout(),
344 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
345 kFakeAudioFrameSize, kNoTimestamp);
346 scoped_refptr<AudioBuffer> frame_b = AudioBuffer::CreateEmptyBuffer(
347 config_.channel_layout(),
348 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
349 kFakeAudioFrameSize, kNoTimestamp);
350 decoded_frame_list_.push_back(frame_a);
351 decoded_frame_list_.push_back(frame_b);
353 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
354 .WillOnce(RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
356 EXPECT_CALL(*this, FrameReady(decoded_frame_));
357 EXPECT_CALL(*this, FrameReady(frame_a));
358 EXPECT_CALL(*this, FrameReady(frame_b));
359 DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kOk);
362 // Test the case where the decryptor receives end-of-stream buffer.
363 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) {
365 EnterNormalDecodingState();
366 EnterEndOfStreamState();
369 // Test reinitializing decode with a new encrypted config.
370 TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToEncrypted) {
373 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
375 .WillOnce(RunOnceCallback<1>(true));
377 // The new config is different from the initial config in bits-per-channel,
378 // channel layout and samples_per_second.
379 AudioDecoderConfig new_config(AudioCodec::kVorbis, kSampleFormatPlanarS16,
380 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
381 EncryptionScheme::kCenc);
382 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
383 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
384 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
385 ASSERT_TRUE(new_config.is_encrypted());
387 ReinitializeConfigChange(new_config);
388 base::RunLoop().RunUntilIdle();
391 // Test reinitializing decode with a new clear config.
392 TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToClear) {
395 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
397 .WillOnce(RunOnceCallback<1>(true));
399 // The new config is different from the initial config in bits-per-channel,
400 // channel layout and samples_per_second.
401 AudioDecoderConfig new_config(AudioCodec::kVorbis, kSampleFormatPlanarS16,
402 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
403 EncryptionScheme::kUnencrypted);
404 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
405 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
406 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
407 ASSERT_FALSE(new_config.is_encrypted());
409 ReinitializeConfigChange(new_config);
410 base::RunLoop().RunUntilIdle();
413 // Test the case where the a key is added when the decryptor is in
414 // kWaitingForKey state.
415 TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) {
417 EnterWaitingForKeyState();
419 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
421 RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
422 EXPECT_CALL(*this, FrameReady(decoded_frame_));
423 EXPECT_CALL(*this, DecodeDone(IsOkStatus()));
424 event_cb_.Run(CdmContext::Event::kHasAdditionalUsableKey);
425 base::RunLoop().RunUntilIdle();
428 // Test the case where the a key is added when the decryptor is in
429 // kPendingDecode state.
430 TEST_F(DecryptingAudioDecoderTest, KeyAdded_DruingPendingDecode) {
432 EnterPendingDecodeState();
434 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
436 RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
437 EXPECT_CALL(*this, FrameReady(decoded_frame_));
438 EXPECT_CALL(*this, DecodeDone(IsOkStatus()));
439 // The audio decode callback is returned after the correct decryption key is
441 event_cb_.Run(CdmContext::Event::kHasAdditionalUsableKey);
442 std::move(pending_audio_decode_cb_)
443 .Run(Decryptor::kNoKey, Decryptor::AudioFrames());
444 base::RunLoop().RunUntilIdle();
447 // Test resetting when the decoder is in kIdle state but has not decoded any
449 TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) {
454 // Test resetting when the decoder is in kIdle state after it has decoded one
456 TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
458 EnterNormalDecodingState();
462 // Test resetting when the decoder is in kPendingDecode state.
463 TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) {
465 EnterPendingDecodeState();
467 EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted)));
472 // Test resetting when the decoder is in kWaitingForKey state.
473 TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) {
475 EnterWaitingForKeyState();
477 EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted)));
482 // Test resetting when the decoder has hit end of stream and is in
483 // kDecodeFinished state.
484 TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) {
486 EnterNormalDecodingState();
487 EnterEndOfStreamState();
491 // Test resetting after the decoder has been reset.
492 TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) {
494 EnterNormalDecodingState();