[go: nahoru, domu]

blob: af063901f35846d7658b15203a869fedf9710c2f [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;
xhwang@chromium.org5c5e9b72014-06-17 19:21:1242const int kDecodingDelay = 3;
xhwang@chromium.org97a9ce42012-10-19 10:06:4343
xhwang@chromium.org97a9ce42012-10-19 10:06:4344class DecryptingAudioDecoderTest : public testing::Test {
45 public:
46 DecryptingAudioDecoderTest()
Vikram Pasupathy7c7e28c2023-04-14 23:30:2147 : decoder_(std::make_unique<DecryptingAudioDecoder>(
Gabriel Charettedfa36042019-08-19 17:30:1148 task_environment_.GetMainThreadTaskRunner(),
Carlos Caballero9de7c722019-05-31 21:25:0749 &media_log_)),
Vikram Pasupathy7c7e28c2023-04-14 23:30:2150 cdm_context_(std::make_unique<StrictMock<MockCdmContext>>()),
51 decryptor_(std::make_unique<StrictMock<MockDecryptor>>()),
xhwang@chromium.org5c5e9b72014-06-17 19:21:1252 num_decrypt_and_decode_calls_(0),
53 num_frames_in_decryptor_(0),
xhwang@chromium.org97a9ce42012-10-19 10:06:4354 encrypted_buffer_(CreateFakeEncryptedBuffer()),
kylechar938dc442019-10-29 14:40:2455 decoded_frame_(nullptr),
rileya@chromium.orgd70157792014-03-17 21:45:0356 decoded_frame_list_() {}
xhwang@chromium.org97a9ce42012-10-19 10:06:4357
Peter Boström4c42559f2021-09-22 20:24:3458 DecryptingAudioDecoderTest(const DecryptingAudioDecoderTest&) = delete;
59 DecryptingAudioDecoderTest& operator=(const DecryptingAudioDecoderTest&) =
60 delete;
61
Daniel Cheng9f0b7012018-04-26 21:09:0562 ~DecryptingAudioDecoderTest() override { Destroy(); }
rileya@chromium.orgb960fd02014-01-23 04:48:5463
xhwang59c321f2015-06-05 23:46:5564 void InitializeAndExpectResult(const AudioDecoderConfig& config,
65 bool success) {
dalecurtis@google.come81f5f9d2014-03-29 01:32:1666 // 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());
70 if (channels < 0)
71 channels = 0;
dalecurtis39a7f932016-07-19 18:34:5972 decoded_frame_ = AudioBuffer::CreateEmptyBuffer(
73 config.channel_layout(), channels, kSampleRate, kFakeAudioFrameSize,
74 kNoTimestamp);
jrummell@chromium.org47b37a62013-07-10 03:56:1075 decoded_frame_list_.push_back(decoded_frame_);
76
David Bienvenub8c87522020-11-11 22:59:5077 decoder_->Initialize(
78 config, cdm_context_.get(),
79 base::BindOnce(
Ted Meyera8afec222022-01-12 02:37:2780 [](bool success, DecoderStatus status) {
David Bienvenub8c87522020-11-11 22:59:5081 EXPECT_EQ(status.is_ok(), success);
82 },
83 success),
84 base::BindRepeating(&DecryptingAudioDecoderTest::FrameReady,
85 base::Unretained(this)),
86 base::BindRepeating(&DecryptingAudioDecoderTest::OnWaiting,
87 base::Unretained(this)));
fdorayf920dcf2016-06-27 17:16:5988 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:4389 }
90
xhwanga935e442016-02-11 02:22:4591 enum CdmType { CDM_WITHOUT_DECRYPTOR, CDM_WITH_DECRYPTOR };
xhwang00f69db72015-11-12 07:32:3792
93 void SetCdmType(CdmType cdm_type) {
xhwang00f69db72015-11-12 07:32:3794 const bool has_decryptor = cdm_type == CDM_WITH_DECRYPTOR;
xhwanga935e442016-02-11 02:22:4595 EXPECT_CALL(*cdm_context_, GetDecryptor())
96 .WillRepeatedly(Return(has_decryptor ? decryptor_.get() : nullptr));
jrummell@chromium.org9ebc3b032014-08-13 04:01:2397 }
98
xhwang@chromium.org97a9ce42012-10-19 10:06:4399 void Initialize() {
xhwang00f69db72015-11-12 07:32:37100 SetCdmType(CDM_WITH_DECRYPTOR);
xhwang@chromium.orga3e28672013-03-14 14:54:59101 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
xhwang@chromium.org97a9ce42012-10-19 10:06:43102 .Times(AtMost(1))
Jose Lopes109230ec2020-02-24 10:28:12103 .WillOnce(RunOnceCallback<1>(true));
Xiaohan Wangd72ce5d2020-07-14 01:34:43104 EXPECT_CALL(*cdm_context_, RegisterEventCB(_)).WillOnce([&](auto cb) {
105 event_cb_ = cb;
106 return std::make_unique<CallbackRegistration>();
107 });
xhwang@chromium.org97a9ce42012-10-19 10:06:43108
Dale Curtisbafd563172021-08-13 02:07:47109 config_.Initialize(AudioCodec::kVorbis, kSampleFormatPlanarF32,
chcunningham9812dd82015-10-20 01:42:09110 CHANNEL_LAYOUT_STEREO, kSampleRate, EmptyExtraData(),
Yuchen Liub33bfc12019-11-08 20:16:12111 EncryptionScheme::kCenc, base::TimeDelta(), 0);
xhwang59c321f2015-06-05 23:46:55112 InitializeAndExpectResult(config_, true);
xhwang@chromium.org97a9ce42012-10-19 10:06:43113 }
114
Xiaohan Wangc03ce232018-05-30 21:07:58115 void Reinitialize() { ReinitializeConfigChange(config_); }
rileya@chromium.orgd70157792014-03-17 21:45:03116
dalecurtis@google.com6fb86542014-04-18 19:58:13117 void ReinitializeConfigChange(const AudioDecoderConfig& new_config) {
rileya@chromium.orgd70157792014-03-17 21:45:03118 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
119 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
Jose Lopes109230ec2020-02-24 10:28:12120 .WillOnce(RunOnceCallback<1>(true));
Ted Meyer2a41e242020-03-20 08:01:27121 decoder_->Initialize(
122 new_config, cdm_context_.get(),
Ted Meyera8afec222022-01-12 02:37:27123 base::BindOnce(
124 [](DecoderStatus status) { EXPECT_TRUE(status.is_ok()); }),
David Bienvenub8c87522020-11-11 22:59:50125 base::BindRepeating(&DecryptingAudioDecoderTest::FrameReady,
126 base::Unretained(this)),
127 base::BindRepeating(&DecryptingAudioDecoderTest::OnWaiting,
128 base::Unretained(this)));
rileya@chromium.orgd70157792014-03-17 21:45:03129 }
130
xhwang@chromium.org5c5e9b72014-06-17 19:21:12131 // Decode |buffer| and expect DecodeDone to get called with |status|.
Ted Meyera8afec222022-01-12 02:37:27132 void DecodeAndExpect(scoped_refptr<DecoderBuffer> buffer,
133 DecoderStatus status) {
Frank Liberato3d157ba2020-09-24 18:19:30134 EXPECT_CALL(*this, DecodeDone(HasStatusCode(status)));
David Bienvenub8c87522020-11-11 22:59:50135 decoder_->Decode(buffer,
136 base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
137 base::Unretained(this)));
fdorayf920dcf2016-06-27 17:16:59138 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43139 }
140
xhwang@chromium.org5c5e9b72014-06-17 19:21:12141 // Helper function to simulate the decrypting and decoding process in the
142 // |decryptor_| with a decoding delay of kDecodingDelay buffers.
Dale Curtisca8ad982018-04-09 20:23:14143 void DecryptAndDecodeAudio(scoped_refptr<DecoderBuffer> encrypted,
Daniel Cheng868ab272021-02-24 17:07:15144 Decryptor::AudioDecodeCB audio_decode_cb) {
xhwang@chromium.org5c5e9b72014-06-17 19:21:12145 num_decrypt_and_decode_calls_++;
146 if (!encrypted->end_of_stream())
147 num_frames_in_decryptor_++;
148
149 if (num_decrypt_and_decode_calls_ <= kDecodingDelay ||
150 num_frames_in_decryptor_ == 0) {
Daniel Cheng868ab272021-02-24 17:07:15151 std::move(audio_decode_cb)
152 .Run(Decryptor::kNeedMoreData, Decryptor::AudioFrames());
xhwang@chromium.org5c5e9b72014-06-17 19:21:12153 return;
154 }
155
156 num_frames_in_decryptor_--;
Daniel Cheng868ab272021-02-24 17:07:15157 std::move(audio_decode_cb)
158 .Run(Decryptor::kSuccess, Decryptor::AudioFrames(1, decoded_frame_));
xhwang@chromium.org5c5e9b72014-06-17 19:21:12159 }
160
xhwang@chromium.org97a9ce42012-10-19 10:06:43161 // Sets up expectations and actions to put DecryptingAudioDecoder in an
162 // active normal decoding state.
163 void EnterNormalDecodingState() {
Xiaohan Wangc03ce232018-05-30 21:07:58164 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
165 .WillRepeatedly(
166 Invoke(this, &DecryptingAudioDecoderTest::DecryptAndDecodeAudio));
xhwang@chromium.org5c5e9b72014-06-17 19:21:12167 EXPECT_CALL(*this, FrameReady(decoded_frame_));
168 for (int i = 0; i < kDecodingDelay + 1; ++i)
Ted Meyera8afec222022-01-12 02:37:27169 DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kOk);
xhwang@chromium.org97a9ce42012-10-19 10:06:43170 }
171
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() {
xhwang@chromium.orgff757032014-06-19 01:42:24176 // The codec in the |decryptor_| will be flushed.
Xiaohan Wangc03ce232018-05-30 21:07:58177 EXPECT_CALL(*this, FrameReady(decoded_frame_)).Times(kDecodingDelay);
Ted Meyera8afec222022-01-12 02:37:27178 DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(),
179 DecoderStatus::Codes::kOk);
xhwang@chromium.org5c5e9b72014-06-17 19:21:12180 EXPECT_EQ(0, num_frames_in_decryptor_);
xhwang@chromium.org97a9ce42012-10-19 10:06:43181 }
182
183 // Make the audio decode callback pending by saving and not firing it.
184 void EnterPendingDecodeState() {
Dale Curtise25163812018-09-21 22:13:39185 EXPECT_TRUE(!pending_audio_decode_cb_);
xhwang@chromium.org97a9ce42012-10-19 10:06:43186 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
Daniel Cheng868ab272021-02-24 17:07:15187 .WillOnce(MoveArg<1>(&pending_audio_decode_cb_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43188
rileya@chromium.orgd70157792014-03-17 21:45:03189 decoder_->Decode(encrypted_buffer_,
David Bienvenub8c87522020-11-11 22:59:50190 base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
191 base::Unretained(this)));
fdorayf920dcf2016-06-27 17:16:59192 base::RunLoop().RunUntilIdle();
rileya@chromium.orgd70157792014-03-17 21:45:03193 // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
194 // the decryptor.
Dale Curtise25163812018-09-21 22:13:39195 EXPECT_FALSE(!pending_audio_decode_cb_);
xhwang@chromium.org97a9ce42012-10-19 10:06:43196 }
197
198 void EnterWaitingForKeyState() {
xhwang@chromium.org2b454ff82012-11-15 03:57:58199 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
Xiaohan Wangc03ce232018-05-30 21:07:58200 .WillRepeatedly(
Daniel Cheng868ab272021-02-24 17:07:15201 RunOnceCallback<1>(Decryptor::kNoKey, Decryptor::AudioFrames()));
Xiaohan Wang640b41d2018-12-18 19:00:46202 EXPECT_CALL(*this, OnWaiting(WaitingReason::kNoDecryptionKey));
rileya@chromium.orgd70157792014-03-17 21:45:03203 decoder_->Decode(encrypted_buffer_,
David Bienvenub8c87522020-11-11 22:59:50204 base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
205 base::Unretained(this)));
Xiaohan Wang689cd4282017-08-04 07:54:55206
fdorayf920dcf2016-06-27 17:16:59207 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43208 }
209
210 void AbortPendingAudioDecodeCB() {
Dale Curtise25163812018-09-21 22:13:39211 if (pending_audio_decode_cb_) {
212 std::move(pending_audio_decode_cb_)
Xiaohan Wangc03ce232018-05-30 21:07:58213 .Run(Decryptor::kSuccess, Decryptor::AudioFrames());
xhwang@chromium.org97a9ce42012-10-19 10:06:43214 }
215 }
216
rileya@chromium.orgb960fd02014-01-23 04:48:54217 void AbortAllPendingCBs() {
Dale Curtise25163812018-09-21 22:13:39218 if (pending_init_cb_) {
219 ASSERT_TRUE(!pending_audio_decode_cb_);
220 std::move(pending_init_cb_).Run(false);
rileya@chromium.orgb960fd02014-01-23 04:48:54221 return;
222 }
223
224 AbortPendingAudioDecodeCB();
225 }
226
xhwang@chromium.org97a9ce42012-10-19 10:06:43227 void Reset() {
228 EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio))
229 .WillRepeatedly(InvokeWithoutArgs(
230 this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB));
231
232 decoder_->Reset(NewExpectedClosure());
fdorayf920dcf2016-06-27 17:16:59233 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43234 }
235
xhwang@chromium.org83fb2a9e2014-07-16 23:36:41236 void Destroy() {
rileya@chromium.orgb960fd02014-01-23 04:48:54237 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio))
238 .WillRepeatedly(InvokeWithoutArgs(
239 this, &DecryptingAudioDecoderTest::AbortAllPendingCBs));
240
xhwang@chromium.org83fb2a9e2014-07-16 23:36:41241 decoder_.reset();
fdorayf920dcf2016-06-27 17:16:59242 base::RunLoop().RunUntilIdle();
rileya@chromium.orgb960fd02014-01-23 04:48:54243 }
244
John Rummell1b2b63d2019-04-26 20:45:57245 MOCK_METHOD1(FrameReady, void(scoped_refptr<AudioBuffer>));
Ted Meyera8afec222022-01-12 02:37:27246 MOCK_METHOD1(DecodeDone, void(DecoderStatus));
xhwang@chromium.org97a9ce42012-10-19 10:06:43247
Xiaohan Wang640b41d2018-12-18 19:00:46248 MOCK_METHOD1(OnWaiting, void(WaitingReason));
jrummell74fc4f942015-03-02 22:48:27249
Gabriel Charette311b0e92019-09-09 20:01:25250 base::test::SingleThreadTaskEnvironment task_environment_;
Vikram Pasupathyabfd18a2023-01-26 20:56:20251 StrictMock<MockMediaLog> media_log_;
dcheng254c5362016-04-22 01:12:48252 std::unique_ptr<DecryptingAudioDecoder> decoder_;
253 std::unique_ptr<StrictMock<MockCdmContext>> cdm_context_;
254 std::unique_ptr<StrictMock<MockDecryptor>> decryptor_;
xhwang@chromium.org7c39486c2013-01-06 15:36:09255 AudioDecoderConfig config_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43256
xhwang@chromium.org5c5e9b72014-06-17 19:21:12257 // Variables to help the |decryptor_| to simulate decoding delay and flushing.
258 int num_decrypt_and_decode_calls_;
259 int num_frames_in_decryptor_;
260
xhwang@chromium.org97a9ce42012-10-19 10:06:43261 Decryptor::DecoderInitCB pending_init_cb_;
Xiaohan Wangd72ce5d2020-07-14 01:34:43262 CdmContext::EventCB event_cb_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43263 Decryptor::AudioDecodeCB pending_audio_decode_cb_;
264
rileya@chromium.orgd70157792014-03-17 21:45:03265 // Constant buffer/frames, to be used/returned by |decoder_| and |decryptor_|.
xhwang@chromium.org97a9ce42012-10-19 10:06:43266 scoped_refptr<DecoderBuffer> encrypted_buffer_;
jrummell@chromium.org47b37a62013-07-10 03:56:10267 scoped_refptr<AudioBuffer> decoded_frame_;
anujk.sharmaf1cb600a2015-01-07 19:11:13268 Decryptor::AudioFrames decoded_frame_list_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43269};
270
271TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) {
272 Initialize();
273}
274
xhwang@chromium.org97a9ce42012-10-19 10:06:43275// Ensure decoder handles invalid audio configs without crashing.
276TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) {
Dale Curtisbafd563172021-08-13 02:07:47277 AudioDecoderConfig config(AudioCodec::kUnknown, kUnknownSampleFormat,
dougsteed8d5275f2016-03-12 00:04:30278 CHANNEL_LAYOUT_STEREO, 0, EmptyExtraData(),
Yuchen Liub33bfc12019-11-08 20:16:12279 EncryptionScheme::kCenc);
xhwang@chromium.org97a9ce42012-10-19 10:06:43280
xhwang59c321f2015-06-05 23:46:55281 InitializeAndExpectResult(config, false);
xhwang@chromium.org97a9ce42012-10-19 10:06:43282}
283
284// Ensure decoder handles unsupported audio configs without crashing.
285TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) {
xhwang00f69db72015-11-12 07:32:37286 SetCdmType(CDM_WITH_DECRYPTOR);
Xiaohan Wangd72ce5d2020-07-14 01:34:43287 EXPECT_CALL(*cdm_context_, RegisterEventCB(_)).WillOnce([&](auto cb) {
288 event_cb_ = cb;
289 return std::make_unique<CallbackRegistration>();
290 });
xhwang@chromium.orga3e28672013-03-14 14:54:59291 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
Jose Lopes109230ec2020-02-24 10:28:12292 .WillOnce(RunOnceCallback<1>(false));
xhwang@chromium.org97a9ce42012-10-19 10:06:43293
Dale Curtisbafd563172021-08-13 02:07:47294 AudioDecoderConfig config(AudioCodec::kVorbis, kSampleFormatPlanarF32,
chcunningham9812dd82015-10-20 01:42:09295 CHANNEL_LAYOUT_STEREO, kSampleRate,
Yuchen Liub33bfc12019-11-08 20:16:12296 EmptyExtraData(), EncryptionScheme::kCenc);
xhwang59c321f2015-06-05 23:46:55297 InitializeAndExpectResult(config, false);
xhwang@chromium.org97a9ce42012-10-19 10:06:43298}
299
xhwang00f69db72015-11-12 07:32:37300TEST_F(DecryptingAudioDecoderTest, Initialize_CdmWithoutDecryptor) {
301 SetCdmType(CDM_WITHOUT_DECRYPTOR);
Dale Curtisbafd563172021-08-13 02:07:47302 AudioDecoderConfig config(AudioCodec::kVorbis, kSampleFormatPlanarF32,
chcunningham9812dd82015-10-20 01:42:09303 CHANNEL_LAYOUT_STEREO, kSampleRate,
Yuchen Liub33bfc12019-11-08 20:16:12304 EmptyExtraData(), EncryptionScheme::kCenc);
xhwang59c321f2015-06-05 23:46:55305 InitializeAndExpectResult(config, false);
xhwang@chromium.org699b64a2013-06-19 07:36:05306}
307
xhwang@chromium.org97a9ce42012-10-19 10:06:43308// Test normal decrypt and decode case.
309TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) {
310 Initialize();
311 EnterNormalDecodingState();
312}
313
Vikram Pasupathyabfd18a2023-01-26 20:56:20314// Test the case where the decryptor errors for mismatched subsamples
315TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_SubsampleError) {
316 Initialize();
317
318 scoped_refptr<media::DecoderBuffer> mismatched_encrypted_buffer =
319 CreateMismatchedBufferForTest();
320
321 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
322 .WillRepeatedly(
323 RunOnceCallback<1>(Decryptor::kError, Decryptor::AudioFrames()));
324 EXPECT_MEDIA_LOG(
325 HasSubstr("DecryptingAudioDecoder: Subsamples for Buffer do not match"));
326
327 DecodeAndExpect(mismatched_encrypted_buffer, DecoderStatus::Codes::kFailed);
328}
329
xhwang@chromium.org97a9ce42012-10-19 10:06:43330// Test the case where the decryptor returns error when doing decrypt and
331// decode.
332TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) {
333 Initialize();
334
xhwang@chromium.org97a9ce42012-10-19 10:06:43335 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
Xiaohan Wangc03ce232018-05-30 21:07:58336 .WillRepeatedly(
Daniel Cheng868ab272021-02-24 17:07:15337 RunOnceCallback<1>(Decryptor::kError, Decryptor::AudioFrames()));
Vikram Pasupathyabfd18a2023-01-26 20:56:20338 EXPECT_MEDIA_LOG(HasSubstr("DecryptingAudioDecoder: decode error"));
xhwang@chromium.org97a9ce42012-10-19 10:06:43339
Ted Meyera8afec222022-01-12 02:37:27340 DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kFailed);
xhwang@chromium.org97a9ce42012-10-19 10:06:43341}
342
343// Test the case where the decryptor returns multiple decoded frames.
344TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) {
345 Initialize();
346
jrummell@chromium.org47b37a62013-07-10 03:56:10347 scoped_refptr<AudioBuffer> frame_a = AudioBuffer::CreateEmptyBuffer(
rileya@chromium.org16ecd5f2014-03-20 05:41:07348 config_.channel_layout(),
dalecurtis39a7f932016-07-19 18:34:59349 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
350 kFakeAudioFrameSize, kNoTimestamp);
jrummell@chromium.org47b37a62013-07-10 03:56:10351 scoped_refptr<AudioBuffer> frame_b = AudioBuffer::CreateEmptyBuffer(
rileya@chromium.org16ecd5f2014-03-20 05:41:07352 config_.channel_layout(),
dalecurtis39a7f932016-07-19 18:34:59353 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
354 kFakeAudioFrameSize, kNoTimestamp);
xhwang@chromium.orgecbb9762012-10-24 22:33:54355 decoded_frame_list_.push_back(frame_a);
356 decoded_frame_list_.push_back(frame_b);
xhwang@chromium.org97a9ce42012-10-19 10:06:43357
xhwang@chromium.org97a9ce42012-10-19 10:06:43358 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
Daniel Cheng868ab272021-02-24 17:07:15359 .WillOnce(RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43360
xhwang@chromium.org5c5e9b72014-06-17 19:21:12361 EXPECT_CALL(*this, FrameReady(decoded_frame_));
362 EXPECT_CALL(*this, FrameReady(frame_a));
363 EXPECT_CALL(*this, FrameReady(frame_b));
Ted Meyera8afec222022-01-12 02:37:27364 DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kOk);
xhwang@chromium.org97a9ce42012-10-19 10:06:43365}
366
367// Test the case where the decryptor receives end-of-stream buffer.
368TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) {
369 Initialize();
370 EnterNormalDecodingState();
371 EnterEndOfStreamState();
372}
373
xhwang65c23032017-02-17 04:37:42374// Test reinitializing decode with a new encrypted config.
375TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToEncrypted) {
xhwang@chromium.org7c39486c2013-01-06 15:36:09376 Initialize();
377
rileya@chromium.orgd70157792014-03-17 21:45:03378 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
379 .Times(AtMost(1))
Jose Lopes109230ec2020-02-24 10:28:12380 .WillOnce(RunOnceCallback<1>(true));
xhwang@chromium.org7c39486c2013-01-06 15:36:09381
Vikram Pasupathyc1a11312023-10-09 18:52:57382 // The new config is different from the initial config in bytes-per-channel,
xhwang@chromium.orgecf16912013-01-12 16:55:22383 // channel layout and samples_per_second.
Dale Curtisbafd563172021-08-13 02:07:47384 AudioDecoderConfig new_config(AudioCodec::kVorbis, kSampleFormatPlanarS16,
chcunningham9812dd82015-10-20 01:42:09385 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
Yuchen Liub33bfc12019-11-08 20:16:12386 EncryptionScheme::kCenc);
Vikram Pasupathyc1a11312023-10-09 18:52:57387 EXPECT_NE(new_config.bytes_per_channel(), config_.bytes_per_channel());
xhwang@chromium.orgecf16912013-01-12 16:55:22388 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
389 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
xhwang65c23032017-02-17 04:37:42390 ASSERT_TRUE(new_config.is_encrypted());
391
392 ReinitializeConfigChange(new_config);
393 base::RunLoop().RunUntilIdle();
394}
395
396// Test reinitializing decode with a new clear config.
397TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToClear) {
398 Initialize();
399
400 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
401 .Times(AtMost(1))
Jose Lopes109230ec2020-02-24 10:28:12402 .WillOnce(RunOnceCallback<1>(true));
xhwang65c23032017-02-17 04:37:42403
Vikram Pasupathyc1a11312023-10-09 18:52:57404 // The new config is different from the initial config in bytes-per-channel,
xhwang65c23032017-02-17 04:37:42405 // channel layout and samples_per_second.
Dale Curtisbafd563172021-08-13 02:07:47406 AudioDecoderConfig new_config(AudioCodec::kVorbis, kSampleFormatPlanarS16,
xhwang65c23032017-02-17 04:37:42407 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
Yuchen Liub33bfc12019-11-08 20:16:12408 EncryptionScheme::kUnencrypted);
Vikram Pasupathyc1a11312023-10-09 18:52:57409 EXPECT_NE(new_config.bytes_per_channel(), config_.bytes_per_channel());
xhwang65c23032017-02-17 04:37:42410 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());
xhwang@chromium.orgecf16912013-01-12 16:55:22413
rileya@chromium.orgd70157792014-03-17 21:45:03414 ReinitializeConfigChange(new_config);
fdorayf920dcf2016-06-27 17:16:59415 base::RunLoop().RunUntilIdle();
xhwang@chromium.org7c39486c2013-01-06 15:36:09416}
417
xhwang@chromium.org97a9ce42012-10-19 10:06:43418// Test the case where the a key is added when the decryptor is in
419// kWaitingForKey state.
420TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) {
421 Initialize();
Vikram Pasupathyabfd18a2023-01-26 20:56:20422 EXPECT_MEDIA_LOG(HasSubstr("DecryptingAudioDecoder: no key for key"));
xhwang@chromium.org97a9ce42012-10-19 10:06:43423 EnterWaitingForKeyState();
424
425 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
Daniel Cheng868ab272021-02-24 17:07:15426 .WillRepeatedly(
427 RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
sergeyu@chromium.org49cea862014-06-11 11:11:50428 EXPECT_CALL(*this, FrameReady(decoded_frame_));
Frank Liberato3d157ba2020-09-24 18:19:30429 EXPECT_CALL(*this, DecodeDone(IsOkStatus()));
Vikram Pasupathyabfd18a2023-01-26 20:56:20430 EXPECT_MEDIA_LOG(
431 HasSubstr("DecryptingAudioDecoder: key added, resuming decode"));
Xiaohan Wangd72ce5d2020-07-14 01:34:43432 event_cb_.Run(CdmContext::Event::kHasAdditionalUsableKey);
fdorayf920dcf2016-06-27 17:16:59433 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43434}
435
436// Test the case where the a key is added when the decryptor is in
437// kPendingDecode state.
Vikram Pasupathyabfd18a2023-01-26 20:56:20438TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringPendingDecode) {
xhwang@chromium.org97a9ce42012-10-19 10:06:43439 Initialize();
Vikram Pasupathyabfd18a2023-01-26 20:56:20440 EXPECT_MEDIA_LOG(HasSubstr("DecryptingAudioDecoder: no key for key"));
xhwang@chromium.org97a9ce42012-10-19 10:06:43441 EnterPendingDecodeState();
442
443 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
Daniel Cheng868ab272021-02-24 17:07:15444 .WillRepeatedly(
445 RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
sergeyu@chromium.org49cea862014-06-11 11:11:50446 EXPECT_CALL(*this, FrameReady(decoded_frame_));
Frank Liberato3d157ba2020-09-24 18:19:30447 EXPECT_CALL(*this, DecodeDone(IsOkStatus()));
Vikram Pasupathyabfd18a2023-01-26 20:56:20448 EXPECT_MEDIA_LOG(
449 HasSubstr("DecryptingAudioDecoder: key was added, resuming decode"));
xhwang@chromium.org97a9ce42012-10-19 10:06:43450 // The audio decode callback is returned after the correct decryption key is
451 // added.
Xiaohan Wangd72ce5d2020-07-14 01:34:43452 event_cb_.Run(CdmContext::Event::kHasAdditionalUsableKey);
Dale Curtise25163812018-09-21 22:13:39453 std::move(pending_audio_decode_cb_)
Xiaohan Wangc03ce232018-05-30 21:07:58454 .Run(Decryptor::kNoKey, Decryptor::AudioFrames());
fdorayf920dcf2016-06-27 17:16:59455 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43456}
457
458// Test resetting when the decoder is in kIdle state but has not decoded any
459// frame.
460TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) {
461 Initialize();
462 Reset();
463}
464
465// Test resetting when the decoder is in kIdle state after it has decoded one
466// frame.
467TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
468 Initialize();
469 EnterNormalDecodingState();
470 Reset();
471}
472
xhwang@chromium.org97a9ce42012-10-19 10:06:43473// Test resetting when the decoder is in kPendingDecode state.
474TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) {
475 Initialize();
476 EnterPendingDecodeState();
477
Ted Meyera8afec222022-01-12 02:37:27478 EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted)));
xhwang@chromium.org97a9ce42012-10-19 10:06:43479
480 Reset();
481}
482
483// Test resetting when the decoder is in kWaitingForKey state.
484TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) {
485 Initialize();
Vikram Pasupathyabfd18a2023-01-26 20:56:20486 EXPECT_MEDIA_LOG(HasSubstr("DecryptingAudioDecoder: no key for key"));
xhwang@chromium.org97a9ce42012-10-19 10:06:43487 EnterWaitingForKeyState();
488
Ted Meyera8afec222022-01-12 02:37:27489 EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted)));
xhwang@chromium.org97a9ce42012-10-19 10:06:43490
491 Reset();
492}
493
494// Test resetting when the decoder has hit end of stream and is in
495// kDecodeFinished state.
496TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) {
497 Initialize();
498 EnterNormalDecodingState();
499 EnterEndOfStreamState();
500 Reset();
501}
502
503// Test resetting after the decoder has been reset.
504TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) {
505 Initialize();
506 EnterNormalDecodingState();
507 Reset();
508 Reset();
509}
510
xhwang@chromium.org97a9ce42012-10-19 10:06:43511} // namespace media