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 |