OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <utility> | 5 #include <utility> |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
10 #include "base/debug/stack_trace.h" | 10 #include "base/debug/stack_trace.h" |
(...skipping 18 matching lines...) Expand all Loading... | |
29 using ::testing::AnyNumber; | 29 using ::testing::AnyNumber; |
30 using ::testing::Invoke; | 30 using ::testing::Invoke; |
31 using ::testing::Mock; | 31 using ::testing::Mock; |
32 using ::testing::NiceMock; | 32 using ::testing::NiceMock; |
33 using ::testing::Return; | 33 using ::testing::Return; |
34 using ::testing::SaveArg; | 34 using ::testing::SaveArg; |
35 using ::testing::StrictMock; | 35 using ::testing::StrictMock; |
36 | 36 |
37 namespace media { | 37 namespace media { |
38 | 38 |
39 // Threshold for Render() callbacks used for testing; should not be zero. | |
40 static const int kTestBackgroundRenderTimeoutMs = 25; | |
41 | |
39 ACTION_P(RunClosure, closure) { | 42 ACTION_P(RunClosure, closure) { |
40 closure.Run(); | 43 closure.Run(); |
41 } | 44 } |
42 | 45 |
43 MATCHER_P(HasTimestamp, ms, "") { | 46 MATCHER_P(HasTimestamp, ms, "") { |
44 *result_listener << "has timestamp " << arg->timestamp().InMilliseconds(); | 47 *result_listener << "has timestamp " << arg->timestamp().InMilliseconds(); |
45 return arg->timestamp().InMilliseconds() == ms; | 48 return arg->timestamp().InMilliseconds() == ms; |
46 } | 49 } |
47 | 50 |
48 class VideoRendererImplTest : public ::testing::Test { | 51 // TODO(dalecurtis): Switch this to TestWithValues() and TEST_P() to get both |
52 // paths tested. | |
53 | |
54 class VideoRendererImplTest : public testing::TestWithParam<bool> { | |
49 public: | 55 public: |
50 VideoRendererImplTest() | 56 VideoRendererImplTest() |
51 : tick_clock_(new base::SimpleTestTickClock()), | 57 : tick_clock_(new base::SimpleTestTickClock()), |
52 decoder_(new MockVideoDecoder()), | 58 decoder_(new MockVideoDecoder()), |
53 demuxer_stream_(DemuxerStream::VIDEO) { | 59 demuxer_stream_(DemuxerStream::VIDEO) { |
54 ScopedVector<VideoDecoder> decoders; | 60 ScopedVector<VideoDecoder> decoders; |
55 decoders.push_back(decoder_); | 61 decoders.push_back(decoder_); |
56 | 62 |
57 // Since the Underflow test needs a render interval shorter than the frame | 63 // Since the Underflow test needs a render interval shorter than the frame |
58 // duration, use 120Hz (which makes each interval is < 10ms; ~9.9ms). | 64 // duration, use 120Hz (which makes each interval is < 10ms; ~9.9ms). |
59 null_video_sink_.reset(new NullVideoSink( | 65 null_video_sink_.reset(new NullVideoSink( |
60 false, base::TimeDelta::FromSecondsD(1.0 / 120), | 66 false, base::TimeDelta::FromSecondsD(1.0 / 120), |
61 base::Bind(&MockCB::FrameReceived, base::Unretained(&mock_cb_)), | 67 base::Bind(&MockCB::FrameReceived, base::Unretained(&mock_cb_)), |
62 message_loop_.task_runner())); | 68 message_loop_.task_runner())); |
63 | 69 |
64 renderer_.reset(new VideoRendererImpl( | 70 renderer_.reset(new VideoRendererImpl( |
65 message_loop_.message_loop_proxy(), null_video_sink_.get(), | 71 message_loop_.message_loop_proxy(), null_video_sink_.get(), |
66 decoders.Pass(), true, new MediaLog())); | 72 decoders.Pass(), true, new MediaLog())); |
67 | 73 if (GetParam()) |
74 renderer_->enable_new_video_renderer_for_testing(); | |
68 renderer_->SetTickClockForTesting(scoped_ptr<base::TickClock>(tick_clock_)); | 75 renderer_->SetTickClockForTesting(scoped_ptr<base::TickClock>(tick_clock_)); |
69 null_video_sink_->set_tick_clock_for_testing(tick_clock_); | 76 null_video_sink_->set_tick_clock_for_testing(tick_clock_); |
70 | 77 |
78 // Disable background rendering for tests by default. | |
79 renderer_->SetBackgroundRenderingForTesting(false, base::TimeDelta()); | |
80 | |
71 // Start wallclock time at a non-zero value. | 81 // Start wallclock time at a non-zero value. |
72 AdvanceWallclockTimeInMs(12345); | 82 AdvanceWallclockTimeInMs(12345); |
73 | 83 |
74 demuxer_stream_.set_video_decoder_config(TestVideoConfig::Normal()); | 84 demuxer_stream_.set_video_decoder_config(TestVideoConfig::Normal()); |
75 | 85 |
76 // We expect these to be called but we don't care how/when. | 86 // We expect these to be called but we don't care how/when. |
77 EXPECT_CALL(demuxer_stream_, Read(_)).WillRepeatedly( | 87 EXPECT_CALL(demuxer_stream_, Read(_)).WillRepeatedly( |
78 RunCallback<0>(DemuxerStream::kOk, | 88 RunCallback<0>(DemuxerStream::kOk, |
79 scoped_refptr<DecoderBuffer>(new DecoderBuffer(0)))); | 89 scoped_refptr<DecoderBuffer>(new DecoderBuffer(0)))); |
80 } | 90 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
138 renderer_->Flush(event.GetClosure()); | 148 renderer_->Flush(event.GetClosure()); |
139 event.RunAndWait(); | 149 event.RunAndWait(); |
140 } | 150 } |
141 | 151 |
142 void Destroy() { | 152 void Destroy() { |
143 SCOPED_TRACE("Destroy()"); | 153 SCOPED_TRACE("Destroy()"); |
144 renderer_.reset(); | 154 renderer_.reset(); |
145 message_loop_.RunUntilIdle(); | 155 message_loop_.RunUntilIdle(); |
146 } | 156 } |
147 | 157 |
158 void SuspendRenderCallbacks() { | |
159 null_video_sink_->pause_callbacks(base::TimeTicks() + | |
160 base::TimeDelta::Max()); | |
161 } | |
162 | |
148 // Parses a string representation of video frames and generates corresponding | 163 // Parses a string representation of video frames and generates corresponding |
149 // VideoFrame objects in |decode_results_|. | 164 // VideoFrame objects in |decode_results_|. |
150 // | 165 // |
151 // Syntax: | 166 // Syntax: |
152 // nn - Queue a decoder buffer with timestamp nn * 1000us | 167 // nn - Queue a decoder buffer with timestamp nn * 1000us |
153 // abort - Queue an aborted read | 168 // abort - Queue an aborted read |
154 // error - Queue a decoder error | 169 // error - Queue a decoder error |
155 // | 170 // |
156 // Examples: | 171 // Examples: |
157 // A clip that is four frames long: "0 10 20 30" | 172 // A clip that is four frames long: "0 10 20 30" |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
259 base::AutoLock l(lock_); | 274 base::AutoLock l(lock_); |
260 tick_clock_->Advance(base::TimeDelta::FromMilliseconds(time_ms)); | 275 tick_clock_->Advance(base::TimeDelta::FromMilliseconds(time_ms)); |
261 } | 276 } |
262 | 277 |
263 void AdvanceTimeInMs(int time_ms) { | 278 void AdvanceTimeInMs(int time_ms) { |
264 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); | 279 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); |
265 base::AutoLock l(lock_); | 280 base::AutoLock l(lock_); |
266 time_ += base::TimeDelta::FromMilliseconds(time_ms); | 281 time_ += base::TimeDelta::FromMilliseconds(time_ms); |
267 } | 282 } |
268 | 283 |
284 bool has_ended() const { | |
285 return ended_event_.is_signaled(); | |
286 } | |
287 | |
269 protected: | 288 protected: |
270 // Fixture members. | 289 // Fixture members. |
271 scoped_ptr<VideoRendererImpl> renderer_; | 290 scoped_ptr<VideoRendererImpl> renderer_; |
272 base::SimpleTestTickClock* tick_clock_; // Owned by |renderer_|. | 291 base::SimpleTestTickClock* tick_clock_; // Owned by |renderer_|. |
273 MockVideoDecoder* decoder_; // Owned by |renderer_|. | 292 MockVideoDecoder* decoder_; // Owned by |renderer_|. |
274 NiceMock<MockDemuxerStream> demuxer_stream_; | 293 NiceMock<MockDemuxerStream> demuxer_stream_; |
275 | 294 |
276 // Use StrictMock<T> to catch missing/extra callbacks. | 295 // Use StrictMock<T> to catch missing/extra callbacks. |
277 class MockCB { | 296 class MockCB { |
278 public: | 297 public: |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
337 | 356 |
338 // Run during DecodeRequested() to unblock WaitForPendingRead(). | 357 // Run during DecodeRequested() to unblock WaitForPendingRead(). |
339 base::Closure wait_for_pending_decode_cb_; | 358 base::Closure wait_for_pending_decode_cb_; |
340 | 359 |
341 std::deque<std::pair< | 360 std::deque<std::pair< |
342 VideoDecoder::Status, scoped_refptr<VideoFrame> > > decode_results_; | 361 VideoDecoder::Status, scoped_refptr<VideoFrame> > > decode_results_; |
343 | 362 |
344 DISALLOW_COPY_AND_ASSIGN(VideoRendererImplTest); | 363 DISALLOW_COPY_AND_ASSIGN(VideoRendererImplTest); |
345 }; | 364 }; |
346 | 365 |
347 TEST_F(VideoRendererImplTest, DoNothing) { | 366 TEST_P(VideoRendererImplTest, DoNothing) { |
348 // Test that creation and deletion doesn't depend on calls to Initialize() | 367 // Test that creation and deletion doesn't depend on calls to Initialize() |
349 // and/or Destroy(). | 368 // and/or Destroy(). |
350 } | 369 } |
351 | 370 |
352 TEST_F(VideoRendererImplTest, DestroyWithoutInitialize) { | 371 TEST_P(VideoRendererImplTest, DestroyWithoutInitialize) { |
353 Destroy(); | 372 Destroy(); |
354 } | 373 } |
355 | 374 |
356 TEST_F(VideoRendererImplTest, Initialize) { | 375 TEST_P(VideoRendererImplTest, Initialize) { |
357 Initialize(); | 376 Initialize(); |
358 Destroy(); | 377 Destroy(); |
359 } | 378 } |
360 | 379 |
361 TEST_F(VideoRendererImplTest, InitializeAndStartPlayingFrom) { | 380 TEST_P(VideoRendererImplTest, InitializeAndStartPlayingFrom) { |
362 Initialize(); | 381 Initialize(); |
363 QueueFrames("0 10 20 30"); | 382 QueueFrames("0 10 20 30"); |
364 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); | 383 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); |
365 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); | 384 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
366 StartPlayingFrom(0); | 385 StartPlayingFrom(0); |
367 Destroy(); | 386 Destroy(); |
368 } | 387 } |
369 | 388 |
370 TEST_F(VideoRendererImplTest, DestroyWhileInitializing) { | 389 TEST_P(VideoRendererImplTest, DestroyWhileInitializing) { |
371 CallInitialize(NewExpectedStatusCB(PIPELINE_ERROR_ABORT), false, PIPELINE_OK); | 390 CallInitialize(NewExpectedStatusCB(PIPELINE_ERROR_ABORT), false, PIPELINE_OK); |
372 Destroy(); | 391 Destroy(); |
373 } | 392 } |
374 | 393 |
375 TEST_F(VideoRendererImplTest, DestroyWhileFlushing) { | 394 TEST_P(VideoRendererImplTest, DestroyWhileFlushing) { |
376 Initialize(); | 395 Initialize(); |
377 QueueFrames("0 10 20 30"); | 396 QueueFrames("0 10 20 30"); |
378 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); | 397 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); |
379 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); | 398 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
380 StartPlayingFrom(0); | 399 StartPlayingFrom(0); |
381 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_NOTHING)); | 400 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_NOTHING)); |
382 renderer_->Flush(NewExpectedClosure()); | 401 renderer_->Flush(NewExpectedClosure()); |
383 Destroy(); | 402 Destroy(); |
384 } | 403 } |
385 | 404 |
386 TEST_F(VideoRendererImplTest, Play) { | 405 TEST_P(VideoRendererImplTest, Play) { |
387 Initialize(); | 406 Initialize(); |
388 QueueFrames("0 10 20 30"); | 407 QueueFrames("0 10 20 30"); |
389 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); | 408 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); |
390 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); | 409 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
391 StartPlayingFrom(0); | 410 StartPlayingFrom(0); |
392 Destroy(); | 411 Destroy(); |
393 } | 412 } |
394 | 413 |
395 TEST_F(VideoRendererImplTest, FlushWithNothingBuffered) { | 414 TEST_P(VideoRendererImplTest, FlushWithNothingBuffered) { |
396 Initialize(); | 415 Initialize(); |
397 StartPlayingFrom(0); | 416 StartPlayingFrom(0); |
398 | 417 |
399 // We shouldn't expect a buffering state change since we never reached | 418 // We shouldn't expect a buffering state change since we never reached |
400 // BUFFERING_HAVE_ENOUGH. | 419 // BUFFERING_HAVE_ENOUGH. |
401 Flush(); | 420 Flush(); |
402 Destroy(); | 421 Destroy(); |
403 } | 422 } |
404 | 423 |
405 TEST_F(VideoRendererImplTest, DecodeError_Playing) { | 424 TEST_P(VideoRendererImplTest, DecodeError_Playing) { |
406 Initialize(); | 425 Initialize(); |
407 QueueFrames("0 10 20 30"); | 426 QueueFrames("0 10 20 30"); |
408 EXPECT_CALL(mock_cb_, FrameReceived(_)).Times(testing::AtLeast(1)); | 427 EXPECT_CALL(mock_cb_, FrameReceived(_)).Times(testing::AtLeast(1)); |
409 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); | 428 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
410 StartPlayingFrom(0); | 429 StartPlayingFrom(0); |
411 | 430 |
412 WaitForPendingRead(); | |
413 | |
414 QueueFrames("error"); | 431 QueueFrames("error"); |
415 SatisfyPendingRead(); | 432 SatisfyPendingRead(); |
416 WaitForError(PIPELINE_ERROR_DECODE); | 433 WaitForError(PIPELINE_ERROR_DECODE); |
417 Destroy(); | 434 Destroy(); |
418 } | 435 } |
419 | 436 |
420 TEST_F(VideoRendererImplTest, DecodeError_DuringStartPlayingFrom) { | 437 TEST_P(VideoRendererImplTest, DecodeError_DuringStartPlayingFrom) { |
421 Initialize(); | 438 Initialize(); |
422 QueueFrames("error"); | 439 QueueFrames("error"); |
423 StartPlayingFrom(0); | 440 StartPlayingFrom(0); |
424 Destroy(); | 441 Destroy(); |
425 } | 442 } |
426 | 443 |
427 TEST_F(VideoRendererImplTest, StartPlayingFrom_Exact) { | 444 TEST_P(VideoRendererImplTest, StartPlayingFrom_Exact) { |
428 Initialize(); | 445 Initialize(); |
429 QueueFrames("50 60 70 80 90"); | 446 QueueFrames("50 60 70 80 90"); |
430 | 447 |
431 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(60))); | 448 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(60))); |
432 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); | 449 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
433 StartPlayingFrom(60); | 450 StartPlayingFrom(60); |
434 Destroy(); | 451 Destroy(); |
435 } | 452 } |
436 | 453 |
437 TEST_F(VideoRendererImplTest, StartPlayingFrom_RightBefore) { | 454 TEST_P(VideoRendererImplTest, StartPlayingFrom_RightBefore) { |
438 Initialize(); | 455 Initialize(); |
439 QueueFrames("50 60 70 80 90"); | 456 QueueFrames("50 60 70 80 90"); |
440 | 457 |
441 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(50))); | 458 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(50))); |
442 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); | 459 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
443 StartPlayingFrom(59); | 460 StartPlayingFrom(59); |
444 Destroy(); | 461 Destroy(); |
445 } | 462 } |
446 | 463 |
447 TEST_F(VideoRendererImplTest, StartPlayingFrom_RightAfter) { | 464 TEST_P(VideoRendererImplTest, StartPlayingFrom_RightAfter) { |
448 Initialize(); | 465 Initialize(); |
449 QueueFrames("50 60 70 80 90"); | 466 QueueFrames("50 60 70 80 90"); |
450 | 467 |
451 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(60))); | 468 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(60))); |
452 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); | 469 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
453 StartPlayingFrom(61); | 470 StartPlayingFrom(61); |
454 Destroy(); | 471 Destroy(); |
455 } | 472 } |
456 | 473 |
457 TEST_F(VideoRendererImplTest, StartPlayingFrom_LowDelay) { | 474 TEST_P(VideoRendererImplTest, StartPlayingFrom_LowDelay) { |
458 // In low-delay mode only one frame is required to finish preroll. | 475 // In low-delay mode only one frame is required to finish preroll. |
459 InitializeWithLowDelay(true); | 476 InitializeWithLowDelay(true); |
460 QueueFrames("0"); | 477 QueueFrames("0"); |
461 | 478 |
462 // Expect some amount of have enough/nothing due to only requiring one frame. | 479 // Expect some amount of have enough/nothing due to only requiring one frame. |
463 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); | 480 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); |
464 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)) | 481 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)) |
465 .Times(AnyNumber()); | 482 .Times(AnyNumber()); |
466 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_NOTHING)) | 483 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_NOTHING)) |
467 .Times(AnyNumber()); | 484 .Times(AnyNumber()); |
468 StartPlayingFrom(0); | 485 StartPlayingFrom(0); |
469 | 486 |
470 QueueFrames("10"); | 487 QueueFrames("10"); |
471 SatisfyPendingRead(); | 488 SatisfyPendingRead(); |
472 | 489 |
490 renderer_->OnTimeStateChanged(true); | |
473 WaitableMessageLoopEvent event; | 491 WaitableMessageLoopEvent event; |
474 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(10))) | 492 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(10))) |
475 .WillOnce(RunClosure(event.GetClosure())); | 493 .WillOnce(RunClosure(event.GetClosure())); |
476 AdvanceTimeInMs(10); | 494 AdvanceTimeInMs(10); |
477 event.RunAndWait(); | 495 event.RunAndWait(); |
478 | 496 |
479 Destroy(); | 497 Destroy(); |
480 } | 498 } |
481 | 499 |
482 // Verify that a late decoder response doesn't break invariants in the renderer. | 500 // Verify that a late decoder response doesn't break invariants in the renderer. |
483 TEST_F(VideoRendererImplTest, DestroyDuringOutstandingRead) { | 501 TEST_P(VideoRendererImplTest, DestroyDuringOutstandingRead) { |
484 Initialize(); | 502 Initialize(); |
485 QueueFrames("0 10 20 30"); | 503 QueueFrames("0 10 20 30"); |
486 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); | 504 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); |
487 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); | 505 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
488 StartPlayingFrom(0); | 506 StartPlayingFrom(0); |
489 | 507 |
490 // Check that there is an outstanding Read() request. | 508 // Check that there is an outstanding Read() request. |
491 EXPECT_TRUE(IsReadPending()); | 509 EXPECT_TRUE(IsReadPending()); |
492 | 510 |
493 Destroy(); | 511 Destroy(); |
494 } | 512 } |
495 | 513 |
496 TEST_F(VideoRendererImplTest, VideoDecoder_InitFailure) { | 514 TEST_P(VideoRendererImplTest, VideoDecoder_InitFailure) { |
497 InitializeRenderer(DECODER_ERROR_NOT_SUPPORTED, false); | 515 InitializeRenderer(DECODER_ERROR_NOT_SUPPORTED, false); |
498 Destroy(); | 516 Destroy(); |
499 } | 517 } |
500 | 518 |
501 TEST_F(VideoRendererImplTest, Underflow) { | 519 TEST_P(VideoRendererImplTest, Underflow) { |
502 Initialize(); | 520 Initialize(); |
503 QueueFrames("0 10 20 30"); | 521 QueueFrames("0 10 20 30"); |
504 | 522 |
505 { | 523 { |
506 WaitableMessageLoopEvent event; | 524 WaitableMessageLoopEvent event; |
507 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); | 525 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); |
508 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)) | 526 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)) |
509 .WillOnce(RunClosure(event.GetClosure())); | 527 .WillOnce(RunClosure(event.GetClosure())); |
510 StartPlayingFrom(0); | 528 StartPlayingFrom(0); |
511 event.RunAndWait(); | 529 event.RunAndWait(); |
512 Mock::VerifyAndClearExpectations(&mock_cb_); | 530 Mock::VerifyAndClearExpectations(&mock_cb_); |
513 } | 531 } |
514 | 532 |
533 renderer_->OnTimeStateChanged(true); | |
534 | |
515 // Advance time slightly, but enough to exceed the duration of the last frame. | 535 // Advance time slightly, but enough to exceed the duration of the last frame. |
516 // Frames should be dropped and we should NOT signal having nothing. | 536 // Frames should be dropped and we should NOT signal having nothing. |
517 { | 537 { |
518 SCOPED_TRACE("Waiting for frame drops"); | 538 SCOPED_TRACE("Waiting for frame drops"); |
519 WaitableMessageLoopEvent event; | 539 WaitableMessageLoopEvent event; |
520 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(10))) | 540 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(10))) |
521 .Times(0); | 541 .Times(0); |
522 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(20))) | 542 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(20))) |
523 .Times(0); | 543 .Times(0); |
524 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(30))) | 544 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(30))) |
(...skipping 22 matching lines...) Expand all Loading... | |
547 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)) | 567 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)) |
548 .WillOnce(RunClosure(event.GetClosure())); | 568 .WillOnce(RunClosure(event.GetClosure())); |
549 SatisfyPendingReadWithEndOfStream(); | 569 SatisfyPendingReadWithEndOfStream(); |
550 event.RunAndWait(); | 570 event.RunAndWait(); |
551 } | 571 } |
552 | 572 |
553 WaitForEnded(); | 573 WaitForEnded(); |
554 Destroy(); | 574 Destroy(); |
555 } | 575 } |
556 | 576 |
577 // Tests the case where the video started in the background and never received | |
578 // any Render() calls and time never started progressing (so the sink should be | |
579 // stopped immediately). | |
580 TEST_P(VideoRendererImplTest, BackgroundRenderingStopsAfterFirstFrame) { | |
581 // This test is only for the new rendering path. | |
582 if (!GetParam()) | |
583 return; | |
584 | |
585 // By default, tests disable background rendering, so enable it now and give | |
586 // a short, but non-zero, timeout. | |
587 renderer_->SetBackgroundRenderingForTesting( | |
588 true, base::TimeDelta::FromMilliseconds(kTestBackgroundRenderTimeoutMs)); | |
589 | |
590 InitializeWithLowDelay(true); | |
591 QueueFrames("0"); | |
592 | |
593 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); | |
594 | |
595 // Pause callbacks forever, but don't start the sink. Ended should not fire. | |
596 SuspendRenderCallbacks(); | |
597 StartPlayingFrom(0); | |
598 EXPECT_TRUE(IsReadPending()); | |
599 SatisfyPendingReadWithEndOfStream(); | |
600 | |
601 { | |
602 SCOPED_TRACE("Waiting for sink to stop."); | |
603 WaitableMessageLoopEvent event; | |
604 null_video_sink_->set_stop_callback(event.GetClosure()); | |
605 event.RunAndWait(); | |
606 } | |
607 | |
608 EXPECT_FALSE(has_ended()); | |
609 Destroy(); | |
610 } | |
611 | |
612 // Tests the case where the video started in the background and never received | |
613 // any Render() calls, but time is progressing. | |
614 TEST_P(VideoRendererImplTest, BackgroundRenderingNeverStarted) { | |
615 // This test is only for the new rendering path. | |
616 if (!GetParam()) | |
617 return; | |
618 | |
619 // By default, tests disable background rendering, so enable it now and give | |
620 // a short, but non-zero, timeout. | |
621 renderer_->SetBackgroundRenderingForTesting( | |
622 true, base::TimeDelta::FromMilliseconds(kTestBackgroundRenderTimeoutMs)); | |
623 | |
624 Initialize(); | |
625 QueueFrames("0 10 20 30"); | |
626 | |
627 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); | |
628 | |
629 // Start the sink and pause callbacks forever. | |
630 renderer_->OnTimeStateChanged(true); | |
631 SuspendRenderCallbacks(); | |
632 StartPlayingFrom(0); | |
633 AdvanceTimeInMs(41); | |
634 | |
635 // Eventually background rendering should request new buffers and at that | |
636 // point fire the ended event if rendering has completed. | |
637 WaitForPendingRead(); | |
638 SatisfyPendingReadWithEndOfStream(); | |
639 WaitForEnded(); | |
640 Destroy(); | |
641 } | |
642 | |
643 // Tests the case where the video started in the background and never received | |
644 // any Render() calls, but time is progressing and there's only a single frame | |
645 // in the video. | |
646 TEST_P(VideoRendererImplTest, BackgroundRenderingNeverStartedSingleFrame) { | |
647 // This test is only for the new rendering path. | |
648 if (!GetParam()) | |
649 return; | |
650 | |
651 // By default, tests disable background rendering, so enable it now and give | |
652 // a short, but non-zero, timeout. | |
653 renderer_->SetBackgroundRenderingForTesting( | |
654 true, base::TimeDelta::FromMilliseconds(kTestBackgroundRenderTimeoutMs)); | |
655 | |
656 Initialize(); | |
657 QueueFrames("0"); | |
658 | |
659 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); | |
660 | |
661 // Start the sink and pause callbacks forever. | |
662 renderer_->OnTimeStateChanged(true); | |
663 SuspendRenderCallbacks(); | |
664 StartPlayingFrom(0); | |
665 | |
666 // Eventually background rendering should request new buffers and at that | |
667 // point fire the ended event if rendering has completed. | |
668 WaitForPendingRead(); | |
669 SatisfyPendingReadWithEndOfStream(); | |
670 WaitForEnded(); | |
671 Destroy(); | |
672 } | |
673 | |
674 // Tests the case where the video started and received a single Render() call, | |
675 // then the video was put into the background. | |
676 TEST_P(VideoRendererImplTest, BackgroundRenderingRenderStartedThenStopped) { | |
677 // This test is only for the new rendering path. | |
678 if (!GetParam()) | |
679 return; | |
680 | |
681 // By default, tests disable background rendering, so enable it now and give | |
682 // a short, but non-zero, timeout. | |
683 renderer_->SetBackgroundRenderingForTesting( | |
684 true, base::TimeDelta::FromMilliseconds(kTestBackgroundRenderTimeoutMs)); | |
685 | |
686 Initialize(); | |
687 QueueFrames("0 10 20 30"); | |
688 | |
689 // Start the sink and wait for the first callback. | |
690 { | |
691 WaitableMessageLoopEvent event; | |
692 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); | |
693 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)) | |
694 .WillOnce(RunClosure(event.GetClosure())); | |
695 StartPlayingFrom(0); | |
696 event.RunAndWait(); | |
697 Mock::VerifyAndClearExpectations(&mock_cb_); | |
698 } | |
699 | |
700 renderer_->OnTimeStateChanged(true); | |
701 | |
702 // Suspend all future callbacks and synthetically advance the media time. | |
703 SuspendRenderCallbacks(); | |
704 AdvanceTimeInMs(41); | |
705 | |
706 // Eventually background rendering should request new buffers and at that | |
707 // point fire the ended event if rendering has completed. | |
708 WaitForPendingRead(); | |
709 SatisfyPendingReadWithEndOfStream(); | |
710 WaitForEnded(); | |
711 Destroy(); | |
712 } | |
713 | |
714 INSTANTIATE_TEST_CASE_P(VideoRendererImplTest, | |
715 VideoRendererImplTest, | |
716 testing::Bool()); | |
xhwang
2015/04/29 06:51:55
For better test names, use different prefix for di
DaleCurtis
2015/04/30 03:49:37
Done.
| |
717 | |
557 } // namespace media | 718 } // namespace media |
OLD | NEW |