[go: nahoru, domu]

blob: 830a5a1147901768b40c4f2a6905b715898c00d2 [file] [log] [blame]
xhwang@chromium.org97a9ce42012-10-19 10:06:431// 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.
4
avi1323b9c22015-12-23 06:22:365#include <stdint.h>
6
xhwang@chromium.org97a9ce42012-10-19 10:06:437#include <string>
8#include <vector>
9
10#include "base/bind.h"
11#include "base/callback_helpers.h"
avi1323b9c22015-12-23 06:22:3612#include "base/macros.h"
avi@chromium.org5821fa0e2013-07-18 04:32:3513#include "base/message_loop/message_loop.h"
fdorayf920dcf2016-06-27 17:16:5914#include "base/run_loop.h"
jrummell@chromium.org47b37a62013-07-10 03:56:1015#include "media/base/audio_buffer.h"
xhwang@chromium.org97a9ce42012-10-19 10:06:4316#include "media/base/decoder_buffer.h"
17#include "media/base/decrypt_config.h"
xhwang@chromium.org8b10f2222012-11-13 05:49:4818#include "media/base/gmock_callback_support.h"
chcunningham9812dd82015-10-20 01:42:0919#include "media/base/media_util.h"
xhwang@chromium.org97a9ce42012-10-19 10:06:4320#include "media/base/mock_filters.h"
scherkus@chromium.org1848da02012-12-06 06:58:3821#include "media/base/test_helpers.h"
watk9f9dfdc92015-09-04 21:33:2922#include "media/base/timestamp_constants.h"
xhwang@chromium.org97a9ce42012-10-19 10:06:4323#include "media/filters/decrypting_audio_decoder.h"
xhwang@chromium.org97a9ce42012-10-19 10:06:4324#include "testing/gmock/include/gmock/gmock.h"
25
26using ::testing::_;
27using ::testing::AtMost;
xhwang00f69db72015-11-12 07:32:3728using ::testing::Return;
xhwang@chromium.org97a9ce42012-10-19 10:06:4329using ::testing::SaveArg;
30using ::testing::StrictMock;
31
32namespace media {
33
xhwang@chromium.org5c5e9b72014-06-17 19:21:1234const int kSampleRate = 44100;
rileya@chromium.org16ecd5f2014-03-20 05:41:0735
xhwang@chromium.orgecf16912013-01-12 16:55:2236// Make sure the kFakeAudioFrameSize is a valid frame size for all audio decoder
37// configs used in this test.
xhwang@chromium.org5c5e9b72014-06-17 19:21:1238const int kFakeAudioFrameSize = 48;
Avi Drissman97785ea2015-12-19 01:11:3139const uint8_t kFakeKeyId[] = {0x4b, 0x65, 0x79, 0x20, 0x49, 0x44};
40const uint8_t kFakeIv[DecryptConfig::kDecryptionKeySize] = {0};
xhwang@chromium.org5c5e9b72014-06-17 19:21:1241const int kDecodingDelay = 3;
xhwang@chromium.org97a9ce42012-10-19 10:06:4342
43// Create a fake non-empty encrypted buffer.
44static scoped_refptr<DecoderBuffer> CreateFakeEncryptedBuffer() {
45 const int buffer_size = 16; // Need a non-empty buffer;
46 scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(buffer_size));
dcheng254c5362016-04-22 01:12:4847 buffer->set_decrypt_config(std::unique_ptr<DecryptConfig>(new DecryptConfig(
xhwang@chromium.org97a9ce42012-10-19 10:06:4348 std::string(reinterpret_cast<const char*>(kFakeKeyId),
49 arraysize(kFakeKeyId)),
50 std::string(reinterpret_cast<const char*>(kFakeIv), arraysize(kFakeIv)),
xhwang@chromium.org97a9ce42012-10-19 10:06:4351 std::vector<SubsampleEntry>())));
52 return buffer;
53}
54
55// Use anonymous namespace here to prevent the actions to be defined multiple
56// times across multiple test files. Sadly we can't use static for them.
57namespace {
58
59ACTION_P(ReturnBuffer, buffer) {
rileya@chromium.orgd70157792014-03-17 21:45:0360 return buffer;
xhwang@chromium.org97a9ce42012-10-19 10:06:4361}
62
xhwang@chromium.org97a9ce42012-10-19 10:06:4363} // namespace
64
65class DecryptingAudioDecoderTest : public testing::Test {
66 public:
67 DecryptingAudioDecoderTest()
xhwang@chromium.org2b454ff82012-11-15 03:57:5868 : decoder_(new DecryptingAudioDecoder(
skyostil6f5f1402015-06-17 15:49:0969 message_loop_.task_runner(),
xhwanga9ca9db2015-06-11 23:52:3970 new MediaLog(),
jrummell74fc4f942015-03-02 22:48:2771 base::Bind(&DecryptingAudioDecoderTest::OnWaitingForDecryptionKey,
72 base::Unretained(this)))),
xhwang00f69db72015-11-12 07:32:3773 cdm_context_(new StrictMock<MockCdmContext>()),
xhwang@chromium.org97a9ce42012-10-19 10:06:4374 decryptor_(new StrictMock<MockDecryptor>()),
xhwang@chromium.org5c5e9b72014-06-17 19:21:1275 num_decrypt_and_decode_calls_(0),
76 num_frames_in_decryptor_(0),
xhwang@chromium.org97a9ce42012-10-19 10:06:4377 encrypted_buffer_(CreateFakeEncryptedBuffer()),
xhwang@chromium.orgecbb9762012-10-24 22:33:5478 decoded_frame_(NULL),
rileya@chromium.orgd70157792014-03-17 21:45:0379 decoded_frame_list_() {}
xhwang@chromium.org97a9ce42012-10-19 10:06:4380
rileya@chromium.orgb960fd02014-01-23 04:48:5481 virtual ~DecryptingAudioDecoderTest() {
xhwang@chromium.org83fb2a9e2014-07-16 23:36:4182 Destroy();
rileya@chromium.orgb960fd02014-01-23 04:48:5483 }
84
xhwang59c321f2015-06-05 23:46:5585 void InitializeAndExpectResult(const AudioDecoderConfig& config,
86 bool success) {
dalecurtis@google.come81f5f9d2014-03-29 01:32:1687 // Initialize data now that the config is known. Since the code uses
88 // invalid values (that CreateEmptyBuffer() doesn't support), tweak them
89 // just for CreateEmptyBuffer().
90 int channels = ChannelLayoutToChannelCount(config.channel_layout());
91 if (channels < 0)
92 channels = 0;
dalecurtis39a7f932016-07-19 18:34:5993 decoded_frame_ = AudioBuffer::CreateEmptyBuffer(
94 config.channel_layout(), channels, kSampleRate, kFakeAudioFrameSize,
95 kNoTimestamp);
jrummell@chromium.org47b37a62013-07-10 03:56:1096 decoded_frame_list_.push_back(decoded_frame_);
97
xhwanga935e442016-02-11 02:22:4598 decoder_->Initialize(config, cdm_context_.get(), NewExpectedBoolCB(success),
99 base::Bind(&DecryptingAudioDecoderTest::FrameReady,
100 base::Unretained(this)));
fdorayf920dcf2016-06-27 17:16:59101 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43102 }
103
xhwanga935e442016-02-11 02:22:45104 enum CdmType { CDM_WITHOUT_DECRYPTOR, CDM_WITH_DECRYPTOR };
xhwang00f69db72015-11-12 07:32:37105
106 void SetCdmType(CdmType cdm_type) {
xhwang00f69db72015-11-12 07:32:37107 const bool has_decryptor = cdm_type == CDM_WITH_DECRYPTOR;
xhwanga935e442016-02-11 02:22:45108 EXPECT_CALL(*cdm_context_, GetDecryptor())
109 .WillRepeatedly(Return(has_decryptor ? decryptor_.get() : nullptr));
jrummell@chromium.org9ebc3b032014-08-13 04:01:23110 }
111
xhwang@chromium.org97a9ce42012-10-19 10:06:43112 void Initialize() {
xhwang00f69db72015-11-12 07:32:37113 SetCdmType(CDM_WITH_DECRYPTOR);
xhwang@chromium.orga3e28672013-03-14 14:54:59114 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
xhwang@chromium.org97a9ce42012-10-19 10:06:43115 .Times(AtMost(1))
xhwang@chromium.org8b10f2222012-11-13 05:49:48116 .WillOnce(RunCallback<1>(true));
xhwang@chromium.orgabd36b3af2012-12-22 03:42:02117 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
xhwang@chromium.org82d7abd2012-11-02 23:04:03118 .WillOnce(SaveArg<1>(&key_added_cb_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43119
xhwang@chromium.org7c39486c2013-01-06 15:36:09120 config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32,
chcunningham9812dd82015-10-20 01:42:09121 CHANNEL_LAYOUT_STEREO, kSampleRate, EmptyExtraData(),
dougsteed8d5275f2016-03-12 00:04:30122 AesCtrEncryptionScheme(), base::TimeDelta(), 0);
xhwang59c321f2015-06-05 23:46:55123 InitializeAndExpectResult(config_, true);
xhwang@chromium.org97a9ce42012-10-19 10:06:43124 }
125
rileya@chromium.orgd70157792014-03-17 21:45:03126 void Reinitialize() {
127 ReinitializeConfigChange(config_);
128 }
129
dalecurtis@google.com6fb86542014-04-18 19:58:13130 void ReinitializeConfigChange(const AudioDecoderConfig& new_config) {
rileya@chromium.orgd70157792014-03-17 21:45:03131 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
132 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
133 .WillOnce(RunCallback<1>(true));
134 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
135 .WillOnce(SaveArg<1>(&key_added_cb_));
xhwanga935e442016-02-11 02:22:45136 decoder_->Initialize(new_config, nullptr, NewExpectedBoolCB(true),
sergeyu@chromium.org49cea862014-06-11 11:11:50137 base::Bind(&DecryptingAudioDecoderTest::FrameReady,
138 base::Unretained(this)));
rileya@chromium.orgd70157792014-03-17 21:45:03139 }
140
xhwang@chromium.org5c5e9b72014-06-17 19:21:12141 // Decode |buffer| and expect DecodeDone to get called with |status|.
142 void DecodeAndExpect(const scoped_refptr<DecoderBuffer>& buffer,
dalecurtis8f75b992016-03-30 17:54:59143 DecodeStatus status) {
sergeyu@chromium.org49cea862014-06-11 11:11:50144 EXPECT_CALL(*this, DecodeDone(status));
xhwang@chromium.org5c5e9b72014-06-17 19:21:12145 decoder_->Decode(buffer,
sergeyu@chromium.org49cea862014-06-11 11:11:50146 base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
rileya@chromium.orgd70157792014-03-17 21:45:03147 base::Unretained(this)));
fdorayf920dcf2016-06-27 17:16:59148 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43149 }
150
xhwang@chromium.org5c5e9b72014-06-17 19:21:12151 // Helper function to simulate the decrypting and decoding process in the
152 // |decryptor_| with a decoding delay of kDecodingDelay buffers.
153 void DecryptAndDecodeAudio(const scoped_refptr<DecoderBuffer>& encrypted,
154 const Decryptor::AudioDecodeCB& audio_decode_cb) {
155 num_decrypt_and_decode_calls_++;
156 if (!encrypted->end_of_stream())
157 num_frames_in_decryptor_++;
158
159 if (num_decrypt_and_decode_calls_ <= kDecodingDelay ||
160 num_frames_in_decryptor_ == 0) {
anujk.sharmaf1cb600a2015-01-07 19:11:13161 audio_decode_cb.Run(Decryptor::kNeedMoreData, Decryptor::AudioFrames());
xhwang@chromium.org5c5e9b72014-06-17 19:21:12162 return;
163 }
164
165 num_frames_in_decryptor_--;
166 audio_decode_cb.Run(Decryptor::kSuccess,
anujk.sharmaf1cb600a2015-01-07 19:11:13167 Decryptor::AudioFrames(1, decoded_frame_));
xhwang@chromium.org5c5e9b72014-06-17 19:21:12168 }
169
xhwang@chromium.org97a9ce42012-10-19 10:06:43170 // Sets up expectations and actions to put DecryptingAudioDecoder in an
171 // active normal decoding state.
172 void EnterNormalDecodingState() {
xhwang@chromium.org5c5e9b72014-06-17 19:21:12173 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _)).WillRepeatedly(
174 Invoke(this, &DecryptingAudioDecoderTest::DecryptAndDecodeAudio));
175 EXPECT_CALL(*this, FrameReady(decoded_frame_));
176 for (int i = 0; i < kDecodingDelay + 1; ++i)
dalecurtis8f75b992016-03-30 17:54:59177 DecodeAndExpect(encrypted_buffer_, DecodeStatus::OK);
xhwang@chromium.org97a9ce42012-10-19 10:06:43178 }
179
180 // Sets up expectations and actions to put DecryptingAudioDecoder in an end
181 // of stream state. This function must be called after
182 // EnterNormalDecodingState() to work.
183 void EnterEndOfStreamState() {
xhwang@chromium.orgff757032014-06-19 01:42:24184 // The codec in the |decryptor_| will be flushed.
xhwang@chromium.org5c5e9b72014-06-17 19:21:12185 EXPECT_CALL(*this, FrameReady(decoded_frame_))
186 .Times(kDecodingDelay);
dalecurtis8f75b992016-03-30 17:54:59187 DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(), DecodeStatus::OK);
xhwang@chromium.org5c5e9b72014-06-17 19:21:12188 EXPECT_EQ(0, num_frames_in_decryptor_);
xhwang@chromium.org97a9ce42012-10-19 10:06:43189 }
190
191 // Make the audio decode callback pending by saving and not firing it.
192 void EnterPendingDecodeState() {
193 EXPECT_TRUE(pending_audio_decode_cb_.is_null());
xhwang@chromium.org97a9ce42012-10-19 10:06:43194 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
195 .WillOnce(SaveArg<1>(&pending_audio_decode_cb_));
196
rileya@chromium.orgd70157792014-03-17 21:45:03197 decoder_->Decode(encrypted_buffer_,
sergeyu@chromium.org49cea862014-06-11 11:11:50198 base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
rileya@chromium.orgd70157792014-03-17 21:45:03199 base::Unretained(this)));
fdorayf920dcf2016-06-27 17:16:59200 base::RunLoop().RunUntilIdle();
rileya@chromium.orgd70157792014-03-17 21:45:03201 // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
202 // the decryptor.
xhwang@chromium.org97a9ce42012-10-19 10:06:43203 EXPECT_FALSE(pending_audio_decode_cb_.is_null());
204 }
205
206 void EnterWaitingForKeyState() {
xhwang@chromium.org2b454ff82012-11-15 03:57:58207 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48208 .WillRepeatedly(RunCallback<1>(Decryptor::kNoKey,
anujk.sharmaf1cb600a2015-01-07 19:11:13209 Decryptor::AudioFrames()));
jrummell74fc4f942015-03-02 22:48:27210 EXPECT_CALL(*this, OnWaitingForDecryptionKey());
rileya@chromium.orgd70157792014-03-17 21:45:03211 decoder_->Decode(encrypted_buffer_,
sergeyu@chromium.org49cea862014-06-11 11:11:50212 base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
rileya@chromium.orgd70157792014-03-17 21:45:03213 base::Unretained(this)));
fdorayf920dcf2016-06-27 17:16:59214 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43215 }
216
217 void AbortPendingAudioDecodeCB() {
218 if (!pending_audio_decode_cb_.is_null()) {
219 base::ResetAndReturn(&pending_audio_decode_cb_).Run(
anujk.sharmaf1cb600a2015-01-07 19:11:13220 Decryptor::kSuccess, Decryptor::AudioFrames());
xhwang@chromium.org97a9ce42012-10-19 10:06:43221 }
222 }
223
rileya@chromium.orgb960fd02014-01-23 04:48:54224 void AbortAllPendingCBs() {
225 if (!pending_init_cb_.is_null()) {
226 ASSERT_TRUE(pending_audio_decode_cb_.is_null());
227 base::ResetAndReturn(&pending_init_cb_).Run(false);
228 return;
229 }
230
231 AbortPendingAudioDecodeCB();
232 }
233
xhwang@chromium.org97a9ce42012-10-19 10:06:43234 void Reset() {
235 EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio))
236 .WillRepeatedly(InvokeWithoutArgs(
237 this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB));
238
239 decoder_->Reset(NewExpectedClosure());
fdorayf920dcf2016-06-27 17:16:59240 base::RunLoop().RunUntilIdle();
rileya@chromium.org3c0e4062014-01-15 22:23:12241 }
242
xhwang@chromium.org83fb2a9e2014-07-16 23:36:41243 void Destroy() {
rileya@chromium.orgb960fd02014-01-23 04:48:54244 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio))
245 .WillRepeatedly(InvokeWithoutArgs(
246 this, &DecryptingAudioDecoderTest::AbortAllPendingCBs));
247
xhwang@chromium.org83fb2a9e2014-07-16 23:36:41248 decoder_.reset();
fdorayf920dcf2016-06-27 17:16:59249 base::RunLoop().RunUntilIdle();
rileya@chromium.orgb960fd02014-01-23 04:48:54250 }
251
sergeyu@chromium.org49cea862014-06-11 11:11:50252 MOCK_METHOD1(FrameReady, void(const scoped_refptr<AudioBuffer>&));
dalecurtis8f75b992016-03-30 17:54:59253 MOCK_METHOD1(DecodeDone, void(DecodeStatus));
jrummell@chromium.org9ebc3b032014-08-13 04:01:23254
jrummell74fc4f942015-03-02 22:48:27255 MOCK_METHOD0(OnWaitingForDecryptionKey, void(void));
256
xhwang@chromium.orgfb5af232013-04-22 22:40:03257 base::MessageLoop message_loop_;
dcheng254c5362016-04-22 01:12:48258 std::unique_ptr<DecryptingAudioDecoder> decoder_;
259 std::unique_ptr<StrictMock<MockCdmContext>> cdm_context_;
260 std::unique_ptr<StrictMock<MockDecryptor>> decryptor_;
xhwang@chromium.org7c39486c2013-01-06 15:36:09261 AudioDecoderConfig config_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43262
xhwang@chromium.org5c5e9b72014-06-17 19:21:12263 // Variables to help the |decryptor_| to simulate decoding delay and flushing.
264 int num_decrypt_and_decode_calls_;
265 int num_frames_in_decryptor_;
266
xhwang@chromium.org97a9ce42012-10-19 10:06:43267 Decryptor::DecoderInitCB pending_init_cb_;
xhwang@chromium.orgabd36b3af2012-12-22 03:42:02268 Decryptor::NewKeyCB key_added_cb_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43269 Decryptor::AudioDecodeCB pending_audio_decode_cb_;
270
rileya@chromium.orgd70157792014-03-17 21:45:03271 // Constant buffer/frames, to be used/returned by |decoder_| and |decryptor_|.
xhwang@chromium.org97a9ce42012-10-19 10:06:43272 scoped_refptr<DecoderBuffer> encrypted_buffer_;
jrummell@chromium.org47b37a62013-07-10 03:56:10273 scoped_refptr<AudioBuffer> decoded_frame_;
anujk.sharmaf1cb600a2015-01-07 19:11:13274 Decryptor::AudioFrames decoded_frame_list_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43275
276 private:
277 DISALLOW_COPY_AND_ASSIGN(DecryptingAudioDecoderTest);
278};
279
280TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) {
281 Initialize();
282}
283
xhwang@chromium.org97a9ce42012-10-19 10:06:43284// Ensure decoder handles invalid audio configs without crashing.
285TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) {
dalecurtis@google.comb5eca3c2013-01-04 20:20:15286 AudioDecoderConfig config(kUnknownAudioCodec, kUnknownSampleFormat,
dougsteed8d5275f2016-03-12 00:04:30287 CHANNEL_LAYOUT_STEREO, 0, EmptyExtraData(),
288 AesCtrEncryptionScheme());
xhwang@chromium.org97a9ce42012-10-19 10:06:43289
xhwang59c321f2015-06-05 23:46:55290 InitializeAndExpectResult(config, false);
xhwang@chromium.org97a9ce42012-10-19 10:06:43291}
292
293// Ensure decoder handles unsupported audio configs without crashing.
294TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) {
xhwang00f69db72015-11-12 07:32:37295 SetCdmType(CDM_WITH_DECRYPTOR);
xhwang@chromium.orga3e28672013-03-14 14:54:59296 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48297 .WillOnce(RunCallback<1>(false));
xhwang@chromium.org97a9ce42012-10-19 10:06:43298
xhwang00f69db72015-11-12 07:32:37299 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
300 CHANNEL_LAYOUT_STEREO, kSampleRate,
dougsteed8d5275f2016-03-12 00:04:30301 EmptyExtraData(), AesCtrEncryptionScheme());
xhwang00f69db72015-11-12 07:32:37302 InitializeAndExpectResult(config, false);
303}
304
305TEST_F(DecryptingAudioDecoderTest, Initialize_CdmWithoutDecryptor) {
306 SetCdmType(CDM_WITHOUT_DECRYPTOR);
xhwang@chromium.org699b64a2013-06-19 07:36:05307 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
chcunningham9812dd82015-10-20 01:42:09308 CHANNEL_LAYOUT_STEREO, kSampleRate,
dougsteed8d5275f2016-03-12 00:04:30309 EmptyExtraData(), AesCtrEncryptionScheme());
xhwang59c321f2015-06-05 23:46:55310 InitializeAndExpectResult(config, false);
xhwang@chromium.org699b64a2013-06-19 07:36:05311}
312
xhwang@chromium.org97a9ce42012-10-19 10:06:43313// Test normal decrypt and decode case.
314TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) {
315 Initialize();
316 EnterNormalDecodingState();
317}
318
319// Test the case where the decryptor returns error when doing decrypt and
320// decode.
321TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) {
322 Initialize();
323
xhwang@chromium.org97a9ce42012-10-19 10:06:43324 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48325 .WillRepeatedly(RunCallback<1>(Decryptor::kError,
anujk.sharmaf1cb600a2015-01-07 19:11:13326 Decryptor::AudioFrames()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43327
dalecurtis8f75b992016-03-30 17:54:59328 DecodeAndExpect(encrypted_buffer_, DecodeStatus::DECODE_ERROR);
xhwang@chromium.org97a9ce42012-10-19 10:06:43329}
330
331// Test the case where the decryptor returns multiple decoded frames.
332TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) {
333 Initialize();
334
jrummell@chromium.org47b37a62013-07-10 03:56:10335 scoped_refptr<AudioBuffer> frame_a = AudioBuffer::CreateEmptyBuffer(
rileya@chromium.org16ecd5f2014-03-20 05:41:07336 config_.channel_layout(),
dalecurtis39a7f932016-07-19 18:34:59337 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
338 kFakeAudioFrameSize, kNoTimestamp);
jrummell@chromium.org47b37a62013-07-10 03:56:10339 scoped_refptr<AudioBuffer> frame_b = AudioBuffer::CreateEmptyBuffer(
rileya@chromium.org16ecd5f2014-03-20 05:41:07340 config_.channel_layout(),
dalecurtis39a7f932016-07-19 18:34:59341 ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
342 kFakeAudioFrameSize, kNoTimestamp);
xhwang@chromium.orgecbb9762012-10-24 22:33:54343 decoded_frame_list_.push_back(frame_a);
344 decoded_frame_list_.push_back(frame_b);
xhwang@chromium.org97a9ce42012-10-19 10:06:43345
xhwang@chromium.org97a9ce42012-10-19 10:06:43346 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48347 .WillOnce(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43348
xhwang@chromium.org5c5e9b72014-06-17 19:21:12349 EXPECT_CALL(*this, FrameReady(decoded_frame_));
350 EXPECT_CALL(*this, FrameReady(frame_a));
351 EXPECT_CALL(*this, FrameReady(frame_b));
dalecurtis8f75b992016-03-30 17:54:59352 DecodeAndExpect(encrypted_buffer_, DecodeStatus::OK);
xhwang@chromium.org97a9ce42012-10-19 10:06:43353}
354
355// Test the case where the decryptor receives end-of-stream buffer.
356TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) {
357 Initialize();
358 EnterNormalDecodingState();
359 EnterEndOfStreamState();
xhwang@chromium.org97a9ce42012-10-19 10:06:43360}
361
xhwang65c23032017-02-17 04:37:42362// Test reinitializing decode with a new encrypted config.
363TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToEncrypted) {
xhwang@chromium.org7c39486c2013-01-06 15:36:09364 Initialize();
365
rileya@chromium.orgd70157792014-03-17 21:45:03366 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
367 .Times(AtMost(1))
368 .WillOnce(RunCallback<1>(true));
xhwang@chromium.org7c39486c2013-01-06 15:36:09369
xhwang@chromium.orgecf16912013-01-12 16:55:22370 // The new config is different from the initial config in bits-per-channel,
371 // channel layout and samples_per_second.
372 AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16,
chcunningham9812dd82015-10-20 01:42:09373 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
dougsteed8d5275f2016-03-12 00:04:30374 AesCtrEncryptionScheme());
xhwang@chromium.orgecf16912013-01-12 16:55:22375 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
376 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
377 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
xhwang65c23032017-02-17 04:37:42378 ASSERT_TRUE(new_config.is_encrypted());
379
380 ReinitializeConfigChange(new_config);
381 base::RunLoop().RunUntilIdle();
382}
383
384// Test reinitializing decode with a new clear config.
385TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToClear) {
386 Initialize();
387
388 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
389 .Times(AtMost(1))
390 .WillOnce(RunCallback<1>(true));
391
392 // The new config is different from the initial config in bits-per-channel,
393 // channel layout and samples_per_second.
394 AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16,
395 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
396 Unencrypted());
397 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
398 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
399 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
400 ASSERT_FALSE(new_config.is_encrypted());
xhwang@chromium.orgecf16912013-01-12 16:55:22401
rileya@chromium.orgd70157792014-03-17 21:45:03402 ReinitializeConfigChange(new_config);
fdorayf920dcf2016-06-27 17:16:59403 base::RunLoop().RunUntilIdle();
xhwang@chromium.org7c39486c2013-01-06 15:36:09404}
405
xhwang@chromium.org97a9ce42012-10-19 10:06:43406// Test the case where the a key is added when the decryptor is in
407// kWaitingForKey state.
408TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) {
409 Initialize();
410 EnterWaitingForKeyState();
411
412 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48413 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
sergeyu@chromium.org49cea862014-06-11 11:11:50414 EXPECT_CALL(*this, FrameReady(decoded_frame_));
dalecurtis8f75b992016-03-30 17:54:59415 EXPECT_CALL(*this, DecodeDone(DecodeStatus::OK));
xhwang@chromium.org97a9ce42012-10-19 10:06:43416 key_added_cb_.Run();
fdorayf920dcf2016-06-27 17:16:59417 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43418}
419
420// Test the case where the a key is added when the decryptor is in
421// kPendingDecode state.
422TEST_F(DecryptingAudioDecoderTest, KeyAdded_DruingPendingDecode) {
423 Initialize();
424 EnterPendingDecodeState();
425
426 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48427 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
sergeyu@chromium.org49cea862014-06-11 11:11:50428 EXPECT_CALL(*this, FrameReady(decoded_frame_));
dalecurtis8f75b992016-03-30 17:54:59429 EXPECT_CALL(*this, DecodeDone(DecodeStatus::OK));
xhwang@chromium.org97a9ce42012-10-19 10:06:43430 // The audio decode callback is returned after the correct decryption key is
431 // added.
432 key_added_cb_.Run();
433 base::ResetAndReturn(&pending_audio_decode_cb_).Run(
anujk.sharmaf1cb600a2015-01-07 19:11:13434 Decryptor::kNoKey, Decryptor::AudioFrames());
fdorayf920dcf2016-06-27 17:16:59435 base::RunLoop().RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43436}
437
438// Test resetting when the decoder is in kIdle state but has not decoded any
439// frame.
440TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) {
441 Initialize();
442 Reset();
443}
444
445// Test resetting when the decoder is in kIdle state after it has decoded one
446// frame.
447TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
448 Initialize();
449 EnterNormalDecodingState();
450 Reset();
xhwang@chromium.org97a9ce42012-10-19 10:06:43451}
452
453// Test resetting when the decoder is in kPendingDecode state.
454TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) {
455 Initialize();
456 EnterPendingDecodeState();
457
dalecurtis8f75b992016-03-30 17:54:59458 EXPECT_CALL(*this, DecodeDone(DecodeStatus::ABORTED));
xhwang@chromium.org97a9ce42012-10-19 10:06:43459
460 Reset();
461}
462
463// Test resetting when the decoder is in kWaitingForKey state.
464TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) {
465 Initialize();
466 EnterWaitingForKeyState();
467
dalecurtis8f75b992016-03-30 17:54:59468 EXPECT_CALL(*this, DecodeDone(DecodeStatus::ABORTED));
xhwang@chromium.org97a9ce42012-10-19 10:06:43469
470 Reset();
471}
472
473// Test resetting when the decoder has hit end of stream and is in
474// kDecodeFinished state.
475TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) {
476 Initialize();
477 EnterNormalDecodingState();
478 EnterEndOfStreamState();
479 Reset();
480}
481
482// Test resetting after the decoder has been reset.
483TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) {
484 Initialize();
485 EnterNormalDecodingState();
486 Reset();
487 Reset();
xhwang@chromium.org97a9ce42012-10-19 10:06:43488}
489
490} // namespace media