Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/callback.h" | 6 #include "base/callback.h" |
| 7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 56 EXPECT_CALL(*demuxer_stream_, video_decoder_config()) | 56 EXPECT_CALL(*demuxer_stream_, video_decoder_config()) |
| 57 .WillRepeatedly(ReturnRef(video_config_)); | 57 .WillRepeatedly(ReturnRef(video_config_)); |
| 58 | 58 |
| 59 // We expect these to be called but we don't care how/when. | 59 // We expect these to be called but we don't care how/when. |
| 60 EXPECT_CALL(*decoder_, Stop(_)) | 60 EXPECT_CALL(*decoder_, Stop(_)) |
| 61 .WillRepeatedly(RunClosure<0>()); | 61 .WillRepeatedly(RunClosure<0>()); |
| 62 EXPECT_CALL(statistics_cb_object_, OnStatistics(_)) | 62 EXPECT_CALL(statistics_cb_object_, OnStatistics(_)) |
| 63 .Times(AnyNumber()); | 63 .Times(AnyNumber()); |
| 64 EXPECT_CALL(*this, OnTimeUpdate(_)) | 64 EXPECT_CALL(*this, OnTimeUpdate(_)) |
| 65 .Times(AnyNumber()); | 65 .Times(AnyNumber()); |
| 66 EXPECT_CALL(*this, OnPaint()) | |
| 67 .Times(AnyNumber()); | |
| 68 EXPECT_CALL(*this, OnSetOpaque(_)) | 66 EXPECT_CALL(*this, OnSetOpaque(_)) |
| 69 .Times(AnyNumber()); | 67 .Times(AnyNumber()); |
| 70 } | 68 } |
| 71 | 69 |
| 72 virtual ~VideoRendererBaseTest() {} | 70 virtual ~VideoRendererBaseTest() {} |
| 73 | 71 |
| 74 // Callbacks passed into VideoRendererBase(). | 72 // Callbacks passed into VideoRendererBase(). |
| 75 MOCK_CONST_METHOD0(OnPaint, void()); | |
| 76 MOCK_CONST_METHOD1(OnSetOpaque, void(bool)); | 73 MOCK_CONST_METHOD1(OnSetOpaque, void(bool)); |
| 77 | 74 |
| 78 // Callbacks passed into Initialize(). | 75 // Callbacks passed into Initialize(). |
| 79 MOCK_METHOD1(OnTimeUpdate, void(base::TimeDelta)); | 76 MOCK_METHOD1(OnTimeUpdate, void(base::TimeDelta)); |
| 80 MOCK_METHOD1(OnNaturalSizeChanged, void(const gfx::Size&)); | 77 MOCK_METHOD1(OnNaturalSizeChanged, void(const gfx::Size&)); |
| 81 | 78 |
| 82 void Initialize() { | 79 void Initialize() { |
| 83 InitializeWithDuration(kVideoDurationInMs); | 80 InitializeWithDuration(kVideoDurationInMs); |
| 84 } | 81 } |
| 85 | 82 |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 QueueNextFrame(); | 219 QueueNextFrame(); |
| 223 } | 220 } |
| 224 | 221 |
| 225 // Queue the frame at |timestamp| plus additional ones for prerolling. | 222 // Queue the frame at |timestamp| plus additional ones for prerolling. |
| 226 for (int i = 0; i < limits::kMaxVideoFrames; ++i) { | 223 for (int i = 0; i < limits::kMaxVideoFrames; ++i) { |
| 227 QueueNextFrame(); | 224 QueueNextFrame(); |
| 228 } | 225 } |
| 229 } | 226 } |
| 230 | 227 |
| 231 scoped_refptr<VideoFrame> GetCurrentFrame() { | 228 scoped_refptr<VideoFrame> GetCurrentFrame() { |
| 232 scoped_refptr<VideoFrame> frame; | 229 base::AutoLock l(lock_); |
| 233 renderer_->GetCurrentFrame(&frame); | 230 return current_frame_; |
| 234 renderer_->PutCurrentFrame(frame); | |
| 235 return frame; | |
| 236 } | 231 } |
| 237 | 232 |
| 238 int GetCurrentTimestampInMs() { | 233 int GetCurrentTimestampInMs() { |
| 239 scoped_refptr<VideoFrame> frame = GetCurrentFrame(); | 234 scoped_refptr<VideoFrame> frame = GetCurrentFrame(); |
| 240 if (!frame) | 235 if (!frame) |
| 241 return -1; | 236 return -1; |
| 242 return frame->GetTimestamp().InMilliseconds(); | 237 return frame->GetTimestamp().InMilliseconds(); |
| 243 } | 238 } |
| 244 | 239 |
| 245 void WaitForError(PipelineStatus expected) { | 240 void WaitForError(PipelineStatus expected) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 298 private: | 293 private: |
| 299 base::TimeDelta GetTime() { | 294 base::TimeDelta GetTime() { |
| 300 base::AutoLock l(lock_); | 295 base::AutoLock l(lock_); |
| 301 return time_; | 296 return time_; |
| 302 } | 297 } |
| 303 | 298 |
| 304 base::TimeDelta GetDuration() { | 299 base::TimeDelta GetDuration() { |
| 305 return duration_; | 300 return duration_; |
| 306 } | 301 } |
| 307 | 302 |
| 303 void OnPaint(const scoped_refptr<VideoFrame>& frame) { | |
| 304 base::AutoLock l(lock_); | |
| 305 current_frame_ = frame; | |
| 306 } | |
| 307 | |
| 308 void FrameRequested(const VideoDecoder::ReadCB& read_cb) { | 308 void FrameRequested(const VideoDecoder::ReadCB& read_cb) { |
| 309 DCHECK_EQ(&message_loop_, MessageLoop::current()); | 309 DCHECK_EQ(&message_loop_, MessageLoop::current()); |
| 310 CHECK(read_cb_.is_null()); | 310 CHECK(read_cb_.is_null()); |
| 311 read_cb_ = read_cb; | 311 read_cb_ = read_cb; |
| 312 | 312 |
| 313 // Wake up WaitForPendingRead() if needed. | 313 // Wake up WaitForPendingRead() if needed. |
| 314 if (!pending_read_cb_.is_null()) | 314 if (!pending_read_cb_.is_null()) |
| 315 base::ResetAndReturn(&pending_read_cb_).Run(); | 315 base::ResetAndReturn(&pending_read_cb_).Run(); |
| 316 | 316 |
| 317 if (decode_results_.empty()) | 317 if (decode_results_.empty()) |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 328 SatisfyPendingRead(); | 328 SatisfyPendingRead(); |
| 329 } | 329 } |
| 330 | 330 |
| 331 message_loop_.PostTask(FROM_HERE, callback); | 331 message_loop_.PostTask(FROM_HERE, callback); |
| 332 } | 332 } |
| 333 | 333 |
| 334 MessageLoop message_loop_; | 334 MessageLoop message_loop_; |
| 335 | 335 |
| 336 VideoDecoderConfig video_config_; | 336 VideoDecoderConfig video_config_; |
| 337 | 337 |
| 338 // Used to protect |time_|. | 338 // Used to protect |time_| and |current_frame_|. |
| 339 base::Lock lock_; | 339 base::Lock lock_; |
| 340 base::TimeDelta time_; | 340 base::TimeDelta time_; |
| 341 scoped_refptr<VideoFrame> current_frame_; | |
| 341 | 342 |
| 342 // Used for satisfying reads. | 343 // Used for satisfying reads. |
| 343 VideoDecoder::ReadCB read_cb_; | 344 VideoDecoder::ReadCB read_cb_; |
| 344 base::TimeDelta next_frame_timestamp_; | 345 base::TimeDelta next_frame_timestamp_; |
| 345 base::TimeDelta duration_; | 346 base::TimeDelta duration_; |
| 346 | 347 |
| 347 WaitableMessageLoopEvent error_event_; | 348 WaitableMessageLoopEvent error_event_; |
| 348 WaitableMessageLoopEvent ended_event_; | 349 WaitableMessageLoopEvent ended_event_; |
| 349 base::Closure pending_read_cb_; | 350 base::Closure pending_read_cb_; |
| 350 | 351 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 479 Play(); | 480 Play(); |
| 480 Pause(); | 481 Pause(); |
| 481 EXPECT_TRUE(GetCurrentFrame()); | 482 EXPECT_TRUE(GetCurrentFrame()); |
| 482 Shutdown(); | 483 Shutdown(); |
| 483 } | 484 } |
| 484 | 485 |
| 485 TEST_F(VideoRendererBaseTest, GetCurrentFrame_Flushed) { | 486 TEST_F(VideoRendererBaseTest, GetCurrentFrame_Flushed) { |
| 486 Initialize(); | 487 Initialize(); |
| 487 Play(); | 488 Play(); |
| 488 Pause(); | 489 Pause(); |
| 490 | |
| 491 // Frame shouldn't be updated. | |
| 492 scoped_refptr<VideoFrame> expected = GetCurrentFrame(); | |
|
scherkus (not reviewing)
2013/01/31 17:54:05
I went down the path of using very fancy gmock EXP
acolwell GONE FROM CHROMIUM
2013/02/01 00:24:34
Doesn't this slightly change the test. Don't you w
scherkus (not reviewing)
2013/02/01 22:45:25
Good catch *and* I get to keep my gmock-free code
| |
| 489 Flush(); | 493 Flush(); |
| 490 EXPECT_FALSE(GetCurrentFrame()); | 494 EXPECT_EQ(expected, GetCurrentFrame()); |
| 495 | |
| 491 Shutdown(); | 496 Shutdown(); |
| 492 } | 497 } |
| 493 | 498 |
| 494 TEST_F(VideoRendererBaseTest, GetCurrentFrame_EndOfStream) { | 499 TEST_F(VideoRendererBaseTest, GetCurrentFrame_EndOfStream) { |
| 495 Initialize(); | 500 Initialize(); |
| 496 Play(); | 501 Play(); |
| 497 Pause(); | 502 Pause(); |
| 498 Flush(); | 503 Flush(); |
| 499 | 504 |
| 500 // Preroll only end of stream frames. | 505 // Preroll only end of stream frames. |
| 501 QueueEndOfStream(); | 506 QueueEndOfStream(); |
| 507 | |
| 508 // Frame shouldn't be updated. | |
| 509 scoped_refptr<VideoFrame> expected = GetCurrentFrame(); | |
|
acolwell GONE FROM CHROMIUM
2013/02/01 00:24:34
ditto here and below. This doesn't discriminate th
scherkus (not reviewing)
2013/02/01 22:45:25
Done.
| |
| 502 Preroll(0, PIPELINE_OK); | 510 Preroll(0, PIPELINE_OK); |
| 503 EXPECT_FALSE(GetCurrentFrame()); | 511 EXPECT_EQ(expected, GetCurrentFrame()); |
| 504 | 512 |
| 505 // Start playing, we should immediately get notified of end of stream. | 513 // Start playing, we should immediately get notified of end of stream. |
| 506 Play(); | 514 Play(); |
| 507 WaitForEnded(); | 515 WaitForEnded(); |
| 508 | 516 |
| 509 Shutdown(); | 517 Shutdown(); |
| 510 } | 518 } |
| 511 | 519 |
| 512 TEST_F(VideoRendererBaseTest, GetCurrentFrame_Shutdown) { | 520 TEST_F(VideoRendererBaseTest, GetCurrentFrame_Shutdown) { |
| 513 Initialize(); | 521 Initialize(); |
| 522 | |
| 523 // Frame shouldn't be updated. | |
| 524 scoped_refptr<VideoFrame> expected = GetCurrentFrame(); | |
| 514 Shutdown(); | 525 Shutdown(); |
| 515 EXPECT_FALSE(GetCurrentFrame()); | 526 EXPECT_EQ(expected, GetCurrentFrame()); |
| 516 } | 527 } |
| 517 | 528 |
| 518 // Stop() is called immediately during an error. | 529 // Stop() is called immediately during an error. |
| 519 TEST_F(VideoRendererBaseTest, GetCurrentFrame_Error) { | 530 TEST_F(VideoRendererBaseTest, GetCurrentFrame_Error) { |
| 520 Initialize(); | 531 Initialize(); |
| 532 | |
| 533 // Frame shouldn't be updated. | |
| 534 scoped_refptr<VideoFrame> expected = GetCurrentFrame(); | |
| 521 Stop(); | 535 Stop(); |
| 522 EXPECT_FALSE(GetCurrentFrame()); | 536 EXPECT_EQ(expected, GetCurrentFrame()); |
| 523 } | |
| 524 | |
| 525 // Verify that shutdown can only proceed after we return the current frame. | |
| 526 TEST_F(VideoRendererBaseTest, Shutdown_DuringPaint) { | |
|
scherkus (not reviewing)
2013/01/31 17:54:05
this test doesn't makes sense anymore because we p
| |
| 527 Initialize(); | |
| 528 Play(); | |
| 529 | |
| 530 // Grab the frame. | |
| 531 scoped_refptr<VideoFrame> frame; | |
| 532 renderer_->GetCurrentFrame(&frame); | |
| 533 EXPECT_TRUE(frame); | |
| 534 | |
| 535 Pause(); | |
| 536 | |
| 537 // Start flushing -- it won't complete until we return the frame. | |
| 538 WaitableMessageLoopEvent event; | |
| 539 renderer_->Flush(event.GetClosure()); | |
| 540 | |
| 541 // Return the frame and wait. | |
| 542 renderer_->PutCurrentFrame(frame); | |
| 543 event.RunAndWait(); | |
| 544 | |
| 545 Stop(); | |
| 546 } | 537 } |
| 547 | 538 |
| 548 // Verify that a late decoder response doesn't break invariants in the renderer. | 539 // Verify that a late decoder response doesn't break invariants in the renderer. |
| 549 TEST_F(VideoRendererBaseTest, StopDuringOutstandingRead) { | 540 TEST_F(VideoRendererBaseTest, StopDuringOutstandingRead) { |
| 550 Initialize(); | 541 Initialize(); |
| 551 Play(); | 542 Play(); |
| 552 | 543 |
| 553 // Advance time a bit to trigger a Read(). | 544 // Advance time a bit to trigger a Read(). |
| 554 AdvanceTimeInMs(kFrameDurationInMs); | 545 AdvanceTimeInMs(kFrameDurationInMs); |
| 555 WaitForPendingRead(); | 546 WaitForPendingRead(); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 609 InSequence s; | 600 InSequence s; |
| 610 | 601 |
| 611 EXPECT_CALL(*decoder_, Initialize(_, _, _)) | 602 EXPECT_CALL(*decoder_, Initialize(_, _, _)) |
| 612 .WillOnce(RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED)); | 603 .WillOnce(RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED)); |
| 613 InitializeRenderer(DECODER_ERROR_NOT_SUPPORTED); | 604 InitializeRenderer(DECODER_ERROR_NOT_SUPPORTED); |
| 614 | 605 |
| 615 Stop(); | 606 Stop(); |
| 616 } | 607 } |
| 617 | 608 |
| 618 } // namespace media | 609 } // namespace media |
| OLD | NEW |