[go: nahoru, domu]

blob: e0d1d643c5e8d256e20fec4ec3d0fa1c45878a8c [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
5#include <string>
6#include <vector>
7
8#include "base/bind.h"
9#include "base/callback_helpers.h"
avi@chromium.org5821fa0e2013-07-18 04:32:3510#include "base/message_loop/message_loop.h"
jrummell@chromium.org47b37a62013-07-10 03:56:1011#include "media/base/audio_buffer.h"
xhwang@chromium.org97a9ce42012-10-19 10:06:4312#include "media/base/buffers.h"
xhwang@chromium.org97a9ce42012-10-19 10:06:4313#include "media/base/decoder_buffer.h"
14#include "media/base/decrypt_config.h"
xhwang@chromium.org8b10f2222012-11-13 05:49:4815#include "media/base/gmock_callback_support.h"
xhwang@chromium.org97a9ce42012-10-19 10:06:4316#include "media/base/mock_filters.h"
scherkus@chromium.org1848da02012-12-06 06:58:3817#include "media/base/test_helpers.h"
xhwang@chromium.org97a9ce42012-10-19 10:06:4318#include "media/filters/decrypting_audio_decoder.h"
xhwang@chromium.org97a9ce42012-10-19 10:06:4319#include "testing/gmock/include/gmock/gmock.h"
20
21using ::testing::_;
22using ::testing::AtMost;
xhwang@chromium.org97a9ce42012-10-19 10:06:4323using ::testing::SaveArg;
24using ::testing::StrictMock;
25
26namespace media {
27
xhwang@chromium.org5c5e9b72014-06-17 19:21:1228const int kSampleRate = 44100;
rileya@chromium.org16ecd5f2014-03-20 05:41:0729
xhwang@chromium.orgecf16912013-01-12 16:55:2230// Make sure the kFakeAudioFrameSize is a valid frame size for all audio decoder
31// configs used in this test.
xhwang@chromium.org5c5e9b72014-06-17 19:21:1232const int kFakeAudioFrameSize = 48;
33const uint8 kFakeKeyId[] = { 0x4b, 0x65, 0x79, 0x20, 0x49, 0x44 };
34const uint8 kFakeIv[DecryptConfig::kDecryptionKeySize] = { 0 };
35const int kDecodingDelay = 3;
xhwang@chromium.org97a9ce42012-10-19 10:06:4336
37// Create a fake non-empty encrypted buffer.
38static scoped_refptr<DecoderBuffer> CreateFakeEncryptedBuffer() {
39 const int buffer_size = 16; // Need a non-empty buffer;
40 scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(buffer_size));
tyoverby@chromium.org464f253b2013-07-18 18:49:4341 buffer->set_decrypt_config(scoped_ptr<DecryptConfig>(new DecryptConfig(
xhwang@chromium.org97a9ce42012-10-19 10:06:4342 std::string(reinterpret_cast<const char*>(kFakeKeyId),
43 arraysize(kFakeKeyId)),
44 std::string(reinterpret_cast<const char*>(kFakeIv), arraysize(kFakeIv)),
xhwang@chromium.org97a9ce42012-10-19 10:06:4345 std::vector<SubsampleEntry>())));
46 return buffer;
47}
48
49// Use anonymous namespace here to prevent the actions to be defined multiple
50// times across multiple test files. Sadly we can't use static for them.
51namespace {
52
53ACTION_P(ReturnBuffer, buffer) {
rileya@chromium.orgd70157792014-03-17 21:45:0354 return buffer;
xhwang@chromium.org97a9ce42012-10-19 10:06:4355}
56
xhwang@chromium.org8b10f2222012-11-13 05:49:4857ACTION_P(RunCallbackIfNotNull, param) {
xhwang@chromium.org97a9ce42012-10-19 10:06:4358 if (!arg0.is_null())
59 arg0.Run(param);
xhwang@chromium.org97a9ce42012-10-19 10:06:4360}
61
xhwang@chromium.org8b10f2222012-11-13 05:49:4862MATCHER(IsEndOfStream, "end of stream") {
tyoverby@chromium.org71a8d5a2013-06-25 08:41:0163 return (arg->end_of_stream());
xhwang@chromium.org8f5a9a52012-10-23 20:49:2064}
65
xhwang@chromium.org97a9ce42012-10-19 10:06:4366} // namespace
67
68class DecryptingAudioDecoderTest : public testing::Test {
69 public:
70 DecryptingAudioDecoderTest()
xhwang@chromium.org2b454ff82012-11-15 03:57:5871 : decoder_(new DecryptingAudioDecoder(
scherkus@chromium.org8c076cb2012-11-28 21:06:1672 message_loop_.message_loop_proxy(),
xhwang@chromium.org97a9ce42012-10-19 10:06:4373 base::Bind(
74 &DecryptingAudioDecoderTest::RequestDecryptorNotification,
75 base::Unretained(this)))),
76 decryptor_(new StrictMock<MockDecryptor>()),
xhwang@chromium.org5c5e9b72014-06-17 19:21:1277 num_decrypt_and_decode_calls_(0),
78 num_frames_in_decryptor_(0),
xhwang@chromium.org97a9ce42012-10-19 10:06:4379 encrypted_buffer_(CreateFakeEncryptedBuffer()),
xhwang@chromium.orgecbb9762012-10-24 22:33:5480 decoded_frame_(NULL),
rileya@chromium.orgd70157792014-03-17 21:45:0381 decoded_frame_list_() {}
xhwang@chromium.org97a9ce42012-10-19 10:06:4382
rileya@chromium.orgb960fd02014-01-23 04:48:5483 virtual ~DecryptingAudioDecoderTest() {
rileya@chromium.orgd70157792014-03-17 21:45:0384 EXPECT_CALL(*this, RequestDecryptorNotification(_))
85 .Times(testing::AnyNumber());
rileya@chromium.orgb960fd02014-01-23 04:48:5486 Stop();
87 }
88
xhwang@chromium.org97a9ce42012-10-19 10:06:4389 void InitializeAndExpectStatus(const AudioDecoderConfig& config,
90 PipelineStatus status) {
dalecurtis@google.come81f5f9d2014-03-29 01:32:1691 // Initialize data now that the config is known. Since the code uses
92 // invalid values (that CreateEmptyBuffer() doesn't support), tweak them
93 // just for CreateEmptyBuffer().
94 int channels = ChannelLayoutToChannelCount(config.channel_layout());
95 if (channels < 0)
96 channels = 0;
rileya@chromium.org16ecd5f2014-03-20 05:41:0797 decoded_frame_ = AudioBuffer::CreateEmptyBuffer(config.channel_layout(),
dalecurtis@google.come81f5f9d2014-03-29 01:32:1698 channels,
rileya@chromium.org16ecd5f2014-03-20 05:41:0799 kSampleRate,
100 kFakeAudioFrameSize,
rileya@chromium.org16ecd5f2014-03-20 05:41:07101 kNoTimestamp());
jrummell@chromium.org47b37a62013-07-10 03:56:10102 decoded_frame_list_.push_back(decoded_frame_);
103
sergeyu@chromium.org49cea862014-06-11 11:11:50104 decoder_->Initialize(config, NewExpectedStatusCB(status),
105 base::Bind(&DecryptingAudioDecoderTest::FrameReady,
106 base::Unretained(this)));
xhwang@chromium.org643d5442012-11-14 05:08:32107 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43108 }
109
110 void Initialize() {
xhwang@chromium.orga3e28672013-03-14 14:54:59111 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
xhwang@chromium.org97a9ce42012-10-19 10:06:43112 .Times(AtMost(1))
xhwang@chromium.org8b10f2222012-11-13 05:49:48113 .WillOnce(RunCallback<1>(true));
xhwang@chromium.org97a9ce42012-10-19 10:06:43114 EXPECT_CALL(*this, RequestDecryptorNotification(_))
xhwang@chromium.org8b10f2222012-11-13 05:49:48115 .WillOnce(RunCallbackIfNotNull(decryptor_.get()));
xhwang@chromium.orgabd36b3af2012-12-22 03:42:02116 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
xhwang@chromium.org82d7abd2012-11-02 23:04:03117 .WillOnce(SaveArg<1>(&key_added_cb_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43118
xhwang@chromium.org7c39486c2013-01-06 15:36:09119 config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32,
rileya@chromium.org16ecd5f2014-03-20 05:41:07120 CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, true, true,
dalecurtis@google.com6fb86542014-04-18 19:58:13121 base::TimeDelta(), 0);
xhwang@chromium.org7c39486c2013-01-06 15:36:09122 InitializeAndExpectStatus(config_, PIPELINE_OK);
xhwang@chromium.org97a9ce42012-10-19 10:06:43123 }
124
rileya@chromium.orgd70157792014-03-17 21:45:03125 void Reinitialize() {
126 ReinitializeConfigChange(config_);
127 }
128
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(_, _))
132 .WillOnce(RunCallback<1>(true));
133 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
134 .WillOnce(SaveArg<1>(&key_added_cb_));
sergeyu@chromium.org49cea862014-06-11 11:11:50135 decoder_->Initialize(new_config, NewExpectedStatusCB(PIPELINE_OK),
136 base::Bind(&DecryptingAudioDecoderTest::FrameReady,
137 base::Unretained(this)));
rileya@chromium.orgd70157792014-03-17 21:45:03138 }
139
xhwang@chromium.org5c5e9b72014-06-17 19:21:12140 // Decode |buffer| and expect DecodeDone to get called with |status|.
141 void DecodeAndExpect(const scoped_refptr<DecoderBuffer>& buffer,
142 AudioDecoder::Status status) {
sergeyu@chromium.org49cea862014-06-11 11:11:50143 EXPECT_CALL(*this, DecodeDone(status));
xhwang@chromium.org5c5e9b72014-06-17 19:21:12144 decoder_->Decode(buffer,
sergeyu@chromium.org49cea862014-06-11 11:11:50145 base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
rileya@chromium.orgd70157792014-03-17 21:45:03146 base::Unretained(this)));
xhwang@chromium.org643d5442012-11-14 05:08:32147 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43148 }
149
xhwang@chromium.org5c5e9b72014-06-17 19:21:12150 // Helper function to simulate the decrypting and decoding process in the
151 // |decryptor_| with a decoding delay of kDecodingDelay buffers.
152 void DecryptAndDecodeAudio(const scoped_refptr<DecoderBuffer>& encrypted,
153 const Decryptor::AudioDecodeCB& audio_decode_cb) {
154 num_decrypt_and_decode_calls_++;
155 if (!encrypted->end_of_stream())
156 num_frames_in_decryptor_++;
157
158 if (num_decrypt_and_decode_calls_ <= kDecodingDelay ||
159 num_frames_in_decryptor_ == 0) {
160 audio_decode_cb.Run(Decryptor::kNeedMoreData, Decryptor::AudioBuffers());
161 return;
162 }
163
164 num_frames_in_decryptor_--;
165 audio_decode_cb.Run(Decryptor::kSuccess,
166 Decryptor::AudioBuffers(1, decoded_frame_));
167 }
168
xhwang@chromium.org97a9ce42012-10-19 10:06:43169 // Sets up expectations and actions to put DecryptingAudioDecoder in an
170 // active normal decoding state.
171 void EnterNormalDecodingState() {
xhwang@chromium.org5c5e9b72014-06-17 19:21:12172 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _)).WillRepeatedly(
173 Invoke(this, &DecryptingAudioDecoderTest::DecryptAndDecodeAudio));
174 EXPECT_CALL(*this, FrameReady(decoded_frame_));
175 for (int i = 0; i < kDecodingDelay + 1; ++i)
176 DecodeAndExpect(encrypted_buffer_, AudioDecoder::kOk);
xhwang@chromium.org97a9ce42012-10-19 10:06:43177 }
178
179 // Sets up expectations and actions to put DecryptingAudioDecoder in an end
180 // of stream state. This function must be called after
181 // EnterNormalDecodingState() to work.
182 void EnterEndOfStreamState() {
xhwang@chromium.org5c5e9b72014-06-17 19:21:12183 // The codec in the |decryptor_| will be flushed. We expect kDecodingDelay
184 // frames to be returned followed by a EOS frame.
185 EXPECT_CALL(*this, FrameReady(IsEndOfStream()));
186 EXPECT_CALL(*this, FrameReady(decoded_frame_))
187 .Times(kDecodingDelay);
188 DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(), AudioDecoder::kOk);
189 EXPECT_EQ(0, num_frames_in_decryptor_);
xhwang@chromium.org97a9ce42012-10-19 10:06:43190 }
191
192 // Make the audio decode callback pending by saving and not firing it.
193 void EnterPendingDecodeState() {
194 EXPECT_TRUE(pending_audio_decode_cb_.is_null());
xhwang@chromium.org97a9ce42012-10-19 10:06:43195 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
196 .WillOnce(SaveArg<1>(&pending_audio_decode_cb_));
197
rileya@chromium.orgd70157792014-03-17 21:45:03198 decoder_->Decode(encrypted_buffer_,
sergeyu@chromium.org49cea862014-06-11 11:11:50199 base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
rileya@chromium.orgd70157792014-03-17 21:45:03200 base::Unretained(this)));
xhwang@chromium.org643d5442012-11-14 05:08:32201 message_loop_.RunUntilIdle();
rileya@chromium.orgd70157792014-03-17 21:45:03202 // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
203 // the decryptor.
xhwang@chromium.org97a9ce42012-10-19 10:06:43204 EXPECT_FALSE(pending_audio_decode_cb_.is_null());
205 }
206
207 void EnterWaitingForKeyState() {
xhwang@chromium.org2b454ff82012-11-15 03:57:58208 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48209 .WillRepeatedly(RunCallback<1>(Decryptor::kNoKey,
210 Decryptor::AudioBuffers()));
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)));
xhwang@chromium.org643d5442012-11-14 05:08:32214 message_loop_.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(
220 Decryptor::kSuccess, Decryptor::AudioBuffers());
221 }
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());
rileya@chromium.org3c0e4062014-01-15 22:23:12240 message_loop_.RunUntilIdle();
241 }
242
rileya@chromium.orgb960fd02014-01-23 04:48:54243 void Stop() {
rileya@chromium.orgb960fd02014-01-23 04:48:54244 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio))
245 .WillRepeatedly(InvokeWithoutArgs(
246 this, &DecryptingAudioDecoderTest::AbortAllPendingCBs));
247
xhwang@chromium.orgb9eda9ec2014-03-31 19:59:18248 decoder_->Stop();
rileya@chromium.orgb960fd02014-01-23 04:48:54249 message_loop_.RunUntilIdle();
250 }
251
xhwang@chromium.orgdaede9b92012-12-14 00:57:25252 MOCK_METHOD1(RequestDecryptorNotification, void(const DecryptorReadyCB&));
xhwang@chromium.org97a9ce42012-10-19 10:06:43253
sergeyu@chromium.org49cea862014-06-11 11:11:50254 MOCK_METHOD1(FrameReady, void(const scoped_refptr<AudioBuffer>&));
255 MOCK_METHOD1(DecodeDone, void(AudioDecoder::Status));
xhwang@chromium.org97a9ce42012-10-19 10:06:43256
xhwang@chromium.orgfb5af232013-04-22 22:40:03257 base::MessageLoop message_loop_;
scherkus@chromium.org7dd4c742013-03-21 22:33:47258 scoped_ptr<DecryptingAudioDecoder> decoder_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43259 scoped_ptr<StrictMock<MockDecryptor> > decryptor_;
xhwang@chromium.org7c39486c2013-01-06 15:36:09260 AudioDecoderConfig config_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43261
xhwang@chromium.org5c5e9b72014-06-17 19:21:12262 // Variables to help the |decryptor_| to simulate decoding delay and flushing.
263 int num_decrypt_and_decode_calls_;
264 int num_frames_in_decryptor_;
265
xhwang@chromium.org97a9ce42012-10-19 10:06:43266 Decryptor::DecoderInitCB pending_init_cb_;
xhwang@chromium.orgabd36b3af2012-12-22 03:42:02267 Decryptor::NewKeyCB key_added_cb_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43268 Decryptor::AudioDecodeCB pending_audio_decode_cb_;
269
rileya@chromium.orgd70157792014-03-17 21:45:03270 // Constant buffer/frames, to be used/returned by |decoder_| and |decryptor_|.
xhwang@chromium.org97a9ce42012-10-19 10:06:43271 scoped_refptr<DecoderBuffer> encrypted_buffer_;
jrummell@chromium.org47b37a62013-07-10 03:56:10272 scoped_refptr<AudioBuffer> decoded_frame_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43273 Decryptor::AudioBuffers decoded_frame_list_;
274
275 private:
276 DISALLOW_COPY_AND_ASSIGN(DecryptingAudioDecoderTest);
277};
278
279TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) {
280 Initialize();
281}
282
283// Ensure that DecryptingAudioDecoder only accepts encrypted audio.
284TEST_F(DecryptingAudioDecoderTest, Initialize_UnencryptedAudioConfig) {
dalecurtis@google.comb5eca3c2013-01-04 20:20:15285 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
rileya@chromium.org16ecd5f2014-03-20 05:41:07286 CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, false);
xhwang@chromium.org97a9ce42012-10-19 10:06:43287
288 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED);
289}
290
291// Ensure decoder handles invalid audio configs without crashing.
292TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) {
dalecurtis@google.comb5eca3c2013-01-04 20:20:15293 AudioDecoderConfig config(kUnknownAudioCodec, kUnknownSampleFormat,
294 CHANNEL_LAYOUT_STEREO, 0, NULL, 0, true);
xhwang@chromium.org97a9ce42012-10-19 10:06:43295
296 InitializeAndExpectStatus(config, PIPELINE_ERROR_DECODE);
297}
298
299// Ensure decoder handles unsupported audio configs without crashing.
300TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) {
xhwang@chromium.orga3e28672013-03-14 14:54:59301 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48302 .WillOnce(RunCallback<1>(false));
xhwang@chromium.org97a9ce42012-10-19 10:06:43303 EXPECT_CALL(*this, RequestDecryptorNotification(_))
xhwang@chromium.org8b10f2222012-11-13 05:49:48304 .WillOnce(RunCallbackIfNotNull(decryptor_.get()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43305
dalecurtis@google.comb5eca3c2013-01-04 20:20:15306 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
rileya@chromium.org16ecd5f2014-03-20 05:41:07307 CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, true);
xhwang@chromium.org97a9ce42012-10-19 10:06:43308 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED);
309}
310
xhwang@chromium.org699b64a2013-06-19 07:36:05311TEST_F(DecryptingAudioDecoderTest, Initialize_NullDecryptor) {
312 EXPECT_CALL(*this, RequestDecryptorNotification(_))
313 .WillRepeatedly(RunCallbackIfNotNull(static_cast<Decryptor*>(NULL)));
314
315 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
rileya@chromium.org16ecd5f2014-03-20 05:41:07316 CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, true);
xhwang@chromium.org699b64a2013-06-19 07:36:05317 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED);
318}
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(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48332 .WillRepeatedly(RunCallback<1>(Decryptor::kError,
333 Decryptor::AudioBuffers()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43334
xhwang@chromium.org5c5e9b72014-06-17 19:21:12335 DecodeAndExpect(encrypted_buffer_, AudioDecoder::kDecodeError);
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(),
dalecurtis@google.come81f5f9d2014-03-29 01:32:16344 ChannelLayoutToChannelCount(config_.channel_layout()),
rileya@chromium.org16ecd5f2014-03-20 05:41:07345 kSampleRate,
jrummell@chromium.org47b37a62013-07-10 03:56:10346 kFakeAudioFrameSize,
jrummell@chromium.org47b37a62013-07-10 03:56:10347 kNoTimestamp());
348 scoped_refptr<AudioBuffer> frame_b = AudioBuffer::CreateEmptyBuffer(
rileya@chromium.org16ecd5f2014-03-20 05:41:07349 config_.channel_layout(),
dalecurtis@google.come81f5f9d2014-03-29 01:32:16350 ChannelLayoutToChannelCount(config_.channel_layout()),
rileya@chromium.org16ecd5f2014-03-20 05:41:07351 kSampleRate,
jrummell@chromium.org47b37a62013-07-10 03:56:10352 kFakeAudioFrameSize,
jrummell@chromium.org47b37a62013-07-10 03:56:10353 kNoTimestamp());
xhwang@chromium.orgecbb9762012-10-24 22:33:54354 decoded_frame_list_.push_back(frame_a);
355 decoded_frame_list_.push_back(frame_b);
xhwang@chromium.org97a9ce42012-10-19 10:06:43356
xhwang@chromium.org97a9ce42012-10-19 10:06:43357 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48358 .WillOnce(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43359
xhwang@chromium.org5c5e9b72014-06-17 19:21:12360 EXPECT_CALL(*this, FrameReady(decoded_frame_));
361 EXPECT_CALL(*this, FrameReady(frame_a));
362 EXPECT_CALL(*this, FrameReady(frame_b));
363 DecodeAndExpect(encrypted_buffer_, AudioDecoder::kOk);
xhwang@chromium.org97a9ce42012-10-19 10:06:43364}
365
366// Test the case where the decryptor receives end-of-stream buffer.
367TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) {
368 Initialize();
369 EnterNormalDecodingState();
370 EnterEndOfStreamState();
xhwang@chromium.org97a9ce42012-10-19 10:06:43371}
372
rileya@chromium.orgd70157792014-03-17 21:45:03373// Test reinitializing decode with a new config
374TEST_F(DecryptingAudioDecoderTest, Reinitialize_ConfigChange) {
xhwang@chromium.org7c39486c2013-01-06 15:36:09375 Initialize();
376
rileya@chromium.orgd70157792014-03-17 21:45:03377 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
378 .Times(AtMost(1))
379 .WillOnce(RunCallback<1>(true));
xhwang@chromium.org7c39486c2013-01-06 15:36:09380
xhwang@chromium.orgecf16912013-01-12 16:55:22381 // The new config is different from the initial config in bits-per-channel,
382 // channel layout and samples_per_second.
383 AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16,
rileya@chromium.orgd70157792014-03-17 21:45:03384 CHANNEL_LAYOUT_5_1, 88200, NULL, 0, true);
xhwang@chromium.orgecf16912013-01-12 16:55:22385 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
386 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
387 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
388
rileya@chromium.orgd70157792014-03-17 21:45:03389 ReinitializeConfigChange(new_config);
390 message_loop_.RunUntilIdle();
xhwang@chromium.org7c39486c2013-01-06 15:36:09391}
392
xhwang@chromium.org97a9ce42012-10-19 10:06:43393// Test the case where the a key is added when the decryptor is in
394// kWaitingForKey state.
395TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) {
396 Initialize();
397 EnterWaitingForKeyState();
398
399 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48400 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
sergeyu@chromium.org49cea862014-06-11 11:11:50401 EXPECT_CALL(*this, FrameReady(decoded_frame_));
402 EXPECT_CALL(*this, DecodeDone(AudioDecoder::kOk));
xhwang@chromium.org97a9ce42012-10-19 10:06:43403 key_added_cb_.Run();
xhwang@chromium.org643d5442012-11-14 05:08:32404 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43405}
406
407// Test the case where the a key is added when the decryptor is in
408// kPendingDecode state.
409TEST_F(DecryptingAudioDecoderTest, KeyAdded_DruingPendingDecode) {
410 Initialize();
411 EnterPendingDecodeState();
412
413 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48414 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
sergeyu@chromium.org49cea862014-06-11 11:11:50415 EXPECT_CALL(*this, FrameReady(decoded_frame_));
416 EXPECT_CALL(*this, DecodeDone(AudioDecoder::kOk));
xhwang@chromium.org97a9ce42012-10-19 10:06:43417 // The audio decode callback is returned after the correct decryption key is
418 // added.
419 key_added_cb_.Run();
420 base::ResetAndReturn(&pending_audio_decode_cb_).Run(
421 Decryptor::kNoKey, Decryptor::AudioBuffers());
xhwang@chromium.org643d5442012-11-14 05:08:32422 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43423}
424
425// Test resetting when the decoder is in kIdle state but has not decoded any
426// frame.
427TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) {
428 Initialize();
429 Reset();
430}
431
432// Test resetting when the decoder is in kIdle state after it has decoded one
433// frame.
434TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
435 Initialize();
436 EnterNormalDecodingState();
437 Reset();
xhwang@chromium.org97a9ce42012-10-19 10:06:43438}
439
440// Test resetting when the decoder is in kPendingDecode state.
441TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) {
442 Initialize();
443 EnterPendingDecodeState();
444
sergeyu@chromium.org49cea862014-06-11 11:11:50445 EXPECT_CALL(*this, DecodeDone(AudioDecoder::kAborted));
xhwang@chromium.org97a9ce42012-10-19 10:06:43446
447 Reset();
448}
449
450// Test resetting when the decoder is in kWaitingForKey state.
451TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) {
452 Initialize();
453 EnterWaitingForKeyState();
454
sergeyu@chromium.org49cea862014-06-11 11:11:50455 EXPECT_CALL(*this, DecodeDone(AudioDecoder::kAborted));
xhwang@chromium.org97a9ce42012-10-19 10:06:43456
457 Reset();
458}
459
460// Test resetting when the decoder has hit end of stream and is in
461// kDecodeFinished state.
462TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) {
463 Initialize();
464 EnterNormalDecodingState();
465 EnterEndOfStreamState();
466 Reset();
467}
468
469// Test resetting after the decoder has been reset.
470TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) {
471 Initialize();
472 EnterNormalDecodingState();
473 Reset();
474 Reset();
xhwang@chromium.org97a9ce42012-10-19 10:06:43475}
476
477} // namespace media