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/run_loop.h"
13 #include "base/stl_util.h"
14 #include "base/test/gmock_callback_support.h"
15 #include "base/test/task_environment.h"
16 #include "media/base/audio_buffer.h"
17 #include "media/base/decoder_buffer.h"
18 #include "media/base/decrypt_config.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"
26 using ::base::test::RunCallback;
27 using ::base::test::RunOnceCallback;
29 using ::testing::AtMost;
30 using ::testing::Return;
31 using ::testing::SaveArg;
32 using ::testing::StrictMock;
36 const int kSampleRate = 44100;
38 // Make sure the kFakeAudioFrameSize is a valid frame size for all audio decoder
39 // configs used in this test.
40 const int kFakeAudioFrameSize = 48;
41 const uint8_t kFakeKeyId[] = {0x4b, 0x65, 0x79, 0x20, 0x49, 0x44};
42 const uint8_t kFakeIv[DecryptConfig::kDecryptionKeySize] = {0};
43 const int kDecodingDelay = 3;
45 // Create a fake non-empty encrypted buffer.
46 static scoped_refptr<DecoderBuffer> CreateFakeEncryptedBuffer() {
47 const int buffer_size = 16; // Need a non-empty buffer;
48 scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(buffer_size));
49 buffer->set_decrypt_config(DecryptConfig::CreateCencConfig(
50 std::string(reinterpret_cast<const char*>(kFakeKeyId),
51 base::size(kFakeKeyId)),
52 std::string(reinterpret_cast<const char*>(kFakeIv), base::size(kFakeIv)),
53 std::vector<SubsampleEntry>()));
57 class DecryptingAudioDecoderTest : public testing::Test {
59 DecryptingAudioDecoderTest()
60 : decoder_(new DecryptingAudioDecoder(
61 task_environment_.GetMainThreadTaskRunner(),
63 cdm_context_(new StrictMock<MockCdmContext>()),
64 decryptor_(new StrictMock<MockDecryptor>()),
65 num_decrypt_and_decode_calls_(0),
66 num_frames_in_decryptor_(0),
67 encrypted_buffer_(CreateFakeEncryptedBuffer()),
68 decoded_frame_(nullptr),
69 decoded_frame_list_() {}
71 ~DecryptingAudioDecoderTest() override { Destroy(); }
73 void InitializeAndExpectResult(const AudioDecoderConfig& config,
75 // Initialize data now that the config is known. Since the code uses
76 // invalid values (that CreateEmptyBuffer() doesn't support), tweak them
77 // just for CreateEmptyBuffer().
78 int channels = ChannelLayoutToChannelCount(config.channel_layout());
81 decoded_frame_ = AudioBuffer::CreateEmptyBuffer(
82 config.channel_layout(), channels, kSampleRate, kFakeAudioFrameSize,
84 decoded_frame_list_.push_back(decoded_frame_);
86 decoder_->Initialize(config, cdm_context_.get(),
88 [](bool success, Status status) {
89 EXPECT_EQ(status.is_ok(), success);
92 base::Bind(&DecryptingAudioDecoderTest::FrameReady,
93 base::Unretained(this)),
94 base::Bind(&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(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
113 .WillOnce(SaveArg<1>(&key_added_cb_));
115 config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32,
116 CHANNEL_LAYOUT_STEREO, kSampleRate, EmptyExtraData(),
117 EncryptionScheme::kCenc, base::TimeDelta(), 0);
118 InitializeAndExpectResult(config_, true);
121 void Reinitialize() { ReinitializeConfigChange(config_); }
123 void ReinitializeConfigChange(const AudioDecoderConfig& new_config) {
124 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
125 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
126 .WillOnce(RunOnceCallback<1>(true));
127 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
128 .WillOnce(SaveArg<1>(&key_added_cb_));
129 decoder_->Initialize(
130 new_config, cdm_context_.get(),
131 base::BindOnce([](Status status) { EXPECT_TRUE(status.is_ok()); }),
132 base::Bind(&DecryptingAudioDecoderTest::FrameReady,
133 base::Unretained(this)),
134 base::Bind(&DecryptingAudioDecoderTest::OnWaiting,
135 base::Unretained(this)));
138 // Decode |buffer| and expect DecodeDone to get called with |status|.
139 void DecodeAndExpect(scoped_refptr<DecoderBuffer> buffer,
140 DecodeStatus status) {
141 EXPECT_CALL(*this, DecodeDone(status));
142 decoder_->Decode(buffer, base::Bind(&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 const 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 audio_decode_cb.Run(Decryptor::kNeedMoreData, Decryptor::AudioFrames());
161 num_frames_in_decryptor_--;
162 audio_decode_cb.Run(Decryptor::kSuccess,
163 Decryptor::AudioFrames(1, decoded_frame_));
166 // Sets up expectations and actions to put DecryptingAudioDecoder in an
167 // active normal decoding state.
168 void EnterNormalDecodingState() {
169 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
171 Invoke(this, &DecryptingAudioDecoderTest::DecryptAndDecodeAudio));
172 EXPECT_CALL(*this, FrameReady(decoded_frame_));
173 for (int i = 0; i < kDecodingDelay + 1; ++i)
174 DecodeAndExpect(encrypted_buffer_, DecodeStatus::OK);
177 // Sets up expectations and actions to put DecryptingAudioDecoder in an end
178 // of stream state. This function must be called after
179 // EnterNormalDecodingState() to work.
180 void EnterEndOfStreamState() {
181 // The codec in the |decryptor_| will be flushed.
182 EXPECT_CALL(*this, FrameReady(decoded_frame_)).Times(kDecodingDelay);
183 DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(), DecodeStatus::OK);
184 EXPECT_EQ(0, num_frames_in_decryptor_);
187 // Make the audio decode callback pending by saving and not firing it.
188 void EnterPendingDecodeState() {
189 EXPECT_TRUE(!pending_audio_decode_cb_);
190 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
191 .WillOnce(SaveArg<1>(&pending_audio_decode_cb_));
193 decoder_->Decode(encrypted_buffer_,
194 base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
195 base::Unretained(this)));
196 base::RunLoop().RunUntilIdle();
197 // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
199 EXPECT_FALSE(!pending_audio_decode_cb_);
202 void EnterWaitingForKeyState() {
203 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
205 RunCallback<1>(Decryptor::kNoKey, Decryptor::AudioFrames()));
206 EXPECT_CALL(*this, OnWaiting(WaitingReason::kNoDecryptionKey));
207 decoder_->Decode(encrypted_buffer_,
208 base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
209 base::Unretained(this)));
211 base::RunLoop().RunUntilIdle();
214 void AbortPendingAudioDecodeCB() {
215 if (pending_audio_decode_cb_) {
216 std::move(pending_audio_decode_cb_)
217 .Run(Decryptor::kSuccess, Decryptor::AudioFrames());
221 void AbortAllPendingCBs() {
222 if (pending_init_cb_) {
223 ASSERT_TRUE(!pending_audio_decode_cb_);
224 std::move(pending_init_cb_).Run(false);
228 AbortPendingAudioDecodeCB();
232 EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio))
233 .WillRepeatedly(InvokeWithoutArgs(
234 this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB));
236 decoder_->Reset(NewExpectedClosure());
237 base::RunLoop().RunUntilIdle();
241 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio))
242 .WillRepeatedly(InvokeWithoutArgs(
243 this, &DecryptingAudioDecoderTest::AbortAllPendingCBs));
246 base::RunLoop().RunUntilIdle();
249 MOCK_METHOD1(FrameReady, void(scoped_refptr<AudioBuffer>));
250 MOCK_METHOD1(DecodeDone, void(DecodeStatus));
252 MOCK_METHOD1(OnWaiting, void(WaitingReason));
254 base::test::SingleThreadTaskEnvironment task_environment_;
255 NullMediaLog media_log_;
256 std::unique_ptr<DecryptingAudioDecoder> decoder_;
257 std::unique_ptr<StrictMock<MockCdmContext>> cdm_context_;
258 std::unique_ptr<StrictMock<MockDecryptor>> decryptor_;
259 AudioDecoderConfig config_;
261 // Variables to help the |decryptor_| to simulate decoding delay and flushing.
262 int num_decrypt_and_decode_calls_;
263 int num_frames_in_decryptor_;
265 Decryptor::DecoderInitCB pending_init_cb_;
266 Decryptor::NewKeyCB key_added_cb_;
267 Decryptor::AudioDecodeCB pending_audio_decode_cb_;
269 // Constant buffer/frames, to be used/returned by |decoder_| and |decryptor_|.
270 scoped_refptr<DecoderBuffer> encrypted_buffer_;
271 scoped_refptr<AudioBuffer> decoded_frame_;
272 Decryptor::AudioFrames decoded_frame_list_;
275 DISALLOW_COPY_AND_ASSIGN(DecryptingAudioDecoderTest);
278 TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) {
282 // Ensure decoder handles invalid audio configs without crashing.
283 TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) {
284 AudioDecoderConfig config(kUnknownAudioCodec, kUnknownSampleFormat,
285 CHANNEL_LAYOUT_STEREO, 0, EmptyExtraData(),
286 EncryptionScheme::kCenc);
288 InitializeAndExpectResult(config, false);
291 // Ensure decoder handles unsupported audio configs without crashing.
292 TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) {
293 SetCdmType(CDM_WITH_DECRYPTOR);
294 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
295 .WillOnce(RunOnceCallback<1>(false));
297 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
298 CHANNEL_LAYOUT_STEREO, kSampleRate,
299 EmptyExtraData(), EncryptionScheme::kCenc);
300 InitializeAndExpectResult(config, false);
303 TEST_F(DecryptingAudioDecoderTest, Initialize_CdmWithoutDecryptor) {
304 SetCdmType(CDM_WITHOUT_DECRYPTOR);
305 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
306 CHANNEL_LAYOUT_STEREO, kSampleRate,
307 EmptyExtraData(), EncryptionScheme::kCenc);
308 InitializeAndExpectResult(config, false);
311 // Test normal decrypt and decode case.
312 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) {
314 EnterNormalDecodingState();
317 // Test the case where the decryptor returns error when doing decrypt and
319 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) {
322 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
324 RunCallback<1>(Decryptor::kError, Decryptor::AudioFrames()));
326 DecodeAndExpect(encrypted_buffer_, DecodeStatus::DECODE_ERROR);
329 // Test the case where the decryptor returns multiple decoded frames.
330 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) {
333 scoped_refptr<AudioBuffer> frame_a = AudioBuffer::CreateEmptyBuffer(
334 config_.channel_layout(),
335 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
336 kFakeAudioFrameSize, kNoTimestamp);
337 scoped_refptr<AudioBuffer> frame_b = AudioBuffer::CreateEmptyBuffer(
338 config_.channel_layout(),
339 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
340 kFakeAudioFrameSize, kNoTimestamp);
341 decoded_frame_list_.push_back(frame_a);
342 decoded_frame_list_.push_back(frame_b);
344 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
345 .WillOnce(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
347 EXPECT_CALL(*this, FrameReady(decoded_frame_));
348 EXPECT_CALL(*this, FrameReady(frame_a));
349 EXPECT_CALL(*this, FrameReady(frame_b));
350 DecodeAndExpect(encrypted_buffer_, DecodeStatus::OK);
353 // Test the case where the decryptor receives end-of-stream buffer.
354 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) {
356 EnterNormalDecodingState();
357 EnterEndOfStreamState();
360 // Test reinitializing decode with a new encrypted config.
361 TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToEncrypted) {
364 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
366 .WillOnce(RunOnceCallback<1>(true));
368 // The new config is different from the initial config in bits-per-channel,
369 // channel layout and samples_per_second.
370 AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16,
371 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
372 EncryptionScheme::kCenc);
373 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
374 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
375 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
376 ASSERT_TRUE(new_config.is_encrypted());
378 ReinitializeConfigChange(new_config);
379 base::RunLoop().RunUntilIdle();
382 // Test reinitializing decode with a new clear config.
383 TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToClear) {
386 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
388 .WillOnce(RunOnceCallback<1>(true));
390 // The new config is different from the initial config in bits-per-channel,
391 // channel layout and samples_per_second.
392 AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16,
393 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
394 EncryptionScheme::kUnencrypted);
395 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
396 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
397 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
398 ASSERT_FALSE(new_config.is_encrypted());
400 ReinitializeConfigChange(new_config);
401 base::RunLoop().RunUntilIdle();
404 // Test the case where the a key is added when the decryptor is in
405 // kWaitingForKey state.
406 TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) {
408 EnterWaitingForKeyState();
410 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
411 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
412 EXPECT_CALL(*this, FrameReady(decoded_frame_));
413 EXPECT_CALL(*this, DecodeDone(DecodeStatus::OK));
415 base::RunLoop().RunUntilIdle();
418 // Test the case where the a key is added when the decryptor is in
419 // kPendingDecode state.
420 TEST_F(DecryptingAudioDecoderTest, KeyAdded_DruingPendingDecode) {
422 EnterPendingDecodeState();
424 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
425 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
426 EXPECT_CALL(*this, FrameReady(decoded_frame_));
427 EXPECT_CALL(*this, DecodeDone(DecodeStatus::OK));
428 // The audio decode callback is returned after the correct decryption key is
431 std::move(pending_audio_decode_cb_)
432 .Run(Decryptor::kNoKey, Decryptor::AudioFrames());
433 base::RunLoop().RunUntilIdle();
436 // Test resetting when the decoder is in kIdle state but has not decoded any
438 TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) {
443 // Test resetting when the decoder is in kIdle state after it has decoded one
445 TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
447 EnterNormalDecodingState();
451 // Test resetting when the decoder is in kPendingDecode state.
452 TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) {
454 EnterPendingDecodeState();
456 EXPECT_CALL(*this, DecodeDone(DecodeStatus::ABORTED));
461 // Test resetting when the decoder is in kWaitingForKey state.
462 TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) {
464 EnterWaitingForKeyState();
466 EXPECT_CALL(*this, DecodeDone(DecodeStatus::ABORTED));
471 // Test resetting when the decoder has hit end of stream and is in
472 // kDecodeFinished state.
473 TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) {
475 EnterNormalDecodingState();
476 EnterEndOfStreamState();
480 // Test resetting after the decoder has been reset.
481 TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) {
483 EnterNormalDecodingState();