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