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/functional/bind.h"
13 #include "base/functional/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/mock_media_log.h"
24 #include "media/base/test_helpers.h"
25 #include "media/base/timestamp_constants.h"
26 #include "testing/gmock/include/gmock/gmock.h"
28 using ::base::test::RunOnceCallback;
30 using ::testing::AtMost;
31 using ::testing::HasSubstr;
32 using ::testing::Return;
33 using ::testing::StrictMock;
37 const int kSampleRate = 44100;
39 // Make sure the kFakeAudioFrameSize is a valid frame size for all audio decoder
40 // configs used in this test.
41 const int kFakeAudioFrameSize = 48;
42 const int kDecodingDelay = 3;
44 class DecryptingAudioDecoderTest : public testing::Test {
46 DecryptingAudioDecoderTest()
47 : decoder_(std::make_unique<DecryptingAudioDecoder>(
48 task_environment_.GetMainThreadTaskRunner(),
50 cdm_context_(std::make_unique<StrictMock<MockCdmContext>>()),
51 decryptor_(std::make_unique<StrictMock<MockDecryptor>>()),
52 num_decrypt_and_decode_calls_(0),
53 num_frames_in_decryptor_(0),
54 encrypted_buffer_(CreateFakeEncryptedBuffer()),
55 decoded_frame_(nullptr),
56 decoded_frame_list_() {}
58 DecryptingAudioDecoderTest(const DecryptingAudioDecoderTest&) = delete;
59 DecryptingAudioDecoderTest& operator=(const DecryptingAudioDecoderTest&) =
62 ~DecryptingAudioDecoderTest() override { Destroy(); }
64 void InitializeAndExpectResult(const AudioDecoderConfig& config,
66 // Initialize data now that the config is known. Since the code uses
67 // invalid values (that CreateEmptyBuffer() doesn't support), tweak them
68 // just for CreateEmptyBuffer().
69 int channels = ChannelLayoutToChannelCount(config.channel_layout());
72 decoded_frame_ = AudioBuffer::CreateEmptyBuffer(
73 config.channel_layout(), channels, kSampleRate, kFakeAudioFrameSize,
75 decoded_frame_list_.push_back(decoded_frame_);
78 config, cdm_context_.get(),
80 [](bool success, DecoderStatus status) {
81 EXPECT_EQ(status.is_ok(), success);
84 base::BindRepeating(&DecryptingAudioDecoderTest::FrameReady,
85 base::Unretained(this)),
86 base::BindRepeating(&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(RunOnceCallback<1>(true));
104 EXPECT_CALL(*cdm_context_, RegisterEventCB(_)).WillOnce([&](auto cb) {
106 return std::make_unique<CallbackRegistration>();
109 config_.Initialize(AudioCodec::kVorbis, kSampleFormatPlanarF32,
110 CHANNEL_LAYOUT_STEREO, kSampleRate, EmptyExtraData(),
111 EncryptionScheme::kCenc, base::TimeDelta(), 0);
112 InitializeAndExpectResult(config_, true);
115 void Reinitialize() { ReinitializeConfigChange(config_); }
117 void ReinitializeConfigChange(const AudioDecoderConfig& new_config) {
118 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
119 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
120 .WillOnce(RunOnceCallback<1>(true));
121 decoder_->Initialize(
122 new_config, cdm_context_.get(),
124 [](DecoderStatus status) { EXPECT_TRUE(status.is_ok()); }),
125 base::BindRepeating(&DecryptingAudioDecoderTest::FrameReady,
126 base::Unretained(this)),
127 base::BindRepeating(&DecryptingAudioDecoderTest::OnWaiting,
128 base::Unretained(this)));
131 // Decode |buffer| and expect DecodeDone to get called with |status|.
132 void DecodeAndExpect(scoped_refptr<DecoderBuffer> buffer,
133 DecoderStatus status) {
134 EXPECT_CALL(*this, DecodeDone(HasStatusCode(status)));
135 decoder_->Decode(buffer,
136 base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
137 base::Unretained(this)));
138 base::RunLoop().RunUntilIdle();
141 // Helper function to simulate the decrypting and decoding process in the
142 // |decryptor_| with a decoding delay of kDecodingDelay buffers.
143 void DecryptAndDecodeAudio(scoped_refptr<DecoderBuffer> encrypted,
144 Decryptor::AudioDecodeCB audio_decode_cb) {
145 num_decrypt_and_decode_calls_++;
146 if (!encrypted->end_of_stream())
147 num_frames_in_decryptor_++;
149 if (num_decrypt_and_decode_calls_ <= kDecodingDelay ||
150 num_frames_in_decryptor_ == 0) {
151 std::move(audio_decode_cb)
152 .Run(Decryptor::kNeedMoreData, Decryptor::AudioFrames());
156 num_frames_in_decryptor_--;
157 std::move(audio_decode_cb)
158 .Run(Decryptor::kSuccess, Decryptor::AudioFrames(1, decoded_frame_));
161 // Sets up expectations and actions to put DecryptingAudioDecoder in an
162 // active normal decoding state.
163 void EnterNormalDecodingState() {
164 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
166 Invoke(this, &DecryptingAudioDecoderTest::DecryptAndDecodeAudio));
167 EXPECT_CALL(*this, FrameReady(decoded_frame_));
168 for (int i = 0; i < kDecodingDelay + 1; ++i)
169 DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kOk);
172 // Sets up expectations and actions to put DecryptingAudioDecoder in an end
173 // of stream state. This function must be called after
174 // EnterNormalDecodingState() to work.
175 void EnterEndOfStreamState() {
176 // The codec in the |decryptor_| will be flushed.
177 EXPECT_CALL(*this, FrameReady(decoded_frame_)).Times(kDecodingDelay);
178 DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(),
179 DecoderStatus::Codes::kOk);
180 EXPECT_EQ(0, num_frames_in_decryptor_);
183 // Make the audio decode callback pending by saving and not firing it.
184 void EnterPendingDecodeState() {
185 EXPECT_TRUE(!pending_audio_decode_cb_);
186 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
187 .WillOnce(MoveArg<1>(&pending_audio_decode_cb_));
189 decoder_->Decode(encrypted_buffer_,
190 base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
191 base::Unretained(this)));
192 base::RunLoop().RunUntilIdle();
193 // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
195 EXPECT_FALSE(!pending_audio_decode_cb_);
198 void EnterWaitingForKeyState() {
199 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
201 RunOnceCallback<1>(Decryptor::kNoKey, Decryptor::AudioFrames()));
202 EXPECT_CALL(*this, OnWaiting(WaitingReason::kNoDecryptionKey));
203 decoder_->Decode(encrypted_buffer_,
204 base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
205 base::Unretained(this)));
207 base::RunLoop().RunUntilIdle();
210 void AbortPendingAudioDecodeCB() {
211 if (pending_audio_decode_cb_) {
212 std::move(pending_audio_decode_cb_)
213 .Run(Decryptor::kSuccess, Decryptor::AudioFrames());
217 void AbortAllPendingCBs() {
218 if (pending_init_cb_) {
219 ASSERT_TRUE(!pending_audio_decode_cb_);
220 std::move(pending_init_cb_).Run(false);
224 AbortPendingAudioDecodeCB();
228 EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio))
229 .WillRepeatedly(InvokeWithoutArgs(
230 this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB));
232 decoder_->Reset(NewExpectedClosure());
233 base::RunLoop().RunUntilIdle();
237 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio))
238 .WillRepeatedly(InvokeWithoutArgs(
239 this, &DecryptingAudioDecoderTest::AbortAllPendingCBs));
242 base::RunLoop().RunUntilIdle();
245 MOCK_METHOD1(FrameReady, void(scoped_refptr<AudioBuffer>));
246 MOCK_METHOD1(DecodeDone, void(DecoderStatus));
248 MOCK_METHOD1(OnWaiting, void(WaitingReason));
250 base::test::SingleThreadTaskEnvironment task_environment_;
251 StrictMock<MockMediaLog> media_log_;
252 std::unique_ptr<DecryptingAudioDecoder> decoder_;
253 std::unique_ptr<StrictMock<MockCdmContext>> cdm_context_;
254 std::unique_ptr<StrictMock<MockDecryptor>> decryptor_;
255 AudioDecoderConfig config_;
257 // Variables to help the |decryptor_| to simulate decoding delay and flushing.
258 int num_decrypt_and_decode_calls_;
259 int num_frames_in_decryptor_;
261 Decryptor::DecoderInitCB pending_init_cb_;
262 CdmContext::EventCB event_cb_;
263 Decryptor::AudioDecodeCB pending_audio_decode_cb_;
265 // Constant buffer/frames, to be used/returned by |decoder_| and |decryptor_|.
266 scoped_refptr<DecoderBuffer> encrypted_buffer_;
267 scoped_refptr<AudioBuffer> decoded_frame_;
268 Decryptor::AudioFrames decoded_frame_list_;
271 TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) {
275 // Ensure decoder handles invalid audio configs without crashing.
276 TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) {
277 AudioDecoderConfig config(AudioCodec::kUnknown, kUnknownSampleFormat,
278 CHANNEL_LAYOUT_STEREO, 0, EmptyExtraData(),
279 EncryptionScheme::kCenc);
281 InitializeAndExpectResult(config, false);
284 // Ensure decoder handles unsupported audio configs without crashing.
285 TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) {
286 SetCdmType(CDM_WITH_DECRYPTOR);
287 EXPECT_CALL(*cdm_context_, RegisterEventCB(_)).WillOnce([&](auto cb) {
289 return std::make_unique<CallbackRegistration>();
291 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
292 .WillOnce(RunOnceCallback<1>(false));
294 AudioDecoderConfig config(AudioCodec::kVorbis, kSampleFormatPlanarF32,
295 CHANNEL_LAYOUT_STEREO, kSampleRate,
296 EmptyExtraData(), EncryptionScheme::kCenc);
297 InitializeAndExpectResult(config, false);
300 TEST_F(DecryptingAudioDecoderTest, Initialize_CdmWithoutDecryptor) {
301 SetCdmType(CDM_WITHOUT_DECRYPTOR);
302 AudioDecoderConfig config(AudioCodec::kVorbis, kSampleFormatPlanarF32,
303 CHANNEL_LAYOUT_STEREO, kSampleRate,
304 EmptyExtraData(), EncryptionScheme::kCenc);
305 InitializeAndExpectResult(config, false);
308 // Test normal decrypt and decode case.
309 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) {
311 EnterNormalDecodingState();
314 // Test the case where the decryptor errors for mismatched subsamples
315 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_SubsampleError) {
318 scoped_refptr<media::DecoderBuffer> mismatched_encrypted_buffer =
319 CreateMismatchedBufferForTest();
321 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
323 RunOnceCallback<1>(Decryptor::kError, Decryptor::AudioFrames()));
325 HasSubstr("DecryptingAudioDecoder: Subsamples for Buffer do not match"));
327 DecodeAndExpect(mismatched_encrypted_buffer, DecoderStatus::Codes::kFailed);
330 // Test the case where the decryptor returns error when doing decrypt and
332 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) {
335 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
337 RunOnceCallback<1>(Decryptor::kError, Decryptor::AudioFrames()));
338 EXPECT_MEDIA_LOG(HasSubstr("DecryptingAudioDecoder: decode error"));
340 DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kFailed);
343 // Test the case where the decryptor returns multiple decoded frames.
344 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) {
347 scoped_refptr<AudioBuffer> frame_a = AudioBuffer::CreateEmptyBuffer(
348 config_.channel_layout(),
349 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
350 kFakeAudioFrameSize, kNoTimestamp);
351 scoped_refptr<AudioBuffer> frame_b = AudioBuffer::CreateEmptyBuffer(
352 config_.channel_layout(),
353 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
354 kFakeAudioFrameSize, kNoTimestamp);
355 decoded_frame_list_.push_back(frame_a);
356 decoded_frame_list_.push_back(frame_b);
358 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
359 .WillOnce(RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
361 EXPECT_CALL(*this, FrameReady(decoded_frame_));
362 EXPECT_CALL(*this, FrameReady(frame_a));
363 EXPECT_CALL(*this, FrameReady(frame_b));
364 DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kOk);
367 // Test the case where the decryptor receives end-of-stream buffer.
368 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) {
370 EnterNormalDecodingState();
371 EnterEndOfStreamState();
374 // Test reinitializing decode with a new encrypted config.
375 TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToEncrypted) {
378 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
380 .WillOnce(RunOnceCallback<1>(true));
382 // The new config is different from the initial config in bytes-per-channel,
383 // channel layout and samples_per_second.
384 AudioDecoderConfig new_config(AudioCodec::kVorbis, kSampleFormatPlanarS16,
385 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
386 EncryptionScheme::kCenc);
387 EXPECT_NE(new_config.bytes_per_channel(), config_.bytes_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_TRUE(new_config.is_encrypted());
392 ReinitializeConfigChange(new_config);
393 base::RunLoop().RunUntilIdle();
396 // Test reinitializing decode with a new clear config.
397 TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToClear) {
400 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
402 .WillOnce(RunOnceCallback<1>(true));
404 // The new config is different from the initial config in bytes-per-channel,
405 // channel layout and samples_per_second.
406 AudioDecoderConfig new_config(AudioCodec::kVorbis, kSampleFormatPlanarS16,
407 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
408 EncryptionScheme::kUnencrypted);
409 EXPECT_NE(new_config.bytes_per_channel(), config_.bytes_per_channel());
410 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
411 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
412 ASSERT_FALSE(new_config.is_encrypted());
414 ReinitializeConfigChange(new_config);
415 base::RunLoop().RunUntilIdle();
418 // Test the case where the a key is added when the decryptor is in
419 // kWaitingForKey state.
420 TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) {
422 EXPECT_MEDIA_LOG(HasSubstr("DecryptingAudioDecoder: no key for key"));
423 EnterWaitingForKeyState();
425 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
427 RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
428 EXPECT_CALL(*this, FrameReady(decoded_frame_));
429 EXPECT_CALL(*this, DecodeDone(IsOkStatus()));
431 HasSubstr("DecryptingAudioDecoder: key added, resuming decode"));
432 event_cb_.Run(CdmContext::Event::kHasAdditionalUsableKey);
433 base::RunLoop().RunUntilIdle();
436 // Test the case where the a key is added when the decryptor is in
437 // kPendingDecode state.
438 TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringPendingDecode) {
440 EXPECT_MEDIA_LOG(HasSubstr("DecryptingAudioDecoder: no key for key"));
441 EnterPendingDecodeState();
443 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
445 RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
446 EXPECT_CALL(*this, FrameReady(decoded_frame_));
447 EXPECT_CALL(*this, DecodeDone(IsOkStatus()));
449 HasSubstr("DecryptingAudioDecoder: key was added, resuming decode"));
450 // The audio decode callback is returned after the correct decryption key is
452 event_cb_.Run(CdmContext::Event::kHasAdditionalUsableKey);
453 std::move(pending_audio_decode_cb_)
454 .Run(Decryptor::kNoKey, Decryptor::AudioFrames());
455 base::RunLoop().RunUntilIdle();
458 // Test resetting when the decoder is in kIdle state but has not decoded any
460 TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) {
465 // Test resetting when the decoder is in kIdle state after it has decoded one
467 TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
469 EnterNormalDecodingState();
473 // Test resetting when the decoder is in kPendingDecode state.
474 TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) {
476 EnterPendingDecodeState();
478 EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted)));
483 // Test resetting when the decoder is in kWaitingForKey state.
484 TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) {
486 EXPECT_MEDIA_LOG(HasSubstr("DecryptingAudioDecoder: no key for key"));
487 EnterWaitingForKeyState();
489 EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted)));
494 // Test resetting when the decoder has hit end of stream and is in
495 // kDecodeFinished state.
496 TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) {
498 EnterNormalDecodingState();
499 EnterEndOfStreamState();
503 // Test resetting after the decoder has been reset.
504 TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) {
506 EnterNormalDecodingState();