OLD | NEW |
(Empty) | |
| 1 // 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" |
| 15 #include "media/base/mock_callback.h" |
| 16 #include "media/base/mock_filters.h" |
| 17 #include "media/filters/decrypting_audio_decoder.h" |
| 18 #include "media/filters/ffmpeg_decoder_unittest.h" |
| 19 #include "testing/gmock/include/gmock/gmock.h" |
| 20 |
| 21 using ::testing::_; |
| 22 using ::testing::AtMost; |
| 23 using ::testing::Invoke; |
| 24 using ::testing::IsNull; |
| 25 using ::testing::ReturnRef; |
| 26 using ::testing::SaveArg; |
| 27 using ::testing::StrictMock; |
| 28 |
| 29 namespace media { |
| 30 |
| 31 static const int kFakeAudioFrameSize = 16; |
| 32 static const uint8 kFakeKeyId[] = { 0x4b, 0x65, 0x79, 0x20, 0x49, 0x44 }; |
| 33 static const uint8 kFakeIv[DecryptConfig::kDecryptionKeySize] = { 0 }; |
| 34 |
| 35 // Create a fake non-empty encrypted buffer. |
| 36 static 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 ACTION_P(ReturnBuffer, buffer) { |
| 49 arg0.Run(buffer ? DemuxerStream::kOk : DemuxerStream::kAborted, buffer); |
| 50 } |
| 51 |
| 52 ACTION(ReturnConfigChanged) { |
| 53 arg0.Run(DemuxerStream::kConfigChanged, scoped_refptr<DecoderBuffer>(NULL)); |
| 54 } |
| 55 |
| 56 ACTION_P(RunCallback0, param) { |
| 57 arg0.Run(param); |
| 58 } |
| 59 |
| 60 ACTION_P(RunCallback1, param) { |
| 61 arg1.Run(param); |
| 62 } |
| 63 |
| 64 ACTION_P2(RunCallback2, param1, param2) { |
| 65 arg1.Run(param1, param2); |
| 66 } |
| 67 |
| 68 ACTION_P2(ResetAndRunCallback, callback, param) { |
| 69 base::ResetAndReturn(callback).Run(param); |
| 70 } |
| 71 |
| 72 MATCHER(IsNullCallback, "") { |
| 73 return (arg.is_null()); |
| 74 } |
| 75 |
| 76 class DecryptingAudioDecoderTest : public testing::Test { |
| 77 public: |
| 78 DecryptingAudioDecoderTest() |
| 79 : decoder_(new StrictMock<DecryptingAudioDecoder>( |
| 80 base::Bind(&Identity<scoped_refptr<base::MessageLoopProxy> >, |
| 81 message_loop_.message_loop_proxy()), |
| 82 base::Bind( |
| 83 &DecryptingAudioDecoderTest::RequestDecryptorNotification, |
| 84 base::Unretained(this)))), |
| 85 decryptor_(new StrictMock<MockDecryptor>()), |
| 86 demuxer_(new StrictMock<MockDemuxerStream>()), |
| 87 encrypted_buffer_(CreateFakeEncryptedBuffer()), |
| 88 decoded_frame_(new DataBuffer(kFakeAudioFrameSize)), |
| 89 end_of_stream_frame_(new DataBuffer(0)), |
| 90 decoded_frame_list_(1, decoded_frame_) { |
| 91 } |
| 92 |
| 93 void InitializeAndExpectStatus(const AudioDecoderConfig& config, |
| 94 PipelineStatus status) { |
| 95 EXPECT_CALL(*demuxer_, audio_decoder_config()) |
| 96 .WillRepeatedly(ReturnRef(config)); |
| 97 EXPECT_CALL(*this, RequestDecryptorNotification(_)) |
| 98 .WillRepeatedly(RunCallback0(decryptor_.get())); |
| 99 |
| 100 decoder_->Initialize(demuxer_, NewExpectedStatusCB(status), |
| 101 base::Bind(&MockStatisticsCB::OnStatistics, |
| 102 base::Unretained(&statistics_cb_))); |
| 103 message_loop_.RunAllPending(); |
| 104 } |
| 105 |
| 106 void Initialize() { |
| 107 EXPECT_CALL(*decryptor_, InitializeAudioDecoderMock(_, _, _)) |
| 108 .Times(AtMost(1)) |
| 109 .WillOnce(DoAll(RunCallback1(true), SaveArg<2>(&key_added_cb_))); |
| 110 |
| 111 config_.Initialize(kCodecVorbis, 16, CHANNEL_LAYOUT_STEREO, 44100, |
| 112 NULL, 0, true, true); |
| 113 |
| 114 InitializeAndExpectStatus(config_, PIPELINE_OK); |
| 115 EXPECT_EQ(16, decoder_->bits_per_channel()); |
| 116 EXPECT_EQ(CHANNEL_LAYOUT_STEREO, decoder_->channel_layout()); |
| 117 EXPECT_EQ(44100, decoder_->samples_per_second()); |
| 118 } |
| 119 |
| 120 void ReadAndExpectFrameReadyWith( |
| 121 AudioDecoder::Status status, |
| 122 const scoped_refptr<Buffer>& audio_frame) { |
| 123 if (status != AudioDecoder::kOk) |
| 124 EXPECT_CALL(*this, FrameReady(status, IsNull())); |
| 125 else |
| 126 EXPECT_CALL(*this, FrameReady(status, audio_frame)); |
| 127 |
| 128 decoder_->Read(base::Bind(&DecryptingAudioDecoderTest::FrameReady, |
| 129 base::Unretained(this))); |
| 130 message_loop_.RunAllPending(); |
| 131 } |
| 132 |
| 133 // Sets up expectations and actions to put DecryptingAudioDecoder in an |
| 134 // active normal decoding state. |
| 135 void EnterNormalDecodingState() { |
| 136 Decryptor::AudioBuffers end_of_stream_frames_(1, end_of_stream_frame_); |
| 137 |
| 138 EXPECT_CALL(*demuxer_, Read(_)) |
| 139 .WillOnce(ReturnBuffer(encrypted_buffer_)) |
| 140 .WillRepeatedly(ReturnBuffer(DecoderBuffer::CreateEOSBuffer())); |
| 141 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _)) |
| 142 .WillOnce(RunCallback2(Decryptor::kSuccess, |
| 143 decoded_frame_list_)) |
| 144 .WillRepeatedly(RunCallback2(Decryptor::kSuccess, |
| 145 end_of_stream_frames_)); |
| 146 EXPECT_CALL(statistics_cb_, OnStatistics(_)); |
| 147 |
| 148 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, decoded_frame_); |
| 149 } |
| 150 |
| 151 // Sets up expectations and actions to put DecryptingAudioDecoder in an end |
| 152 // of stream state. This function must be called after |
| 153 // EnterNormalDecodingState() to work. |
| 154 void EnterEndOfStreamState() { |
| 155 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, end_of_stream_frame_); |
| 156 } |
| 157 |
| 158 // Make the read callback pending by saving and not firing it. |
| 159 void EnterPendingReadState() { |
| 160 EXPECT_TRUE(pending_demuxer_read_cb_.is_null()); |
| 161 EXPECT_CALL(*demuxer_, Read(_)) |
| 162 .WillOnce(SaveArg<0>(&pending_demuxer_read_cb_)); |
| 163 decoder_->Read(base::Bind(&DecryptingAudioDecoderTest::FrameReady, |
| 164 base::Unretained(this))); |
| 165 message_loop_.RunAllPending(); |
| 166 // Make sure the Read() on the decoder triggers a Read() on the demuxer. |
| 167 EXPECT_FALSE(pending_demuxer_read_cb_.is_null()); |
| 168 } |
| 169 |
| 170 // Make the audio decode callback pending by saving and not firing it. |
| 171 void EnterPendingDecodeState() { |
| 172 EXPECT_TRUE(pending_audio_decode_cb_.is_null()); |
| 173 EXPECT_CALL(*demuxer_, Read(_)) |
| 174 .WillRepeatedly(ReturnBuffer(encrypted_buffer_)); |
| 175 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _)) |
| 176 .WillOnce(SaveArg<1>(&pending_audio_decode_cb_)); |
| 177 |
| 178 decoder_->Read(base::Bind(&DecryptingAudioDecoderTest::FrameReady, |
| 179 base::Unretained(this))); |
| 180 message_loop_.RunAllPending(); |
| 181 // Make sure the Read() on the decoder triggers a DecryptAndDecode() on the |
| 182 // decryptor. |
| 183 EXPECT_FALSE(pending_audio_decode_cb_.is_null()); |
| 184 } |
| 185 |
| 186 void EnterWaitingForKeyState() { |
| 187 EXPECT_CALL(*demuxer_, Read(_)) |
| 188 .WillRepeatedly(ReturnBuffer(encrypted_buffer_)); |
| 189 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _)) |
| 190 .WillRepeatedly(RunCallback2(Decryptor::kNoKey, |
| 191 Decryptor::AudioBuffers())); |
| 192 decoder_->Read(base::Bind(&DecryptingAudioDecoderTest::FrameReady, |
| 193 base::Unretained(this))); |
| 194 message_loop_.RunAllPending(); |
| 195 } |
| 196 |
| 197 void AbortPendingAudioDecodeCB() { |
| 198 if (!pending_audio_decode_cb_.is_null()) { |
| 199 base::ResetAndReturn(&pending_audio_decode_cb_).Run( |
| 200 Decryptor::kSuccess, Decryptor::AudioBuffers()); |
| 201 } |
| 202 } |
| 203 |
| 204 void Reset() { |
| 205 EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio)) |
| 206 .WillRepeatedly(InvokeWithoutArgs( |
| 207 this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB)); |
| 208 |
| 209 decoder_->Reset(NewExpectedClosure()); |
| 210 message_loop_.RunAllPending(); |
| 211 } |
| 212 |
| 213 MOCK_METHOD1(RequestDecryptorNotification, |
| 214 void(const DecryptingAudioDecoder::DecryptorNotificationCB&)); |
| 215 |
| 216 MOCK_METHOD2(FrameReady, void(AudioDecoder::Status, |
| 217 const scoped_refptr<Buffer>&)); |
| 218 |
| 219 MessageLoop message_loop_; |
| 220 scoped_refptr<StrictMock<DecryptingAudioDecoder> > decoder_; |
| 221 scoped_ptr<StrictMock<MockDecryptor> > decryptor_; |
| 222 scoped_refptr<StrictMock<MockDemuxerStream> > demuxer_; |
| 223 MockStatisticsCB statistics_cb_; |
| 224 AudioDecoderConfig config_; |
| 225 |
| 226 DemuxerStream::ReadCB pending_demuxer_read_cb_; |
| 227 Decryptor::DecoderInitCB pending_init_cb_; |
| 228 Decryptor::KeyAddedCB key_added_cb_; |
| 229 Decryptor::AudioDecodeCB pending_audio_decode_cb_; |
| 230 |
| 231 // Constant buffer/frames to be returned by the |demuxer_| and |decryptor_|. |
| 232 scoped_refptr<DecoderBuffer> encrypted_buffer_; |
| 233 scoped_refptr<Buffer> decoded_frame_; |
| 234 scoped_refptr<Buffer> end_of_stream_frame_; |
| 235 Decryptor::AudioBuffers decoded_frame_list_; |
| 236 |
| 237 private: |
| 238 DISALLOW_COPY_AND_ASSIGN(DecryptingAudioDecoderTest); |
| 239 }; |
| 240 |
| 241 TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) { |
| 242 Initialize(); |
| 243 } |
| 244 |
| 245 // Ensure that DecryptingAudioDecoder only accepts encrypted audio. |
| 246 TEST_F(DecryptingAudioDecoderTest, Initialize_UnencryptedAudioConfig) { |
| 247 AudioDecoderConfig config(kCodecVorbis, 16, CHANNEL_LAYOUT_STEREO, 44100, |
| 248 NULL, 0, false); |
| 249 |
| 250 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED); |
| 251 } |
| 252 |
| 253 // Ensure decoder handles invalid audio configs without crashing. |
| 254 TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) { |
| 255 AudioDecoderConfig config(kUnknownAudioCodec, 0, CHANNEL_LAYOUT_STEREO, 0, |
| 256 NULL, 0, true); |
| 257 |
| 258 InitializeAndExpectStatus(config, PIPELINE_ERROR_DECODE); |
| 259 } |
| 260 |
| 261 // Ensure decoder handles unsupported audio configs without crashing. |
| 262 TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) { |
| 263 EXPECT_CALL(*decryptor_, InitializeAudioDecoderMock(_, _, _)) |
| 264 .WillOnce(RunCallback1(false)); |
| 265 |
| 266 AudioDecoderConfig config(kCodecVorbis, 16, CHANNEL_LAYOUT_STEREO, 44100, |
| 267 NULL, 0, true); |
| 268 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED); |
| 269 } |
| 270 |
| 271 // Test normal decrypt and decode case. |
| 272 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) { |
| 273 Initialize(); |
| 274 EnterNormalDecodingState(); |
| 275 } |
| 276 |
| 277 // Test the case where the decryptor returns error when doing decrypt and |
| 278 // decode. |
| 279 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) { |
| 280 Initialize(); |
| 281 |
| 282 EXPECT_CALL(*demuxer_, Read(_)) |
| 283 .WillRepeatedly(ReturnBuffer(encrypted_buffer_)); |
| 284 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _)) |
| 285 .WillRepeatedly(RunCallback2(Decryptor::kError, |
| 286 Decryptor::AudioBuffers())); |
| 287 |
| 288 ReadAndExpectFrameReadyWith(AudioDecoder::kDecodeError, NULL); |
| 289 } |
| 290 |
| 291 // Test the case where the decryptor returns kNeedMoreData to ask for more |
| 292 // buffers before it can produce a frame. |
| 293 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_NeedMoreData) { |
| 294 Initialize(); |
| 295 |
| 296 EXPECT_CALL(*demuxer_, Read(_)) |
| 297 .Times(2) |
| 298 .WillRepeatedly(ReturnBuffer(encrypted_buffer_)); |
| 299 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _)) |
| 300 .WillOnce(RunCallback2(Decryptor::kNeedMoreData, |
| 301 Decryptor::AudioBuffers())) |
| 302 .WillRepeatedly(RunCallback2(Decryptor::kSuccess, decoded_frame_list_)); |
| 303 EXPECT_CALL(statistics_cb_, OnStatistics(_)) |
| 304 .Times(2); |
| 305 |
| 306 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, decoded_frame_); |
| 307 } |
| 308 |
| 309 // Test the case where the decryptor returns multiple decoded frames. |
| 310 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) { |
| 311 Initialize(); |
| 312 |
| 313 scoped_refptr<Buffer> decoded_frame_a(new DataBuffer(kFakeAudioFrameSize)); |
| 314 scoped_refptr<Buffer> decoded_frame_b(new DataBuffer(kFakeAudioFrameSize)); |
| 315 decoded_frame_list_.push_back(decoded_frame_a); |
| 316 decoded_frame_list_.push_back(decoded_frame_b); |
| 317 |
| 318 EXPECT_CALL(*demuxer_, Read(_)) |
| 319 .WillOnce(ReturnBuffer(encrypted_buffer_)); |
| 320 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _)) |
| 321 .WillOnce(RunCallback2(Decryptor::kSuccess, decoded_frame_list_)); |
| 322 EXPECT_CALL(statistics_cb_, OnStatistics(_)); |
| 323 |
| 324 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, decoded_frame_); |
| 325 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, decoded_frame_a); |
| 326 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, decoded_frame_b); |
| 327 } |
| 328 |
| 329 // Test the case where the decryptor receives end-of-stream buffer. |
| 330 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) { |
| 331 Initialize(); |
| 332 EnterNormalDecodingState(); |
| 333 EnterEndOfStreamState(); |
| 334 } |
| 335 |
| 336 // Test the case where the decryptor returns multiple decoded frames, the last |
| 337 // of which is end-of-stream frame. |
| 338 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFramesWithEos) { |
| 339 Initialize(); |
| 340 |
| 341 scoped_refptr<Buffer> decoded_frame_a(new DataBuffer(kFakeAudioFrameSize)); |
| 342 scoped_refptr<Buffer> decoded_frame_b(new DataBuffer(kFakeAudioFrameSize)); |
| 343 Decryptor::AudioBuffers second_decoded_frame_list; |
| 344 second_decoded_frame_list.push_back(decoded_frame_a); |
| 345 second_decoded_frame_list.push_back(decoded_frame_b); |
| 346 second_decoded_frame_list.push_back(end_of_stream_frame_); |
| 347 |
| 348 EXPECT_CALL(*demuxer_, Read(_)) |
| 349 .WillOnce(ReturnBuffer(encrypted_buffer_)) |
| 350 .WillOnce(ReturnBuffer(DecoderBuffer::CreateEOSBuffer())); |
| 351 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _)) |
| 352 .WillOnce(RunCallback2(Decryptor::kSuccess, decoded_frame_list_)) |
| 353 .WillOnce(RunCallback2(Decryptor::kSuccess, second_decoded_frame_list)); |
| 354 // Expect only one OnStatistics() here because EOS input buffer doesn't |
| 355 // trigger statistics reporting. |
| 356 EXPECT_CALL(statistics_cb_, OnStatistics(_)); |
| 357 |
| 358 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, decoded_frame_); |
| 359 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, decoded_frame_a); |
| 360 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, decoded_frame_b); |
| 361 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, end_of_stream_frame_); |
| 362 } |
| 363 |
| 364 // Test the case where the a key is added when the decryptor is in |
| 365 // kWaitingForKey state. |
| 366 TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) { |
| 367 Initialize(); |
| 368 EnterWaitingForKeyState(); |
| 369 |
| 370 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _)) |
| 371 .WillRepeatedly(RunCallback2(Decryptor::kSuccess, decoded_frame_list_)); |
| 372 EXPECT_CALL(statistics_cb_, OnStatistics(_)); |
| 373 EXPECT_CALL(*this, FrameReady(AudioDecoder::kOk, decoded_frame_)); |
| 374 key_added_cb_.Run(); |
| 375 message_loop_.RunAllPending(); |
| 376 } |
| 377 |
| 378 // Test the case where the a key is added when the decryptor is in |
| 379 // kPendingDecode state. |
| 380 TEST_F(DecryptingAudioDecoderTest, KeyAdded_DruingPendingDecode) { |
| 381 Initialize(); |
| 382 EnterPendingDecodeState(); |
| 383 |
| 384 EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _)) |
| 385 .WillRepeatedly(RunCallback2(Decryptor::kSuccess, decoded_frame_list_)); |
| 386 EXPECT_CALL(statistics_cb_, OnStatistics(_)); |
| 387 EXPECT_CALL(*this, FrameReady(AudioDecoder::kOk, decoded_frame_)); |
| 388 // The audio decode callback is returned after the correct decryption key is |
| 389 // added. |
| 390 key_added_cb_.Run(); |
| 391 base::ResetAndReturn(&pending_audio_decode_cb_).Run( |
| 392 Decryptor::kNoKey, Decryptor::AudioBuffers()); |
| 393 message_loop_.RunAllPending(); |
| 394 } |
| 395 |
| 396 // Test resetting when the decoder is in kIdle state but has not decoded any |
| 397 // frame. |
| 398 TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) { |
| 399 Initialize(); |
| 400 Reset(); |
| 401 } |
| 402 |
| 403 // Test resetting when the decoder is in kIdle state after it has decoded one |
| 404 // frame. |
| 405 TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) { |
| 406 Initialize(); |
| 407 EnterNormalDecodingState(); |
| 408 Reset(); |
| 409 } |
| 410 |
| 411 // Test resetting when the decoder is in kPendingDemuxerRead state. |
| 412 TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDemuxerRead) { |
| 413 Initialize(); |
| 414 EnterPendingReadState(); |
| 415 |
| 416 EXPECT_CALL(*this, FrameReady(AudioDecoder::kOk, IsNull())); |
| 417 |
| 418 Reset(); |
| 419 base::ResetAndReturn(&pending_demuxer_read_cb_).Run(DemuxerStream::kOk, |
| 420 encrypted_buffer_); |
| 421 message_loop_.RunAllPending(); |
| 422 } |
| 423 |
| 424 // Test resetting when the decoder is in kPendingDecode state. |
| 425 TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) { |
| 426 Initialize(); |
| 427 EnterPendingDecodeState(); |
| 428 |
| 429 EXPECT_CALL(*this, FrameReady(AudioDecoder::kOk, IsNull())); |
| 430 |
| 431 Reset(); |
| 432 } |
| 433 |
| 434 // Test resetting when the decoder is in kWaitingForKey state. |
| 435 TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) { |
| 436 Initialize(); |
| 437 EnterWaitingForKeyState(); |
| 438 |
| 439 EXPECT_CALL(*this, FrameReady(AudioDecoder::kOk, IsNull())); |
| 440 |
| 441 Reset(); |
| 442 } |
| 443 |
| 444 // Test resetting when the decoder has hit end of stream and is in |
| 445 // kDecodeFinished state. |
| 446 TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) { |
| 447 Initialize(); |
| 448 EnterNormalDecodingState(); |
| 449 EnterEndOfStreamState(); |
| 450 Reset(); |
| 451 } |
| 452 |
| 453 // Test resetting after the decoder has been reset. |
| 454 TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) { |
| 455 Initialize(); |
| 456 EnterNormalDecodingState(); |
| 457 Reset(); |
| 458 Reset(); |
| 459 } |
| 460 |
| 461 // Test aborted read on the demuxer stream. |
| 462 TEST_F(DecryptingAudioDecoderTest, DemuxerRead_Aborted) { |
| 463 Initialize(); |
| 464 |
| 465 // ReturnBuffer() with NULL triggers aborted demuxer read. |
| 466 EXPECT_CALL(*demuxer_, Read(_)) |
| 467 .WillOnce(ReturnBuffer(scoped_refptr<DecoderBuffer>())); |
| 468 |
| 469 ReadAndExpectFrameReadyWith(AudioDecoder::kOk, NULL); |
| 470 } |
| 471 |
| 472 // Test aborted read on the demuxer stream when the decoder is being reset. |
| 473 TEST_F(DecryptingAudioDecoderTest, DemuxerRead_AbortedDuringReset) { |
| 474 Initialize(); |
| 475 EnterPendingReadState(); |
| 476 |
| 477 // Make sure we get a NULL audio frame returned. |
| 478 EXPECT_CALL(*this, FrameReady(AudioDecoder::kOk, IsNull())); |
| 479 |
| 480 Reset(); |
| 481 base::ResetAndReturn(&pending_demuxer_read_cb_).Run(DemuxerStream::kAborted, |
| 482 NULL); |
| 483 message_loop_.RunAllPending(); |
| 484 } |
| 485 |
| 486 // Test config change on the demuxer stream. |
| 487 TEST_F(DecryptingAudioDecoderTest, DemuxerRead_ConfigChanged) { |
| 488 Initialize(); |
| 489 |
| 490 EXPECT_CALL(*demuxer_, Read(_)) |
| 491 .WillOnce(ReturnConfigChanged()); |
| 492 |
| 493 // TODO(xhwang): Update this test when kConfigChanged is supported in |
| 494 // DecryptingAudioDecoder. |
| 495 ReadAndExpectFrameReadyWith(AudioDecoder::kDecodeError, NULL); |
| 496 } |
| 497 |
| 498 } // namespace media |
OLD | NEW |