[go: nahoru, domu]

blob: cbb1a5f75d40a39d65498da7a6e50fb3b77f510a [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"
10#include "base/message_loop.h"
11#include "media/base/buffers.h"
12#include "media/base/data_buffer.h"
13#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_callback.h"
17#include "media/base/mock_filters.h"
18#include "media/filters/decrypting_audio_decoder.h"
19#include "media/filters/ffmpeg_decoder_unittest.h"
20#include "testing/gmock/include/gmock/gmock.h"
21
22using ::testing::_;
23using ::testing::AtMost;
xhwang@chromium.org97a9ce42012-10-19 10:06:4324using ::testing::IsNull;
25using ::testing::ReturnRef;
26using ::testing::SaveArg;
27using ::testing::StrictMock;
28
29namespace media {
30
31static const int kFakeAudioFrameSize = 16;
32static const uint8 kFakeKeyId[] = { 0x4b, 0x65, 0x79, 0x20, 0x49, 0x44 };
33static const uint8 kFakeIv[DecryptConfig::kDecryptionKeySize] = { 0 };
34
35// Create a fake non-empty encrypted buffer.
36static scoped_refptr<DecoderBuffer> CreateFakeEncryptedBuffer() {
37 const int buffer_size = 16; // Need a non-empty buffer;
38 scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(buffer_size));
39 buffer->SetDecryptConfig(scoped_ptr<DecryptConfig>(new DecryptConfig(
40 std::string(reinterpret_cast<const char*>(kFakeKeyId),
41 arraysize(kFakeKeyId)),
42 std::string(reinterpret_cast<const char*>(kFakeIv), arraysize(kFakeIv)),
43 0,
44 std::vector<SubsampleEntry>())));
45 return buffer;
46}
47
48// Use anonymous namespace here to prevent the actions to be defined multiple
49// times across multiple test files. Sadly we can't use static for them.
50namespace {
51
52ACTION_P(ReturnBuffer, buffer) {
53 arg0.Run(buffer ? DemuxerStream::kOk : DemuxerStream::kAborted, buffer);
54}
55
xhwang@chromium.org8b10f2222012-11-13 05:49:4856ACTION_P(RunCallbackIfNotNull, param) {
xhwang@chromium.org97a9ce42012-10-19 10:06:4357 if (!arg0.is_null())
58 arg0.Run(param);
xhwang@chromium.org97a9ce42012-10-19 10:06:4359}
60
61ACTION_P2(ResetAndRunCallback, callback, param) {
62 base::ResetAndReturn(callback).Run(param);
63}
64
xhwang@chromium.org8b10f2222012-11-13 05:49:4865MATCHER(IsEndOfStream, "end of stream") {
xhwang@chromium.org8f5a9a52012-10-23 20:49:2066 return (arg->IsEndOfStream());
67}
68
xhwang@chromium.org97a9ce42012-10-19 10:06:4369} // namespace
70
71class DecryptingAudioDecoderTest : public testing::Test {
72 public:
73 DecryptingAudioDecoderTest()
xhwang@chromium.org2b454ff82012-11-15 03:57:5874 : decoder_(new DecryptingAudioDecoder(
xhwang@chromium.org97a9ce42012-10-19 10:06:4375 base::Bind(&Identity<scoped_refptr<base::MessageLoopProxy> >,
76 message_loop_.message_loop_proxy()),
77 base::Bind(
78 &DecryptingAudioDecoderTest::RequestDecryptorNotification,
79 base::Unretained(this)))),
80 decryptor_(new StrictMock<MockDecryptor>()),
81 demuxer_(new StrictMock<MockDemuxerStream>()),
82 encrypted_buffer_(CreateFakeEncryptedBuffer()),
xhwang@chromium.orgecbb9762012-10-24 22:33:5483 decoded_frame_(NULL),
xhwang@chromium.org97a9ce42012-10-19 10:06:4384 end_of_stream_frame_(new DataBuffer(0)),
xhwang@chromium.orgecbb9762012-10-24 22:33:5485 decoded_frame_list_() {
xhwang@chromium.org2b454ff82012-11-15 03:57:5886 scoped_refptr<DataBuffer> data_buffer = new DataBuffer(kFakeAudioFrameSize);
87 data_buffer->SetDataSize(kFakeAudioFrameSize);
88 // |decoded_frame_| contains random data.
89 decoded_frame_ = data_buffer;
xhwang@chromium.orgecbb9762012-10-24 22:33:5490 decoded_frame_list_.push_back(decoded_frame_);
xhwang@chromium.org97a9ce42012-10-19 10:06:4391 }
92
93 void InitializeAndExpectStatus(const AudioDecoderConfig& config,
94 PipelineStatus status) {
95 EXPECT_CALL(*demuxer_, audio_decoder_config())
96 .WillRepeatedly(ReturnRef(config));
97
98 decoder_->Initialize(demuxer_, NewExpectedStatusCB(status),
99 base::Bind(&MockStatisticsCB::OnStatistics,
100 base::Unretained(&statistics_cb_)));
xhwang@chromium.org643d5442012-11-14 05:08:32101 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43102 }
103
104 void Initialize() {
xhwang@chromium.org82d7abd2012-11-02 23:04:03105 EXPECT_CALL(*decryptor_, InitializeAudioDecoderMock(_, _))
xhwang@chromium.org97a9ce42012-10-19 10:06:43106 .Times(AtMost(1))
xhwang@chromium.org8b10f2222012-11-13 05:49:48107 .WillOnce(RunCallback<1>(true));
xhwang@chromium.org97a9ce42012-10-19 10:06:43108 EXPECT_CALL(*this, RequestDecryptorNotification(_))
xhwang@chromium.org8b10f2222012-11-13 05:49:48109 .WillOnce(RunCallbackIfNotNull(decryptor_.get()));
xhwang@chromium.org82d7abd2012-11-02 23:04:03110 EXPECT_CALL(*decryptor_, RegisterKeyAddedCB(Decryptor::kAudio, _))
111 .WillOnce(SaveArg<1>(&key_added_cb_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43112
xhwang@chromium.org2b454ff82012-11-15 03:57:58113 AudioDecoderConfig config(kCodecVorbis, 16, CHANNEL_LAYOUT_STEREO, 44100,
114 NULL, 0, true);
115 InitializeAndExpectStatus(config, PIPELINE_OK);
xhwang@chromium.org97a9ce42012-10-19 10:06:43116
xhwang@chromium.org97a9ce42012-10-19 10:06:43117 EXPECT_EQ(16, decoder_->bits_per_channel());
118 EXPECT_EQ(CHANNEL_LAYOUT_STEREO, decoder_->channel_layout());
119 EXPECT_EQ(44100, decoder_->samples_per_second());
120 }
121
122 void ReadAndExpectFrameReadyWith(
123 AudioDecoder::Status status,
124 const scoped_refptr<Buffer>& audio_frame) {
125 if (status != AudioDecoder::kOk)
126 EXPECT_CALL(*this, FrameReady(status, IsNull()));
xhwang@chromium.org8f5a9a52012-10-23 20:49:20127 else if (audio_frame->IsEndOfStream())
128 EXPECT_CALL(*this, FrameReady(status, IsEndOfStream()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43129 else
130 EXPECT_CALL(*this, FrameReady(status, audio_frame));
131
132 decoder_->Read(base::Bind(&DecryptingAudioDecoderTest::FrameReady,
133 base::Unretained(this)));
xhwang@chromium.org643d5442012-11-14 05:08:32134 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43135 }
136
137 // Sets up expectations and actions to put DecryptingAudioDecoder in an
138 // active normal decoding state.
139 void EnterNormalDecodingState() {
140 Decryptor::AudioBuffers end_of_stream_frames_(1, end_of_stream_frame_);
141
142 EXPECT_CALL(*demuxer_, Read(_))
143 .WillOnce(ReturnBuffer(encrypted_buffer_))
144 .WillRepeatedly(ReturnBuffer(DecoderBuffer::CreateEOSBuffer()));
145 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48146 .WillOnce(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_))
147 .WillRepeatedly(RunCallback<1>(Decryptor::kNeedMoreData,
148 Decryptor::AudioBuffers()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43149 EXPECT_CALL(statistics_cb_, OnStatistics(_));
150
151 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, decoded_frame_);
152 }
153
154 // Sets up expectations and actions to put DecryptingAudioDecoder in an end
155 // of stream state. This function must be called after
156 // EnterNormalDecodingState() to work.
157 void EnterEndOfStreamState() {
158 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, end_of_stream_frame_);
159 }
160
161 // Make the read callback pending by saving and not firing it.
162 void EnterPendingReadState() {
163 EXPECT_TRUE(pending_demuxer_read_cb_.is_null());
164 EXPECT_CALL(*demuxer_, Read(_))
165 .WillOnce(SaveArg<0>(&pending_demuxer_read_cb_));
166 decoder_->Read(base::Bind(&DecryptingAudioDecoderTest::FrameReady,
167 base::Unretained(this)));
xhwang@chromium.org643d5442012-11-14 05:08:32168 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43169 // Make sure the Read() on the decoder triggers a Read() on the demuxer.
170 EXPECT_FALSE(pending_demuxer_read_cb_.is_null());
171 }
172
173 // Make the audio decode callback pending by saving and not firing it.
174 void EnterPendingDecodeState() {
175 EXPECT_TRUE(pending_audio_decode_cb_.is_null());
176 EXPECT_CALL(*demuxer_, Read(_))
177 .WillRepeatedly(ReturnBuffer(encrypted_buffer_));
178 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
179 .WillOnce(SaveArg<1>(&pending_audio_decode_cb_));
180
181 decoder_->Read(base::Bind(&DecryptingAudioDecoderTest::FrameReady,
182 base::Unretained(this)));
xhwang@chromium.org643d5442012-11-14 05:08:32183 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43184 // Make sure the Read() on the decoder triggers a DecryptAndDecode() on the
185 // decryptor.
186 EXPECT_FALSE(pending_audio_decode_cb_.is_null());
187 }
188
189 void EnterWaitingForKeyState() {
190 EXPECT_CALL(*demuxer_, Read(_))
191 .WillRepeatedly(ReturnBuffer(encrypted_buffer_));
xhwang@chromium.org2b454ff82012-11-15 03:57:58192 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48193 .WillRepeatedly(RunCallback<1>(Decryptor::kNoKey,
194 Decryptor::AudioBuffers()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43195 decoder_->Read(base::Bind(&DecryptingAudioDecoderTest::FrameReady,
196 base::Unretained(this)));
xhwang@chromium.org643d5442012-11-14 05:08:32197 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43198 }
199
200 void AbortPendingAudioDecodeCB() {
201 if (!pending_audio_decode_cb_.is_null()) {
202 base::ResetAndReturn(&pending_audio_decode_cb_).Run(
203 Decryptor::kSuccess, Decryptor::AudioBuffers());
204 }
205 }
206
207 void Reset() {
208 EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio))
209 .WillRepeatedly(InvokeWithoutArgs(
210 this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB));
211
212 decoder_->Reset(NewExpectedClosure());
xhwang@chromium.org643d5442012-11-14 05:08:32213 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43214 }
215
216 MOCK_METHOD1(RequestDecryptorNotification,
217 void(const DecryptingAudioDecoder::DecryptorNotificationCB&));
218
219 MOCK_METHOD2(FrameReady, void(AudioDecoder::Status,
220 const scoped_refptr<Buffer>&));
221
222 MessageLoop message_loop_;
xhwang@chromium.org2b454ff82012-11-15 03:57:58223 scoped_refptr<DecryptingAudioDecoder> decoder_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43224 scoped_ptr<StrictMock<MockDecryptor> > decryptor_;
225 scoped_refptr<StrictMock<MockDemuxerStream> > demuxer_;
226 MockStatisticsCB statistics_cb_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43227
228 DemuxerStream::ReadCB pending_demuxer_read_cb_;
229 Decryptor::DecoderInitCB pending_init_cb_;
230 Decryptor::KeyAddedCB key_added_cb_;
231 Decryptor::AudioDecodeCB pending_audio_decode_cb_;
232
233 // Constant buffer/frames to be returned by the |demuxer_| and |decryptor_|.
234 scoped_refptr<DecoderBuffer> encrypted_buffer_;
235 scoped_refptr<Buffer> decoded_frame_;
236 scoped_refptr<Buffer> end_of_stream_frame_;
237 Decryptor::AudioBuffers decoded_frame_list_;
238
239 private:
240 DISALLOW_COPY_AND_ASSIGN(DecryptingAudioDecoderTest);
241};
242
243TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) {
244 Initialize();
245}
246
247// Ensure that DecryptingAudioDecoder only accepts encrypted audio.
248TEST_F(DecryptingAudioDecoderTest, Initialize_UnencryptedAudioConfig) {
249 AudioDecoderConfig config(kCodecVorbis, 16, CHANNEL_LAYOUT_STEREO, 44100,
250 NULL, 0, false);
251
252 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED);
253}
254
255// Ensure decoder handles invalid audio configs without crashing.
256TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) {
257 AudioDecoderConfig config(kUnknownAudioCodec, 0, CHANNEL_LAYOUT_STEREO, 0,
258 NULL, 0, true);
259
260 InitializeAndExpectStatus(config, PIPELINE_ERROR_DECODE);
261}
262
263// Ensure decoder handles unsupported audio configs without crashing.
264TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) {
xhwang@chromium.org82d7abd2012-11-02 23:04:03265 EXPECT_CALL(*decryptor_, InitializeAudioDecoderMock(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48266 .WillOnce(RunCallback<1>(false));
xhwang@chromium.org97a9ce42012-10-19 10:06:43267 EXPECT_CALL(*this, RequestDecryptorNotification(_))
xhwang@chromium.org8b10f2222012-11-13 05:49:48268 .WillOnce(RunCallbackIfNotNull(decryptor_.get()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43269
270 AudioDecoderConfig config(kCodecVorbis, 16, CHANNEL_LAYOUT_STEREO, 44100,
271 NULL, 0, true);
272 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED);
273}
274
275// Test normal decrypt and decode case.
276TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) {
277 Initialize();
278 EnterNormalDecodingState();
279}
280
281// Test the case where the decryptor returns error when doing decrypt and
282// decode.
283TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) {
284 Initialize();
285
286 EXPECT_CALL(*demuxer_, Read(_))
287 .WillRepeatedly(ReturnBuffer(encrypted_buffer_));
288 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48289 .WillRepeatedly(RunCallback<1>(Decryptor::kError,
290 Decryptor::AudioBuffers()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43291
292 ReadAndExpectFrameReadyWith(AudioDecoder::kDecodeError, NULL);
293}
294
295// Test the case where the decryptor returns kNeedMoreData to ask for more
296// buffers before it can produce a frame.
297TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_NeedMoreData) {
298 Initialize();
299
300 EXPECT_CALL(*demuxer_, Read(_))
301 .Times(2)
302 .WillRepeatedly(ReturnBuffer(encrypted_buffer_));
303 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48304 .WillOnce(RunCallback<1>(Decryptor::kNeedMoreData,
305 Decryptor::AudioBuffers()))
306 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43307 EXPECT_CALL(statistics_cb_, OnStatistics(_))
308 .Times(2);
309
310 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, decoded_frame_);
311}
312
313// Test the case where the decryptor returns multiple decoded frames.
314TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) {
315 Initialize();
316
xhwang@chromium.orgecbb9762012-10-24 22:33:54317 scoped_refptr<DataBuffer> frame_a = new DataBuffer(kFakeAudioFrameSize);
318 frame_a->SetDataSize(kFakeAudioFrameSize);
319 scoped_refptr<DataBuffer> frame_b = new DataBuffer(kFakeAudioFrameSize);
320 frame_b->SetDataSize(kFakeAudioFrameSize);
321 decoded_frame_list_.push_back(frame_a);
322 decoded_frame_list_.push_back(frame_b);
xhwang@chromium.org97a9ce42012-10-19 10:06:43323
324 EXPECT_CALL(*demuxer_, Read(_))
325 .WillOnce(ReturnBuffer(encrypted_buffer_));
326 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48327 .WillOnce(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43328 EXPECT_CALL(statistics_cb_, OnStatistics(_));
329
330 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, decoded_frame_);
xhwang@chromium.orgecbb9762012-10-24 22:33:54331 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, frame_a);
332 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, frame_b);
xhwang@chromium.org97a9ce42012-10-19 10:06:43333}
334
335// Test the case where the decryptor receives end-of-stream buffer.
336TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) {
337 Initialize();
338 EnterNormalDecodingState();
339 EnterEndOfStreamState();
xhwang@chromium.org97a9ce42012-10-19 10:06:43340}
341
342// Test the case where the a key is added when the decryptor is in
343// kWaitingForKey state.
344TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) {
345 Initialize();
346 EnterWaitingForKeyState();
347
348 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48349 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43350 EXPECT_CALL(statistics_cb_, OnStatistics(_));
351 EXPECT_CALL(*this, FrameReady(AudioDecoder::kOk, decoded_frame_));
352 key_added_cb_.Run();
xhwang@chromium.org643d5442012-11-14 05:08:32353 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43354}
355
356// Test the case where the a key is added when the decryptor is in
357// kPendingDecode state.
358TEST_F(DecryptingAudioDecoderTest, KeyAdded_DruingPendingDecode) {
359 Initialize();
360 EnterPendingDecodeState();
361
362 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48363 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43364 EXPECT_CALL(statistics_cb_, OnStatistics(_));
365 EXPECT_CALL(*this, FrameReady(AudioDecoder::kOk, decoded_frame_));
366 // The audio decode callback is returned after the correct decryption key is
367 // added.
368 key_added_cb_.Run();
369 base::ResetAndReturn(&pending_audio_decode_cb_).Run(
370 Decryptor::kNoKey, Decryptor::AudioBuffers());
xhwang@chromium.org643d5442012-11-14 05:08:32371 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43372}
373
374// Test resetting when the decoder is in kIdle state but has not decoded any
375// frame.
376TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) {
377 Initialize();
378 Reset();
379}
380
381// Test resetting when the decoder is in kIdle state after it has decoded one
382// frame.
383TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
384 Initialize();
385 EnterNormalDecodingState();
386 Reset();
387}
388
389// Test resetting when the decoder is in kPendingDemuxerRead state.
390TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDemuxerRead) {
391 Initialize();
392 EnterPendingReadState();
393
xhwang@chromium.org8f5a9a52012-10-23 20:49:20394 EXPECT_CALL(*this, FrameReady(AudioDecoder::kAborted, IsNull()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43395
396 Reset();
397 base::ResetAndReturn(&pending_demuxer_read_cb_).Run(DemuxerStream::kOk,
398 encrypted_buffer_);
xhwang@chromium.org643d5442012-11-14 05:08:32399 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43400}
401
402// Test resetting when the decoder is in kPendingDecode state.
403TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) {
404 Initialize();
405 EnterPendingDecodeState();
406
xhwang@chromium.org8f5a9a52012-10-23 20:49:20407 EXPECT_CALL(*this, FrameReady(AudioDecoder::kAborted, IsNull()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43408
409 Reset();
410}
411
412// Test resetting when the decoder is in kWaitingForKey state.
413TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) {
414 Initialize();
415 EnterWaitingForKeyState();
416
xhwang@chromium.org8f5a9a52012-10-23 20:49:20417 EXPECT_CALL(*this, FrameReady(AudioDecoder::kAborted, IsNull()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43418
419 Reset();
420}
421
422// Test resetting when the decoder has hit end of stream and is in
423// kDecodeFinished state.
424TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) {
425 Initialize();
426 EnterNormalDecodingState();
427 EnterEndOfStreamState();
428 Reset();
429}
430
431// Test resetting after the decoder has been reset.
432TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) {
433 Initialize();
434 EnterNormalDecodingState();
435 Reset();
436 Reset();
437}
438
439// Test aborted read on the demuxer stream.
440TEST_F(DecryptingAudioDecoderTest, DemuxerRead_Aborted) {
441 Initialize();
442
443 // ReturnBuffer() with NULL triggers aborted demuxer read.
444 EXPECT_CALL(*demuxer_, Read(_))
445 .WillOnce(ReturnBuffer(scoped_refptr<DecoderBuffer>()));
446
xhwang@chromium.org8f5a9a52012-10-23 20:49:20447 ReadAndExpectFrameReadyWith(AudioDecoder::kAborted, NULL);
xhwang@chromium.org97a9ce42012-10-19 10:06:43448}
449
450// Test aborted read on the demuxer stream when the decoder is being reset.
451TEST_F(DecryptingAudioDecoderTest, DemuxerRead_AbortedDuringReset) {
452 Initialize();
453 EnterPendingReadState();
454
455 // Make sure we get a NULL audio frame returned.
xhwang@chromium.org8f5a9a52012-10-23 20:49:20456 EXPECT_CALL(*this, FrameReady(AudioDecoder::kAborted, IsNull()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43457
458 Reset();
459 base::ResetAndReturn(&pending_demuxer_read_cb_).Run(DemuxerStream::kAborted,
460 NULL);
xhwang@chromium.org643d5442012-11-14 05:08:32461 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43462}
463
464// Test config change on the demuxer stream.
465TEST_F(DecryptingAudioDecoderTest, DemuxerRead_ConfigChanged) {
466 Initialize();
467
468 EXPECT_CALL(*demuxer_, Read(_))
xhwang@chromium.org8b10f2222012-11-13 05:49:48469 .WillOnce(RunCallback<0>(DemuxerStream::kConfigChanged,
470 scoped_refptr<DecoderBuffer>()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43471
472 // TODO(xhwang): Update this test when kConfigChanged is supported in
473 // DecryptingAudioDecoder.
474 ReadAndExpectFrameReadyWith(AudioDecoder::kDecodeError, NULL);
475}
476
477} // namespace media