[go: nahoru, domu]

blob: 1a8751cca4dc6f6831e8d067d0a7ab0cc9af5753 [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"
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
xhwang@chromium.orgecf16912013-01-12 16:55:2229// Make sure the kFakeAudioFrameSize is a valid frame size for all audio decoder
30// configs used in this test.
31static const int kFakeAudioFrameSize = 48;
xhwang@chromium.org97a9ce42012-10-19 10:06:4332static 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) {
rsleevi@chromium.org5b7ca4282013-06-03 00:19:1653 arg0.Run(buffer.get() ? DemuxerStream::kOk : DemuxerStream::kAborted, buffer);
xhwang@chromium.org97a9ce42012-10-19 10:06:4354}
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") {
tyoverby@chromium.org71a8d5a2013-06-25 08:41:0166 return (arg->end_of_stream());
xhwang@chromium.org8f5a9a52012-10-23 20:49:2067}
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(
scherkus@chromium.org8c076cb2012-11-28 21:06:1675 message_loop_.message_loop_proxy(),
xhwang@chromium.org97a9ce42012-10-19 10:06:4376 base::Bind(
77 &DecryptingAudioDecoderTest::RequestDecryptorNotification,
78 base::Unretained(this)))),
79 decryptor_(new StrictMock<MockDecryptor>()),
xhwang@chromium.orgac853e02013-04-25 01:15:5280 demuxer_(new StrictMock<MockDemuxerStream>(DemuxerStream::AUDIO)),
xhwang@chromium.org97a9ce42012-10-19 10:06:4381 encrypted_buffer_(CreateFakeEncryptedBuffer()),
xhwang@chromium.orgecbb9762012-10-24 22:33:5482 decoded_frame_(NULL),
jrummell@chromium.org47b37a62013-07-10 03:56:1083 end_of_stream_frame_(AudioBuffer::CreateEOSBuffer()),
xhwang@chromium.orgecbb9762012-10-24 22:33:5484 decoded_frame_list_() {
xhwang@chromium.org97a9ce42012-10-19 10:06:4385 }
86
87 void InitializeAndExpectStatus(const AudioDecoderConfig& config,
88 PipelineStatus status) {
jrummell@chromium.org47b37a62013-07-10 03:56:1089 // Initialize data now that the config is known. Since the code uses
90 // invalid values (that CreateEmptyBuffer() doesn't support), tweak them
91 // just for CreateEmptyBuffer().
92 int channels = ChannelLayoutToChannelCount(config.channel_layout());
93 if (channels < 1)
94 channels = 1;
95 decoded_frame_ = AudioBuffer::CreateEmptyBuffer(
96 channels, kFakeAudioFrameSize, kNoTimestamp(), kNoTimestamp());
97 decoded_frame_list_.push_back(decoded_frame_);
98
xhwang@chromium.orgac853e02013-04-25 01:15:5299 demuxer_->set_audio_decoder_config(config);
scherkus@chromium.org34811ef2013-04-25 08:51:47100 decoder_->Initialize(demuxer_.get(), NewExpectedStatusCB(status),
xhwang@chromium.org97a9ce42012-10-19 10:06:43101 base::Bind(&MockStatisticsCB::OnStatistics,
102 base::Unretained(&statistics_cb_)));
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,
116 CHANNEL_LAYOUT_STEREO, 44100, NULL, 0, true, true);
117 InitializeAndExpectStatus(config_, PIPELINE_OK);
xhwang@chromium.org97a9ce42012-10-19 10:06:43118
xhwang@chromium.orgca1d8f72013-01-15 06:25:03119 EXPECT_EQ(DecryptingAudioDecoder::kSupportedBitsPerChannel,
120 decoder_->bits_per_channel());
xhwang@chromium.org7c39486c2013-01-06 15:36:09121 EXPECT_EQ(config_.channel_layout(), decoder_->channel_layout());
122 EXPECT_EQ(config_.samples_per_second(), decoder_->samples_per_second());
xhwang@chromium.org97a9ce42012-10-19 10:06:43123 }
124
125 void ReadAndExpectFrameReadyWith(
126 AudioDecoder::Status status,
jrummell@chromium.org47b37a62013-07-10 03:56:10127 const scoped_refptr<AudioBuffer>& audio_frame) {
xhwang@chromium.org97a9ce42012-10-19 10:06:43128 if (status != AudioDecoder::kOk)
129 EXPECT_CALL(*this, FrameReady(status, IsNull()));
tyoverby@chromium.org71a8d5a2013-06-25 08:41:01130 else if (audio_frame->end_of_stream())
xhwang@chromium.org8f5a9a52012-10-23 20:49:20131 EXPECT_CALL(*this, FrameReady(status, IsEndOfStream()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43132 else
133 EXPECT_CALL(*this, FrameReady(status, audio_frame));
134
135 decoder_->Read(base::Bind(&DecryptingAudioDecoderTest::FrameReady,
136 base::Unretained(this)));
xhwang@chromium.org643d5442012-11-14 05:08:32137 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43138 }
139
140 // Sets up expectations and actions to put DecryptingAudioDecoder in an
141 // active normal decoding state.
142 void EnterNormalDecodingState() {
143 Decryptor::AudioBuffers end_of_stream_frames_(1, end_of_stream_frame_);
144
145 EXPECT_CALL(*demuxer_, Read(_))
146 .WillOnce(ReturnBuffer(encrypted_buffer_))
147 .WillRepeatedly(ReturnBuffer(DecoderBuffer::CreateEOSBuffer()));
148 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48149 .WillOnce(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_))
150 .WillRepeatedly(RunCallback<1>(Decryptor::kNeedMoreData,
151 Decryptor::AudioBuffers()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43152 EXPECT_CALL(statistics_cb_, OnStatistics(_));
153
154 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, decoded_frame_);
155 }
156
157 // Sets up expectations and actions to put DecryptingAudioDecoder in an end
158 // of stream state. This function must be called after
159 // EnterNormalDecodingState() to work.
160 void EnterEndOfStreamState() {
161 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, end_of_stream_frame_);
162 }
163
164 // Make the read callback pending by saving and not firing it.
165 void EnterPendingReadState() {
166 EXPECT_TRUE(pending_demuxer_read_cb_.is_null());
167 EXPECT_CALL(*demuxer_, Read(_))
168 .WillOnce(SaveArg<0>(&pending_demuxer_read_cb_));
169 decoder_->Read(base::Bind(&DecryptingAudioDecoderTest::FrameReady,
170 base::Unretained(this)));
xhwang@chromium.org643d5442012-11-14 05:08:32171 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43172 // Make sure the Read() on the decoder triggers a Read() on the demuxer.
173 EXPECT_FALSE(pending_demuxer_read_cb_.is_null());
174 }
175
176 // Make the audio decode callback pending by saving and not firing it.
177 void EnterPendingDecodeState() {
178 EXPECT_TRUE(pending_audio_decode_cb_.is_null());
179 EXPECT_CALL(*demuxer_, Read(_))
180 .WillRepeatedly(ReturnBuffer(encrypted_buffer_));
181 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
182 .WillOnce(SaveArg<1>(&pending_audio_decode_cb_));
183
184 decoder_->Read(base::Bind(&DecryptingAudioDecoderTest::FrameReady,
185 base::Unretained(this)));
xhwang@chromium.org643d5442012-11-14 05:08:32186 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43187 // Make sure the Read() on the decoder triggers a DecryptAndDecode() on the
188 // decryptor.
189 EXPECT_FALSE(pending_audio_decode_cb_.is_null());
190 }
191
192 void EnterWaitingForKeyState() {
193 EXPECT_CALL(*demuxer_, Read(_))
194 .WillRepeatedly(ReturnBuffer(encrypted_buffer_));
xhwang@chromium.org2b454ff82012-11-15 03:57:58195 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48196 .WillRepeatedly(RunCallback<1>(Decryptor::kNoKey,
197 Decryptor::AudioBuffers()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43198 decoder_->Read(base::Bind(&DecryptingAudioDecoderTest::FrameReady,
199 base::Unretained(this)));
xhwang@chromium.org643d5442012-11-14 05:08:32200 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43201 }
202
203 void AbortPendingAudioDecodeCB() {
204 if (!pending_audio_decode_cb_.is_null()) {
205 base::ResetAndReturn(&pending_audio_decode_cb_).Run(
206 Decryptor::kSuccess, Decryptor::AudioBuffers());
207 }
208 }
209
210 void Reset() {
211 EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio))
212 .WillRepeatedly(InvokeWithoutArgs(
213 this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB));
214
215 decoder_->Reset(NewExpectedClosure());
xhwang@chromium.org643d5442012-11-14 05:08:32216 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43217 }
218
xhwang@chromium.orgdaede9b92012-12-14 00:57:25219 MOCK_METHOD1(RequestDecryptorNotification, void(const DecryptorReadyCB&));
xhwang@chromium.org97a9ce42012-10-19 10:06:43220
jrummell@chromium.org47b37a62013-07-10 03:56:10221 MOCK_METHOD2(FrameReady,
222 void(AudioDecoder::Status, const scoped_refptr<AudioBuffer>&));
xhwang@chromium.org97a9ce42012-10-19 10:06:43223
xhwang@chromium.orgfb5af232013-04-22 22:40:03224 base::MessageLoop message_loop_;
scherkus@chromium.org7dd4c742013-03-21 22:33:47225 scoped_ptr<DecryptingAudioDecoder> decoder_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43226 scoped_ptr<StrictMock<MockDecryptor> > decryptor_;
scherkus@chromium.org34811ef2013-04-25 08:51:47227 scoped_ptr<StrictMock<MockDemuxerStream> > demuxer_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43228 MockStatisticsCB statistics_cb_;
xhwang@chromium.org7c39486c2013-01-06 15:36:09229 AudioDecoderConfig config_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43230
231 DemuxerStream::ReadCB pending_demuxer_read_cb_;
232 Decryptor::DecoderInitCB pending_init_cb_;
xhwang@chromium.orgabd36b3af2012-12-22 03:42:02233 Decryptor::NewKeyCB key_added_cb_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43234 Decryptor::AudioDecodeCB pending_audio_decode_cb_;
235
236 // Constant buffer/frames to be returned by the |demuxer_| and |decryptor_|.
237 scoped_refptr<DecoderBuffer> encrypted_buffer_;
jrummell@chromium.org47b37a62013-07-10 03:56:10238 scoped_refptr<AudioBuffer> decoded_frame_;
239 scoped_refptr<AudioBuffer> end_of_stream_frame_;
xhwang@chromium.org97a9ce42012-10-19 10:06:43240 Decryptor::AudioBuffers decoded_frame_list_;
241
242 private:
243 DISALLOW_COPY_AND_ASSIGN(DecryptingAudioDecoderTest);
244};
245
246TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) {
247 Initialize();
248}
249
250// Ensure that DecryptingAudioDecoder only accepts encrypted audio.
251TEST_F(DecryptingAudioDecoderTest, Initialize_UnencryptedAudioConfig) {
dalecurtis@google.comb5eca3c2013-01-04 20:20:15252 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
253 CHANNEL_LAYOUT_STEREO, 44100, NULL, 0, false);
xhwang@chromium.org97a9ce42012-10-19 10:06:43254
255 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED);
256}
257
258// Ensure decoder handles invalid audio configs without crashing.
259TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) {
dalecurtis@google.comb5eca3c2013-01-04 20:20:15260 AudioDecoderConfig config(kUnknownAudioCodec, kUnknownSampleFormat,
261 CHANNEL_LAYOUT_STEREO, 0, NULL, 0, true);
xhwang@chromium.org97a9ce42012-10-19 10:06:43262
263 InitializeAndExpectStatus(config, PIPELINE_ERROR_DECODE);
264}
265
266// Ensure decoder handles unsupported audio configs without crashing.
267TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) {
xhwang@chromium.orga3e28672013-03-14 14:54:59268 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48269 .WillOnce(RunCallback<1>(false));
xhwang@chromium.org97a9ce42012-10-19 10:06:43270 EXPECT_CALL(*this, RequestDecryptorNotification(_))
xhwang@chromium.org8b10f2222012-11-13 05:49:48271 .WillOnce(RunCallbackIfNotNull(decryptor_.get()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43272
dalecurtis@google.comb5eca3c2013-01-04 20:20:15273 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
274 CHANNEL_LAYOUT_STEREO, 44100, NULL, 0, true);
xhwang@chromium.org97a9ce42012-10-19 10:06:43275 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED);
276}
277
xhwang@chromium.org699b64a2013-06-19 07:36:05278TEST_F(DecryptingAudioDecoderTest, Initialize_NullDecryptor) {
279 EXPECT_CALL(*this, RequestDecryptorNotification(_))
280 .WillRepeatedly(RunCallbackIfNotNull(static_cast<Decryptor*>(NULL)));
281
282 AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
283 CHANNEL_LAYOUT_STEREO, 44100, NULL, 0, true);
284 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED);
285}
286
xhwang@chromium.org97a9ce42012-10-19 10:06:43287// Test normal decrypt and decode case.
288TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) {
289 Initialize();
290 EnterNormalDecodingState();
291}
292
293// Test the case where the decryptor returns error when doing decrypt and
294// decode.
295TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) {
296 Initialize();
297
298 EXPECT_CALL(*demuxer_, Read(_))
299 .WillRepeatedly(ReturnBuffer(encrypted_buffer_));
300 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48301 .WillRepeatedly(RunCallback<1>(Decryptor::kError,
302 Decryptor::AudioBuffers()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43303
304 ReadAndExpectFrameReadyWith(AudioDecoder::kDecodeError, NULL);
305}
306
307// Test the case where the decryptor returns kNeedMoreData to ask for more
308// buffers before it can produce a frame.
309TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_NeedMoreData) {
310 Initialize();
311
312 EXPECT_CALL(*demuxer_, Read(_))
313 .Times(2)
314 .WillRepeatedly(ReturnBuffer(encrypted_buffer_));
315 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48316 .WillOnce(RunCallback<1>(Decryptor::kNeedMoreData,
317 Decryptor::AudioBuffers()))
318 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43319 EXPECT_CALL(statistics_cb_, OnStatistics(_))
320 .Times(2);
321
322 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, decoded_frame_);
323}
324
325// Test the case where the decryptor returns multiple decoded frames.
326TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) {
327 Initialize();
328
jrummell@chromium.org47b37a62013-07-10 03:56:10329 scoped_refptr<AudioBuffer> frame_a = AudioBuffer::CreateEmptyBuffer(
330 ChannelLayoutToChannelCount(config_.channel_layout()),
331 kFakeAudioFrameSize,
332 kNoTimestamp(),
333 kNoTimestamp());
334 scoped_refptr<AudioBuffer> frame_b = AudioBuffer::CreateEmptyBuffer(
335 ChannelLayoutToChannelCount(config_.channel_layout()),
336 kFakeAudioFrameSize,
337 kNoTimestamp(),
338 kNoTimestamp());
xhwang@chromium.orgecbb9762012-10-24 22:33:54339 decoded_frame_list_.push_back(frame_a);
340 decoded_frame_list_.push_back(frame_b);
xhwang@chromium.org97a9ce42012-10-19 10:06:43341
342 EXPECT_CALL(*demuxer_, Read(_))
343 .WillOnce(ReturnBuffer(encrypted_buffer_));
344 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48345 .WillOnce(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43346 EXPECT_CALL(statistics_cb_, OnStatistics(_));
347
348 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, decoded_frame_);
xhwang@chromium.orgecbb9762012-10-24 22:33:54349 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, frame_a);
350 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, frame_b);
xhwang@chromium.org97a9ce42012-10-19 10:06:43351}
352
353// Test the case where the decryptor receives end-of-stream buffer.
354TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) {
355 Initialize();
356 EnterNormalDecodingState();
357 EnterEndOfStreamState();
xhwang@chromium.org97a9ce42012-10-19 10:06:43358}
359
xhwang@chromium.org7c39486c2013-01-06 15:36:09360// Test aborted read on the demuxer stream.
361TEST_F(DecryptingAudioDecoderTest, DemuxerRead_Aborted) {
362 Initialize();
363
364 // ReturnBuffer() with NULL triggers aborted demuxer read.
365 EXPECT_CALL(*demuxer_, Read(_))
366 .WillOnce(ReturnBuffer(scoped_refptr<DecoderBuffer>()));
367
368 ReadAndExpectFrameReadyWith(AudioDecoder::kAborted, NULL);
369}
370
371// Test config change on the demuxer stream.
372TEST_F(DecryptingAudioDecoderTest, DemuxerRead_ConfigChange) {
373 Initialize();
374
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,
378 CHANNEL_LAYOUT_5_1, 88200, NULL, 0, false);
379 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
xhwang@chromium.orgac853e02013-04-25 01:15:52383 demuxer_->set_audio_decoder_config(new_config);
xhwang@chromium.org7c39486c2013-01-06 15:36:09384 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
xhwang@chromium.orga3e28672013-03-14 14:54:59385 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
xhwang@chromium.org7c39486c2013-01-06 15:36:09386 .WillOnce(RunCallback<1>(true));
387 EXPECT_CALL(*demuxer_, Read(_))
388 .WillOnce(RunCallback<0>(DemuxerStream::kConfigChanged,
389 scoped_refptr<DecoderBuffer>()))
390 .WillRepeatedly(ReturnBuffer(encrypted_buffer_));
391 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
392 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
393 EXPECT_CALL(statistics_cb_, OnStatistics(_));
394
395 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, decoded_frame_);
xhwang@chromium.orgecf16912013-01-12 16:55:22396
397 EXPECT_EQ(new_config.bits_per_channel(), decoder_->bits_per_channel());
398 EXPECT_EQ(new_config.channel_layout(), decoder_->channel_layout());
399 EXPECT_EQ(new_config.samples_per_second(), decoder_->samples_per_second());
xhwang@chromium.org7c39486c2013-01-06 15:36:09400}
401
402// Test config change failure.
403TEST_F(DecryptingAudioDecoderTest, DemuxerRead_ConfigChangeFailed) {
404 Initialize();
405
406 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
xhwang@chromium.orga3e28672013-03-14 14:54:59407 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
xhwang@chromium.org7c39486c2013-01-06 15:36:09408 .WillOnce(RunCallback<1>(false));
409 EXPECT_CALL(*demuxer_, Read(_))
410 .WillOnce(RunCallback<0>(DemuxerStream::kConfigChanged,
411 scoped_refptr<DecoderBuffer>()))
412 .WillRepeatedly(ReturnBuffer(encrypted_buffer_));
413
414 ReadAndExpectFrameReadyWith(AudioDecoder::kDecodeError, NULL);
415}
416
xhwang@chromium.org97a9ce42012-10-19 10:06:43417// Test the case where the a key is added when the decryptor is in
418// kWaitingForKey state.
419TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) {
420 Initialize();
421 EnterWaitingForKeyState();
422
423 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48424 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43425 EXPECT_CALL(statistics_cb_, OnStatistics(_));
426 EXPECT_CALL(*this, FrameReady(AudioDecoder::kOk, decoded_frame_));
427 key_added_cb_.Run();
xhwang@chromium.org643d5442012-11-14 05:08:32428 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43429}
430
431// Test the case where the a key is added when the decryptor is in
432// kPendingDecode state.
433TEST_F(DecryptingAudioDecoderTest, KeyAdded_DruingPendingDecode) {
434 Initialize();
435 EnterPendingDecodeState();
436
437 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
xhwang@chromium.org8b10f2222012-11-13 05:49:48438 .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
xhwang@chromium.org97a9ce42012-10-19 10:06:43439 EXPECT_CALL(statistics_cb_, OnStatistics(_));
440 EXPECT_CALL(*this, FrameReady(AudioDecoder::kOk, decoded_frame_));
441 // The audio decode callback is returned after the correct decryption key is
442 // added.
443 key_added_cb_.Run();
444 base::ResetAndReturn(&pending_audio_decode_cb_).Run(
445 Decryptor::kNoKey, Decryptor::AudioBuffers());
xhwang@chromium.org643d5442012-11-14 05:08:32446 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43447}
448
449// Test resetting when the decoder is in kIdle state but has not decoded any
450// frame.
451TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) {
452 Initialize();
453 Reset();
454}
455
456// Test resetting when the decoder is in kIdle state after it has decoded one
457// frame.
458TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
459 Initialize();
460 EnterNormalDecodingState();
461 Reset();
462}
463
xhwang@chromium.org7c39486c2013-01-06 15:36:09464// Test resetting when the decoder is in kPendingDemuxerRead state and the read
465// callback is returned with kOk.
466TEST_F(DecryptingAudioDecoderTest, Reset_DuringDemuxerRead_Ok) {
xhwang@chromium.org97a9ce42012-10-19 10:06:43467 Initialize();
468 EnterPendingReadState();
469
xhwang@chromium.org8f5a9a52012-10-23 20:49:20470 EXPECT_CALL(*this, FrameReady(AudioDecoder::kAborted, IsNull()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43471
472 Reset();
473 base::ResetAndReturn(&pending_demuxer_read_cb_).Run(DemuxerStream::kOk,
474 encrypted_buffer_);
xhwang@chromium.org7c39486c2013-01-06 15:36:09475 message_loop_.RunUntilIdle();
476}
477
478// Test resetting when the decoder is in kPendingDemuxerRead state and the read
479// callback is returned with kAborted.
480TEST_F(DecryptingAudioDecoderTest, Reset_DuringDemuxerRead_Aborted) {
481 Initialize();
482 EnterPendingReadState();
483
484 // Make sure we get a NULL audio frame returned.
485 EXPECT_CALL(*this, FrameReady(AudioDecoder::kAborted, IsNull()));
486
487 Reset();
488 base::ResetAndReturn(&pending_demuxer_read_cb_).Run(DemuxerStream::kAborted,
489 NULL);
490 message_loop_.RunUntilIdle();
491}
492
493// Test resetting when the decoder is in kPendingDemuxerRead state and the read
494// callback is returned with kConfigChanged.
495TEST_F(DecryptingAudioDecoderTest, Reset_DuringDemuxerRead_ConfigChange) {
496 Initialize();
497 EnterPendingReadState();
498
499 Reset();
500
xhwang@chromium.orgecf16912013-01-12 16:55:22501 // The new config is different from the initial config in bits-per-channel,
502 // channel layout and samples_per_second.
503 AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16,
504 CHANNEL_LAYOUT_5_1, 88200, NULL, 0, false);
505 EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
506 EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
507 EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
508
xhwang@chromium.org7c39486c2013-01-06 15:36:09509 // Even during pending reset, the decoder still needs to be initialized with
510 // the new config.
xhwang@chromium.orgac853e02013-04-25 01:15:52511 demuxer_->set_audio_decoder_config(new_config);
xhwang@chromium.org7c39486c2013-01-06 15:36:09512 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
xhwang@chromium.orga3e28672013-03-14 14:54:59513 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
xhwang@chromium.org7c39486c2013-01-06 15:36:09514 .WillOnce(RunCallback<1>(true));
515 EXPECT_CALL(*this, FrameReady(AudioDecoder::kAborted, IsNull()));
516
517 base::ResetAndReturn(&pending_demuxer_read_cb_)
518 .Run(DemuxerStream::kConfigChanged, NULL);
519 message_loop_.RunUntilIdle();
xhwang@chromium.orgecf16912013-01-12 16:55:22520
521 EXPECT_EQ(new_config.bits_per_channel(), decoder_->bits_per_channel());
522 EXPECT_EQ(new_config.channel_layout(), decoder_->channel_layout());
523 EXPECT_EQ(new_config.samples_per_second(), decoder_->samples_per_second());
xhwang@chromium.org7c39486c2013-01-06 15:36:09524}
525
526// Test resetting when the decoder is in kPendingDemuxerRead state, the read
527// callback is returned with kConfigChanged and the config change fails.
528TEST_F(DecryptingAudioDecoderTest, Reset_DuringDemuxerRead_ConfigChangeFailed) {
529 Initialize();
530 EnterPendingReadState();
531
532 Reset();
533
534 // Even during pending reset, the decoder still needs to be initialized with
535 // the new config.
536 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
xhwang@chromium.orga3e28672013-03-14 14:54:59537 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
xhwang@chromium.org7c39486c2013-01-06 15:36:09538 .WillOnce(RunCallback<1>(false));
539 EXPECT_CALL(*this, FrameReady(AudioDecoder::kDecodeError, IsNull()));
540
541 base::ResetAndReturn(&pending_demuxer_read_cb_)
542 .Run(DemuxerStream::kConfigChanged, NULL);
543 message_loop_.RunUntilIdle();
544}
545
546// Test resetting when the decoder is in kPendingConfigChange state.
547TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingConfigChange) {
548 Initialize();
549 EnterNormalDecodingState();
550
551 EXPECT_CALL(*demuxer_, Read(_))
552 .WillOnce(RunCallback<0>(DemuxerStream::kConfigChanged,
553 scoped_refptr<DecoderBuffer>()));
554 EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
xhwang@chromium.orga3e28672013-03-14 14:54:59555 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
xhwang@chromium.org7c39486c2013-01-06 15:36:09556 .WillOnce(SaveArg<1>(&pending_init_cb_));
557
558 decoder_->Read(base::Bind(&DecryptingAudioDecoderTest::FrameReady,
559 base::Unretained(this)));
560 message_loop_.RunUntilIdle();
561 EXPECT_FALSE(pending_init_cb_.is_null());
562
563 EXPECT_CALL(*this, FrameReady(AudioDecoder::kAborted, IsNull()));
564
565 Reset();
566 base::ResetAndReturn(&pending_init_cb_).Run(true);
xhwang@chromium.org643d5442012-11-14 05:08:32567 message_loop_.RunUntilIdle();
xhwang@chromium.org97a9ce42012-10-19 10:06:43568}
569
570// Test resetting when the decoder is in kPendingDecode state.
571TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) {
572 Initialize();
573 EnterPendingDecodeState();
574
xhwang@chromium.org8f5a9a52012-10-23 20:49:20575 EXPECT_CALL(*this, FrameReady(AudioDecoder::kAborted, IsNull()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43576
577 Reset();
578}
579
580// Test resetting when the decoder is in kWaitingForKey state.
581TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) {
582 Initialize();
583 EnterWaitingForKeyState();
584
xhwang@chromium.org8f5a9a52012-10-23 20:49:20585 EXPECT_CALL(*this, FrameReady(AudioDecoder::kAborted, IsNull()));
xhwang@chromium.org97a9ce42012-10-19 10:06:43586
587 Reset();
588}
589
590// Test resetting when the decoder has hit end of stream and is in
591// kDecodeFinished state.
592TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) {
593 Initialize();
594 EnterNormalDecodingState();
595 EnterEndOfStreamState();
596 Reset();
597}
598
599// Test resetting after the decoder has been reset.
600TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) {
601 Initialize();
602 EnterNormalDecodingState();
603 Reset();
604 Reset();
xhwang@chromium.org97a9ce42012-10-19 10:06:43605}
606
607} // namespace media