[go: nahoru, domu]

blob: 327c25785eb57aa9d55487c6c986f20f9637f335 [file] [log] [blame]
Avi Drissmand387f0922022-09-14 20:51:311// Copyright 2012 The Chromium Authors
xhwang@chromium.org97a9ce42012-10-19 10:06:432// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Daniel Cheng9e37dfb2022-02-28 07:30:125#include "media/filters/decrypting_audio_decoder.h"
6
avi1323b9c22015-12-23 06:22:367#include <stdint.h>
8
xhwang@chromium.org97a9ce42012-10-19 10:06:439#include <string>
10#include <vector>
11
Avi Drissmand70f89a2023-01-11 23:52:5512#include "base/functional/bind.h"
13#include "base/functional/callback_helpers.h"
fdorayf920dcf2016-06-27 17:16:5914#include "base/run_loop.h"
Marijn Kruisselbrink52a35242019-06-05 22:58:2915#include "base/test/gmock_callback_support.h"
Daniel Cheng868ab272021-02-24 17:07:1516#include "base/test/gmock_move_support.h"
Gabriel Charettec7108742019-08-23 03:31:4017#include "base/test/task_environment.h"
jrummell@chromium.org47b37a62013-07-10 03:56:1018#include "media/base/audio_buffer.h"
xhwang@chromium.org97a9ce42012-10-19 10:06:4319#include "media/base/decoder_buffer.h"
20#include "media/base/decrypt_config.h"
chcunningham9812dd82015-10-20 01:42:0921#include "media/base/media_util.h"
xhwang@chromium.org97a9ce42012-10-19 10:06:4322#include "media/base/mock_filters.h"
scherkus@chromium.org1848da02012-12-06 06:58:3823#include "media/base/test_helpers.h"
watk9f9dfdc92015-09-04 21:33:2924#include "media/base/timestamp_constants.h"
xhwang@chromium.org97a9ce42012-10-19 10:06:4325#include "testing/gmock/include/gmock/gmock.h"
26
Jose Lopes109230ec2020-02-24 10:28:1227using ::base::test::RunOnceCallback;
xhwang@chromium.org97a9ce42012-10-19 10:06:4328using ::testing::_;
29using ::testing::AtMost;
xhwang00f69db72015-11-12 07:32:3730using ::testing::Return;
xhwang@chromium.org97a9ce42012-10-19 10:06:4331using ::testing::StrictMock;
32
33namespace media {
34
xhwang@chromium.org5c5e9b72014-06-17 19:21:1235const int kSampleRate = 44100;
rileya@chromium.org16ecd5f2014-03-20 05:41:0736
xhwang@chromium.orgecf16912013-01-12 16:55:2237// Make sure the kFakeAudioFrameSize is a valid frame size for all audio decoder
38// configs used in this test.
xhwang@chromium.org5c5e9b72014-06-17 19:21:1239const int kFakeAudioFrameSize = 48;
Avi Drissman97785ea2015-12-19 01:11:3140const uint8_t kFakeKeyId[] = {0x4b, 0x65, 0x79, 0x20, 0x49, 0x44};
41const uint8_t kFakeIv[DecryptConfig::kDecryptionKeySize] = {0};
xhwang@chromium.org5c5e9b72014-06-17 19:21:1242const int kDecodingDelay = 3;
xhwang@chromium.org97a9ce42012-10-19 10:06:4343
44// Create a fake non-empty encrypted buffer.
45static scoped_refptr<DecoderBuffer> CreateFakeEncryptedBuffer() {
46 const int buffer_size = 16; // Need a non-empty buffer;
47 scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(buffer_size));
John Rummell9044a762018-04-19 01:24:0748 buffer->set_decrypt_config(DecryptConfig::CreateCencConfig(
xhwang@chromium.org97a9ce42012-10-19 10:06:4349 std::string(reinterpret_cast<const char*>(kFakeKeyId),
Daniel Cheng9e37dfb2022-02-28 07:30:1250 std::size(kFakeKeyId)),
51 std::string(reinterpret_cast<const char*>(kFakeIv), std::size(kFakeIv)),
John Rummell9044a762018-04-19 01:24:0752 std::vector<SubsampleEntry>()));
xhwang@chromium.org97a9ce42012-10-19 10:06:4353 return buffer;
54}
55
xhwang@chromium.org97a9ce42012-10-19 10:06:4356class DecryptingAudioDecoderTest : public testing::Test {
57 public:
58 DecryptingAudioDecoderTest()
Carlos Caballero9de7c722019-05-31 21:25:0759 : decoder_(new DecryptingAudioDecoder(
Gabriel Charettedfa36042019-08-19 17:30:1160 task_environment_.GetMainThreadTaskRunner(),
Carlos Caballero9de7c722019-05-31 21:25:0761 &media_log_)),
xhwang00f69db72015-11-12 07:32:3762 cdm_context_(new StrictMock<MockCdmContext>()),
xhwang@chromium.org97a9ce42012-10-19 10:06:4363 decryptor_(new StrictMock<MockDecryptor>()),
xhwang@chromium.org5c5e9b72014-06-17 19:21:1264 num_decrypt_and_decode_calls_(0),
65 num_frames_in_decryptor_(0),
xhwang@chromium.org97a9ce42012-10-19 10:06:4366 encrypted_buffer_(CreateFakeEncryptedBuffer()),
kylechar938dc442019-10-29 14:40:2467 decoded_frame_(nullptr),
rileya@chromium.orgd70157792014-03-17 21:45:0368 decoded_frame_list_() {}
xhwang@chromium.org97a9ce42012-10-19 10:06:4369
Peter Boström4c42559f2021-09-22 20:24:3470 DecryptingAudioDecoderTest(const DecryptingAudioDecoderTest&) = delete;
71 DecryptingAudioDecoderTest& operator=(const DecryptingAudioDecoderTest&) =
72 delete;
73
Daniel Cheng9f0b7012018-04-26 21:09:0574 ~DecryptingAudioDecoderTest() override { Destroy(); }
rileya@chromium.orgb960fd02014-01-23 04:48:5475
xhwang59c321f2015-06-05 23:46:5576 void InitializeAndExpectResult(const AudioDecoderConfig& config,
77 bool success) {
dalecurtis@google.come81f5f9d2014-03-29 01:32:1678 // 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());
82 if (channels < 0)
83 channels = 0;
dalecurtis39a7f932016-07-19 18:34:5984 decoded_frame_ = AudioBuffer::CreateEmptyBuffer(
85 config.channel_layout(), channels, kSampleRate, kFakeAudioFrameSize,
86 kNoTimestamp);
jrummell@chromium.org47b37a62013-07-10 03:56:1087 decoded_frame_list_.push_back(decoded_frame_);
88
David Bienvenub8c87522020-11-11 22:59:5089 decoder_->Initialize(
90 config, cdm_context_.get(),
91 base::BindOnce(
Ted Meyera8afec222022-01-12 02:37:2792 [](bool success, DecoderStatus status) {
David Bienvenub8c87522020-11-11 22:59:5093 EXPECT_EQ(status.is_ok(), success);
94 },
95 success),
96 base::BindRepeating(&DecryptingAudioDecoderTest::FrameReady,
97 base::Unretained(this)),
98 base::BindRepeating(&DecryptingAudioDecoderTest::OnWaiting,
99 base::Unretained(this)));
fdorayf920dcf2016-06-27 17:16:59100 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43101 }
102
xhwanga935e442016-02-11 02:22:45103 enum CdmType { CDM_WITHOUT_DECRYPTOR, CDM_WITH_DECRYPTOR };
xhwang00f69db72015-11-12 07:32:37104
105 void SetCdmType(CdmType cdm_type) {
xhwang00f69db72015-11-12 07:32:37106 const bool has_decryptor = cdm_type == CDM_WITH_DECRYPTOR;
xhwanga935e442016-02-11 02:22:45107 EXPECT_CALL(*cdm_context_, GetDecryptor())
108 .WillRepeatedly(Return(has_decryptor ? decryptor_.get() : nullptr));
jrummell@chromium.org9ebc3b032014-08-13 04:01:23109 }
110
xhwang@chromium.org97a9ce42012-10-19 10:06:43111 void Initialize() {
xhwang00f69db72015-11-12 07:32:37112 SetCdmType(CDM_WITH_DECRYPTOR);
xhwang@chromium.orga3e28672013-03-14 14:54:59113 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
xhwang@chromium.org97a9ce42012-10-19 10:06:43114 .Times(AtMost(1))
Jose Lopes109230ec2020-02-24 10:28:12115 .WillOnce(RunOnceCallback<1>(true));
Xiaohan Wangd72ce5d2020-07-14 01:34:43116 EXPECT_CALL(*cdm_context_, RegisterEventCB(_)).WillOnce([&](auto cb) {
117 event_cb_ = cb;
118 return std::make_unique<CallbackRegistration>();
119 });
xhwang@chromium.org97a9ce42012-10-19 10:06:43120
Dale Curtisbafd563172021-08-13 02:07:47121 config_.Initialize(AudioCodec::kVorbis, kSampleFormatPlanarF32,
chcunningham9812dd82015-10-20 01:42:09122 CHANNEL_LAYOUT_STEREO, kSampleRate, EmptyExtraData(),
Yuchen Liub33bfc12019-11-08 20:16:12123 EncryptionScheme::kCenc, base::TimeDelta(), 0);
xhwang59c321f2015-06-05 23:46:55124 InitializeAndExpectResult(config_, true);
xhwang@chromium.org97a9ce42012-10-19 10:06:43125 }
126
Xiaohan Wangc03ce232018-05-30 21:07:58127 void Reinitialize() { ReinitializeConfigChange(config_); }
rileya@chromium.orgd70157792014-03-17 21:45:03128
dalecurtis@google.com6fb86542014-04-18 19:58:13129 void ReinitializeConfigChange(const AudioDecoderConfig& new_config) {
rileya@chromium.orgd70157792014-03-17 21:45:03130 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
131 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
Jose Lopes109230ec2020-02-24 10:28:12132 .WillOnce(RunOnceCallback<1>(true));
Ted Meyer2a41e242020-03-20 08:01:27133 decoder_->Initialize(
134 new_config, cdm_context_.get(),
Ted Meyera8afec222022-01-12 02:37:27135 base::BindOnce(
136 [](DecoderStatus status) { EXPECT_TRUE(status.is_ok()); }),
David Bienvenub8c87522020-11-11 22:59:50137 base::BindRepeating(&DecryptingAudioDecoderTest::FrameReady,
138 base::Unretained(this)),
139 base::BindRepeating(&DecryptingAudioDecoderTest::OnWaiting,
140 base::Unretained(this)));
rileya@chromium.orgd70157792014-03-17 21:45:03141 }
142
xhwang@chromium.org5c5e9b72014-06-17 19:21:12143 // Decode |buffer| and expect DecodeDone to get called with |status|.
Ted Meyera8afec222022-01-12 02:37:27144 void DecodeAndExpect(scoped_refptr<DecoderBuffer> buffer,
145 DecoderStatus status) {
Frank Liberato3d157ba2020-09-24 18:19:30146 EXPECT_CALL(*this, DecodeDone(HasStatusCode(status)));
David Bienvenub8c87522020-11-11 22:59:50147 decoder_->Decode(buffer,
148 base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
149 base::Unretained(this)));
fdorayf920dcf2016-06-27 17:16:59150 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43151 }
152
xhwang@chromium.org5c5e9b72014-06-17 19:21:12153 // Helper function to simulate the decrypting and decoding process in the
154 // |decryptor_| with a decoding delay of kDecodingDelay buffers.
Dale Curtisca8ad982018-04-09 20:23:14155 void DecryptAndDecodeAudio(scoped_refptr<DecoderBuffer> encrypted,
Daniel Cheng868ab272021-02-24 17:07:15156 Decryptor::AudioDecodeCB audio_decode_cb) {
xhwang@chromium.org5c5e9b72014-06-17 19:21:12157 num_decrypt_and_decode_calls_++;
158 if (!encrypted->end_of_stream())
159 num_frames_in_decryptor_++;
160
161 if (num_decrypt_and_decode_calls_ <= kDecodingDelay ||
162 num_frames_in_decryptor_ == 0) {
Daniel Cheng868ab272021-02-24 17:07:15163 std::move(audio_decode_cb)
164 .Run(Decryptor::kNeedMoreData, Decryptor::AudioFrames());
xhwang@chromium.org5c5e9b72014-06-17 19:21:12165 return;
166 }
167
168 num_frames_in_decryptor_--;
Daniel Cheng868ab272021-02-24 17:07:15169 std::move(audio_decode_cb)
170 .Run(Decryptor::kSuccess, Decryptor::AudioFrames(1, decoded_frame_));
xhwang@chromium.org5c5e9b72014-06-17 19:21:12171 }
172
xhwang@chromium.org97a9ce42012-10-19 10:06:43173 // Sets up expectations and actions to put DecryptingAudioDecoder in an
174 // active normal decoding state.
175 void EnterNormalDecodingState() {
Xiaohan Wangc03ce232018-05-30 21:07:58176 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
177 .WillRepeatedly(
178 Invoke(this, &DecryptingAudioDecoderTest::DecryptAndDecodeAudio));
xhwang@chromium.org5c5e9b72014-06-17 19:21:12179 EXPECT_CALL(*this, FrameReady(decoded_frame_));
180 for (int i = 0; i < kDecodingDelay + 1; ++i)
Ted Meyera8afec222022-01-12 02:37:27181 DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kOk);
xhwang@chromium.org97a9ce42012-10-19 10:06:43182 }
183
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() {
xhwang@chromium.orgff757032014-06-19 01:42:24188 // The codec in the |decryptor_| will be flushed.
Xiaohan Wangc03ce232018-05-30 21:07:58189 EXPECT_CALL(*this, FrameReady(decoded_frame_)).Times(kDecodingDelay);
Ted Meyera8afec222022-01-12 02:37:27190 DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(),
191 DecoderStatus::Codes::kOk);
xhwang@chromium.org5c5e9b72014-06-17 19:21:12192 EXPECT_EQ(0, num_frames_in_decryptor_);
xhwang@chromium.org97a9ce42012-10-19 10:06:43193 }
194
195 // Make the audio decode callback pending by saving and not firing it.
196 void EnterPendingDecodeState() {
Dale Curtise25163812018-09-21 22:13:39197 EXPECT_TRUE(!pending_audio_decode_cb_);
xhwang@chromium.org97a9ce42012-10-19 10:06:43198 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
Daniel Cheng868ab272021-02-24 17:07:15199 .WillOnce(MoveArg<1>(&pending_audio_decode_cb_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43200
rileya@chromium.orgd70157792014-03-17 21:45:03201 decoder_->Decode(encrypted_buffer_,
David Bienvenub8c87522020-11-11 22:59:50202 base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
203 base::Unretained(this)));
fdorayf920dcf2016-06-27 17:16:59204 base::RunLoop().RunUntilIdle();
rileya@chromium.orgd70157792014-03-17 21:45:03205 // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
206 // the decryptor.
Dale Curtise25163812018-09-21 22:13:39207 EXPECT_FALSE(!pending_audio_decode_cb_);
xhwang@chromium.org97a9ce42012-10-19 10:06:43208 }
209
210 void EnterWaitingForKeyState() {
xhwang@chromium.org2b454ff82012-11-15 03:57:58211 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
Xiaohan Wangc03ce232018-05-30 21:07:58212 .WillRepeatedly(
Daniel Cheng868ab272021-02-24 17:07:15213 RunOnceCallback<1>(Decryptor::kNoKey, Decryptor::AudioFrames()));
Xiaohan Wang640b41d2018-12-18 19:00:46214 EXPECT_CALL(*this, OnWaiting(WaitingReason::kNoDecryptionKey));
rileya@chromium.orgd70157792014-03-17 21:45:03215 decoder_->Decode(encrypted_buffer_,
David Bienvenub8c87522020-11-11 22:59:50216 base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
217 base::Unretained(this)));
Xiaohan Wang689cd4282017-08-04 07:54:55218
fdorayf920dcf2016-06-27 17:16:59219 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43220 }
221
222 void AbortPendingAudioDecodeCB() {
Dale Curtise25163812018-09-21 22:13:39223 if (pending_audio_decode_cb_) {
224 std::move(pending_audio_decode_cb_)
Xiaohan Wangc03ce232018-05-30 21:07:58225 .Run(Decryptor::kSuccess, Decryptor::AudioFrames());
xhwang@chromium.org97a9ce42012-10-19 10:06:43226 }
227 }
228
rileya@chromium.orgb960fd02014-01-23 04:48:54229 void AbortAllPendingCBs() {
Dale Curtise25163812018-09-21 22:13:39230 if (pending_init_cb_) {
231 ASSERT_TRUE(!pending_audio_decode_cb_);
232 std::move(pending_init_cb_).Run(false);
rileya@chromium.orgb960fd02014-01-23 04:48:54233 return;
234 }
235
236 AbortPendingAudioDecodeCB();
237 }
238
xhwang@chromium.org97a9ce42012-10-19 10:06:43239 void Reset() {
240 EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio))
241 .WillRepeatedly(InvokeWithoutArgs(
242 this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB));
243
244 decoder_->Reset(NewExpectedClosure());
fdorayf920dcf2016-06-27 17:16:59245 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43246 }
247
xhwang@chromium.org83fb2a9e2014-07-16 23:36:41248 void Destroy() {
rileya@chromium.orgb960fd02014-01-23 04:48:54249 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio))
250 .WillRepeatedly(InvokeWithoutArgs(
251 this, &DecryptingAudioDecoderTest::AbortAllPendingCBs));
252
xhwang@chromium.org83fb2a9e2014-07-16 23:36:41253 decoder_.reset();
fdorayf920dcf2016-06-27 17:16:59254 base::RunLoop().RunUntilIdle();
rileya@chromium.orgb960fd02014-01-23 04:48:54255 }
256
John Rummell1b2b63d2019-04-26 20:45:57257 MOCK_METHOD1(FrameReady, void(scoped_refptr<AudioBuffer>));
Ted Meyera8afec222022-01-12 02:37:27258 MOCK_METHOD1(DecodeDone, void(DecoderStatus));
xhwang@chromium.org97a9ce42012-10-19 10:06:43259
Xiaohan Wang640b41d2018-12-18 19:00:46260 MOCK_METHOD1(OnWaiting, void(WaitingReason));
jrummell74fc4f942015-03-02 22:48:27261
Gabriel Charette311b0e92019-09-09 20:01:25262 base::test::SingleThreadTaskEnvironment task_environment_;
Xiaohan Wang14b3166d2018-12-28 21:05:46263 NullMediaLog media_log_;
dcheng254c5362016-04-22 01:12:48264 std::unique_ptr<DecryptingAudioDecoder> decoder_;
265 std::unique_ptr<StrictMock<MockCdmContext>> cdm_context_;
266 std::unique_ptr<StrictMock<MockDecryptor>> decryptor_;
xhwang@chromium.org7c39486c2013-01-06 15:36:09267 AudioDecoderConfig config_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43268
xhwang@chromium.org5c5e9b72014-06-17 19:21:12269 // Variables to help the |decryptor_| to simulate decoding delay and flushing.
270 int num_decrypt_and_decode_calls_;
271 int num_frames_in_decryptor_;
272
xhwang@chromium.org97a9ce42012-10-19 10:06:43273 Decryptor::DecoderInitCB pending_init_cb_;
Xiaohan Wangd72ce5d2020-07-14 01:34:43274 CdmContext::EventCB event_cb_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43275 Decryptor::AudioDecodeCB pending_audio_decode_cb_;
276
rileya@chromium.orgd70157792014-03-17 21:45:03277 // Constant buffer/frames, to be used/returned by |decoder_| and |decryptor_|.
xhwang@chromium.org97a9ce42012-10-19 10:06:43278 scoped_refptr<DecoderBuffer> encrypted_buffer_;
jrummell@chromium.org47b37a62013-07-10 03:56:10279 scoped_refptr<AudioBuffer> decoded_frame_;
anujk.sharmaf1cb600a2015-01-07 19:11:13280 Decryptor::AudioFrames decoded_frame_list_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43281};
282
283TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) {
284 Initialize();
285}
286
xhwang@chromium.org97a9ce42012-10-19 10:06:43287// Ensure decoder handles invalid audio configs without crashing.
288TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) {
Dale Curtisbafd563172021-08-13 02:07:47289 AudioDecoderConfig config(AudioCodec::kUnknown, kUnknownSampleFormat,
dougsteed8d5275f2016-03-12 00:04:30290 CHANNEL_LAYOUT_STEREO, 0, EmptyExtraData(),
Yuchen Liub33bfc12019-11-08 20:16:12291 EncryptionScheme::kCenc);
xhwang@chromium.org97a9ce42012-10-19 10:06:43292
xhwang59c321f2015-06-05 23:46:55293 InitializeAndExpectResult(config, false);
xhwang@chromium.org97a9ce42012-10-19 10:06:43294}
295
296// Ensure decoder handles unsupported audio configs without crashing.
297TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) {
xhwang00f69db72015-11-12 07:32:37298 SetCdmType(CDM_WITH_DECRYPTOR);
Xiaohan Wangd72ce5d2020-07-14 01:34:43299 EXPECT_CALL(*cdm_context_, RegisterEventCB(_)).WillOnce([&](auto cb) {
300 event_cb_ = cb;
301 return std::make_unique<CallbackRegistration>();
302 });
xhwang@chromium.orga3e28672013-03-14 14:54:59303 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
Jose Lopes109230ec2020-02-24 10:28:12304 .WillOnce(RunOnceCallback<1>(false));
xhwang@chromium.org97a9ce42012-10-19 10:06:43305
Dale Curtisbafd563172021-08-13 02:07:47306 AudioDecoderConfig config(AudioCodec::kVorbis, kSampleFormatPlanarF32,
chcunningham9812dd82015-10-20 01:42:09307 CHANNEL_LAYOUT_STEREO, kSampleRate,
Yuchen Liub33bfc12019-11-08 20:16:12308 EmptyExtraData(), EncryptionScheme::kCenc);
xhwang59c321f2015-06-05 23:46:55309 InitializeAndExpectResult(config, false);
xhwang@chromium.org97a9ce42012-10-19 10:06:43310}
311
xhwang00f69db72015-11-12 07:32:37312TEST_F(DecryptingAudioDecoderTest, Initialize_CdmWithoutDecryptor) {
313 SetCdmType(CDM_WITHOUT_DECRYPTOR);
Dale Curtisbafd563172021-08-13 02:07:47314 AudioDecoderConfig config(AudioCodec::kVorbis, kSampleFormatPlanarF32,
chcunningham9812dd82015-10-20 01:42:09315 CHANNEL_LAYOUT_STEREO, kSampleRate,
Yuchen Liub33bfc12019-11-08 20:16:12316 EmptyExtraData(), EncryptionScheme::kCenc);
xhwang59c321f2015-06-05 23:46:55317 InitializeAndExpectResult(config, false);
xhwang@chromium.org699b64a2013-06-19 07:36:05318}
319
xhwang@chromium.org97a9ce42012-10-19 10:06:43320// Test normal decrypt and decode case.
321TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) {
322 Initialize();
323 EnterNormalDecodingState();
324}
325
326// Test the case where the decryptor returns error when doing decrypt and
327// decode.
328TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) {
329 Initialize();
330
xhwang@chromium.org97a9ce42012-10-19 10:06:43331 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
Xiaohan Wangc03ce232018-05-30 21:07:58332 .WillRepeatedly(
Daniel Cheng868ab272021-02-24 17:07:15333 RunOnceCallback<1>(Decryptor::kError, Decryptor::AudioFrames()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43334
Ted Meyera8afec222022-01-12 02:37:27335 DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kFailed);
xhwang@chromium.org97a9ce42012-10-19 10:06:43336}
337
338// Test the case where the decryptor returns multiple decoded frames.
339TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) {
340 Initialize();
341
jrummell@chromium.org47b37a62013-07-10 03:56:10342 scoped_refptr<AudioBuffer> frame_a = AudioBuffer::CreateEmptyBuffer(
rileya@chromium.org16ecd5f2014-03-20 05:41:07343 config_.channel_layout(),
dalecurtis39a7f932016-07-19 18:34:59344 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
345 kFakeAudioFrameSize, kNoTimestamp);
jrummell@chromium.org47b37a62013-07-10 03:56:10346 scoped_refptr<AudioBuffer> frame_b = AudioBuffer::CreateEmptyBuffer(
rileya@chromium.org16ecd5f2014-03-20 05:41:07347 config_.channel_layout(),
dalecurtis39a7f932016-07-19 18:34:59348 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
349 kFakeAudioFrameSize, kNoTimestamp);
xhwang@chromium.orgecbb9762012-10-24 22:33:54350 decoded_frame_list_.push_back(frame_a);
351 decoded_frame_list_.push_back(frame_b);
xhwang@chromium.org97a9ce42012-10-19 10:06:43352
xhwang@chromium.org97a9ce42012-10-19 10:06:43353 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
Daniel Cheng868ab272021-02-24 17:07:15354 .WillOnce(RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43355
xhwang@chromium.org5c5e9b72014-06-17 19:21:12356 EXPECT_CALL(*this, FrameReady(decoded_frame_));
357 EXPECT_CALL(*this, FrameReady(frame_a));
358 EXPECT_CALL(*this, FrameReady(frame_b));
Ted Meyera8afec222022-01-12 02:37:27359 DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kOk);
xhwang@chromium.org97a9ce42012-10-19 10:06:43360}
361
362// Test the case where the decryptor receives end-of-stream buffer.
363TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) {
364 Initialize();
365 EnterNormalDecodingState();
366 EnterEndOfStreamState();
367}
368
xhwang65c23032017-02-17 04:37:42369// Test reinitializing decode with a new encrypted config.
370TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToEncrypted) {
xhwang@chromium.org7c39486c2013-01-06 15:36:09371 Initialize();
372
rileya@chromium.orgd70157792014-03-17 21:45:03373 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
374 .Times(AtMost(1))
Jose Lopes109230ec2020-02-24 10:28:12375 .WillOnce(RunOnceCallback<1>(true));
xhwang@chromium.org7c39486c2013-01-06 15:36:09376
xhwang@chromium.orgecf16912013-01-12 16:55:22377 // The new config is different from the initial config in bits-per-channel,
378 // channel layout and samples_per_second.
Dale Curtisbafd563172021-08-13 02:07:47379 AudioDecoderConfig new_config(AudioCodec::kVorbis, kSampleFormatPlanarS16,
chcunningham9812dd82015-10-20 01:42:09380 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
Yuchen Liub33bfc12019-11-08 20:16:12381 EncryptionScheme::kCenc);
xhwang@chromium.orgecf16912013-01-12 16:55:22382 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());
xhwang65c23032017-02-17 04:37:42385 ASSERT_TRUE(new_config.is_encrypted());
386
387 ReinitializeConfigChange(new_config);
388 base::RunLoop().RunUntilIdle();
389}
390
391// Test reinitializing decode with a new clear config.
392TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToClear) {
393 Initialize();
394
395 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
396 .Times(AtMost(1))
Jose Lopes109230ec2020-02-24 10:28:12397 .WillOnce(RunOnceCallback<1>(true));
xhwang65c23032017-02-17 04:37:42398
399 // The new config is different from the initial config in bits-per-channel,
400 // channel layout and samples_per_second.
Dale Curtisbafd563172021-08-13 02:07:47401 AudioDecoderConfig new_config(AudioCodec::kVorbis, kSampleFormatPlanarS16,
xhwang65c23032017-02-17 04:37:42402 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
Yuchen Liub33bfc12019-11-08 20:16:12403 EncryptionScheme::kUnencrypted);
xhwang65c23032017-02-17 04:37:42404 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());
xhwang@chromium.orgecf16912013-01-12 16:55:22408
rileya@chromium.orgd70157792014-03-17 21:45:03409 ReinitializeConfigChange(new_config);
fdorayf920dcf2016-06-27 17:16:59410 base::RunLoop().RunUntilIdle();
xhwang@chromium.org7c39486c2013-01-06 15:36:09411}
412
xhwang@chromium.org97a9ce42012-10-19 10:06:43413// Test the case where the a key is added when the decryptor is in
414// kWaitingForKey state.
415TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) {
416 Initialize();
417 EnterWaitingForKeyState();
418
419 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
Daniel Cheng868ab272021-02-24 17:07:15420 .WillRepeatedly(
421 RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
sergeyu@chromium.org49cea862014-06-11 11:11:50422 EXPECT_CALL(*this, FrameReady(decoded_frame_));
Frank Liberato3d157ba2020-09-24 18:19:30423 EXPECT_CALL(*this, DecodeDone(IsOkStatus()));
Xiaohan Wangd72ce5d2020-07-14 01:34:43424 event_cb_.Run(CdmContext::Event::kHasAdditionalUsableKey);
fdorayf920dcf2016-06-27 17:16:59425 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43426}
427
428// Test the case where the a key is added when the decryptor is in
429// kPendingDecode state.
430TEST_F(DecryptingAudioDecoderTest, KeyAdded_DruingPendingDecode) {
431 Initialize();
432 EnterPendingDecodeState();
433
434 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
Daniel Cheng868ab272021-02-24 17:07:15435 .WillRepeatedly(
436 RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
sergeyu@chromium.org49cea862014-06-11 11:11:50437 EXPECT_CALL(*this, FrameReady(decoded_frame_));
Frank Liberato3d157ba2020-09-24 18:19:30438 EXPECT_CALL(*this, DecodeDone(IsOkStatus()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43439 // The audio decode callback is returned after the correct decryption key is
440 // added.
Xiaohan Wangd72ce5d2020-07-14 01:34:43441 event_cb_.Run(CdmContext::Event::kHasAdditionalUsableKey);
Dale Curtise25163812018-09-21 22:13:39442 std::move(pending_audio_decode_cb_)
Xiaohan Wangc03ce232018-05-30 21:07:58443 .Run(Decryptor::kNoKey, Decryptor::AudioFrames());
fdorayf920dcf2016-06-27 17:16:59444 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43445}
446
447// Test resetting when the decoder is in kIdle state but has not decoded any
448// frame.
449TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) {
450 Initialize();
451 Reset();
452}
453
454// Test resetting when the decoder is in kIdle state after it has decoded one
455// frame.
456TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
457 Initialize();
458 EnterNormalDecodingState();
459 Reset();
460}
461
xhwang@chromium.org97a9ce42012-10-19 10:06:43462// Test resetting when the decoder is in kPendingDecode state.
463TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) {
464 Initialize();
465 EnterPendingDecodeState();
466
Ted Meyera8afec222022-01-12 02:37:27467 EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted)));
xhwang@chromium.org97a9ce42012-10-19 10:06:43468
469 Reset();
470}
471
472// Test resetting when the decoder is in kWaitingForKey state.
473TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) {
474 Initialize();
475 EnterWaitingForKeyState();
476
Ted Meyera8afec222022-01-12 02:37:27477 EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted)));
xhwang@chromium.org97a9ce42012-10-19 10:06:43478
479 Reset();
480}
481
482// Test resetting when the decoder has hit end of stream and is in
483// kDecodeFinished state.
484TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) {
485 Initialize();
486 EnterNormalDecodingState();
487 EnterEndOfStreamState();
488 Reset();
489}
490
491// Test resetting after the decoder has been reset.
492TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) {
493 Initialize();
494 EnterNormalDecodingState();
495 Reset();
496 Reset();
497}
498
xhwang@chromium.org97a9ce42012-10-19 10:06:43499} // namespace media