[go: nahoru, domu]

blob: c711cbd92a1474bfdf7b71dae3fac8f917a14f5e [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::IsNull;
xhwang@chromium.org97a9ce42012-10-19 10:06:4324using ::testing::SaveArg;
25using ::testing::StrictMock;
26
27namespace media {
28
rileya@chromium.org16ecd5f2014-03-20 05:41:0729static const int kSampleRate = 44100;
30
xhwang@chromium.orgecf16912013-01-12 16:55:2231// Make sure the kFakeAudioFrameSize is a valid frame size for all audio decoder
32// configs used in this test.
33static const int kFakeAudioFrameSize = 48;
xhwang@chromium.org97a9ce42012-10-19 10:06:4334static const uint8 kFakeKeyId[] = { 0x4b, 0x65, 0x79, 0x20, 0x49, 0x44 };
35static const uint8 kFakeIv[DecryptConfig::kDecryptionKeySize] = { 0 };
36
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
rileya@chromium.orgd70157792014-03-17 21:45:0362// Mock action which we use to repeatedly call ReadAndExpectFrameReadyWith() if
63// we get kNotEnoughData from a Decode() call to |decoder_|.
64ACTION_P2(CallExpectFrameReadyMoreData, test, buffer) {
65 test->ReadAndExpectFrameReadyWith(
66 CreateFakeEncryptedBuffer(), AudioDecoder::kNotEnoughData, buffer);
xhwang@chromium.org97a9ce42012-10-19 10:06:4367}
68
xhwang@chromium.org8b10f2222012-11-13 05:49:4869MATCHER(IsEndOfStream, "end of stream") {
tyoverby@chromium.org71a8d5a2013-06-25 08:41:0170 return (arg->end_of_stream());
xhwang@chromium.org8f5a9a52012-10-23 20:49:2071}
72
xhwang@chromium.org97a9ce42012-10-19 10:06:4373} // namespace
74
75class DecryptingAudioDecoderTest : public testing::Test {
76 public:
77 DecryptingAudioDecoderTest()
xhwang@chromium.org2b454ff82012-11-15 03:57:5878 : decoder_(new DecryptingAudioDecoder(
scherkus@chromium.org8c076cb2012-11-28 21:06:1679 message_loop_.message_loop_proxy(),
xhwang@chromium.org97a9ce42012-10-19 10:06:4380 base::Bind(
81 &DecryptingAudioDecoderTest::RequestDecryptorNotification,
82 base::Unretained(this)))),
83 decryptor_(new StrictMock<MockDecryptor>()),
xhwang@chromium.org97a9ce42012-10-19 10:06:4384 encrypted_buffer_(CreateFakeEncryptedBuffer()),
xhwang@chromium.orgecbb9762012-10-24 22:33:5485 decoded_frame_(NULL),
jrummell@chromium.org47b37a62013-07-10 03:56:1086 end_of_stream_frame_(AudioBuffer::CreateEOSBuffer()),
rileya@chromium.orgd70157792014-03-17 21:45:0387 decoded_frame_list_() {}
xhwang@chromium.org97a9ce42012-10-19 10:06:4388
rileya@chromium.orgb960fd02014-01-23 04:48:5489 virtual ~DecryptingAudioDecoderTest() {
rileya@chromium.orgd70157792014-03-17 21:45:0390 EXPECT_CALL(*this, RequestDecryptorNotification(_))
91 .Times(testing::AnyNumber());
rileya@chromium.orgb960fd02014-01-23 04:48:5492 Stop();
93 }
94
xhwang@chromium.org97a9ce42012-10-19 10:06:4395 void InitializeAndExpectStatus(const AudioDecoderConfig& config,
96 PipelineStatus status) {
dalecurtis@google.come81f5f9d2014-03-29 01:32:1697 // Initialize data now that the config is known. Since the code uses
98 // invalid values (that CreateEmptyBuffer() doesn't support), tweak them
99 // just for CreateEmptyBuffer().
100 int channels = ChannelLayoutToChannelCount(config.channel_layout());
101 if (channels < 0)
102 channels = 0;
rileya@chromium.org16ecd5f2014-03-20 05:41:07103 decoded_frame_ = AudioBuffer::CreateEmptyBuffer(config.channel_layout(),
dalecurtis@google.come81f5f9d2014-03-29 01:32:16104 channels,
rileya@chromium.org16ecd5f2014-03-20 05:41:07105 kSampleRate,
106 kFakeAudioFrameSize,
107 kNoTimestamp(),
108 kNoTimestamp());
jrummell@chromium.org47b37a62013-07-10 03:56:10109 decoded_frame_list_.push_back(decoded_frame_);
110
rileya@chromium.orgd70157792014-03-17 21:45:03111 decoder_->Initialize(config, NewExpectedStatusCB(status));
xhwang@chromium.org643d5442012-11-14 05:08:32112 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43113 }
114
115 void Initialize() {
xhwang@chromium.orga3e28672013-03-14 14:54:59116 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
xhwang@chromium.org97a9ce42012-10-19 10:06:43117 .Times(AtMost(1))
xhwang@chromium.org8b10f2222012-11-13 05:49:48118 .WillOnce(RunCallback<1>(true));
xhwang@chromium.org97a9ce42012-10-19 10:06:43119 EXPECT_CALL(*this, RequestDecryptorNotification(_))
xhwang@chromium.org8b10f2222012-11-13 05:49:48120 .WillOnce(RunCallbackIfNotNull(decryptor_.get()));
xhwang@chromium.orgabd36b3af2012-12-22 03:42:02121 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
xhwang@chromium.org82d7abd2012-11-02 23:04:03122 .WillOnce(SaveArg<1>(&key_added_cb_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43123
xhwang@chromium.org7c39486c2013-01-06 15:36:09124 config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32,
rileya@chromium.org16ecd5f2014-03-20 05:41:07125 CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, true, true,
vigneshv@chromium.org5e3484f2013-09-06 05:09:07126 base::TimeDelta(), base::TimeDelta());
xhwang@chromium.org7c39486c2013-01-06 15:36:09127 InitializeAndExpectStatus(config_, PIPELINE_OK);
xhwang@chromium.org97a9ce42012-10-19 10:06:43128 }
129
rileya@chromium.orgd70157792014-03-17 21:45:03130 void Reinitialize() {
131 ReinitializeConfigChange(config_);
132 }
133
134 void ReinitializeConfigChange(AudioDecoderConfig& new_config) {
135 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
136 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
137 .WillOnce(RunCallback<1>(true));
138 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
139 .WillOnce(SaveArg<1>(&key_added_cb_));
140 decoder_->Initialize(new_config, NewExpectedStatusCB(PIPELINE_OK));
141 }
142
xhwang@chromium.org97a9ce42012-10-19 10:06:43143 void ReadAndExpectFrameReadyWith(
rileya@chromium.orgd70157792014-03-17 21:45:03144 scoped_refptr<DecoderBuffer> input,
xhwang@chromium.org97a9ce42012-10-19 10:06:43145 AudioDecoder::Status status,
jrummell@chromium.org47b37a62013-07-10 03:56:10146 const scoped_refptr<AudioBuffer>& audio_frame) {
rileya@chromium.orgd70157792014-03-17 21:45:03147
148 const scoped_refptr<AudioBuffer>& buffer = decoder_->GetDecodeOutput();
149
150 if (buffer) {
151 EXPECT_EQ(audio_frame, buffer);
152 EXPECT_EQ(status, AudioDecoder::kOk);
153 return;
154 }
155
156 if (status == AudioDecoder::kNotEnoughData)
157 // Keep calling again to give it more data if we get kNotEnoughData.
158 EXPECT_CALL(*this, FrameReady(status, scoped_refptr<AudioBuffer>(NULL))).
159 WillRepeatedly(CallExpectFrameReadyMoreData(this, audio_frame));
160 else if (status != AudioDecoder::kOk)
xhwang@chromium.org97a9ce42012-10-19 10:06:43161 EXPECT_CALL(*this, FrameReady(status, IsNull()));
tyoverby@chromium.org71a8d5a2013-06-25 08:41:01162 else if (audio_frame->end_of_stream())
xhwang@chromium.org8f5a9a52012-10-23 20:49:20163 EXPECT_CALL(*this, FrameReady(status, IsEndOfStream()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43164 else
165 EXPECT_CALL(*this, FrameReady(status, audio_frame));
166
rileya@chromium.orgd70157792014-03-17 21:45:03167 decoder_->Decode(input,
168 base::Bind(&DecryptingAudioDecoderTest::FrameReady,
169 base::Unretained(this)));
xhwang@chromium.org643d5442012-11-14 05:08:32170 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43171 }
172
173 // Sets up expectations and actions to put DecryptingAudioDecoder in an
174 // active normal decoding state.
175 void EnterNormalDecodingState() {
176 Decryptor::AudioBuffers end_of_stream_frames_(1, end_of_stream_frame_);
177
xhwang@chromium.org97a9ce42012-10-19 10:06:43178 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48179 .WillOnce(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_))
180 .WillRepeatedly(RunCallback<1>(Decryptor::kNeedMoreData,
181 Decryptor::AudioBuffers()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43182
rileya@chromium.orgd70157792014-03-17 21:45:03183 ReadAndExpectFrameReadyWith(
184 encrypted_buffer_, AudioDecoder::kOk, decoded_frame_);
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() {
rileya@chromium.orgd70157792014-03-17 21:45:03191 ReadAndExpectFrameReadyWith(DecoderBuffer::CreateEOSBuffer(),
192 AudioDecoder::kOk,
193 end_of_stream_frame_);
xhwang@chromium.org97a9ce42012-10-19 10:06:43194 }
195
196 // Make the audio decode callback pending by saving and not firing it.
197 void EnterPendingDecodeState() {
198 EXPECT_TRUE(pending_audio_decode_cb_.is_null());
xhwang@chromium.org97a9ce42012-10-19 10:06:43199 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
200 .WillOnce(SaveArg<1>(&pending_audio_decode_cb_));
201
rileya@chromium.orgd70157792014-03-17 21:45:03202 decoder_->Decode(encrypted_buffer_,
203 base::Bind(&DecryptingAudioDecoderTest::FrameReady,
204 base::Unretained(this)));
xhwang@chromium.org643d5442012-11-14 05:08:32205 message_loop_.RunUntilIdle();
rileya@chromium.orgd70157792014-03-17 21:45:03206 // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
207 // the decryptor.
xhwang@chromium.org97a9ce42012-10-19 10:06:43208 EXPECT_FALSE(pending_audio_decode_cb_.is_null());
209 }
210
211 void EnterWaitingForKeyState() {
xhwang@chromium.org2b454ff82012-11-15 03:57:58212 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48213 .WillRepeatedly(RunCallback<1>(Decryptor::kNoKey,
214 Decryptor::AudioBuffers()));
rileya@chromium.orgd70157792014-03-17 21:45:03215 decoder_->Decode(encrypted_buffer_,
216 base::Bind(&DecryptingAudioDecoderTest::FrameReady,
217 base::Unretained(this)));
xhwang@chromium.org643d5442012-11-14 05:08:32218 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43219 }
220
221 void AbortPendingAudioDecodeCB() {
222 if (!pending_audio_decode_cb_.is_null()) {
223 base::ResetAndReturn(&pending_audio_decode_cb_).Run(
224 Decryptor::kSuccess, Decryptor::AudioBuffers());
225 }
226 }
227
rileya@chromium.orgb960fd02014-01-23 04:48:54228 void AbortAllPendingCBs() {
229 if (!pending_init_cb_.is_null()) {
230 ASSERT_TRUE(pending_audio_decode_cb_.is_null());
231 base::ResetAndReturn(&pending_init_cb_).Run(false);
232 return;
233 }
234
235 AbortPendingAudioDecodeCB();
236 }
237
xhwang@chromium.org97a9ce42012-10-19 10:06:43238 void Reset() {
239 EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio))
240 .WillRepeatedly(InvokeWithoutArgs(
241 this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB));
242
243 decoder_->Reset(NewExpectedClosure());
rileya@chromium.org3c0e4062014-01-15 22:23:12244 message_loop_.RunUntilIdle();
245 }
246
rileya@chromium.orgb960fd02014-01-23 04:48:54247 void Stop() {
rileya@chromium.orgb960fd02014-01-23 04:48:54248 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio))
249 .WillRepeatedly(InvokeWithoutArgs(
250 this, &DecryptingAudioDecoderTest::AbortAllPendingCBs));
251
252 decoder_->Stop(NewExpectedClosure());
253 message_loop_.RunUntilIdle();
254 }
255
xhwang@chromium.orgdaede9b92012-12-14 00:57:25256 MOCK_METHOD1(RequestDecryptorNotification, void(const DecryptorReadyCB&));
xhwang@chromium.org97a9ce42012-10-19 10:06:43257
jrummell@chromium.org47b37a62013-07-10 03:56:10258 MOCK_METHOD2(FrameReady,
259 void(AudioDecoder::Status, const scoped_refptr<AudioBuffer>&));
xhwang@chromium.org97a9ce42012-10-19 10:06:43260
xhwang@chromium.orgfb5af232013-04-22 22:40:03261 base::MessageLoop message_loop_;
scherkus@chromium.org7dd4c742013-03-21 22:33:47262 scoped_ptr<DecryptingAudioDecoder> decoder_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43263 scoped_ptr<StrictMock<MockDecryptor> > decryptor_;
xhwang@chromium.org7c39486c2013-01-06 15:36:09264 AudioDecoderConfig config_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43265
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_;
273 scoped_refptr<AudioBuffer> end_of_stream_frame_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43274 Decryptor::AudioBuffers decoded_frame_list_;
275
276 private:
277 DISALLOW_COPY_AND_ASSIGN(DecryptingAudioDecoderTest);
278};
279
280TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) {
281 Initialize();
282}
283
284// Ensure that DecryptingAudioDecoder only accepts encrypted audio.
285TEST_F(DecryptingAudioDecoderTest, Initialize_UnencryptedAudioConfig) {
dalecurtis@google.comb5eca3c2013-01-04 20:20:15286 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
rileya@chromium.org16ecd5f2014-03-20 05:41:07287 CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, false);
xhwang@chromium.org97a9ce42012-10-19 10:06:43288
289 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED);
290}
291
292// Ensure decoder handles invalid audio configs without crashing.
293TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) {
dalecurtis@google.comb5eca3c2013-01-04 20:20:15294 AudioDecoderConfig config(kUnknownAudioCodec, kUnknownSampleFormat,
295 CHANNEL_LAYOUT_STEREO, 0, NULL, 0, true);
xhwang@chromium.org97a9ce42012-10-19 10:06:43296
297 InitializeAndExpectStatus(config, PIPELINE_ERROR_DECODE);
298}
299
300// Ensure decoder handles unsupported audio configs without crashing.
301TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) {
xhwang@chromium.orga3e28672013-03-14 14:54:59302 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48303 .WillOnce(RunCallback<1>(false));
xhwang@chromium.org97a9ce42012-10-19 10:06:43304 EXPECT_CALL(*this, RequestDecryptorNotification(_))
xhwang@chromium.org8b10f2222012-11-13 05:49:48305 .WillOnce(RunCallbackIfNotNull(decryptor_.get()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43306
dalecurtis@google.comb5eca3c2013-01-04 20:20:15307 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
rileya@chromium.org16ecd5f2014-03-20 05:41:07308 CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, true);
xhwang@chromium.org97a9ce42012-10-19 10:06:43309 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED);
310}
311
xhwang@chromium.org699b64a2013-06-19 07:36:05312TEST_F(DecryptingAudioDecoderTest, Initialize_NullDecryptor) {
313 EXPECT_CALL(*this, RequestDecryptorNotification(_))
314 .WillRepeatedly(RunCallbackIfNotNull(static_cast<Decryptor*>(NULL)));
315
316 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
rileya@chromium.org16ecd5f2014-03-20 05:41:07317 CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, true);
xhwang@chromium.org699b64a2013-06-19 07:36:05318 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED);
319}
320
xhwang@chromium.org97a9ce42012-10-19 10:06:43321// Test normal decrypt and decode case.
322TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) {
323 Initialize();
324 EnterNormalDecodingState();
325}
326
327// Test the case where the decryptor returns error when doing decrypt and
328// decode.
329TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) {
330 Initialize();
331
xhwang@chromium.org97a9ce42012-10-19 10:06:43332 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48333 .WillRepeatedly(RunCallback<1>(Decryptor::kError,
334 Decryptor::AudioBuffers()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43335
rileya@chromium.orgd70157792014-03-17 21:45:03336 ReadAndExpectFrameReadyWith(
337 encrypted_buffer_, AudioDecoder::kDecodeError, NULL);
xhwang@chromium.org97a9ce42012-10-19 10:06:43338}
339
340// Test the case where the decryptor returns kNeedMoreData to ask for more
341// buffers before it can produce a frame.
342TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_NeedMoreData) {
343 Initialize();
344
xhwang@chromium.org97a9ce42012-10-19 10:06:43345 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48346 .WillOnce(RunCallback<1>(Decryptor::kNeedMoreData,
347 Decryptor::AudioBuffers()))
348 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43349
rileya@chromium.orgd70157792014-03-17 21:45:03350 // We expect it to eventually return kOk, with any number of returns of
351 // kNotEnoughData beforehand.
352 EXPECT_CALL(*this, FrameReady(AudioDecoder::kOk, decoded_frame_));
353 ReadAndExpectFrameReadyWith(
354 encrypted_buffer_, AudioDecoder::kNotEnoughData, decoded_frame_);
xhwang@chromium.org97a9ce42012-10-19 10:06:43355}
356
357// Test the case where the decryptor returns multiple decoded frames.
358TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) {
359 Initialize();
360
jrummell@chromium.org47b37a62013-07-10 03:56:10361 scoped_refptr<AudioBuffer> frame_a = AudioBuffer::CreateEmptyBuffer(
rileya@chromium.org16ecd5f2014-03-20 05:41:07362 config_.channel_layout(),
dalecurtis@google.come81f5f9d2014-03-29 01:32:16363 ChannelLayoutToChannelCount(config_.channel_layout()),
rileya@chromium.org16ecd5f2014-03-20 05:41:07364 kSampleRate,
jrummell@chromium.org47b37a62013-07-10 03:56:10365 kFakeAudioFrameSize,
366 kNoTimestamp(),
367 kNoTimestamp());
368 scoped_refptr<AudioBuffer> frame_b = AudioBuffer::CreateEmptyBuffer(
rileya@chromium.org16ecd5f2014-03-20 05:41:07369 config_.channel_layout(),
dalecurtis@google.come81f5f9d2014-03-29 01:32:16370 ChannelLayoutToChannelCount(config_.channel_layout()),
rileya@chromium.org16ecd5f2014-03-20 05:41:07371 kSampleRate,
jrummell@chromium.org47b37a62013-07-10 03:56:10372 kFakeAudioFrameSize,
373 kNoTimestamp(),
374 kNoTimestamp());
xhwang@chromium.orgecbb9762012-10-24 22:33:54375 decoded_frame_list_.push_back(frame_a);
376 decoded_frame_list_.push_back(frame_b);
xhwang@chromium.org97a9ce42012-10-19 10:06:43377
xhwang@chromium.org97a9ce42012-10-19 10:06:43378 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48379 .WillOnce(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43380
rileya@chromium.orgd70157792014-03-17 21:45:03381 ReadAndExpectFrameReadyWith(
382 encrypted_buffer_, AudioDecoder::kOk, decoded_frame_);
383 ReadAndExpectFrameReadyWith(encrypted_buffer_, AudioDecoder::kOk, frame_a);
384 ReadAndExpectFrameReadyWith(encrypted_buffer_, AudioDecoder::kOk, frame_b);
xhwang@chromium.org97a9ce42012-10-19 10:06:43385}
386
387// Test the case where the decryptor receives end-of-stream buffer.
388TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) {
389 Initialize();
390 EnterNormalDecodingState();
391 EnterEndOfStreamState();
xhwang@chromium.org97a9ce42012-10-19 10:06:43392}
393
rileya@chromium.orgd70157792014-03-17 21:45:03394// Test reinitializing decode with a new config
395TEST_F(DecryptingAudioDecoderTest, Reinitialize_ConfigChange) {
xhwang@chromium.org7c39486c2013-01-06 15:36:09396 Initialize();
397
rileya@chromium.orgd70157792014-03-17 21:45:03398 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
399 .Times(AtMost(1))
400 .WillOnce(RunCallback<1>(true));
xhwang@chromium.org7c39486c2013-01-06 15:36:09401
xhwang@chromium.orgecf16912013-01-12 16:55:22402 // The new config is different from the initial config in bits-per-channel,
403 // channel layout and samples_per_second.
404 AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16,
rileya@chromium.orgd70157792014-03-17 21:45:03405 CHANNEL_LAYOUT_5_1, 88200, NULL, 0, true);
xhwang@chromium.orgecf16912013-01-12 16:55:22406 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
407 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
408 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
409
rileya@chromium.orgd70157792014-03-17 21:45:03410 ReinitializeConfigChange(new_config);
411 message_loop_.RunUntilIdle();
xhwang@chromium.org7c39486c2013-01-06 15:36:09412}
413
xhwang@chromium.org97a9ce42012-10-19 10:06:43414// Test the case where the a key is added when the decryptor is in
415// kWaitingForKey state.
416TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) {
417 Initialize();
418 EnterWaitingForKeyState();
419
420 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48421 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43422 EXPECT_CALL(*this, FrameReady(AudioDecoder::kOk, decoded_frame_));
423 key_added_cb_.Run();
xhwang@chromium.org643d5442012-11-14 05:08:32424 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43425}
426
427// Test the case where the a key is added when the decryptor is in
428// kPendingDecode state.
429TEST_F(DecryptingAudioDecoderTest, KeyAdded_DruingPendingDecode) {
430 Initialize();
431 EnterPendingDecodeState();
432
433 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48434 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43435 EXPECT_CALL(*this, FrameReady(AudioDecoder::kOk, decoded_frame_));
436 // The audio decode callback is returned after the correct decryption key is
437 // added.
438 key_added_cb_.Run();
439 base::ResetAndReturn(&pending_audio_decode_cb_).Run(
440 Decryptor::kNoKey, Decryptor::AudioBuffers());
xhwang@chromium.org643d5442012-11-14 05:08:32441 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43442}
443
444// Test resetting when the decoder is in kIdle state but has not decoded any
445// frame.
446TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) {
447 Initialize();
448 Reset();
449}
450
451// Test resetting when the decoder is in kIdle state after it has decoded one
452// frame.
453TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
454 Initialize();
455 EnterNormalDecodingState();
456 Reset();
xhwang@chromium.org97a9ce42012-10-19 10:06:43457}
458
459// Test resetting when the decoder is in kPendingDecode state.
460TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) {
461 Initialize();
462 EnterPendingDecodeState();
463
xhwang@chromium.org8f5a9a52012-10-23 20:49:20464 EXPECT_CALL(*this, FrameReady(AudioDecoder::kAborted, IsNull()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43465
466 Reset();
467}
468
469// Test resetting when the decoder is in kWaitingForKey state.
470TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) {
471 Initialize();
472 EnterWaitingForKeyState();
473
xhwang@chromium.org8f5a9a52012-10-23 20:49:20474 EXPECT_CALL(*this, FrameReady(AudioDecoder::kAborted, IsNull()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43475
476 Reset();
477}
478
479// Test resetting when the decoder has hit end of stream and is in
480// kDecodeFinished state.
481TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) {
482 Initialize();
483 EnterNormalDecodingState();
484 EnterEndOfStreamState();
485 Reset();
486}
487
488// Test resetting after the decoder has been reset.
489TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) {
490 Initialize();
491 EnterNormalDecodingState();
492 Reset();
493 Reset();
xhwang@chromium.org97a9ce42012-10-19 10:06:43494}
495
496} // namespace media