[go: nahoru, domu]

blob: 926d869ecf2070a7e65ca9d1dab922f747fde5a3 [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"
Vikram Pasupathyabfd18a2023-01-26 20:56:2023#include "media/base/mock_media_log.h"
scherkus@chromium.org1848da02012-12-06 06:58:3824#include "media/base/test_helpers.h"
watk9f9dfdc92015-09-04 21:33:2925#include "media/base/timestamp_constants.h"
xhwang@chromium.org97a9ce42012-10-19 10:06:4326#include "testing/gmock/include/gmock/gmock.h"
27
Jose Lopes109230ec2020-02-24 10:28:1228using ::base::test::RunOnceCallback;
xhwang@chromium.org97a9ce42012-10-19 10:06:4329using ::testing::_;
30using ::testing::AtMost;
Vikram Pasupathyabfd18a2023-01-26 20:56:2031using ::testing::HasSubstr;
xhwang00f69db72015-11-12 07:32:3732using ::testing::Return;
xhwang@chromium.org97a9ce42012-10-19 10:06:4333using ::testing::StrictMock;
34
35namespace media {
36
xhwang@chromium.org5c5e9b72014-06-17 19:21:1237const int kSampleRate = 44100;
rileya@chromium.org16ecd5f2014-03-20 05:41:0738
xhwang@chromium.orgecf16912013-01-12 16:55:2239// Make sure the kFakeAudioFrameSize is a valid frame size for all audio decoder
40// configs used in this test.
xhwang@chromium.org5c5e9b72014-06-17 19:21:1241const int kFakeAudioFrameSize = 48;
Avi Drissman97785ea2015-12-19 01:11:3142const uint8_t kFakeKeyId[] = {0x4b, 0x65, 0x79, 0x20, 0x49, 0x44};
43const uint8_t kFakeIv[DecryptConfig::kDecryptionKeySize] = {0};
xhwang@chromium.org5c5e9b72014-06-17 19:21:1244const int kDecodingDelay = 3;
xhwang@chromium.org97a9ce42012-10-19 10:06:4345
46// Create a fake non-empty encrypted buffer.
47static scoped_refptr<DecoderBuffer> CreateFakeEncryptedBuffer() {
48 const int buffer_size = 16; // Need a non-empty buffer;
Vikram Pasupathy7c7e28c2023-04-14 23:30:2149 scoped_refptr<DecoderBuffer> buffer(
50 base::MakeRefCounted<DecoderBuffer>(buffer_size));
John Rummell9044a762018-04-19 01:24:0751 buffer->set_decrypt_config(DecryptConfig::CreateCencConfig(
xhwang@chromium.org97a9ce42012-10-19 10:06:4352 std::string(reinterpret_cast<const char*>(kFakeKeyId),
Daniel Cheng9e37dfb2022-02-28 07:30:1253 std::size(kFakeKeyId)),
54 std::string(reinterpret_cast<const char*>(kFakeIv), std::size(kFakeIv)),
John Rummell9044a762018-04-19 01:24:0755 std::vector<SubsampleEntry>()));
xhwang@chromium.org97a9ce42012-10-19 10:06:4356 return buffer;
57}
58
xhwang@chromium.org97a9ce42012-10-19 10:06:4359class DecryptingAudioDecoderTest : public testing::Test {
60 public:
61 DecryptingAudioDecoderTest()
Vikram Pasupathy7c7e28c2023-04-14 23:30:2162 : decoder_(std::make_unique<DecryptingAudioDecoder>(
Gabriel Charettedfa36042019-08-19 17:30:1163 task_environment_.GetMainThreadTaskRunner(),
Carlos Caballero9de7c722019-05-31 21:25:0764 &media_log_)),
Vikram Pasupathy7c7e28c2023-04-14 23:30:2165 cdm_context_(std::make_unique<StrictMock<MockCdmContext>>()),
66 decryptor_(std::make_unique<StrictMock<MockDecryptor>>()),
xhwang@chromium.org5c5e9b72014-06-17 19:21:1267 num_decrypt_and_decode_calls_(0),
68 num_frames_in_decryptor_(0),
xhwang@chromium.org97a9ce42012-10-19 10:06:4369 encrypted_buffer_(CreateFakeEncryptedBuffer()),
kylechar938dc442019-10-29 14:40:2470 decoded_frame_(nullptr),
rileya@chromium.orgd70157792014-03-17 21:45:0371 decoded_frame_list_() {}
xhwang@chromium.org97a9ce42012-10-19 10:06:4372
Peter Boström4c42559f2021-09-22 20:24:3473 DecryptingAudioDecoderTest(const DecryptingAudioDecoderTest&) = delete;
74 DecryptingAudioDecoderTest& operator=(const DecryptingAudioDecoderTest&) =
75 delete;
76
Daniel Cheng9f0b7012018-04-26 21:09:0577 ~DecryptingAudioDecoderTest() override { Destroy(); }
rileya@chromium.orgb960fd02014-01-23 04:48:5478
xhwang59c321f2015-06-05 23:46:5579 void InitializeAndExpectResult(const AudioDecoderConfig& config,
80 bool success) {
dalecurtis@google.come81f5f9d2014-03-29 01:32:1681 // Initialize data now that the config is known. Since the code uses
82 // invalid values (that CreateEmptyBuffer() doesn't support), tweak them
83 // just for CreateEmptyBuffer().
84 int channels = ChannelLayoutToChannelCount(config.channel_layout());
85 if (channels < 0)
86 channels = 0;
dalecurtis39a7f932016-07-19 18:34:5987 decoded_frame_ = AudioBuffer::CreateEmptyBuffer(
88 config.channel_layout(), channels, kSampleRate, kFakeAudioFrameSize,
89 kNoTimestamp);
jrummell@chromium.org47b37a62013-07-10 03:56:1090 decoded_frame_list_.push_back(decoded_frame_);
91
David Bienvenub8c87522020-11-11 22:59:5092 decoder_->Initialize(
93 config, cdm_context_.get(),
94 base::BindOnce(
Ted Meyera8afec222022-01-12 02:37:2795 [](bool success, DecoderStatus status) {
David Bienvenub8c87522020-11-11 22:59:5096 EXPECT_EQ(status.is_ok(), success);
97 },
98 success),
99 base::BindRepeating(&DecryptingAudioDecoderTest::FrameReady,
100 base::Unretained(this)),
101 base::BindRepeating(&DecryptingAudioDecoderTest::OnWaiting,
102 base::Unretained(this)));
fdorayf920dcf2016-06-27 17:16:59103 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43104 }
105
xhwanga935e442016-02-11 02:22:45106 enum CdmType { CDM_WITHOUT_DECRYPTOR, CDM_WITH_DECRYPTOR };
xhwang00f69db72015-11-12 07:32:37107
108 void SetCdmType(CdmType cdm_type) {
xhwang00f69db72015-11-12 07:32:37109 const bool has_decryptor = cdm_type == CDM_WITH_DECRYPTOR;
xhwanga935e442016-02-11 02:22:45110 EXPECT_CALL(*cdm_context_, GetDecryptor())
111 .WillRepeatedly(Return(has_decryptor ? decryptor_.get() : nullptr));
jrummell@chromium.org9ebc3b032014-08-13 04:01:23112 }
113
xhwang@chromium.org97a9ce42012-10-19 10:06:43114 void Initialize() {
xhwang00f69db72015-11-12 07:32:37115 SetCdmType(CDM_WITH_DECRYPTOR);
xhwang@chromium.orga3e28672013-03-14 14:54:59116 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
xhwang@chromium.org97a9ce42012-10-19 10:06:43117 .Times(AtMost(1))
Jose Lopes109230ec2020-02-24 10:28:12118 .WillOnce(RunOnceCallback<1>(true));
Xiaohan Wangd72ce5d2020-07-14 01:34:43119 EXPECT_CALL(*cdm_context_, RegisterEventCB(_)).WillOnce([&](auto cb) {
120 event_cb_ = cb;
121 return std::make_unique<CallbackRegistration>();
122 });
xhwang@chromium.org97a9ce42012-10-19 10:06:43123
Dale Curtisbafd563172021-08-13 02:07:47124 config_.Initialize(AudioCodec::kVorbis, kSampleFormatPlanarF32,
chcunningham9812dd82015-10-20 01:42:09125 CHANNEL_LAYOUT_STEREO, kSampleRate, EmptyExtraData(),
Yuchen Liub33bfc12019-11-08 20:16:12126 EncryptionScheme::kCenc, base::TimeDelta(), 0);
xhwang59c321f2015-06-05 23:46:55127 InitializeAndExpectResult(config_, true);
xhwang@chromium.org97a9ce42012-10-19 10:06:43128 }
129
Xiaohan Wangc03ce232018-05-30 21:07:58130 void Reinitialize() { ReinitializeConfigChange(config_); }
rileya@chromium.orgd70157792014-03-17 21:45:03131
dalecurtis@google.com6fb86542014-04-18 19:58:13132 void ReinitializeConfigChange(const AudioDecoderConfig& new_config) {
rileya@chromium.orgd70157792014-03-17 21:45:03133 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
134 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
Jose Lopes109230ec2020-02-24 10:28:12135 .WillOnce(RunOnceCallback<1>(true));
Ted Meyer2a41e242020-03-20 08:01:27136 decoder_->Initialize(
137 new_config, cdm_context_.get(),
Ted Meyera8afec222022-01-12 02:37:27138 base::BindOnce(
139 [](DecoderStatus status) { EXPECT_TRUE(status.is_ok()); }),
David Bienvenub8c87522020-11-11 22:59:50140 base::BindRepeating(&DecryptingAudioDecoderTest::FrameReady,
141 base::Unretained(this)),
142 base::BindRepeating(&DecryptingAudioDecoderTest::OnWaiting,
143 base::Unretained(this)));
rileya@chromium.orgd70157792014-03-17 21:45:03144 }
145
xhwang@chromium.org5c5e9b72014-06-17 19:21:12146 // Decode |buffer| and expect DecodeDone to get called with |status|.
Ted Meyera8afec222022-01-12 02:37:27147 void DecodeAndExpect(scoped_refptr<DecoderBuffer> buffer,
148 DecoderStatus status) {
Frank Liberato3d157ba2020-09-24 18:19:30149 EXPECT_CALL(*this, DecodeDone(HasStatusCode(status)));
David Bienvenub8c87522020-11-11 22:59:50150 decoder_->Decode(buffer,
151 base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
152 base::Unretained(this)));
fdorayf920dcf2016-06-27 17:16:59153 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43154 }
155
xhwang@chromium.org5c5e9b72014-06-17 19:21:12156 // Helper function to simulate the decrypting and decoding process in the
157 // |decryptor_| with a decoding delay of kDecodingDelay buffers.
Dale Curtisca8ad982018-04-09 20:23:14158 void DecryptAndDecodeAudio(scoped_refptr<DecoderBuffer> encrypted,
Daniel Cheng868ab272021-02-24 17:07:15159 Decryptor::AudioDecodeCB audio_decode_cb) {
xhwang@chromium.org5c5e9b72014-06-17 19:21:12160 num_decrypt_and_decode_calls_++;
161 if (!encrypted->end_of_stream())
162 num_frames_in_decryptor_++;
163
164 if (num_decrypt_and_decode_calls_ <= kDecodingDelay ||
165 num_frames_in_decryptor_ == 0) {
Daniel Cheng868ab272021-02-24 17:07:15166 std::move(audio_decode_cb)
167 .Run(Decryptor::kNeedMoreData, Decryptor::AudioFrames());
xhwang@chromium.org5c5e9b72014-06-17 19:21:12168 return;
169 }
170
171 num_frames_in_decryptor_--;
Daniel Cheng868ab272021-02-24 17:07:15172 std::move(audio_decode_cb)
173 .Run(Decryptor::kSuccess, Decryptor::AudioFrames(1, decoded_frame_));
xhwang@chromium.org5c5e9b72014-06-17 19:21:12174 }
175
xhwang@chromium.org97a9ce42012-10-19 10:06:43176 // Sets up expectations and actions to put DecryptingAudioDecoder in an
177 // active normal decoding state.
178 void EnterNormalDecodingState() {
Xiaohan Wangc03ce232018-05-30 21:07:58179 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
180 .WillRepeatedly(
181 Invoke(this, &DecryptingAudioDecoderTest::DecryptAndDecodeAudio));
xhwang@chromium.org5c5e9b72014-06-17 19:21:12182 EXPECT_CALL(*this, FrameReady(decoded_frame_));
183 for (int i = 0; i < kDecodingDelay + 1; ++i)
Ted Meyera8afec222022-01-12 02:37:27184 DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kOk);
xhwang@chromium.org97a9ce42012-10-19 10:06:43185 }
186
187 // Sets up expectations and actions to put DecryptingAudioDecoder in an end
188 // of stream state. This function must be called after
189 // EnterNormalDecodingState() to work.
190 void EnterEndOfStreamState() {
xhwang@chromium.orgff757032014-06-19 01:42:24191 // The codec in the |decryptor_| will be flushed.
Xiaohan Wangc03ce232018-05-30 21:07:58192 EXPECT_CALL(*this, FrameReady(decoded_frame_)).Times(kDecodingDelay);
Ted Meyera8afec222022-01-12 02:37:27193 DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(),
194 DecoderStatus::Codes::kOk);
xhwang@chromium.org5c5e9b72014-06-17 19:21:12195 EXPECT_EQ(0, num_frames_in_decryptor_);
xhwang@chromium.org97a9ce42012-10-19 10:06:43196 }
197
198 // Make the audio decode callback pending by saving and not firing it.
199 void EnterPendingDecodeState() {
Dale Curtise25163812018-09-21 22:13:39200 EXPECT_TRUE(!pending_audio_decode_cb_);
xhwang@chromium.org97a9ce42012-10-19 10:06:43201 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
Daniel Cheng868ab272021-02-24 17:07:15202 .WillOnce(MoveArg<1>(&pending_audio_decode_cb_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43203
rileya@chromium.orgd70157792014-03-17 21:45:03204 decoder_->Decode(encrypted_buffer_,
David Bienvenub8c87522020-11-11 22:59:50205 base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
206 base::Unretained(this)));
fdorayf920dcf2016-06-27 17:16:59207 base::RunLoop().RunUntilIdle();
rileya@chromium.orgd70157792014-03-17 21:45:03208 // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
209 // the decryptor.
Dale Curtise25163812018-09-21 22:13:39210 EXPECT_FALSE(!pending_audio_decode_cb_);
xhwang@chromium.org97a9ce42012-10-19 10:06:43211 }
212
213 void EnterWaitingForKeyState() {
xhwang@chromium.org2b454ff82012-11-15 03:57:58214 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
Xiaohan Wangc03ce232018-05-30 21:07:58215 .WillRepeatedly(
Daniel Cheng868ab272021-02-24 17:07:15216 RunOnceCallback<1>(Decryptor::kNoKey, Decryptor::AudioFrames()));
Xiaohan Wang640b41d2018-12-18 19:00:46217 EXPECT_CALL(*this, OnWaiting(WaitingReason::kNoDecryptionKey));
rileya@chromium.orgd70157792014-03-17 21:45:03218 decoder_->Decode(encrypted_buffer_,
David Bienvenub8c87522020-11-11 22:59:50219 base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
220 base::Unretained(this)));
Xiaohan Wang689cd4282017-08-04 07:54:55221
fdorayf920dcf2016-06-27 17:16:59222 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43223 }
224
225 void AbortPendingAudioDecodeCB() {
Dale Curtise25163812018-09-21 22:13:39226 if (pending_audio_decode_cb_) {
227 std::move(pending_audio_decode_cb_)
Xiaohan Wangc03ce232018-05-30 21:07:58228 .Run(Decryptor::kSuccess, Decryptor::AudioFrames());
xhwang@chromium.org97a9ce42012-10-19 10:06:43229 }
230 }
231
rileya@chromium.orgb960fd02014-01-23 04:48:54232 void AbortAllPendingCBs() {
Dale Curtise25163812018-09-21 22:13:39233 if (pending_init_cb_) {
234 ASSERT_TRUE(!pending_audio_decode_cb_);
235 std::move(pending_init_cb_).Run(false);
rileya@chromium.orgb960fd02014-01-23 04:48:54236 return;
237 }
238
239 AbortPendingAudioDecodeCB();
240 }
241
xhwang@chromium.org97a9ce42012-10-19 10:06:43242 void Reset() {
243 EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio))
244 .WillRepeatedly(InvokeWithoutArgs(
245 this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB));
246
247 decoder_->Reset(NewExpectedClosure());
fdorayf920dcf2016-06-27 17:16:59248 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43249 }
250
xhwang@chromium.org83fb2a9e2014-07-16 23:36:41251 void Destroy() {
rileya@chromium.orgb960fd02014-01-23 04:48:54252 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio))
253 .WillRepeatedly(InvokeWithoutArgs(
254 this, &DecryptingAudioDecoderTest::AbortAllPendingCBs));
255
xhwang@chromium.org83fb2a9e2014-07-16 23:36:41256 decoder_.reset();
fdorayf920dcf2016-06-27 17:16:59257 base::RunLoop().RunUntilIdle();
rileya@chromium.orgb960fd02014-01-23 04:48:54258 }
259
John Rummell1b2b63d2019-04-26 20:45:57260 MOCK_METHOD1(FrameReady, void(scoped_refptr<AudioBuffer>));
Ted Meyera8afec222022-01-12 02:37:27261 MOCK_METHOD1(DecodeDone, void(DecoderStatus));
xhwang@chromium.org97a9ce42012-10-19 10:06:43262
Xiaohan Wang640b41d2018-12-18 19:00:46263 MOCK_METHOD1(OnWaiting, void(WaitingReason));
jrummell74fc4f942015-03-02 22:48:27264
Gabriel Charette311b0e92019-09-09 20:01:25265 base::test::SingleThreadTaskEnvironment task_environment_;
Vikram Pasupathyabfd18a2023-01-26 20:56:20266 StrictMock<MockMediaLog> media_log_;
dcheng254c5362016-04-22 01:12:48267 std::unique_ptr<DecryptingAudioDecoder> decoder_;
268 std::unique_ptr<StrictMock<MockCdmContext>> cdm_context_;
269 std::unique_ptr<StrictMock<MockDecryptor>> decryptor_;
xhwang@chromium.org7c39486c2013-01-06 15:36:09270 AudioDecoderConfig config_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43271
xhwang@chromium.org5c5e9b72014-06-17 19:21:12272 // Variables to help the |decryptor_| to simulate decoding delay and flushing.
273 int num_decrypt_and_decode_calls_;
274 int num_frames_in_decryptor_;
275
xhwang@chromium.org97a9ce42012-10-19 10:06:43276 Decryptor::DecoderInitCB pending_init_cb_;
Xiaohan Wangd72ce5d2020-07-14 01:34:43277 CdmContext::EventCB event_cb_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43278 Decryptor::AudioDecodeCB pending_audio_decode_cb_;
279
rileya@chromium.orgd70157792014-03-17 21:45:03280 // Constant buffer/frames, to be used/returned by |decoder_| and |decryptor_|.
xhwang@chromium.org97a9ce42012-10-19 10:06:43281 scoped_refptr<DecoderBuffer> encrypted_buffer_;
jrummell@chromium.org47b37a62013-07-10 03:56:10282 scoped_refptr<AudioBuffer> decoded_frame_;
anujk.sharmaf1cb600a2015-01-07 19:11:13283 Decryptor::AudioFrames decoded_frame_list_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43284};
285
286TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) {
287 Initialize();
288}
289
xhwang@chromium.org97a9ce42012-10-19 10:06:43290// Ensure decoder handles invalid audio configs without crashing.
291TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) {
Dale Curtisbafd563172021-08-13 02:07:47292 AudioDecoderConfig config(AudioCodec::kUnknown, kUnknownSampleFormat,
dougsteed8d5275f2016-03-12 00:04:30293 CHANNEL_LAYOUT_STEREO, 0, EmptyExtraData(),
Yuchen Liub33bfc12019-11-08 20:16:12294 EncryptionScheme::kCenc);
xhwang@chromium.org97a9ce42012-10-19 10:06:43295
xhwang59c321f2015-06-05 23:46:55296 InitializeAndExpectResult(config, false);
xhwang@chromium.org97a9ce42012-10-19 10:06:43297}
298
299// Ensure decoder handles unsupported audio configs without crashing.
300TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) {
xhwang00f69db72015-11-12 07:32:37301 SetCdmType(CDM_WITH_DECRYPTOR);
Xiaohan Wangd72ce5d2020-07-14 01:34:43302 EXPECT_CALL(*cdm_context_, RegisterEventCB(_)).WillOnce([&](auto cb) {
303 event_cb_ = cb;
304 return std::make_unique<CallbackRegistration>();
305 });
xhwang@chromium.orga3e28672013-03-14 14:54:59306 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
Jose Lopes109230ec2020-02-24 10:28:12307 .WillOnce(RunOnceCallback<1>(false));
xhwang@chromium.org97a9ce42012-10-19 10:06:43308
Dale Curtisbafd563172021-08-13 02:07:47309 AudioDecoderConfig config(AudioCodec::kVorbis, kSampleFormatPlanarF32,
chcunningham9812dd82015-10-20 01:42:09310 CHANNEL_LAYOUT_STEREO, kSampleRate,
Yuchen Liub33bfc12019-11-08 20:16:12311 EmptyExtraData(), EncryptionScheme::kCenc);
xhwang59c321f2015-06-05 23:46:55312 InitializeAndExpectResult(config, false);
xhwang@chromium.org97a9ce42012-10-19 10:06:43313}
314
xhwang00f69db72015-11-12 07:32:37315TEST_F(DecryptingAudioDecoderTest, Initialize_CdmWithoutDecryptor) {
316 SetCdmType(CDM_WITHOUT_DECRYPTOR);
Dale Curtisbafd563172021-08-13 02:07:47317 AudioDecoderConfig config(AudioCodec::kVorbis, kSampleFormatPlanarF32,
chcunningham9812dd82015-10-20 01:42:09318 CHANNEL_LAYOUT_STEREO, kSampleRate,
Yuchen Liub33bfc12019-11-08 20:16:12319 EmptyExtraData(), EncryptionScheme::kCenc);
xhwang59c321f2015-06-05 23:46:55320 InitializeAndExpectResult(config, false);
xhwang@chromium.org699b64a2013-06-19 07:36:05321}
322
xhwang@chromium.org97a9ce42012-10-19 10:06:43323// Test normal decrypt and decode case.
324TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) {
325 Initialize();
326 EnterNormalDecodingState();
327}
328
Vikram Pasupathyabfd18a2023-01-26 20:56:20329// Test the case where the decryptor errors for mismatched subsamples
330TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_SubsampleError) {
331 Initialize();
332
333 scoped_refptr<media::DecoderBuffer> mismatched_encrypted_buffer =
334 CreateMismatchedBufferForTest();
335
336 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
337 .WillRepeatedly(
338 RunOnceCallback<1>(Decryptor::kError, Decryptor::AudioFrames()));
339 EXPECT_MEDIA_LOG(
340 HasSubstr("DecryptingAudioDecoder: Subsamples for Buffer do not match"));
341
342 DecodeAndExpect(mismatched_encrypted_buffer, DecoderStatus::Codes::kFailed);
343}
344
xhwang@chromium.org97a9ce42012-10-19 10:06:43345// Test the case where the decryptor returns error when doing decrypt and
346// decode.
347TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) {
348 Initialize();
349
xhwang@chromium.org97a9ce42012-10-19 10:06:43350 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
Xiaohan Wangc03ce232018-05-30 21:07:58351 .WillRepeatedly(
Daniel Cheng868ab272021-02-24 17:07:15352 RunOnceCallback<1>(Decryptor::kError, Decryptor::AudioFrames()));
Vikram Pasupathyabfd18a2023-01-26 20:56:20353 EXPECT_MEDIA_LOG(HasSubstr("DecryptingAudioDecoder: decode error"));
xhwang@chromium.org97a9ce42012-10-19 10:06:43354
Ted Meyera8afec222022-01-12 02:37:27355 DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kFailed);
xhwang@chromium.org97a9ce42012-10-19 10:06:43356}
357
358// Test the case where the decryptor returns multiple decoded frames.
359TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) {
360 Initialize();
361
jrummell@chromium.org47b37a62013-07-10 03:56:10362 scoped_refptr<AudioBuffer> frame_a = AudioBuffer::CreateEmptyBuffer(
rileya@chromium.org16ecd5f2014-03-20 05:41:07363 config_.channel_layout(),
dalecurtis39a7f932016-07-19 18:34:59364 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
365 kFakeAudioFrameSize, kNoTimestamp);
jrummell@chromium.org47b37a62013-07-10 03:56:10366 scoped_refptr<AudioBuffer> frame_b = AudioBuffer::CreateEmptyBuffer(
rileya@chromium.org16ecd5f2014-03-20 05:41:07367 config_.channel_layout(),
dalecurtis39a7f932016-07-19 18:34:59368 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
369 kFakeAudioFrameSize, kNoTimestamp);
xhwang@chromium.orgecbb9762012-10-24 22:33:54370 decoded_frame_list_.push_back(frame_a);
371 decoded_frame_list_.push_back(frame_b);
xhwang@chromium.org97a9ce42012-10-19 10:06:43372
xhwang@chromium.org97a9ce42012-10-19 10:06:43373 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
Daniel Cheng868ab272021-02-24 17:07:15374 .WillOnce(RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43375
xhwang@chromium.org5c5e9b72014-06-17 19:21:12376 EXPECT_CALL(*this, FrameReady(decoded_frame_));
377 EXPECT_CALL(*this, FrameReady(frame_a));
378 EXPECT_CALL(*this, FrameReady(frame_b));
Ted Meyera8afec222022-01-12 02:37:27379 DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kOk);
xhwang@chromium.org97a9ce42012-10-19 10:06:43380}
381
382// Test the case where the decryptor receives end-of-stream buffer.
383TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) {
384 Initialize();
385 EnterNormalDecodingState();
386 EnterEndOfStreamState();
387}
388
xhwang65c23032017-02-17 04:37:42389// Test reinitializing decode with a new encrypted config.
390TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToEncrypted) {
xhwang@chromium.org7c39486c2013-01-06 15:36:09391 Initialize();
392
rileya@chromium.orgd70157792014-03-17 21:45:03393 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
394 .Times(AtMost(1))
Jose Lopes109230ec2020-02-24 10:28:12395 .WillOnce(RunOnceCallback<1>(true));
xhwang@chromium.org7c39486c2013-01-06 15:36:09396
xhwang@chromium.orgecf16912013-01-12 16:55:22397 // The new config is different from the initial config in bits-per-channel,
398 // channel layout and samples_per_second.
Dale Curtisbafd563172021-08-13 02:07:47399 AudioDecoderConfig new_config(AudioCodec::kVorbis, kSampleFormatPlanarS16,
chcunningham9812dd82015-10-20 01:42:09400 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
Yuchen Liub33bfc12019-11-08 20:16:12401 EncryptionScheme::kCenc);
xhwang@chromium.orgecf16912013-01-12 16:55:22402 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
403 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
404 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
xhwang65c23032017-02-17 04:37:42405 ASSERT_TRUE(new_config.is_encrypted());
406
407 ReinitializeConfigChange(new_config);
408 base::RunLoop().RunUntilIdle();
409}
410
411// Test reinitializing decode with a new clear config.
412TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToClear) {
413 Initialize();
414
415 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
416 .Times(AtMost(1))
Jose Lopes109230ec2020-02-24 10:28:12417 .WillOnce(RunOnceCallback<1>(true));
xhwang65c23032017-02-17 04:37:42418
419 // The new config is different from the initial config in bits-per-channel,
420 // channel layout and samples_per_second.
Dale Curtisbafd563172021-08-13 02:07:47421 AudioDecoderConfig new_config(AudioCodec::kVorbis, kSampleFormatPlanarS16,
xhwang65c23032017-02-17 04:37:42422 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
Yuchen Liub33bfc12019-11-08 20:16:12423 EncryptionScheme::kUnencrypted);
xhwang65c23032017-02-17 04:37:42424 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
425 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
426 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
427 ASSERT_FALSE(new_config.is_encrypted());
xhwang@chromium.orgecf16912013-01-12 16:55:22428
rileya@chromium.orgd70157792014-03-17 21:45:03429 ReinitializeConfigChange(new_config);
fdorayf920dcf2016-06-27 17:16:59430 base::RunLoop().RunUntilIdle();
xhwang@chromium.org7c39486c2013-01-06 15:36:09431}
432
xhwang@chromium.org97a9ce42012-10-19 10:06:43433// Test the case where the a key is added when the decryptor is in
434// kWaitingForKey state.
435TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) {
436 Initialize();
Vikram Pasupathyabfd18a2023-01-26 20:56:20437 EXPECT_MEDIA_LOG(HasSubstr("DecryptingAudioDecoder: no key for key"));
xhwang@chromium.org97a9ce42012-10-19 10:06:43438 EnterWaitingForKeyState();
439
440 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
Daniel Cheng868ab272021-02-24 17:07:15441 .WillRepeatedly(
442 RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
sergeyu@chromium.org49cea862014-06-11 11:11:50443 EXPECT_CALL(*this, FrameReady(decoded_frame_));
Frank Liberato3d157ba2020-09-24 18:19:30444 EXPECT_CALL(*this, DecodeDone(IsOkStatus()));
Vikram Pasupathyabfd18a2023-01-26 20:56:20445 EXPECT_MEDIA_LOG(
446 HasSubstr("DecryptingAudioDecoder: key added, resuming decode"));
Xiaohan Wangd72ce5d2020-07-14 01:34:43447 event_cb_.Run(CdmContext::Event::kHasAdditionalUsableKey);
fdorayf920dcf2016-06-27 17:16:59448 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43449}
450
451// Test the case where the a key is added when the decryptor is in
452// kPendingDecode state.
Vikram Pasupathyabfd18a2023-01-26 20:56:20453TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringPendingDecode) {
xhwang@chromium.org97a9ce42012-10-19 10:06:43454 Initialize();
Vikram Pasupathyabfd18a2023-01-26 20:56:20455 EXPECT_MEDIA_LOG(HasSubstr("DecryptingAudioDecoder: no key for key"));
xhwang@chromium.org97a9ce42012-10-19 10:06:43456 EnterPendingDecodeState();
457
458 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
Daniel Cheng868ab272021-02-24 17:07:15459 .WillRepeatedly(
460 RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
sergeyu@chromium.org49cea862014-06-11 11:11:50461 EXPECT_CALL(*this, FrameReady(decoded_frame_));
Frank Liberato3d157ba2020-09-24 18:19:30462 EXPECT_CALL(*this, DecodeDone(IsOkStatus()));
Vikram Pasupathyabfd18a2023-01-26 20:56:20463 EXPECT_MEDIA_LOG(
464 HasSubstr("DecryptingAudioDecoder: key was added, resuming decode"));
xhwang@chromium.org97a9ce42012-10-19 10:06:43465 // The audio decode callback is returned after the correct decryption key is
466 // added.
Xiaohan Wangd72ce5d2020-07-14 01:34:43467 event_cb_.Run(CdmContext::Event::kHasAdditionalUsableKey);
Dale Curtise25163812018-09-21 22:13:39468 std::move(pending_audio_decode_cb_)
Xiaohan Wangc03ce232018-05-30 21:07:58469 .Run(Decryptor::kNoKey, Decryptor::AudioFrames());
fdorayf920dcf2016-06-27 17:16:59470 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43471}
472
473// Test resetting when the decoder is in kIdle state but has not decoded any
474// frame.
475TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) {
476 Initialize();
477 Reset();
478}
479
480// Test resetting when the decoder is in kIdle state after it has decoded one
481// frame.
482TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
483 Initialize();
484 EnterNormalDecodingState();
485 Reset();
486}
487
xhwang@chromium.org97a9ce42012-10-19 10:06:43488// Test resetting when the decoder is in kPendingDecode state.
489TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) {
490 Initialize();
491 EnterPendingDecodeState();
492
Ted Meyera8afec222022-01-12 02:37:27493 EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted)));
xhwang@chromium.org97a9ce42012-10-19 10:06:43494
495 Reset();
496}
497
498// Test resetting when the decoder is in kWaitingForKey state.
499TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) {
500 Initialize();
Vikram Pasupathyabfd18a2023-01-26 20:56:20501 EXPECT_MEDIA_LOG(HasSubstr("DecryptingAudioDecoder: no key for key"));
xhwang@chromium.org97a9ce42012-10-19 10:06:43502 EnterWaitingForKeyState();
503
Ted Meyera8afec222022-01-12 02:37:27504 EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted)));
xhwang@chromium.org97a9ce42012-10-19 10:06:43505
506 Reset();
507}
508
509// Test resetting when the decoder has hit end of stream and is in
510// kDecodeFinished state.
511TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) {
512 Initialize();
513 EnterNormalDecodingState();
514 EnterEndOfStreamState();
515 Reset();
516}
517
518// Test resetting after the decoder has been reset.
519TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) {
520 Initialize();
521 EnterNormalDecodingState();
522 Reset();
523 Reset();
524}
525
xhwang@chromium.org97a9ce42012-10-19 10:06:43526} // namespace media