[go: nahoru, domu]

blob: 83d7f5f36bdc9a7fec59aea600c9e2e9538f6953 [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.org97a9ce42012-10-19 10:06:4362} // namespace
63
64class DecryptingAudioDecoderTest : public testing::Test {
65 public:
66 DecryptingAudioDecoderTest()
xhwang@chromium.org2b454ff82012-11-15 03:57:5867 : decoder_(new DecryptingAudioDecoder(
scherkus@chromium.org8c076cb2012-11-28 21:06:1668 message_loop_.message_loop_proxy(),
xhwang@chromium.org97a9ce42012-10-19 10:06:4369 base::Bind(
70 &DecryptingAudioDecoderTest::RequestDecryptorNotification,
71 base::Unretained(this)))),
72 decryptor_(new StrictMock<MockDecryptor>()),
xhwang@chromium.org5c5e9b72014-06-17 19:21:1273 num_decrypt_and_decode_calls_(0),
74 num_frames_in_decryptor_(0),
xhwang@chromium.org97a9ce42012-10-19 10:06:4375 encrypted_buffer_(CreateFakeEncryptedBuffer()),
xhwang@chromium.orgecbb9762012-10-24 22:33:5476 decoded_frame_(NULL),
rileya@chromium.orgd70157792014-03-17 21:45:0377 decoded_frame_list_() {}
xhwang@chromium.org97a9ce42012-10-19 10:06:4378
rileya@chromium.orgb960fd02014-01-23 04:48:5479 virtual ~DecryptingAudioDecoderTest() {
rileya@chromium.orgd70157792014-03-17 21:45:0380 EXPECT_CALL(*this, RequestDecryptorNotification(_))
81 .Times(testing::AnyNumber());
xhwang@chromium.org83fb2a9e2014-07-16 23:36:4182 Destroy();
rileya@chromium.orgb960fd02014-01-23 04:48:5483 }
84
xhwang@chromium.org97a9ce42012-10-19 10:06:4385 void InitializeAndExpectStatus(const AudioDecoderConfig& config,
86 PipelineStatus status) {
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;
rileya@chromium.org16ecd5f2014-03-20 05:41:0793 decoded_frame_ = AudioBuffer::CreateEmptyBuffer(config.channel_layout(),
dalecurtis@google.come81f5f9d2014-03-29 01:32:1694 channels,
rileya@chromium.org16ecd5f2014-03-20 05:41:0795 kSampleRate,
96 kFakeAudioFrameSize,
rileya@chromium.org16ecd5f2014-03-20 05:41:0797 kNoTimestamp());
jrummell@chromium.org47b37a62013-07-10 03:56:1098 decoded_frame_list_.push_back(decoded_frame_);
99
sergeyu@chromium.org49cea862014-06-11 11:11:50100 decoder_->Initialize(config, NewExpectedStatusCB(status),
101 base::Bind(&DecryptingAudioDecoderTest::FrameReady,
102 base::Unretained(this)));
xhwang@chromium.org643d5442012-11-14 05:08:32103 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43104 }
105
106 void Initialize() {
xhwang@chromium.orga3e28672013-03-14 14:54:59107 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
xhwang@chromium.org97a9ce42012-10-19 10:06:43108 .Times(AtMost(1))
xhwang@chromium.org8b10f2222012-11-13 05:49:48109 .WillOnce(RunCallback<1>(true));
xhwang@chromium.org97a9ce42012-10-19 10:06:43110 EXPECT_CALL(*this, RequestDecryptorNotification(_))
xhwang@chromium.org8b10f2222012-11-13 05:49:48111 .WillOnce(RunCallbackIfNotNull(decryptor_.get()));
xhwang@chromium.orgabd36b3af2012-12-22 03:42:02112 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
xhwang@chromium.org82d7abd2012-11-02 23:04:03113 .WillOnce(SaveArg<1>(&key_added_cb_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43114
xhwang@chromium.org7c39486c2013-01-06 15:36:09115 config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32,
rileya@chromium.org16ecd5f2014-03-20 05:41:07116 CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, true, true,
dalecurtis@google.com6fb86542014-04-18 19:58:13117 base::TimeDelta(), 0);
xhwang@chromium.org7c39486c2013-01-06 15:36:09118 InitializeAndExpectStatus(config_, PIPELINE_OK);
xhwang@chromium.org97a9ce42012-10-19 10:06:43119 }
120
rileya@chromium.orgd70157792014-03-17 21:45:03121 void Reinitialize() {
122 ReinitializeConfigChange(config_);
123 }
124
dalecurtis@google.com6fb86542014-04-18 19:58:13125 void ReinitializeConfigChange(const AudioDecoderConfig& new_config) {
rileya@chromium.orgd70157792014-03-17 21:45:03126 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
127 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
128 .WillOnce(RunCallback<1>(true));
129 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
130 .WillOnce(SaveArg<1>(&key_added_cb_));
sergeyu@chromium.org49cea862014-06-11 11:11:50131 decoder_->Initialize(new_config, NewExpectedStatusCB(PIPELINE_OK),
132 base::Bind(&DecryptingAudioDecoderTest::FrameReady,
133 base::Unretained(this)));
rileya@chromium.orgd70157792014-03-17 21:45:03134 }
135
xhwang@chromium.org5c5e9b72014-06-17 19:21:12136 // Decode |buffer| and expect DecodeDone to get called with |status|.
137 void DecodeAndExpect(const scoped_refptr<DecoderBuffer>& buffer,
138 AudioDecoder::Status status) {
sergeyu@chromium.org49cea862014-06-11 11:11:50139 EXPECT_CALL(*this, DecodeDone(status));
xhwang@chromium.org5c5e9b72014-06-17 19:21:12140 decoder_->Decode(buffer,
sergeyu@chromium.org49cea862014-06-11 11:11:50141 base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
rileya@chromium.orgd70157792014-03-17 21:45:03142 base::Unretained(this)));
xhwang@chromium.org643d5442012-11-14 05:08:32143 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43144 }
145
xhwang@chromium.org5c5e9b72014-06-17 19:21:12146 // Helper function to simulate the decrypting and decoding process in the
147 // |decryptor_| with a decoding delay of kDecodingDelay buffers.
148 void DecryptAndDecodeAudio(const scoped_refptr<DecoderBuffer>& encrypted,
149 const Decryptor::AudioDecodeCB& audio_decode_cb) {
150 num_decrypt_and_decode_calls_++;
151 if (!encrypted->end_of_stream())
152 num_frames_in_decryptor_++;
153
154 if (num_decrypt_and_decode_calls_ <= kDecodingDelay ||
155 num_frames_in_decryptor_ == 0) {
156 audio_decode_cb.Run(Decryptor::kNeedMoreData, Decryptor::AudioBuffers());
157 return;
158 }
159
160 num_frames_in_decryptor_--;
161 audio_decode_cb.Run(Decryptor::kSuccess,
162 Decryptor::AudioBuffers(1, decoded_frame_));
163 }
164
xhwang@chromium.org97a9ce42012-10-19 10:06:43165 // Sets up expectations and actions to put DecryptingAudioDecoder in an
166 // active normal decoding state.
167 void EnterNormalDecodingState() {
xhwang@chromium.org5c5e9b72014-06-17 19:21:12168 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _)).WillRepeatedly(
169 Invoke(this, &DecryptingAudioDecoderTest::DecryptAndDecodeAudio));
170 EXPECT_CALL(*this, FrameReady(decoded_frame_));
171 for (int i = 0; i < kDecodingDelay + 1; ++i)
172 DecodeAndExpect(encrypted_buffer_, AudioDecoder::kOk);
xhwang@chromium.org97a9ce42012-10-19 10:06:43173 }
174
175 // Sets up expectations and actions to put DecryptingAudioDecoder in an end
176 // of stream state. This function must be called after
177 // EnterNormalDecodingState() to work.
178 void EnterEndOfStreamState() {
xhwang@chromium.orgff757032014-06-19 01:42:24179 // The codec in the |decryptor_| will be flushed.
xhwang@chromium.org5c5e9b72014-06-17 19:21:12180 EXPECT_CALL(*this, FrameReady(decoded_frame_))
181 .Times(kDecodingDelay);
182 DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(), AudioDecoder::kOk);
183 EXPECT_EQ(0, num_frames_in_decryptor_);
xhwang@chromium.org97a9ce42012-10-19 10:06:43184 }
185
186 // Make the audio decode callback pending by saving and not firing it.
187 void EnterPendingDecodeState() {
188 EXPECT_TRUE(pending_audio_decode_cb_.is_null());
xhwang@chromium.org97a9ce42012-10-19 10:06:43189 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
190 .WillOnce(SaveArg<1>(&pending_audio_decode_cb_));
191
rileya@chromium.orgd70157792014-03-17 21:45:03192 decoder_->Decode(encrypted_buffer_,
sergeyu@chromium.org49cea862014-06-11 11:11:50193 base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
rileya@chromium.orgd70157792014-03-17 21:45:03194 base::Unretained(this)));
xhwang@chromium.org643d5442012-11-14 05:08:32195 message_loop_.RunUntilIdle();
rileya@chromium.orgd70157792014-03-17 21:45:03196 // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
197 // the decryptor.
xhwang@chromium.org97a9ce42012-10-19 10:06:43198 EXPECT_FALSE(pending_audio_decode_cb_.is_null());
199 }
200
201 void EnterWaitingForKeyState() {
xhwang@chromium.org2b454ff82012-11-15 03:57:58202 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48203 .WillRepeatedly(RunCallback<1>(Decryptor::kNoKey,
204 Decryptor::AudioBuffers()));
rileya@chromium.orgd70157792014-03-17 21:45:03205 decoder_->Decode(encrypted_buffer_,
sergeyu@chromium.org49cea862014-06-11 11:11:50206 base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
rileya@chromium.orgd70157792014-03-17 21:45:03207 base::Unretained(this)));
xhwang@chromium.org643d5442012-11-14 05:08:32208 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43209 }
210
211 void AbortPendingAudioDecodeCB() {
212 if (!pending_audio_decode_cb_.is_null()) {
213 base::ResetAndReturn(&pending_audio_decode_cb_).Run(
214 Decryptor::kSuccess, Decryptor::AudioBuffers());
215 }
216 }
217
rileya@chromium.orgb960fd02014-01-23 04:48:54218 void AbortAllPendingCBs() {
219 if (!pending_init_cb_.is_null()) {
220 ASSERT_TRUE(pending_audio_decode_cb_.is_null());
221 base::ResetAndReturn(&pending_init_cb_).Run(false);
222 return;
223 }
224
225 AbortPendingAudioDecodeCB();
226 }
227
xhwang@chromium.org97a9ce42012-10-19 10:06:43228 void Reset() {
229 EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio))
230 .WillRepeatedly(InvokeWithoutArgs(
231 this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB));
232
233 decoder_->Reset(NewExpectedClosure());
rileya@chromium.org3c0e4062014-01-15 22:23:12234 message_loop_.RunUntilIdle();
235 }
236
xhwang@chromium.org83fb2a9e2014-07-16 23:36:41237 void Destroy() {
rileya@chromium.orgb960fd02014-01-23 04:48:54238 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio))
239 .WillRepeatedly(InvokeWithoutArgs(
240 this, &DecryptingAudioDecoderTest::AbortAllPendingCBs));
241
xhwang@chromium.org83fb2a9e2014-07-16 23:36:41242 decoder_.reset();
rileya@chromium.orgb960fd02014-01-23 04:48:54243 message_loop_.RunUntilIdle();
244 }
245
xhwang@chromium.orgdaede9b92012-12-14 00:57:25246 MOCK_METHOD1(RequestDecryptorNotification, void(const DecryptorReadyCB&));
xhwang@chromium.org97a9ce42012-10-19 10:06:43247
sergeyu@chromium.org49cea862014-06-11 11:11:50248 MOCK_METHOD1(FrameReady, void(const scoped_refptr<AudioBuffer>&));
249 MOCK_METHOD1(DecodeDone, void(AudioDecoder::Status));
xhwang@chromium.org97a9ce42012-10-19 10:06:43250
xhwang@chromium.orgfb5af232013-04-22 22:40:03251 base::MessageLoop message_loop_;
scherkus@chromium.org7dd4c742013-03-21 22:33:47252 scoped_ptr<DecryptingAudioDecoder> decoder_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43253 scoped_ptr<StrictMock<MockDecryptor> > decryptor_;
xhwang@chromium.org7c39486c2013-01-06 15:36:09254 AudioDecoderConfig config_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43255
xhwang@chromium.org5c5e9b72014-06-17 19:21:12256 // Variables to help the |decryptor_| to simulate decoding delay and flushing.
257 int num_decrypt_and_decode_calls_;
258 int num_frames_in_decryptor_;
259
xhwang@chromium.org97a9ce42012-10-19 10:06:43260 Decryptor::DecoderInitCB pending_init_cb_;
xhwang@chromium.orgabd36b3af2012-12-22 03:42:02261 Decryptor::NewKeyCB key_added_cb_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43262 Decryptor::AudioDecodeCB pending_audio_decode_cb_;
263
rileya@chromium.orgd70157792014-03-17 21:45:03264 // Constant buffer/frames, to be used/returned by |decoder_| and |decryptor_|.
xhwang@chromium.org97a9ce42012-10-19 10:06:43265 scoped_refptr<DecoderBuffer> encrypted_buffer_;
jrummell@chromium.org47b37a62013-07-10 03:56:10266 scoped_refptr<AudioBuffer> decoded_frame_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43267 Decryptor::AudioBuffers decoded_frame_list_;
268
269 private:
270 DISALLOW_COPY_AND_ASSIGN(DecryptingAudioDecoderTest);
271};
272
273TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) {
274 Initialize();
275}
276
277// Ensure that DecryptingAudioDecoder only accepts encrypted audio.
278TEST_F(DecryptingAudioDecoderTest, Initialize_UnencryptedAudioConfig) {
dalecurtis@google.comb5eca3c2013-01-04 20:20:15279 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
rileya@chromium.org16ecd5f2014-03-20 05:41:07280 CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, false);
xhwang@chromium.org97a9ce42012-10-19 10:06:43281
282 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED);
283}
284
285// Ensure decoder handles invalid audio configs without crashing.
286TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) {
dalecurtis@google.comb5eca3c2013-01-04 20:20:15287 AudioDecoderConfig config(kUnknownAudioCodec, kUnknownSampleFormat,
288 CHANNEL_LAYOUT_STEREO, 0, NULL, 0, true);
xhwang@chromium.org97a9ce42012-10-19 10:06:43289
290 InitializeAndExpectStatus(config, PIPELINE_ERROR_DECODE);
291}
292
293// Ensure decoder handles unsupported audio configs without crashing.
294TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) {
xhwang@chromium.orga3e28672013-03-14 14:54:59295 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48296 .WillOnce(RunCallback<1>(false));
xhwang@chromium.org97a9ce42012-10-19 10:06:43297 EXPECT_CALL(*this, RequestDecryptorNotification(_))
xhwang@chromium.org8b10f2222012-11-13 05:49:48298 .WillOnce(RunCallbackIfNotNull(decryptor_.get()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43299
dalecurtis@google.comb5eca3c2013-01-04 20:20:15300 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
rileya@chromium.org16ecd5f2014-03-20 05:41:07301 CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, true);
xhwang@chromium.org97a9ce42012-10-19 10:06:43302 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED);
303}
304
xhwang@chromium.org699b64a2013-06-19 07:36:05305TEST_F(DecryptingAudioDecoderTest, Initialize_NullDecryptor) {
306 EXPECT_CALL(*this, RequestDecryptorNotification(_))
307 .WillRepeatedly(RunCallbackIfNotNull(static_cast<Decryptor*>(NULL)));
308
309 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
rileya@chromium.org16ecd5f2014-03-20 05:41:07310 CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, true);
xhwang@chromium.org699b64a2013-06-19 07:36:05311 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED);
312}
313
xhwang@chromium.org97a9ce42012-10-19 10:06:43314// Test normal decrypt and decode case.
315TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) {
316 Initialize();
317 EnterNormalDecodingState();
318}
319
320// Test the case where the decryptor returns error when doing decrypt and
321// decode.
322TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) {
323 Initialize();
324
xhwang@chromium.org97a9ce42012-10-19 10:06:43325 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48326 .WillRepeatedly(RunCallback<1>(Decryptor::kError,
327 Decryptor::AudioBuffers()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43328
xhwang@chromium.org5c5e9b72014-06-17 19:21:12329 DecodeAndExpect(encrypted_buffer_, AudioDecoder::kDecodeError);
xhwang@chromium.org97a9ce42012-10-19 10:06:43330}
331
332// Test the case where the decryptor returns multiple decoded frames.
333TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) {
334 Initialize();
335
jrummell@chromium.org47b37a62013-07-10 03:56:10336 scoped_refptr<AudioBuffer> frame_a = AudioBuffer::CreateEmptyBuffer(
rileya@chromium.org16ecd5f2014-03-20 05:41:07337 config_.channel_layout(),
dalecurtis@google.come81f5f9d2014-03-29 01:32:16338 ChannelLayoutToChannelCount(config_.channel_layout()),
rileya@chromium.org16ecd5f2014-03-20 05:41:07339 kSampleRate,
jrummell@chromium.org47b37a62013-07-10 03:56:10340 kFakeAudioFrameSize,
jrummell@chromium.org47b37a62013-07-10 03:56:10341 kNoTimestamp());
342 scoped_refptr<AudioBuffer> frame_b = 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());
xhwang@chromium.orgecbb9762012-10-24 22:33:54348 decoded_frame_list_.push_back(frame_a);
349 decoded_frame_list_.push_back(frame_b);
xhwang@chromium.org97a9ce42012-10-19 10:06:43350
xhwang@chromium.org97a9ce42012-10-19 10:06:43351 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48352 .WillOnce(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43353
xhwang@chromium.org5c5e9b72014-06-17 19:21:12354 EXPECT_CALL(*this, FrameReady(decoded_frame_));
355 EXPECT_CALL(*this, FrameReady(frame_a));
356 EXPECT_CALL(*this, FrameReady(frame_b));
357 DecodeAndExpect(encrypted_buffer_, AudioDecoder::kOk);
xhwang@chromium.org97a9ce42012-10-19 10:06:43358}
359
360// Test the case where the decryptor receives end-of-stream buffer.
361TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) {
362 Initialize();
363 EnterNormalDecodingState();
364 EnterEndOfStreamState();
xhwang@chromium.org97a9ce42012-10-19 10:06:43365}
366
rileya@chromium.orgd70157792014-03-17 21:45:03367// Test reinitializing decode with a new config
368TEST_F(DecryptingAudioDecoderTest, Reinitialize_ConfigChange) {
xhwang@chromium.org7c39486c2013-01-06 15:36:09369 Initialize();
370
rileya@chromium.orgd70157792014-03-17 21:45:03371 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
372 .Times(AtMost(1))
373 .WillOnce(RunCallback<1>(true));
xhwang@chromium.org7c39486c2013-01-06 15:36:09374
xhwang@chromium.orgecf16912013-01-12 16:55:22375 // The new config is different from the initial config in bits-per-channel,
376 // channel layout and samples_per_second.
377 AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16,
rileya@chromium.orgd70157792014-03-17 21:45:03378 CHANNEL_LAYOUT_5_1, 88200, NULL, 0, true);
xhwang@chromium.orgecf16912013-01-12 16:55:22379 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
380 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
381 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
382
rileya@chromium.orgd70157792014-03-17 21:45:03383 ReinitializeConfigChange(new_config);
384 message_loop_.RunUntilIdle();
xhwang@chromium.org7c39486c2013-01-06 15:36:09385}
386
xhwang@chromium.org97a9ce42012-10-19 10:06:43387// Test the case where the a key is added when the decryptor is in
388// kWaitingForKey state.
389TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) {
390 Initialize();
391 EnterWaitingForKeyState();
392
393 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48394 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
sergeyu@chromium.org49cea862014-06-11 11:11:50395 EXPECT_CALL(*this, FrameReady(decoded_frame_));
396 EXPECT_CALL(*this, DecodeDone(AudioDecoder::kOk));
xhwang@chromium.org97a9ce42012-10-19 10:06:43397 key_added_cb_.Run();
xhwang@chromium.org643d5442012-11-14 05:08:32398 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43399}
400
401// Test the case where the a key is added when the decryptor is in
402// kPendingDecode state.
403TEST_F(DecryptingAudioDecoderTest, KeyAdded_DruingPendingDecode) {
404 Initialize();
405 EnterPendingDecodeState();
406
407 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48408 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
sergeyu@chromium.org49cea862014-06-11 11:11:50409 EXPECT_CALL(*this, FrameReady(decoded_frame_));
410 EXPECT_CALL(*this, DecodeDone(AudioDecoder::kOk));
xhwang@chromium.org97a9ce42012-10-19 10:06:43411 // The audio decode callback is returned after the correct decryption key is
412 // added.
413 key_added_cb_.Run();
414 base::ResetAndReturn(&pending_audio_decode_cb_).Run(
415 Decryptor::kNoKey, Decryptor::AudioBuffers());
xhwang@chromium.org643d5442012-11-14 05:08:32416 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43417}
418
419// Test resetting when the decoder is in kIdle state but has not decoded any
420// frame.
421TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) {
422 Initialize();
423 Reset();
424}
425
426// Test resetting when the decoder is in kIdle state after it has decoded one
427// frame.
428TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
429 Initialize();
430 EnterNormalDecodingState();
431 Reset();
xhwang@chromium.org97a9ce42012-10-19 10:06:43432}
433
434// Test resetting when the decoder is in kPendingDecode state.
435TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) {
436 Initialize();
437 EnterPendingDecodeState();
438
sergeyu@chromium.org49cea862014-06-11 11:11:50439 EXPECT_CALL(*this, DecodeDone(AudioDecoder::kAborted));
xhwang@chromium.org97a9ce42012-10-19 10:06:43440
441 Reset();
442}
443
444// Test resetting when the decoder is in kWaitingForKey state.
445TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) {
446 Initialize();
447 EnterWaitingForKeyState();
448
sergeyu@chromium.org49cea862014-06-11 11:11:50449 EXPECT_CALL(*this, DecodeDone(AudioDecoder::kAborted));
xhwang@chromium.org97a9ce42012-10-19 10:06:43450
451 Reset();
452}
453
454// Test resetting when the decoder has hit end of stream and is in
455// kDecodeFinished state.
456TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) {
457 Initialize();
458 EnterNormalDecodingState();
459 EnterEndOfStreamState();
460 Reset();
461}
462
463// Test resetting after the decoder has been reset.
464TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) {
465 Initialize();
466 EnterNormalDecodingState();
467 Reset();
468 Reset();
xhwang@chromium.org97a9ce42012-10-19 10:06:43469}
470
471} // namespace media