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 <stdint.h> | 5 #include <stdint.h> |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 | 44 |
45 namespace media { | 45 namespace media { |
46 | 46 |
47 MATCHER_P(HasTimestampMatcher, ms, "") { | 47 MATCHER_P(HasTimestampMatcher, ms, "") { |
48 *result_listener << "has timestamp " << arg->timestamp().InMilliseconds(); | 48 *result_listener << "has timestamp " << arg->timestamp().InMilliseconds(); |
49 return arg->timestamp().InMilliseconds() == ms; | 49 return arg->timestamp().InMilliseconds() == ms; |
50 } | 50 } |
51 | 51 |
52 class VideoRendererImplTest : public testing::Test { | 52 class VideoRendererImplTest : public testing::Test { |
53 public: | 53 public: |
| 54 ScopedVector<VideoDecoder> CreateVideoDecodersForTest() { |
| 55 decoder_ = new NiceMock<MockVideoDecoder>(); |
| 56 ScopedVector<VideoDecoder> decoders; |
| 57 decoders.push_back(decoder_); |
| 58 EXPECT_CALL(*decoder_, Initialize(_, _, _, _, _)) |
| 59 .WillOnce(DoAll(SaveArg<4>(&output_cb_), |
| 60 RunCallback<3>(expect_init_success_))); |
| 61 // Monitor decodes from the decoder. |
| 62 ON_CALL(*decoder_, Decode(_, _)) |
| 63 .WillByDefault(Invoke(this, &VideoRendererImplTest::DecodeRequested)); |
| 64 ON_CALL(*decoder_, Reset(_)) |
| 65 .WillByDefault(Invoke(this, &VideoRendererImplTest::FlushRequested)); |
| 66 return decoders; |
| 67 } |
| 68 |
54 VideoRendererImplTest() | 69 VideoRendererImplTest() |
55 : tick_clock_(new base::SimpleTestTickClock()), | 70 : tick_clock_(new base::SimpleTestTickClock()), |
56 decoder_(new NiceMock<MockVideoDecoder>()), | 71 decoder_(nullptr), |
57 demuxer_stream_(DemuxerStream::VIDEO) { | 72 demuxer_stream_(DemuxerStream::VIDEO) { |
58 ScopedVector<VideoDecoder> decoders; | |
59 decoders.push_back(decoder_); | |
60 | |
61 null_video_sink_.reset(new NullVideoSink( | 73 null_video_sink_.reset(new NullVideoSink( |
62 false, base::TimeDelta::FromSecondsD(1.0 / 60), | 74 false, base::TimeDelta::FromSecondsD(1.0 / 60), |
63 base::Bind(&MockCB::FrameReceived, base::Unretained(&mock_cb_)), | 75 base::Bind(&MockCB::FrameReceived, base::Unretained(&mock_cb_)), |
64 message_loop_.task_runner())); | 76 message_loop_.task_runner())); |
65 | 77 |
66 renderer_.reset(new VideoRendererImpl( | 78 renderer_.reset(new VideoRendererImpl( |
67 message_loop_.task_runner(), message_loop_.task_runner().get(), | 79 message_loop_.task_runner(), message_loop_.task_runner().get(), |
68 null_video_sink_.get(), std::move(decoders), true, | 80 null_video_sink_.get(), |
| 81 base::Bind(&VideoRendererImplTest::CreateVideoDecodersForTest, |
| 82 base::Unretained(this)), |
| 83 true, |
69 nullptr, // gpu_factories | 84 nullptr, // gpu_factories |
70 new MediaLog())); | 85 new MediaLog())); |
71 renderer_->SetTickClockForTesting( | 86 renderer_->SetTickClockForTesting( |
72 std::unique_ptr<base::TickClock>(tick_clock_)); | 87 std::unique_ptr<base::TickClock>(tick_clock_)); |
73 null_video_sink_->set_tick_clock_for_testing(tick_clock_); | 88 null_video_sink_->set_tick_clock_for_testing(tick_clock_); |
74 time_source_.set_tick_clock_for_testing(tick_clock_); | 89 time_source_.set_tick_clock_for_testing(tick_clock_); |
75 | 90 |
76 // Start wallclock time at a non-zero value. | 91 // Start wallclock time at a non-zero value. |
77 AdvanceWallclockTimeInMs(12345); | 92 AdvanceWallclockTimeInMs(12345); |
78 | 93 |
79 demuxer_stream_.set_video_decoder_config(TestVideoConfig::Normal()); | 94 demuxer_stream_.set_video_decoder_config(TestVideoConfig::Normal()); |
80 | 95 |
81 // We expect these to be called but we don't care how/when. | 96 // We expect these to be called but we don't care how/when. |
82 EXPECT_CALL(demuxer_stream_, Read(_)).WillRepeatedly( | 97 EXPECT_CALL(demuxer_stream_, Read(_)).WillRepeatedly( |
83 RunCallback<0>(DemuxerStream::kOk, | 98 RunCallback<0>(DemuxerStream::kOk, |
84 scoped_refptr<DecoderBuffer>(new DecoderBuffer(0)))); | 99 scoped_refptr<DecoderBuffer>(new DecoderBuffer(0)))); |
85 } | 100 } |
86 | 101 |
87 virtual ~VideoRendererImplTest() {} | 102 virtual ~VideoRendererImplTest() {} |
88 | 103 |
89 void Initialize() { | 104 void Initialize() { |
90 InitializeWithLowDelay(false); | 105 InitializeWithLowDelay(false); |
91 } | 106 } |
92 | 107 |
93 void InitializeWithLowDelay(bool low_delay) { | 108 void InitializeWithLowDelay(bool low_delay) { |
94 // Monitor decodes from the decoder. | |
95 ON_CALL(*decoder_, Decode(_, _)) | |
96 .WillByDefault(Invoke(this, &VideoRendererImplTest::DecodeRequested)); | |
97 ON_CALL(*decoder_, Reset(_)) | |
98 .WillByDefault(Invoke(this, &VideoRendererImplTest::FlushRequested)); | |
99 | |
100 // Initialize, we shouldn't have any reads. | 109 // Initialize, we shouldn't have any reads. |
101 InitializeRenderer(low_delay, true); | 110 InitializeRenderer(&demuxer_stream_, low_delay, true); |
102 } | 111 } |
103 | 112 |
104 void InitializeRenderer(bool low_delay, bool expect_success) { | 113 void InitializeRenderer(MockDemuxerStream* demuxer_stream, |
| 114 bool low_delay, |
| 115 bool expect_success) { |
105 SCOPED_TRACE(base::StringPrintf("InitializeRenderer(%d)", expect_success)); | 116 SCOPED_TRACE(base::StringPrintf("InitializeRenderer(%d)", expect_success)); |
| 117 expect_init_success_ = expect_success; |
106 WaitableMessageLoopEvent event; | 118 WaitableMessageLoopEvent event; |
107 CallInitialize(event.GetPipelineStatusCB(), low_delay, expect_success); | 119 CallInitialize(demuxer_stream, event.GetPipelineStatusCB(), low_delay, |
| 120 expect_success); |
108 event.RunAndWaitForStatus(expect_success ? PIPELINE_OK | 121 event.RunAndWaitForStatus(expect_success ? PIPELINE_OK |
109 : DECODER_ERROR_NOT_SUPPORTED); | 122 : DECODER_ERROR_NOT_SUPPORTED); |
110 } | 123 } |
111 | 124 |
112 void CallInitialize(const PipelineStatusCB& status_cb, | 125 void CallInitialize(MockDemuxerStream* demuxer_stream, |
| 126 const PipelineStatusCB& status_cb, |
113 bool low_delay, | 127 bool low_delay, |
114 bool expect_success) { | 128 bool expect_success) { |
115 if (low_delay) | 129 if (low_delay) |
116 demuxer_stream_.set_liveness(DemuxerStream::LIVENESS_LIVE); | 130 demuxer_stream->set_liveness(DemuxerStream::LIVENESS_LIVE); |
117 EXPECT_CALL(*decoder_, Initialize(_, _, _, _, _)) | |
118 .WillOnce( | |
119 DoAll(SaveArg<4>(&output_cb_), RunCallback<3>(expect_success))); | |
120 EXPECT_CALL(mock_cb_, OnWaitingForDecryptionKey()).Times(0); | 131 EXPECT_CALL(mock_cb_, OnWaitingForDecryptionKey()).Times(0); |
121 renderer_->Initialize(&demuxer_stream_, nullptr, &mock_cb_, | 132 renderer_->Initialize(demuxer_stream, nullptr, &mock_cb_, |
122 base::Bind(&WallClockTimeSource::GetWallClockTimes, | 133 base::Bind(&WallClockTimeSource::GetWallClockTimes, |
123 base::Unretained(&time_source_)), | 134 base::Unretained(&time_source_)), |
124 status_cb); | 135 status_cb); |
125 } | 136 } |
126 | 137 |
127 void StartPlayingFrom(int milliseconds) { | 138 void StartPlayingFrom(int milliseconds) { |
128 SCOPED_TRACE(base::StringPrintf("StartPlayingFrom(%d)", milliseconds)); | 139 SCOPED_TRACE(base::StringPrintf("StartPlayingFrom(%d)", milliseconds)); |
129 const base::TimeDelta media_time = | 140 const base::TimeDelta media_time = |
130 base::TimeDelta::FromMilliseconds(milliseconds); | 141 base::TimeDelta::FromMilliseconds(milliseconds); |
131 time_source_.SetMediaTime(media_time); | 142 time_source_.SetMediaTime(media_time); |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 Destroy(); | 436 Destroy(); |
426 } | 437 } |
427 | 438 |
428 protected: | 439 protected: |
429 // Fixture members. | 440 // Fixture members. |
430 std::unique_ptr<VideoRendererImpl> renderer_; | 441 std::unique_ptr<VideoRendererImpl> renderer_; |
431 base::SimpleTestTickClock* tick_clock_; // Owned by |renderer_|. | 442 base::SimpleTestTickClock* tick_clock_; // Owned by |renderer_|. |
432 NiceMock<MockVideoDecoder>* decoder_; // Owned by |renderer_|. | 443 NiceMock<MockVideoDecoder>* decoder_; // Owned by |renderer_|. |
433 NiceMock<MockDemuxerStream> demuxer_stream_; | 444 NiceMock<MockDemuxerStream> demuxer_stream_; |
434 | 445 |
| 446 bool expect_init_success_; |
| 447 |
435 // Use StrictMock<T> to catch missing/extra callbacks. | 448 // Use StrictMock<T> to catch missing/extra callbacks. |
436 class MockCB : public MockRendererClient { | 449 class MockCB : public MockRendererClient { |
437 public: | 450 public: |
438 MOCK_METHOD1(FrameReceived, void(const scoped_refptr<VideoFrame>&)); | 451 MOCK_METHOD1(FrameReceived, void(const scoped_refptr<VideoFrame>&)); |
439 }; | 452 }; |
440 StrictMock<MockCB> mock_cb_; | 453 StrictMock<MockCB> mock_cb_; |
441 | 454 |
442 // Must be destroyed before |renderer_| since they share |tick_clock_|. | 455 // Must be destroyed before |renderer_| since they share |tick_clock_|. |
443 std::unique_ptr<NullVideoSink> null_video_sink_; | 456 std::unique_ptr<NullVideoSink> null_video_sink_; |
444 | 457 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 EXPECT_CALL(mock_cb_, OnEnded()); | 543 EXPECT_CALL(mock_cb_, OnEnded()); |
531 SatisfyPendingDecodeWithEndOfStream(); | 544 SatisfyPendingDecodeWithEndOfStream(); |
532 event.RunAndWait(); | 545 event.RunAndWait(); |
533 } | 546 } |
534 // Firing a time state changed to true should be ignored... | 547 // Firing a time state changed to true should be ignored... |
535 renderer_->OnTimeProgressing(); | 548 renderer_->OnTimeProgressing(); |
536 EXPECT_FALSE(null_video_sink_->is_started()); | 549 EXPECT_FALSE(null_video_sink_->is_started()); |
537 Destroy(); | 550 Destroy(); |
538 } | 551 } |
539 | 552 |
| 553 TEST_F(VideoRendererImplTest, ReinitializeForAnotherStream) { |
| 554 Initialize(); |
| 555 StartPlayingFrom(0); |
| 556 Flush(); |
| 557 NiceMock<MockDemuxerStream> new_stream(DemuxerStream::VIDEO); |
| 558 new_stream.set_video_decoder_config(TestVideoConfig::Normal()); |
| 559 InitializeRenderer(&new_stream, false, true); |
| 560 } |
| 561 |
540 TEST_F(VideoRendererImplTest, DestroyWhileInitializing) { | 562 TEST_F(VideoRendererImplTest, DestroyWhileInitializing) { |
541 CallInitialize(NewExpectedStatusCB(PIPELINE_ERROR_ABORT), false, PIPELINE_OK); | 563 CallInitialize(&demuxer_stream_, NewExpectedStatusCB(PIPELINE_ERROR_ABORT), |
| 564 false, PIPELINE_OK); |
542 Destroy(); | 565 Destroy(); |
543 } | 566 } |
544 | 567 |
545 TEST_F(VideoRendererImplTest, DestroyWhileFlushing) { | 568 TEST_F(VideoRendererImplTest, DestroyWhileFlushing) { |
546 Initialize(); | 569 Initialize(); |
547 QueueFrames("0 10 20 30"); | 570 QueueFrames("0 10 20 30"); |
548 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0))); | 571 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0))); |
549 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); | 572 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
550 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber()); | 573 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber()); |
551 EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1); | 574 EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1); |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1); | 741 EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1); |
719 StartPlayingFrom(0); | 742 StartPlayingFrom(0); |
720 | 743 |
721 // Check that there is an outstanding Read() request. | 744 // Check that there is an outstanding Read() request. |
722 EXPECT_TRUE(IsReadPending()); | 745 EXPECT_TRUE(IsReadPending()); |
723 | 746 |
724 Destroy(); | 747 Destroy(); |
725 } | 748 } |
726 | 749 |
727 TEST_F(VideoRendererImplTest, VideoDecoder_InitFailure) { | 750 TEST_F(VideoRendererImplTest, VideoDecoder_InitFailure) { |
728 InitializeRenderer(false, false); | 751 InitializeRenderer(&demuxer_stream_, false, false); |
729 Destroy(); | 752 Destroy(); |
730 } | 753 } |
731 | 754 |
732 TEST_F(VideoRendererImplTest, Underflow) { | 755 TEST_F(VideoRendererImplTest, Underflow) { |
733 BasicUnderflowTest(UnderflowTestType::NORMAL); | 756 BasicUnderflowTest(UnderflowTestType::NORMAL); |
734 } | 757 } |
735 | 758 |
736 TEST_F(VideoRendererImplTest, Underflow_LowDelay) { | 759 TEST_F(VideoRendererImplTest, Underflow_LowDelay) { |
737 BasicUnderflowTest(UnderflowTestType::LOW_DELAY); | 760 BasicUnderflowTest(UnderflowTestType::LOW_DELAY); |
738 } | 761 } |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1185 QueueFrames("0 10 20 30"); | 1208 QueueFrames("0 10 20 30"); |
1186 StartPlayingFrom(0); | 1209 StartPlayingFrom(0); |
1187 Flush(); | 1210 Flush(); |
1188 ASSERT_EQ(1u, frame_ready_cbs_.size()); | 1211 ASSERT_EQ(1u, frame_ready_cbs_.size()); |
1189 // This frame will be discarded. | 1212 // This frame will be discarded. |
1190 frame_ready_cbs_.front().Run(); | 1213 frame_ready_cbs_.front().Run(); |
1191 Destroy(); | 1214 Destroy(); |
1192 } | 1215 } |
1193 | 1216 |
1194 } // namespace media | 1217 } // namespace media |
OLD | NEW |