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/decoder_buffer.h" |
| 12 #include "media/base/decrypt_config.h" |
| 13 #include "media/base/mock_callback.h" |
| 14 #include "media/base/mock_filters.h" |
| 15 #include "media/base/video_frame.h" |
| 16 #include "media/filters/ffmpeg_decoder_unittest.h" |
| 17 #include "media/filters/decrypting_video_decoder.h" |
| 18 #include "testing/gmock/include/gmock/gmock.h" |
| 19 |
| 20 using ::testing::_; |
| 21 using ::testing::Invoke; |
| 22 using ::testing::IsNull; |
| 23 using ::testing::ReturnRef; |
| 24 using ::testing::SaveArg; |
| 25 using ::testing::StrictMock; |
| 26 |
| 27 namespace media { |
| 28 |
| 29 static const VideoFrame::Format kVideoFormat = VideoFrame::YV12; |
| 30 static const gfx::Size kCodedSize(320, 240); |
| 31 static const gfx::Rect kVisibleRect(320, 240); |
| 32 static const gfx::Size kNaturalSize(320, 240); |
| 33 static const uint8 kFakeKeyId[] = { 0x4b, 0x65, 0x79, 0x20, 0x49, 0x44 }; |
| 34 static const uint8 kFakeIv[DecryptConfig::kDecryptionKeySize] = { 0 }; |
| 35 |
| 36 // Create a fake non-empty encrypted buffer. |
| 37 static scoped_refptr<DecoderBuffer> CreateFakeEncryptedBuffer() { |
| 38 const int buffer_size = 16; // Need a non-empty buffer; |
| 39 scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(buffer_size)); |
| 40 buffer->SetDecryptConfig(scoped_ptr<DecryptConfig>(new DecryptConfig( |
| 41 std::string(reinterpret_cast<const char*>(kFakeKeyId), |
| 42 arraysize(kFakeKeyId)), |
| 43 std::string(reinterpret_cast<const char*>(kFakeIv), arraysize(kFakeIv)), |
| 44 0, |
| 45 std::vector<SubsampleEntry>()))); |
| 46 return buffer; |
| 47 } |
| 48 |
| 49 ACTION_P(ReturnBuffer, buffer) { |
| 50 arg0.Run(buffer ? DemuxerStream::kOk : DemuxerStream::kAborted, buffer); |
| 51 } |
| 52 |
| 53 ACTION(ReturnConfigChanged) { |
| 54 arg0.Run(DemuxerStream::kConfigChanged, scoped_refptr<DecoderBuffer>(NULL)); |
| 55 } |
| 56 |
| 57 ACTION_P(RunCallback1, param) { |
| 58 arg1.Run(param); |
| 59 } |
| 60 |
| 61 ACTION_P2(RunCallback2, param1, param2) { |
| 62 arg1.Run(param1, param2); |
| 63 } |
| 64 |
| 65 class DecryptingVideoDecoderTest : public testing::Test { |
| 66 public: |
| 67 DecryptingVideoDecoderTest() |
| 68 : decryptor_(new StrictMock<MockDecryptor>()), |
| 69 decoder_(new StrictMock<DecryptingVideoDecoder>( |
| 70 base::Bind(&Identity<scoped_refptr<base::MessageLoopProxy> >, |
| 71 message_loop_.message_loop_proxy()), |
| 72 decryptor_.get())), |
| 73 demuxer_(new StrictMock<MockDemuxerStream>()), |
| 74 encrypted_buffer_(CreateFakeEncryptedBuffer()), |
| 75 decoded_video_frame_(VideoFrame::CreateBlackFrame(kCodedSize)), |
| 76 null_video_frame_(scoped_refptr<VideoFrame>()), |
| 77 end_of_stream_video_frame_(VideoFrame::CreateEmptyFrame()) { |
| 78 } |
| 79 |
| 80 virtual ~DecryptingVideoDecoderTest() { |
| 81 Stop(); |
| 82 } |
| 83 |
| 84 void InitializeAndExpectStatus(const VideoDecoderConfig& config, |
| 85 PipelineStatus status) { |
| 86 EXPECT_CALL(*demuxer_, video_decoder_config()) |
| 87 .WillRepeatedly(ReturnRef(config)); |
| 88 |
| 89 decoder_->Initialize(demuxer_, NewExpectedStatusCB(status), |
| 90 base::Bind(&MockStatisticsCB::OnStatistics, |
| 91 base::Unretained(&statistics_cb_))); |
| 92 message_loop_.RunAllPending(); |
| 93 } |
| 94 |
| 95 void Initialize() { |
| 96 EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _)) |
| 97 .WillOnce(RunCallback1(true)); |
| 98 |
| 99 config_.Initialize(kCodecVP8, VIDEO_CODEC_PROFILE_UNKNOWN, kVideoFormat, |
| 100 kCodedSize, kVisibleRect, kNaturalSize, |
| 101 NULL, 0, true, true); |
| 102 |
| 103 InitializeAndExpectStatus(config_, PIPELINE_OK); |
| 104 } |
| 105 |
| 106 void ReadAndExpectFrameReadyWith( |
| 107 VideoDecoder::Status status, |
| 108 const scoped_refptr<VideoFrame>& video_frame) { |
| 109 EXPECT_CALL(*this, FrameReady(status, video_frame)); |
| 110 |
| 111 decoder_->Read(base::Bind(&DecryptingVideoDecoderTest::FrameReady, |
| 112 base::Unretained(this))); |
| 113 message_loop_.RunAllPending(); |
| 114 } |
| 115 |
| 116 // Sets up expectations and actions to put DecryptingVideoDecoder in an |
| 117 // active normal decoding state. |
| 118 void EnterNormalDecodingState() { |
| 119 EXPECT_CALL(*demuxer_, Read(_)) |
| 120 .WillOnce(ReturnBuffer(encrypted_buffer_)) |
| 121 .WillRepeatedly(ReturnBuffer(DecoderBuffer::CreateEOSBuffer())); |
| 122 EXPECT_CALL(*decryptor_, DecryptAndDecodeVideo(_, _)) |
| 123 .WillOnce(RunCallback2(Decryptor::kSuccess, decoded_video_frame_)) |
| 124 .WillRepeatedly(RunCallback2(Decryptor::kSuccess, |
| 125 end_of_stream_video_frame_)); |
| 126 EXPECT_CALL(statistics_cb_, OnStatistics(_)); |
| 127 |
| 128 ReadAndExpectFrameReadyWith(VideoDecoder::kOk, decoded_video_frame_); |
| 129 } |
| 130 |
| 131 // Sets up expectations and actions to put DecryptingVideoDecoder in an end |
| 132 // of stream state. This function must be called after |
| 133 // EnterNormalDecodingState() to work. |
| 134 void EnterEndOfStreamState() { |
| 135 ReadAndExpectFrameReadyWith(VideoDecoder::kOk, end_of_stream_video_frame_); |
| 136 } |
| 137 |
| 138 // Make the read callback pending by saving and not firing it. |
| 139 void EnterPendingReadState() { |
| 140 EXPECT_TRUE(pending_demuxer_read_cb_.is_null()); |
| 141 EXPECT_CALL(*demuxer_, Read(_)) |
| 142 .WillOnce(SaveArg<0>(&pending_demuxer_read_cb_)); |
| 143 decoder_->Read(base::Bind(&DecryptingVideoDecoderTest::FrameReady, |
| 144 base::Unretained(this))); |
| 145 message_loop_.RunAllPending(); |
| 146 // Make sure the Read() on the decoder triggers a Read() on the demuxer. |
| 147 EXPECT_FALSE(pending_demuxer_read_cb_.is_null()); |
| 148 } |
| 149 |
| 150 // Make the video decode callback pending by saving and not firing it. |
| 151 void EnterPendingDecryptAndDecodeState() { |
| 152 EXPECT_TRUE(pending_video_decode_cb_.is_null()); |
| 153 EXPECT_CALL(*demuxer_, Read(_)) |
| 154 .WillRepeatedly(ReturnBuffer(encrypted_buffer_)); |
| 155 EXPECT_CALL(*decryptor_, DecryptAndDecodeVideo(encrypted_buffer_, _)) |
| 156 .WillOnce(SaveArg<1>(&pending_video_decode_cb_)); |
| 157 |
| 158 decoder_->Read(base::Bind(&DecryptingVideoDecoderTest::FrameReady, |
| 159 base::Unretained(this))); |
| 160 message_loop_.RunAllPending(); |
| 161 // Make sure the Read() on the decoder triggers a DecryptAndDecode() on the |
| 162 // decryptor. |
| 163 EXPECT_FALSE(pending_video_decode_cb_.is_null()); |
| 164 } |
| 165 |
| 166 void AbortPendingVideoDecodeCB() { |
| 167 if (!pending_video_decode_cb_.is_null()) { |
| 168 base::ResetAndReturn(&pending_video_decode_cb_).Run( |
| 169 Decryptor::kSuccess, scoped_refptr<VideoFrame>(NULL)); |
| 170 } |
| 171 } |
| 172 |
| 173 void AbortAllPendingCBs() { |
| 174 if (!pending_init_cb_.is_null()) { |
| 175 ASSERT_TRUE(pending_video_decode_cb_.is_null()); |
| 176 base::ResetAndReturn(&pending_init_cb_).Run(false); |
| 177 return; |
| 178 } |
| 179 |
| 180 AbortPendingVideoDecodeCB(); |
| 181 } |
| 182 |
| 183 void Reset() { |
| 184 EXPECT_CALL(*decryptor_, CancelDecryptAndDecodeVideo()) |
| 185 .WillOnce(Invoke( |
| 186 this, &DecryptingVideoDecoderTest::AbortPendingVideoDecodeCB)); |
| 187 |
| 188 decoder_->Reset(NewExpectedClosure()); |
| 189 message_loop_.RunAllPending(); |
| 190 } |
| 191 |
| 192 void Stop() { |
| 193 EXPECT_CALL(*decryptor_, StopVideoDecoder()) |
| 194 .WillOnce(Invoke( |
| 195 this, &DecryptingVideoDecoderTest::AbortAllPendingCBs)); |
| 196 |
| 197 decoder_->Stop(NewExpectedClosure()); |
| 198 message_loop_.RunAllPending(); |
| 199 } |
| 200 |
| 201 MOCK_METHOD2(FrameReady, void(VideoDecoder::Status, |
| 202 const scoped_refptr<VideoFrame>&)); |
| 203 |
| 204 MessageLoop message_loop_; |
| 205 scoped_ptr<StrictMock<MockDecryptor> > decryptor_; |
| 206 scoped_refptr<StrictMock<DecryptingVideoDecoder> > decoder_; |
| 207 scoped_refptr<StrictMock<MockDemuxerStream> > demuxer_; |
| 208 MockStatisticsCB statistics_cb_; |
| 209 VideoDecoderConfig config_; |
| 210 |
| 211 DemuxerStream::ReadCB pending_demuxer_read_cb_; |
| 212 Decryptor::DecoderInitCB pending_init_cb_; |
| 213 Decryptor::VideoDecodeCB pending_video_decode_cb_; |
| 214 |
| 215 // Constant buffer/frames to be returned by the |demuxer_| and |decryptor_|. |
| 216 scoped_refptr<DecoderBuffer> encrypted_buffer_; |
| 217 scoped_refptr<VideoFrame> decoded_video_frame_; |
| 218 scoped_refptr<VideoFrame> null_video_frame_; |
| 219 scoped_refptr<VideoFrame> end_of_stream_video_frame_; |
| 220 |
| 221 private: |
| 222 DISALLOW_COPY_AND_ASSIGN(DecryptingVideoDecoderTest); |
| 223 }; |
| 224 |
| 225 TEST_F(DecryptingVideoDecoderTest, Initialize_Normal) { |
| 226 Initialize(); |
| 227 } |
| 228 |
| 229 // Ensure that DecryptingVideoDecoder only accepts encrypted video. |
| 230 TEST_F(DecryptingVideoDecoderTest, Initialize_UnencryptedVideoConfig) { |
| 231 VideoDecoderConfig config(kCodecVP8, VIDEO_CODEC_PROFILE_UNKNOWN, |
| 232 kVideoFormat, |
| 233 kCodedSize, kVisibleRect, kNaturalSize, |
| 234 NULL, 0, false); |
| 235 |
| 236 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED); |
| 237 } |
| 238 |
| 239 // Ensure decoder handles invalid video configs without crashing. |
| 240 TEST_F(DecryptingVideoDecoderTest, Initialize_InvalidVideoConfig) { |
| 241 VideoDecoderConfig config(kCodecVP8, VIDEO_CODEC_PROFILE_UNKNOWN, |
| 242 VideoFrame::INVALID, |
| 243 kCodedSize, kVisibleRect, kNaturalSize, |
| 244 NULL, 0, true); |
| 245 |
| 246 InitializeAndExpectStatus(config, PIPELINE_ERROR_DECODE); |
| 247 } |
| 248 |
| 249 // Ensure decoder handles unsupported video configs without crashing. |
| 250 TEST_F(DecryptingVideoDecoderTest, Initialize_UnsupportedVideoConfig) { |
| 251 EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _)) |
| 252 .WillOnce(RunCallback1(false)); |
| 253 |
| 254 VideoDecoderConfig config(kCodecVP8, VIDEO_CODEC_PROFILE_UNKNOWN, |
| 255 kVideoFormat, |
| 256 kCodedSize, kVisibleRect, kNaturalSize, |
| 257 NULL, 0, true); |
| 258 |
| 259 InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED); |
| 260 } |
| 261 |
| 262 // Test normal decrypt and decode case. |
| 263 TEST_F(DecryptingVideoDecoderTest, DecryptAndDecode_Normal) { |
| 264 Initialize(); |
| 265 EnterNormalDecodingState(); |
| 266 } |
| 267 |
| 268 // Test the case where the decryptor returns error when doing decrypt and |
| 269 // decode. |
| 270 TEST_F(DecryptingVideoDecoderTest, DecryptAndDecode_DecodeError) { |
| 271 Initialize(); |
| 272 |
| 273 EXPECT_CALL(*demuxer_, Read(_)) |
| 274 .WillRepeatedly(ReturnBuffer(encrypted_buffer_)); |
| 275 EXPECT_CALL(*decryptor_, DecryptAndDecodeVideo(_, _)) |
| 276 .WillRepeatedly(RunCallback2(Decryptor::kError, |
| 277 scoped_refptr<VideoFrame>(NULL))); |
| 278 |
| 279 ReadAndExpectFrameReadyWith(VideoDecoder::kDecodeError, null_video_frame_); |
| 280 } |
| 281 |
| 282 // Test the case where the decryptor does not have the decryption key to do |
| 283 // decrypt and decode. |
| 284 TEST_F(DecryptingVideoDecoderTest, DecryptAndDecode_NoKey) { |
| 285 Initialize(); |
| 286 |
| 287 EXPECT_CALL(*demuxer_, Read(_)) |
| 288 .WillRepeatedly(ReturnBuffer(encrypted_buffer_)); |
| 289 EXPECT_CALL(*decryptor_, DecryptAndDecodeVideo(_, _)) |
| 290 .WillRepeatedly(RunCallback2(Decryptor::kNoKey, null_video_frame_)); |
| 291 |
| 292 ReadAndExpectFrameReadyWith(VideoDecoder::kDecodeError, null_video_frame_); |
| 293 } |
| 294 |
| 295 // Test the case where the decryptor returns kNeedMoreData to ask for more |
| 296 // buffers before it can produce a frame. |
| 297 TEST_F(DecryptingVideoDecoderTest, DecryptAndDecode_NeedMoreData) { |
| 298 Initialize(); |
| 299 |
| 300 EXPECT_CALL(*demuxer_, Read(_)) |
| 301 .Times(2) |
| 302 .WillRepeatedly(ReturnBuffer(encrypted_buffer_)); |
| 303 EXPECT_CALL(*decryptor_, DecryptAndDecodeVideo(_, _)) |
| 304 .WillOnce(RunCallback2(Decryptor::kNeedMoreData, |
| 305 scoped_refptr<VideoFrame>())) |
| 306 .WillRepeatedly(RunCallback2(Decryptor::kSuccess, decoded_video_frame_)); |
| 307 EXPECT_CALL(statistics_cb_, OnStatistics(_)) |
| 308 .Times(2); |
| 309 |
| 310 ReadAndExpectFrameReadyWith(VideoDecoder::kOk, decoded_video_frame_); |
| 311 } |
| 312 |
| 313 // Test the case where the decryptor receives end-of-stream buffer. |
| 314 TEST_F(DecryptingVideoDecoderTest, DecryptAndDecode_EndOfStream) { |
| 315 Initialize(); |
| 316 EnterNormalDecodingState(); |
| 317 EnterEndOfStreamState(); |
| 318 } |
| 319 |
| 320 // Test resetting when decoder has initialized but has not decoded any frame. |
| 321 TEST_F(DecryptingVideoDecoderTest, Reset_Initialized) { |
| 322 Initialize(); |
| 323 Reset(); |
| 324 } |
| 325 |
| 326 // Test resetting when decoder has decoded single frame. |
| 327 TEST_F(DecryptingVideoDecoderTest, Reset_Decoding) { |
| 328 Initialize(); |
| 329 EnterNormalDecodingState(); |
| 330 Reset(); |
| 331 } |
| 332 |
| 333 // Test resetting when decoder has hit end of stream. |
| 334 TEST_F(DecryptingVideoDecoderTest, Reset_EndOfStream) { |
| 335 Initialize(); |
| 336 EnterNormalDecodingState(); |
| 337 EnterEndOfStreamState(); |
| 338 Reset(); |
| 339 } |
| 340 |
| 341 // Test resetting after the decoder has been reset. |
| 342 TEST_F(DecryptingVideoDecoderTest, Reset_AfterReset) { |
| 343 Initialize(); |
| 344 EnterNormalDecodingState(); |
| 345 Reset(); |
| 346 Reset(); |
| 347 } |
| 348 |
| 349 // Test resetting when there is a pending read on the demuxer. |
| 350 TEST_F(DecryptingVideoDecoderTest, Reset_DuringPendingDemuxerRead) { |
| 351 Initialize(); |
| 352 EnterPendingReadState(); |
| 353 |
| 354 EXPECT_CALL(*this, FrameReady(VideoDecoder::kOk, IsNull())); |
| 355 |
| 356 Reset(); |
| 357 base::ResetAndReturn(&pending_demuxer_read_cb_).Run(DemuxerStream::kOk, |
| 358 encrypted_buffer_); |
| 359 message_loop_.RunAllPending(); |
| 360 } |
| 361 |
| 362 // Test resetting when there is a pending video decode callback on the |
| 363 // decryptor. |
| 364 TEST_F(DecryptingVideoDecoderTest, Reset_DuringPendingDecryptAndDecode) { |
| 365 Initialize(); |
| 366 EnterPendingDecryptAndDecodeState(); |
| 367 |
| 368 EXPECT_CALL(*this, FrameReady(VideoDecoder::kOk, IsNull())); |
| 369 |
| 370 Reset(); |
| 371 } |
| 372 |
| 373 // Test stopping when decoder has initialized but has not decoded any frame. |
| 374 TEST_F(DecryptingVideoDecoderTest, Stop_Initialized) { |
| 375 Initialize(); |
| 376 Stop(); |
| 377 } |
| 378 |
| 379 // Test stopping when decoder has decoded single frame. |
| 380 TEST_F(DecryptingVideoDecoderTest, Stop_Decoding) { |
| 381 Initialize(); |
| 382 EnterNormalDecodingState(); |
| 383 Stop(); |
| 384 } |
| 385 |
| 386 // Test stopping when decoder has hit end of stream. |
| 387 TEST_F(DecryptingVideoDecoderTest, Stop_EndOfStream) { |
| 388 Initialize(); |
| 389 EnterNormalDecodingState(); |
| 390 EnterEndOfStreamState(); |
| 391 Stop(); |
| 392 } |
| 393 |
| 394 // Test stopping when there is a pending read on the demuxer. |
| 395 TEST_F(DecryptingVideoDecoderTest, Stop_DuringPendingInitialize) { |
| 396 EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _)) |
| 397 .WillOnce(SaveArg<1>(&pending_init_cb_)); |
| 398 |
| 399 config_.Initialize(kCodecVP8, VIDEO_CODEC_PROFILE_UNKNOWN, kVideoFormat, |
| 400 kCodedSize, kVisibleRect, kNaturalSize, NULL, 0, true, |
| 401 true); |
| 402 InitializeAndExpectStatus(config_, DECODER_ERROR_NOT_SUPPORTED); |
| 403 EXPECT_FALSE(pending_init_cb_.is_null()); |
| 404 |
| 405 Stop(); |
| 406 } |
| 407 |
| 408 // Test stopping when there is a pending read on the demuxer. |
| 409 TEST_F(DecryptingVideoDecoderTest, Stop_DuringPendingDemuxerRead) { |
| 410 Initialize(); |
| 411 EnterPendingReadState(); |
| 412 |
| 413 EXPECT_CALL(*this, FrameReady(VideoDecoder::kOk, IsNull())); |
| 414 |
| 415 Stop(); |
| 416 base::ResetAndReturn(&pending_demuxer_read_cb_).Run(DemuxerStream::kOk, |
| 417 encrypted_buffer_); |
| 418 message_loop_.RunAllPending(); |
| 419 } |
| 420 |
| 421 // Test stopping when there is a pending video decode callback on the |
| 422 // decryptor. |
| 423 TEST_F(DecryptingVideoDecoderTest, Stop_DuringPendingDecryptAndDecode) { |
| 424 Initialize(); |
| 425 EnterPendingDecryptAndDecodeState(); |
| 426 |
| 427 EXPECT_CALL(*this, FrameReady(VideoDecoder::kOk, IsNull())); |
| 428 |
| 429 Stop(); |
| 430 } |
| 431 |
| 432 // Test stopping when there is a pending reset on the decoder. |
| 433 // Reset is pending because it cannot complete when the video decode callback |
| 434 // is pending. |
| 435 TEST_F(DecryptingVideoDecoderTest, Stop_DuringPendingReset) { |
| 436 Initialize(); |
| 437 EnterPendingDecryptAndDecodeState(); |
| 438 |
| 439 EXPECT_CALL(*decryptor_, CancelDecryptAndDecodeVideo()); |
| 440 EXPECT_CALL(*this, FrameReady(VideoDecoder::kOk, IsNull())); |
| 441 |
| 442 decoder_->Reset(NewExpectedClosure()); |
| 443 Stop(); |
| 444 } |
| 445 |
| 446 // Test stopping after the decoder has been reset. |
| 447 TEST_F(DecryptingVideoDecoderTest, Stop_AfterReset) { |
| 448 Initialize(); |
| 449 EnterNormalDecodingState(); |
| 450 Reset(); |
| 451 Stop(); |
| 452 } |
| 453 |
| 454 // Test stopping after the decoder has been stopped. |
| 455 TEST_F(DecryptingVideoDecoderTest, Stop_AfterStop) { |
| 456 Initialize(); |
| 457 EnterNormalDecodingState(); |
| 458 Stop(); |
| 459 Stop(); |
| 460 } |
| 461 |
| 462 // Test aborted read on the demuxer stream. |
| 463 TEST_F(DecryptingVideoDecoderTest, AbortPendingDemuxerRead) { |
| 464 Initialize(); |
| 465 |
| 466 // ReturnBuffer() with NULL triggers aborted demuxer read. |
| 467 EXPECT_CALL(*demuxer_, Read(_)) |
| 468 .WillOnce(ReturnBuffer(scoped_refptr<DecoderBuffer>())); |
| 469 |
| 470 ReadAndExpectFrameReadyWith(VideoDecoder::kOk, null_video_frame_); |
| 471 } |
| 472 |
| 473 // Test aborted read on the demuxer stream when the decoder is being reset. |
| 474 TEST_F(DecryptingVideoDecoderTest, AbortPendingDemuxerReadDuringReset) { |
| 475 Initialize(); |
| 476 EnterPendingReadState(); |
| 477 |
| 478 // Make sure we get a NULL video frame returned. |
| 479 EXPECT_CALL(*this, FrameReady(VideoDecoder::kOk, IsNull())); |
| 480 |
| 481 Reset(); |
| 482 base::ResetAndReturn(&pending_demuxer_read_cb_).Run(DemuxerStream::kAborted, |
| 483 NULL); |
| 484 message_loop_.RunAllPending(); |
| 485 } |
| 486 |
| 487 // Test config change on the demuxer stream. |
| 488 TEST_F(DecryptingVideoDecoderTest, ConfigChanged) { |
| 489 Initialize(); |
| 490 |
| 491 EXPECT_CALL(*demuxer_, Read(_)) |
| 492 .WillOnce(ReturnConfigChanged()); |
| 493 |
| 494 // TODO(xhwang): Update this test when kConfigChanged is supported in |
| 495 // DecryptingVideoDecoder. |
| 496 ReadAndExpectFrameReadyWith(VideoDecoder::kDecodeError, null_video_frame_); |
| 497 } |
| 498 |
| 499 } // namespace media |
OLD | NEW |