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> | |
6 | |
7 #include "base/bind.h" | 5 #include "base/bind.h" |
8 #include "base/callback.h" | |
9 #include "base/callback_helpers.h" | |
10 #include "base/debug/stack_trace.h" | 6 #include "base/debug/stack_trace.h" |
11 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
12 #include "base/stl_util.h" | |
13 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
14 #include "base/strings/string_split.h" | 9 #include "base/strings/string_split.h" |
15 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
16 #include "base/synchronization/lock.h" | 11 #include "base/test/simple_test_tick_clock.h" |
17 #include "base/timer/timer.h" | |
18 #include "media/base/data_buffer.h" | |
19 #include "media/base/gmock_callback_support.h" | 12 #include "media/base/gmock_callback_support.h" |
20 #include "media/base/limits.h" | |
21 #include "media/base/mock_filters.h" | 13 #include "media/base/mock_filters.h" |
22 #include "media/base/test_helpers.h" | 14 #include "media/base/test_helpers.h" |
23 #include "media/base/video_frame.h" | 15 #include "media/filters/test_video_frame_scheduler.h" |
24 #include "media/filters/video_renderer_impl.h" | 16 #include "media/filters/video_renderer_impl.h" |
25 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
26 | 18 |
27 using ::testing::_; | 19 using ::testing::_; |
28 using ::testing::AnyNumber; | 20 using ::testing::AnyNumber; |
29 using ::testing::InSequence; | |
30 using ::testing::Invoke; | 21 using ::testing::Invoke; |
31 using ::testing::NiceMock; | 22 using ::testing::NiceMock; |
32 using ::testing::NotNull; | |
33 using ::testing::Return; | |
34 using ::testing::StrictMock; | |
35 | 23 |
36 namespace media { | 24 namespace media { |
37 | 25 |
38 MATCHER_P(HasTimestamp, ms, "") { | 26 static void AssignValue(bool* b, bool value) { |
39 *result_listener << "has timestamp " << arg->timestamp().InMilliseconds(); | 27 *b = value; |
40 return arg->timestamp().InMilliseconds() == ms; | |
41 } | 28 } |
42 | 29 |
43 // Arbitrary value. Has to be larger to cover any timestamp value used in tests. | |
44 static const int kVideoDurationInMs = 1000; | |
45 | |
46 class VideoRendererImplTest : public ::testing::Test { | 30 class VideoRendererImplTest : public ::testing::Test { |
47 public: | 31 public: |
48 VideoRendererImplTest() | 32 VideoRendererImplTest() |
49 : decoder_(new MockVideoDecoder()), | 33 : decoder_(new MockVideoDecoder()), |
50 demuxer_stream_(DemuxerStream::VIDEO) { | 34 scheduler_(new TestVideoFrameScheduler()), |
35 tick_clock_(new base::SimpleTestTickClock()), | |
36 demuxer_stream_(DemuxerStream::VIDEO), | |
37 max_time_(kNoTimestamp()), | |
38 decoded_frames_(0), | |
39 dropped_frames_(0), | |
40 ended_cb_run_(false) { | |
51 ScopedVector<VideoDecoder> decoders; | 41 ScopedVector<VideoDecoder> decoders; |
52 decoders.push_back(decoder_); | 42 decoders.push_back(decoder_); |
53 | 43 |
54 renderer_.reset( | 44 renderer_.reset( |
55 new VideoRendererImpl(message_loop_.message_loop_proxy(), | 45 new VideoRendererImpl(message_loop_.message_loop_proxy(), |
46 scoped_ptr<VideoFrameScheduler>(scheduler_), | |
56 decoders.Pass(), | 47 decoders.Pass(), |
57 media::SetDecryptorReadyCB(), | 48 media::SetDecryptorReadyCB())); |
58 base::Bind(&StrictMock<MockDisplayCB>::Display, | 49 renderer_->SetTickClockForTesting(scoped_ptr<base::TickClock>(tick_clock_)); |
59 base::Unretained(&mock_display_cb_)), | |
60 true)); | |
61 | 50 |
62 demuxer_stream_.set_video_decoder_config(TestVideoConfig::Normal()); | 51 demuxer_stream_.set_video_decoder_config(TestVideoConfig::Normal()); |
63 | 52 |
64 // We expect these to be called but we don't care how/when. | 53 // We expect these to be called but we don't care how/when. |
65 EXPECT_CALL(demuxer_stream_, Read(_)) | 54 EXPECT_CALL(demuxer_stream_, Read(_)) |
66 .WillRepeatedly(RunCallback<0>(DemuxerStream::kOk, | 55 .WillRepeatedly(RunCallback<0>(DemuxerStream::kOk, |
67 DecoderBuffer::CreateEOSBuffer())); | 56 DecoderBuffer::CreateEOSBuffer())); |
68 EXPECT_CALL(*decoder_, Stop()) | 57 EXPECT_CALL(*decoder_, Stop()) |
69 .WillRepeatedly(Invoke(this, &VideoRendererImplTest::StopRequested)); | 58 .WillRepeatedly(Invoke(this, &VideoRendererImplTest::StopRequested)); |
70 EXPECT_CALL(statistics_cb_object_, OnStatistics(_)) | |
71 .Times(AnyNumber()); | |
72 EXPECT_CALL(*this, OnTimeUpdate(_)) | |
73 .Times(AnyNumber()); | |
74 } | 59 } |
75 | 60 |
76 virtual ~VideoRendererImplTest() {} | 61 virtual ~VideoRendererImplTest() {} |
77 | 62 |
78 // Callbacks passed into Initialize(). | |
79 MOCK_METHOD1(OnTimeUpdate, void(base::TimeDelta)); | |
80 | |
81 void Initialize() { | 63 void Initialize() { |
82 // Monitor decodes from the decoder. | 64 // Monitor decodes from the decoder. |
83 EXPECT_CALL(*decoder_, Decode(_, _)) | 65 EXPECT_CALL(*decoder_, Decode(_, _)) |
84 .WillRepeatedly(Invoke(this, &VideoRendererImplTest::FrameRequested)); | 66 .WillRepeatedly(Invoke(this, &VideoRendererImplTest::FrameRequested)); |
85 | 67 |
86 EXPECT_CALL(*decoder_, Reset(_)) | 68 EXPECT_CALL(*decoder_, Reset(_)) |
87 .WillRepeatedly(Invoke(this, &VideoRendererImplTest::FlushRequested)); | 69 .WillRepeatedly(Invoke(this, &VideoRendererImplTest::FlushRequested)); |
88 | 70 |
89 InSequence s; | |
90 | |
91 EXPECT_CALL(*decoder_, Initialize(_, _)) | 71 EXPECT_CALL(*decoder_, Initialize(_, _)) |
92 .WillOnce(RunCallback<1>(PIPELINE_OK)); | 72 .WillOnce(RunCallback<1>(PIPELINE_OK)); |
93 | 73 |
94 // Set playback rate before anything else happens. | 74 // Set playback rate before anything else happens. |
95 renderer_->SetPlaybackRate(1.0f); | 75 renderer_->SetPlaybackRate(1.0f); |
96 | 76 |
97 // Initialize, we shouldn't have any reads. | 77 // Initialize, we shouldn't have any reads. |
98 InitializeRenderer(PIPELINE_OK); | 78 InitializeRenderer(PIPELINE_OK); |
99 } | 79 } |
100 | 80 |
101 void InitializeRenderer(PipelineStatus expected) { | 81 void InitializeRenderer(PipelineStatus expected) { |
102 SCOPED_TRACE(base::StringPrintf("InitializeRenderer(%d)", expected)); | 82 SCOPED_TRACE(base::StringPrintf("InitializeRenderer(%d)", expected)); |
103 WaitableMessageLoopEvent event; | 83 WaitableMessageLoopEvent event; |
104 CallInitialize(event.GetPipelineStatusCB()); | 84 CallInitialize(event.GetPipelineStatusCB()); |
105 event.RunAndWaitForStatus(expected); | 85 event.RunAndWaitForStatus(expected); |
106 } | 86 } |
107 | 87 |
108 void CallInitialize(const PipelineStatusCB& status_cb) { | 88 void CallInitialize(const PipelineStatusCB& status_cb) { |
109 renderer_->Initialize( | 89 renderer_->Initialize( |
110 &demuxer_stream_, | 90 &demuxer_stream_, |
111 status_cb, | 91 status_cb, |
112 base::Bind(&MockStatisticsCB::OnStatistics, | 92 base::Bind(&VideoRendererImplTest::OnStatisticsUpdate, |
113 base::Unretained(&statistics_cb_object_)), | |
114 base::Bind(&VideoRendererImplTest::OnTimeUpdate, | |
115 base::Unretained(this)), | 93 base::Unretained(this)), |
116 ended_event_.GetClosure(), | 94 base::Bind(&VideoRendererImplTest::OnMaxTimeUpdate, |
95 base::Unretained(this)), | |
96 base::Bind(&AssignValue, &ended_cb_run_, true), | |
117 error_event_.GetPipelineStatusCB(), | 97 error_event_.GetPipelineStatusCB(), |
118 base::Bind(&VideoRendererImplTest::GetTime, base::Unretained(this)), | 98 base::Bind(&VideoRendererImplTest::time, base::Unretained(this)), |
119 base::Bind(&VideoRendererImplTest::GetDuration, | 99 base::Bind(&VideoRendererImplTest::duration, base::Unretained(this))); |
120 base::Unretained(this))); | |
121 } | 100 } |
122 | 101 |
123 void Play() { | 102 void Play() { |
124 SCOPED_TRACE("Play()"); | 103 SCOPED_TRACE("Play()"); |
125 WaitableMessageLoopEvent event; | 104 WaitableMessageLoopEvent event; |
126 renderer_->Play(event.GetClosure()); | 105 renderer_->Play(event.GetClosure()); |
127 event.RunAndWait(); | 106 event.RunAndWait(); |
128 } | 107 } |
129 | 108 |
130 void Preroll(int timestamp_ms, PipelineStatus expected) { | 109 void Preroll(int timestamp_ms, PipelineStatus expected) { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
214 | 193 |
215 CHECK(false) << "Unrecognized decoder buffer token: " << tokens[i]; | 194 CHECK(false) << "Unrecognized decoder buffer token: " << tokens[i]; |
216 } | 195 } |
217 } | 196 } |
218 | 197 |
219 void WaitForError(PipelineStatus expected) { | 198 void WaitForError(PipelineStatus expected) { |
220 SCOPED_TRACE(base::StringPrintf("WaitForError(%d)", expected)); | 199 SCOPED_TRACE(base::StringPrintf("WaitForError(%d)", expected)); |
221 error_event_.RunAndWaitForStatus(expected); | 200 error_event_.RunAndWaitForStatus(expected); |
222 } | 201 } |
223 | 202 |
224 void WaitForEnded() { | |
225 SCOPED_TRACE("WaitForEnded()"); | |
226 ended_event_.RunAndWait(); | |
227 } | |
228 | |
229 void WaitForPendingRead() { | |
230 SCOPED_TRACE("WaitForPendingRead()"); | |
231 if (!read_cb_.is_null()) | |
232 return; | |
233 | |
234 DCHECK(wait_for_pending_read_cb_.is_null()); | |
235 | |
236 WaitableMessageLoopEvent event; | |
237 wait_for_pending_read_cb_ = event.GetClosure(); | |
238 event.RunAndWait(); | |
239 | |
240 DCHECK(!read_cb_.is_null()); | |
241 DCHECK(wait_for_pending_read_cb_.is_null()); | |
242 } | |
243 | |
244 void SatisfyPendingRead() { | 203 void SatisfyPendingRead() { |
245 CHECK(!read_cb_.is_null()); | 204 CHECK(!read_cb_.is_null()); |
246 CHECK(!decode_results_.empty()); | 205 CHECK(!decode_results_.empty()); |
247 | 206 |
248 base::Closure closure = base::Bind( | 207 base::Closure closure = base::Bind( |
249 read_cb_, decode_results_.front().first, | 208 read_cb_, decode_results_.front().first, |
250 decode_results_.front().second); | 209 decode_results_.front().second); |
251 | 210 |
252 read_cb_.Reset(); | 211 read_cb_.Reset(); |
253 decode_results_.pop_front(); | 212 decode_results_.pop_front(); |
254 | 213 |
255 message_loop_.PostTask(FROM_HERE, closure); | 214 message_loop_.PostTask(FROM_HERE, closure); |
256 } | 215 } |
257 | 216 |
258 void AdvanceTimeInMs(int time_ms) { | 217 bool pending_read() { return !read_cb_.is_null(); } |
259 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); | 218 base::TimeDelta time() { return time_; } |
260 base::AutoLock l(lock_); | 219 void set_time(base::TimeDelta time) { time_ = time; } |
261 time_ += base::TimeDelta::FromMilliseconds(time_ms); | 220 base::TimeDelta max_time() { return max_time_; } |
262 DCHECK_LE(time_.InMicroseconds(), GetDuration().InMicroseconds()); | 221 int decoded_frames() { return decoded_frames_; } |
222 int dropped_frames() { return dropped_frames_; } | |
223 bool ended_cb_run() { return ended_cb_run_; } | |
xhwang
2014/04/24 18:48:44
nit: make getters const?
scherkus (not reviewing)
2014/04/25 02:04:47
Done.
| |
224 | |
225 base::TimeDelta duration() { | |
226 // Arbitrary value. Has to be larger to cover any timestamp used in tests. | |
acolwell GONE FROM CHROMIUM
2014/04/24 16:43:59
nit: s/larger/large/?
scherkus (not reviewing)
2014/04/25 02:04:47
Done.
| |
227 return base::TimeDelta::FromMilliseconds(1000); | |
263 } | 228 } |
264 | 229 |
265 protected: | 230 protected: |
266 // Fixture members. | 231 base::MessageLoop message_loop_; |
232 | |
267 scoped_ptr<VideoRendererImpl> renderer_; | 233 scoped_ptr<VideoRendererImpl> renderer_; |
268 MockVideoDecoder* decoder_; // Owned by |renderer_|. | 234 MockVideoDecoder* decoder_; // Owned by |renderer_|. |
235 TestVideoFrameScheduler* scheduler_; // Owned by |renderer_|. | |
236 base::SimpleTestTickClock* tick_clock_; // Owned by |renderer_|. | |
xhwang
2014/04/24 18:48:44
nit: if you align the comments, why not also align
scherkus (not reviewing)
2014/04/25 02:04:47
Done.
(I think clang-format did this)
| |
269 NiceMock<MockDemuxerStream> demuxer_stream_; | 237 NiceMock<MockDemuxerStream> demuxer_stream_; |
270 MockStatisticsCB statistics_cb_object_; | |
271 | |
272 // Use StrictMock<T> to catch missing/extra display callbacks. | |
273 class MockDisplayCB { | |
274 public: | |
275 MOCK_METHOD1(Display, void(const scoped_refptr<VideoFrame>&)); | |
276 }; | |
277 StrictMock<MockDisplayCB> mock_display_cb_; | |
278 | 238 |
279 private: | 239 private: |
280 base::TimeDelta GetTime() { | |
281 base::AutoLock l(lock_); | |
282 return time_; | |
283 } | |
284 | |
285 base::TimeDelta GetDuration() { | |
286 return base::TimeDelta::FromMilliseconds(kVideoDurationInMs); | |
287 } | |
288 | |
289 void FrameRequested(const scoped_refptr<DecoderBuffer>& buffer, | 240 void FrameRequested(const scoped_refptr<DecoderBuffer>& buffer, |
290 const VideoDecoder::DecodeCB& read_cb) { | 241 const VideoDecoder::DecodeCB& read_cb) { |
291 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); | 242 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); |
292 CHECK(read_cb_.is_null()); | 243 CHECK(read_cb_.is_null()); |
293 read_cb_ = read_cb; | 244 read_cb_ = read_cb; |
294 | 245 |
295 // Wake up WaitForPendingRead() if needed. | |
296 if (!wait_for_pending_read_cb_.is_null()) | |
297 base::ResetAndReturn(&wait_for_pending_read_cb_).Run(); | |
298 | |
299 if (decode_results_.empty()) | 246 if (decode_results_.empty()) |
300 return; | 247 return; |
301 | 248 |
302 SatisfyPendingRead(); | 249 SatisfyPendingRead(); |
303 } | 250 } |
304 | 251 |
305 void FlushRequested(const base::Closure& callback) { | 252 void FlushRequested(const base::Closure& callback) { |
306 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); | 253 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); |
307 decode_results_.clear(); | 254 decode_results_.clear(); |
308 if (!read_cb_.is_null()) { | 255 if (!read_cb_.is_null()) { |
309 QueueFrames("abort"); | 256 QueueFrames("abort"); |
310 SatisfyPendingRead(); | 257 SatisfyPendingRead(); |
311 } | 258 } |
312 | 259 |
313 message_loop_.PostTask(FROM_HERE, callback); | 260 message_loop_.PostTask(FROM_HERE, callback); |
314 } | 261 } |
315 | 262 |
316 void StopRequested() { | 263 void StopRequested() { |
317 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); | 264 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); |
318 decode_results_.clear(); | 265 decode_results_.clear(); |
319 if (!read_cb_.is_null()) { | 266 if (!read_cb_.is_null()) { |
320 QueueFrames("abort"); | 267 QueueFrames("abort"); |
321 SatisfyPendingRead(); | 268 SatisfyPendingRead(); |
322 } | 269 } |
323 } | 270 } |
324 | 271 |
325 base::MessageLoop message_loop_; | 272 void OnMaxTimeUpdate(base::TimeDelta max_time) { max_time_ = max_time; } |
326 | 273 |
327 // Used to protect |time_|. | 274 void OnStatisticsUpdate(const PipelineStatistics& stats) { |
328 base::Lock lock_; | 275 decoded_frames_ = stats.video_frames_decoded; |
329 base::TimeDelta time_; | 276 dropped_frames_ = stats.video_frames_dropped; |
277 } | |
330 | 278 |
331 // Used for satisfying reads. | 279 // Used for satisfying reads. |
332 VideoDecoder::DecodeCB read_cb_; | 280 VideoDecoder::DecodeCB read_cb_; |
333 base::TimeDelta next_frame_timestamp_; | 281 base::TimeDelta next_frame_timestamp_; |
334 | 282 |
335 WaitableMessageLoopEvent error_event_; | 283 WaitableMessageLoopEvent error_event_; |
336 WaitableMessageLoopEvent ended_event_; | |
337 | |
338 // Run during FrameRequested() to unblock WaitForPendingRead(). | |
339 base::Closure wait_for_pending_read_cb_; | |
340 | 284 |
341 std::deque<std::pair< | 285 std::deque<std::pair< |
342 VideoDecoder::Status, scoped_refptr<VideoFrame> > > decode_results_; | 286 VideoDecoder::Status, scoped_refptr<VideoFrame> > > decode_results_; |
343 | 287 |
288 base::TimeDelta time_; | |
289 base::TimeDelta max_time_; | |
290 int decoded_frames_; | |
291 int dropped_frames_; | |
292 bool ended_cb_run_; | |
293 | |
344 DISALLOW_COPY_AND_ASSIGN(VideoRendererImplTest); | 294 DISALLOW_COPY_AND_ASSIGN(VideoRendererImplTest); |
345 }; | 295 }; |
346 | 296 |
347 TEST_F(VideoRendererImplTest, DoNothing) { | 297 TEST_F(VideoRendererImplTest, DoNothing) { |
348 // Test that creation and deletion doesn't depend on calls to Initialize() | 298 // Test that creation and deletion doesn't depend on calls to Initialize() |
349 // and/or Stop(). | 299 // and/or Stop(). |
350 } | 300 } |
351 | 301 |
352 TEST_F(VideoRendererImplTest, StopWithoutInitialize) { | 302 TEST_F(VideoRendererImplTest, StopWithoutInitialize) { |
353 Stop(); | 303 Stop(); |
354 } | 304 } |
355 | 305 |
356 TEST_F(VideoRendererImplTest, Initialize) { | 306 TEST_F(VideoRendererImplTest, Initialize) { |
357 Initialize(); | 307 Initialize(); |
358 Shutdown(); | 308 Shutdown(); |
359 } | 309 } |
360 | 310 |
361 TEST_F(VideoRendererImplTest, InitializeAndPreroll) { | |
362 Initialize(); | |
363 QueueFrames("0 10 20 30"); | |
364 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); | |
365 Preroll(0, PIPELINE_OK); | |
366 Shutdown(); | |
367 } | |
368 | |
369 static void ExpectNotCalled(PipelineStatus) { | 311 static void ExpectNotCalled(PipelineStatus) { |
370 base::debug::StackTrace stack; | 312 base::debug::StackTrace stack; |
371 ADD_FAILURE() << "Expected callback not to be called\n" << stack.ToString(); | 313 ADD_FAILURE() << "Expected callback not to be called\n" << stack.ToString(); |
372 } | 314 } |
373 | 315 |
374 TEST_F(VideoRendererImplTest, StopWhileInitializing) { | 316 TEST_F(VideoRendererImplTest, StopWhileInitializing) { |
375 EXPECT_CALL(*decoder_, Initialize(_, _)) | 317 EXPECT_CALL(*decoder_, Initialize(_, _)) |
376 .WillOnce(RunCallback<1>(PIPELINE_OK)); | 318 .WillOnce(RunCallback<1>(PIPELINE_OK)); |
377 CallInitialize(base::Bind(&ExpectNotCalled)); | 319 CallInitialize(base::Bind(&ExpectNotCalled)); |
378 Stop(); | 320 Stop(); |
379 | 321 |
380 // ~VideoRendererImpl() will CHECK() if we left anything initialized. | 322 // ~VideoRendererImpl() will CHECK() if we left anything initialized. |
381 } | 323 } |
382 | 324 |
383 TEST_F(VideoRendererImplTest, StopWhileFlushing) { | 325 TEST_F(VideoRendererImplTest, StopWhileFlushing) { |
384 Initialize(); | 326 Initialize(); |
385 Pause(); | 327 Pause(); |
386 renderer_->Flush(base::Bind(&ExpectNotCalled, PIPELINE_OK)); | 328 renderer_->Flush(base::Bind(&ExpectNotCalled, PIPELINE_OK)); |
387 Stop(); | 329 Stop(); |
388 | 330 |
389 // ~VideoRendererImpl() will CHECK() if we left anything initialized. | 331 // ~VideoRendererImpl() will CHECK() if we left anything initialized. |
390 } | 332 } |
391 | 333 |
392 TEST_F(VideoRendererImplTest, Play) { | 334 TEST_F(VideoRendererImplTest, PrerollSchedulesFirstFrame) { |
393 Initialize(); | 335 Initialize(); |
394 QueueFrames("0 10 20 30"); | 336 QueueFrames("0 10 20 30"); |
395 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); | 337 Preroll(0, PIPELINE_OK); |
396 Preroll(0, PIPELINE_OK); | 338 |
397 Play(); | 339 EXPECT_EQ(1u, scheduler_->scheduled_frames().size()); |
398 Shutdown(); | 340 EXPECT_EQ(base::TimeDelta(), |
399 } | 341 scheduler_->scheduled_frames().front().frame->timestamp()); |
400 | 342 EXPECT_EQ(base::TimeTicks(), |
xhwang
2014/04/24 18:48:44
Should base::TimeTicks() be tick_clock_->NowTicks(
scherkus (not reviewing)
2014/04/25 02:04:47
Replaced with string format.
| |
401 TEST_F(VideoRendererImplTest, EndOfStream_ClipDuration) { | 343 scheduler_->scheduled_frames().front().wall_ticks); |
402 Initialize(); | 344 |
403 QueueFrames("0 10 20 30"); | 345 Shutdown(); |
404 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); | 346 } |
405 Preroll(0, PIPELINE_OK); | 347 |
406 Play(); | 348 TEST_F(VideoRendererImplTest, PlaySchedulesAllFrames) { |
407 | 349 Initialize(); |
408 // Next frame has timestamp way past duration. Its timestamp will be adjusted | 350 QueueFrames("0 10 20 30"); |
351 Preroll(0, PIPELINE_OK); | |
352 Play(); | |
353 | |
354 EXPECT_EQ(4u, scheduler_->scheduled_frames().size()); | |
355 EXPECT_EQ(base::TimeDelta(), | |
356 scheduler_->scheduled_frames()[0].frame->timestamp()); | |
357 EXPECT_EQ(base::TimeTicks(), scheduler_->scheduled_frames()[0].wall_ticks); | |
acolwell GONE FROM CHROMIUM
2014/04/24 16:43:59
String format verification for these too? Either t
xhwang
2014/04/24 18:48:44
ditto about tick_clock_->NowTicks(). Agreed with a
scherkus (not reviewing)
2014/04/25 02:04:47
Done.
| |
358 EXPECT_EQ(base::TimeDelta::FromMilliseconds(10), | |
359 scheduler_->scheduled_frames()[1].frame->timestamp()); | |
360 EXPECT_EQ(base::TimeTicks::FromInternalValue(10000), | |
361 scheduler_->scheduled_frames()[1].wall_ticks); | |
362 EXPECT_EQ(base::TimeDelta::FromMilliseconds(20), | |
363 scheduler_->scheduled_frames()[2].frame->timestamp()); | |
364 EXPECT_EQ(base::TimeTicks::FromInternalValue(20000), | |
365 scheduler_->scheduled_frames()[2].wall_ticks); | |
366 EXPECT_EQ(base::TimeDelta::FromMilliseconds(30), | |
367 scheduler_->scheduled_frames()[3].frame->timestamp()); | |
368 EXPECT_EQ(base::TimeTicks::FromInternalValue(30000), | |
369 scheduler_->scheduled_frames()[3].wall_ticks); | |
370 | |
371 Shutdown(); | |
372 } | |
373 | |
374 TEST_F(VideoRendererImplTest, PauseResetsScheduledFrames) { | |
375 Initialize(); | |
376 QueueFrames("0 10 20 30"); | |
377 Preroll(0, PIPELINE_OK); | |
378 Play(); | |
379 Pause(); | |
380 | |
381 EXPECT_EQ(0u, scheduler_->scheduled_frames().size()); | |
xhwang
2014/04/24 18:48:44
Also check that "RESET" frames are pushed back to
scherkus (not reviewing)
2014/04/25 02:04:47
Isn't needed due to change in Reset() behaviour
| |
382 | |
383 Shutdown(); | |
384 } | |
385 | |
386 TEST_F(VideoRendererImplTest, PauseWaitsForResetFrames) { | |
387 Initialize(); | |
388 QueueFrames("0 10 20 30"); | |
389 Preroll(0, PIPELINE_OK); | |
390 Play(); | |
391 | |
392 scheduler_->set_should_reset(false); | |
acolwell GONE FROM CHROMIUM
2014/04/24 16:43:59
This is for simulating the proxy VFS case right? A
scherkus (not reviewing)
2014/04/25 02:04:47
Removed this test case due to change in Reset() be
| |
393 | |
394 bool pause_cb_run = false; | |
395 renderer_->Pause(base::Bind(&AssignValue, &pause_cb_run, true)); | |
396 EXPECT_FALSE(pause_cb_run); | |
397 | |
398 scheduler_->set_should_reset(true); | |
399 scheduler_->Reset(); | |
xhwang
2014/04/24 18:48:44
See comments above about calling scheduler_->Reset
scherkus (not reviewing)
2014/04/25 02:04:47
Ditto
| |
400 EXPECT_TRUE(pause_cb_run); | |
401 | |
402 Shutdown(); | |
403 } | |
404 | |
405 TEST_F(VideoRendererImplTest, SetPlaybackRateReschedulesFrames) { | |
406 Initialize(); | |
407 QueueFrames("0 10 20 30"); | |
408 Preroll(0, PIPELINE_OK); | |
409 Play(); | |
410 | |
411 renderer_->SetPlaybackRate(2.0); | |
412 | |
xhwang
2014/04/24 18:48:44
hmm, Reset() and SetPlaybackRate() all finishes sy
scherkus (not reviewing)
2014/04/25 02:04:47
actually this test started failing once I made Res
| |
413 // Wall times should be cut in half. | |
414 EXPECT_EQ(4u, scheduler_->scheduled_frames().size()); | |
acolwell GONE FROM CHROMIUM
2014/04/24 16:43:59
ditto. more concise expectations would be nice.
scherkus (not reviewing)
2014/04/25 02:04:47
Done.
| |
415 EXPECT_EQ(base::TimeTicks(), scheduler_->scheduled_frames()[0].wall_ticks); | |
xhwang
2014/04/24 18:48:44
So even the first frame is rescheduled because Res
scherkus (not reviewing)
2014/04/25 02:04:47
had to change this stuff
| |
416 EXPECT_EQ(base::TimeDelta::FromMilliseconds(10), | |
417 scheduler_->scheduled_frames()[1].frame->timestamp()); | |
418 EXPECT_EQ(base::TimeTicks::FromInternalValue(5000), | |
419 scheduler_->scheduled_frames()[1].wall_ticks); | |
420 EXPECT_EQ(base::TimeDelta::FromMilliseconds(20), | |
421 scheduler_->scheduled_frames()[2].frame->timestamp()); | |
422 EXPECT_EQ(base::TimeTicks::FromInternalValue(10000), | |
423 scheduler_->scheduled_frames()[2].wall_ticks); | |
424 EXPECT_EQ(base::TimeDelta::FromMilliseconds(30), | |
425 scheduler_->scheduled_frames()[3].frame->timestamp()); | |
426 EXPECT_EQ(base::TimeTicks::FromInternalValue(15000), | |
427 scheduler_->scheduled_frames()[3].wall_ticks); | |
428 | |
429 Shutdown(); | |
430 } | |
431 | |
432 TEST_F(VideoRendererImplTest, MediaTimeUsedToScheduleFrames) { | |
433 Initialize(); | |
434 QueueFrames("0 10 20 30"); | |
435 Preroll(0, PIPELINE_OK); | |
436 | |
437 // Introduce an offset in the media time before playing. | |
438 set_time(base::TimeDelta::FromMilliseconds(20)); | |
439 | |
440 Play(); | |
441 | |
442 // All newly scheduled frames should respect the media time. | |
443 EXPECT_EQ(4u, scheduler_->scheduled_frames().size()); | |
444 EXPECT_EQ(base::TimeTicks(), scheduler_->scheduled_frames()[0].wall_ticks); | |
xhwang
2014/04/24 18:48:44
So this is from the ScheduleFirstFrameForImmediate
scherkus (not reviewing)
2014/04/25 02:04:47
Done.
| |
445 EXPECT_EQ(base::TimeDelta::FromMilliseconds(10), | |
446 scheduler_->scheduled_frames()[1].frame->timestamp()); | |
447 EXPECT_EQ(base::TimeTicks::FromInternalValue(-10000), | |
448 scheduler_->scheduled_frames()[1].wall_ticks); | |
449 EXPECT_EQ(base::TimeDelta::FromMilliseconds(20), | |
450 scheduler_->scheduled_frames()[2].frame->timestamp()); | |
451 EXPECT_EQ(base::TimeTicks(), scheduler_->scheduled_frames()[2].wall_ticks); | |
xhwang
2014/04/24 18:48:44
This make it harder to read, I'd rather see base::
scherkus (not reviewing)
2014/04/25 02:04:47
Replaced with string format.
| |
452 EXPECT_EQ(base::TimeDelta::FromMilliseconds(30), | |
453 scheduler_->scheduled_frames()[3].frame->timestamp()); | |
454 EXPECT_EQ(base::TimeTicks::FromInternalValue(10000), | |
455 scheduler_->scheduled_frames()[3].wall_ticks); | |
456 | |
457 Shutdown(); | |
458 } | |
459 | |
460 TEST_F(VideoRendererImplTest, EndedWaitsForLastFrame) { | |
461 Initialize(); | |
462 QueueFrames("0 10 20 30 eos"); | |
463 Preroll(0, PIPELINE_OK); | |
464 Play(); | |
465 | |
466 // Display up to last frame. | |
467 scheduler_->DisplayFrames(base::TimeTicks::FromInternalValue(20000)); | |
xhwang
2014/04/24 18:48:44
Write a helper function DisplayFrames(ms) so that
scherkus (not reviewing)
2014/04/25 02:04:47
Done.
| |
468 message_loop_.RunUntilIdle(); | |
469 EXPECT_FALSE(ended_cb_run()); | |
470 | |
471 // Display last frame. | |
472 scheduler_->DisplayFrames(base::TimeTicks::FromInternalValue(30000)); | |
473 message_loop_.RunUntilIdle(); | |
474 EXPECT_TRUE(ended_cb_run()); | |
475 | |
476 Shutdown(); | |
477 } | |
478 | |
479 TEST_F(VideoRendererImplTest, EndedWaitsForEndOfStream) { | |
480 Initialize(); | |
481 QueueFrames("0 10 20 30"); | |
482 Preroll(0, PIPELINE_OK); | |
483 Play(); | |
484 | |
485 // Display last frame. | |
486 scheduler_->DisplayFrames(base::TimeTicks::FromInternalValue(30000)); | |
487 message_loop_.RunUntilIdle(); | |
488 EXPECT_FALSE(ended_cb_run()); | |
489 | |
490 // Deliver end of stream. | |
491 QueueFrames("eos"); | |
492 SatisfyPendingRead(); | |
493 message_loop_.RunUntilIdle(); | |
494 EXPECT_TRUE(ended_cb_run()); | |
495 | |
496 Shutdown(); | |
497 } | |
498 | |
499 TEST_F(VideoRendererImplTest, AdjustTimestampsPastDuration) { | |
500 Initialize(); | |
501 QueueFrames("0 10 20 30"); | |
502 Preroll(0, PIPELINE_OK); | |
503 Play(); | |
504 | |
505 // Last frame has timestamp way past duration. Its timestamp will be adjusted | |
409 // to match the duration of the video. | 506 // to match the duration of the video. |
410 QueueFrames(base::IntToString(kVideoDurationInMs + 1000)); | 507 QueueFrames(base::IntToString((duration() * 10).InMilliseconds())); |
411 | |
412 // Queue the end of stream frame and wait for the last frame to be rendered. | |
413 QueueFrames("eos"); | 508 QueueFrames("eos"); |
414 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(kVideoDurationInMs))); | 509 |
415 AdvanceTimeInMs(kVideoDurationInMs); | 510 scheduler_->DisplayFrames(base::TimeTicks::FromInternalValue(30000)); |
416 WaitForEnded(); | 511 message_loop_.RunUntilIdle(); |
417 | 512 |
418 Shutdown(); | 513 EXPECT_EQ(1u, scheduler_->scheduled_frames().size()); |
419 } | 514 EXPECT_EQ(duration(), |
515 scheduler_->scheduled_frames().front().frame->timestamp()); | |
516 | |
517 Shutdown(); | |
518 } | |
519 | |
520 TEST_F(VideoRendererImplTest, IncomingFramesUpdateMaxTime) { | |
521 EXPECT_EQ(kNoTimestamp(), max_time()); | |
522 | |
523 Initialize(); | |
524 QueueFrames("0 10 20 30"); | |
525 Preroll(0, PIPELINE_OK); | |
526 | |
527 EXPECT_EQ(base::TimeDelta::FromMilliseconds(30), max_time()); | |
528 | |
529 Shutdown(); | |
530 } | |
531 | |
532 TEST_F(VideoRendererImplTest, EndOfStreamSetsMaxTimeToDuration) { | |
533 EXPECT_EQ(kNoTimestamp(), max_time()); | |
534 | |
535 Initialize(); | |
536 QueueFrames("0 10 20 eos"); | |
537 Preroll(0, PIPELINE_OK); | |
538 | |
539 EXPECT_EQ(duration(), max_time()); | |
540 | |
541 Shutdown(); | |
542 } | |
543 | |
544 TEST_F(VideoRendererImplTest, DisplayedFramesIncrementStatistics) { | |
545 Initialize(); | |
546 QueueFrames("0 10 20 30"); | |
547 Preroll(0, PIPELINE_OK); | |
548 Play(); | |
549 | |
550 EXPECT_EQ(0, decoded_frames()); | |
551 EXPECT_EQ(0, dropped_frames()); | |
552 | |
553 scheduler_->DisplayFrames(base::TimeTicks()); | |
554 | |
555 EXPECT_EQ(1, decoded_frames()); | |
556 EXPECT_EQ(0, dropped_frames()); | |
557 | |
558 Shutdown(); | |
559 } | |
560 | |
561 TEST_F(VideoRendererImplTest, DroppedFramesIncrementStatistics) { | |
562 Initialize(); | |
563 QueueFrames("0 10 20 30"); | |
564 Preroll(0, PIPELINE_OK); | |
565 Play(); | |
566 | |
567 EXPECT_EQ(0, decoded_frames()); | |
568 EXPECT_EQ(0, dropped_frames()); | |
569 | |
570 scheduler_->DropFrames(base::TimeTicks()); | |
571 | |
572 EXPECT_EQ(1, decoded_frames()); | |
573 EXPECT_EQ(1, dropped_frames()); | |
574 | |
575 Shutdown(); | |
576 } | |
420 | 577 |
xhwang
2014/04/24 18:48:44
Also test that reset doesn't affect stats?
scherkus (not reviewing)
2014/04/25 02:04:47
Changed reset so it no longer calls back
| |
421 TEST_F(VideoRendererImplTest, DecodeError_Playing) { | 578 TEST_F(VideoRendererImplTest, DecodeError_Playing) { |
422 Initialize(); | 579 Initialize(); |
423 QueueFrames("0 10 20 30"); | 580 QueueFrames("0 10 20 30"); |
424 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); | |
425 Preroll(0, PIPELINE_OK); | 581 Preroll(0, PIPELINE_OK); |
426 Play(); | 582 Play(); |
427 | 583 |
584 scheduler_->DisplayFrames(base::TimeTicks::FromInternalValue(30000)); | |
585 EXPECT_TRUE(pending_read()); | |
586 | |
428 QueueFrames("error"); | 587 QueueFrames("error"); |
429 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(10))); | 588 SatisfyPendingRead(); |
430 AdvanceTimeInMs(10); | |
431 WaitForError(PIPELINE_ERROR_DECODE); | 589 WaitForError(PIPELINE_ERROR_DECODE); |
432 Shutdown(); | 590 Shutdown(); |
433 } | 591 } |
434 | 592 |
435 TEST_F(VideoRendererImplTest, DecodeError_DuringPreroll) { | 593 TEST_F(VideoRendererImplTest, DecodeError_DuringPreroll) { |
436 Initialize(); | 594 Initialize(); |
437 QueueFrames("error"); | 595 QueueFrames("error"); |
438 Preroll(0, PIPELINE_ERROR_DECODE); | 596 Preroll(0, PIPELINE_ERROR_DECODE); |
439 Shutdown(); | 597 Shutdown(); |
440 } | 598 } |
441 | 599 |
442 TEST_F(VideoRendererImplTest, Preroll_Exact) { | 600 TEST_F(VideoRendererImplTest, Preroll_Exact) { |
443 Initialize(); | 601 Initialize(); |
444 QueueFrames("50 60 70 80 90"); | 602 QueueFrames("50 60 70 80 90"); |
445 | |
446 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(60))); | |
447 Preroll(60, PIPELINE_OK); | 603 Preroll(60, PIPELINE_OK); |
604 EXPECT_EQ(base::TimeDelta::FromMilliseconds(60), | |
605 scheduler_->scheduled_frames().front().frame->timestamp()); | |
448 Shutdown(); | 606 Shutdown(); |
449 } | 607 } |
450 | 608 |
451 TEST_F(VideoRendererImplTest, Preroll_RightBefore) { | 609 TEST_F(VideoRendererImplTest, Preroll_RightBefore) { |
452 Initialize(); | 610 Initialize(); |
453 QueueFrames("50 60 70 80 90"); | 611 QueueFrames("50 60 70 80 90"); |
454 | |
455 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(50))); | |
456 Preroll(59, PIPELINE_OK); | 612 Preroll(59, PIPELINE_OK); |
613 EXPECT_EQ(base::TimeDelta::FromMilliseconds(50), | |
614 scheduler_->scheduled_frames().front().frame->timestamp()); | |
457 Shutdown(); | 615 Shutdown(); |
458 } | 616 } |
459 | 617 |
460 TEST_F(VideoRendererImplTest, Preroll_RightAfter) { | 618 TEST_F(VideoRendererImplTest, Preroll_RightAfter) { |
461 Initialize(); | 619 Initialize(); |
462 QueueFrames("50 60 70 80 90"); | 620 QueueFrames("50 60 70 80 90"); |
463 | |
464 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(60))); | |
465 Preroll(61, PIPELINE_OK); | 621 Preroll(61, PIPELINE_OK); |
622 EXPECT_EQ(base::TimeDelta::FromMilliseconds(60), | |
623 scheduler_->scheduled_frames().front().frame->timestamp()); | |
466 Shutdown(); | 624 Shutdown(); |
467 } | 625 } |
468 | 626 |
469 TEST_F(VideoRendererImplTest, PlayAfterPreroll) { | 627 TEST_F(VideoRendererImplTest, PlayAfterPreroll) { |
470 Initialize(); | 628 Initialize(); |
471 QueueFrames("0 10 20 30"); | 629 QueueFrames("0 10 20 30"); |
472 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); | |
473 Preroll(0, PIPELINE_OK); | 630 Preroll(0, PIPELINE_OK); |
474 Play(); | 631 Play(); |
475 | 632 |
476 // Advance time past prerolled time to trigger a Read(). | 633 scheduler_->DisplayFrames(base::TimeTicks()); |
477 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(10))); | 634 EXPECT_TRUE(pending_read()); |
478 AdvanceTimeInMs(10); | 635 |
479 WaitForPendingRead(); | |
480 Shutdown(); | 636 Shutdown(); |
481 } | 637 } |
482 | 638 |
483 TEST_F(VideoRendererImplTest, Rebuffer) { | 639 TEST_F(VideoRendererImplTest, Rebuffer) { |
484 Initialize(); | 640 Initialize(); |
485 QueueFrames("0 10 20 30"); | 641 QueueFrames("0 10 20 30"); |
486 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); | |
487 Preroll(0, PIPELINE_OK); | 642 Preroll(0, PIPELINE_OK); |
488 Play(); | 643 Play(); |
489 | 644 |
490 // Advance time past prerolled time drain the ready frame queue. | 645 // Display all frames to empty frame buffer. |
491 AdvanceTimeInMs(50); | 646 scheduler_->DisplayFrames(base::TimeTicks::FromInternalValue(30000)); |
492 WaitForPendingRead(); | 647 EXPECT_TRUE(pending_read()); |
493 | 648 |
494 // Simulate a Pause/Preroll/Play rebuffer sequence. | 649 // Simulate a Pause/Preroll/Play rebuffer sequence. |
495 Pause(); | 650 Pause(); |
496 | 651 |
497 WaitableMessageLoopEvent event; | 652 WaitableMessageLoopEvent event; |
498 renderer_->Preroll(kNoTimestamp(), | 653 renderer_->Preroll(kNoTimestamp(), |
499 event.GetPipelineStatusCB()); | 654 event.GetPipelineStatusCB()); |
500 | 655 |
501 // Queue enough frames to satisfy preroll. | 656 // Queue enough frames to satisfy preroll. |
502 QueueFrames("40 50 60 70"); | 657 QueueFrames("40 50 60 70"); |
503 SatisfyPendingRead(); | 658 SatisfyPendingRead(); |
659 event.RunAndWaitForStatus(PIPELINE_OK); | |
504 | 660 |
505 // TODO(scherkus): We shouldn't display the next ready frame in a rebuffer | 661 // TODO(scherkus): We shouldn't display the next ready frame in a rebuffer |
506 // situation, see http://crbug.com/365516 | 662 // situation, see http://crbug.com/365516 |
507 EXPECT_CALL(mock_display_cb_, Display(_)); | 663 EXPECT_EQ(1u, scheduler_->scheduled_frames().size()); |
508 | |
509 event.RunAndWaitForStatus(PIPELINE_OK); | |
510 | 664 |
511 Play(); | 665 Play(); |
512 | 666 |
513 Shutdown(); | 667 Shutdown(); |
514 } | 668 } |
515 | 669 |
516 TEST_F(VideoRendererImplTest, Rebuffer_AlreadyHaveEnoughFrames) { | 670 TEST_F(VideoRendererImplTest, Rebuffer_AlreadyHaveEnoughFrames) { |
517 Initialize(); | 671 Initialize(); |
518 QueueFrames("0 10 20 30"); | 672 QueueFrames("0 10 20 30"); |
519 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); | |
520 Preroll(0, PIPELINE_OK); | 673 Preroll(0, PIPELINE_OK); |
521 | |
522 // Queue an extra frame so that we'll have enough frames to satisfy | |
523 // preroll even after the first frame is painted. | |
524 QueueFrames("40"); | |
525 Play(); | 674 Play(); |
526 | 675 |
527 // Simulate a Pause/Preroll/Play rebuffer sequence. | 676 // Simulate a Pause/Preroll/Play rebuffer sequence. |
528 Pause(); | 677 Pause(); |
529 | 678 |
530 // TODO(scherkus): We shouldn't display the next ready frame in a rebuffer | |
531 // situation, see http://crbug.com/365516 | |
532 EXPECT_CALL(mock_display_cb_, Display(_)); | |
533 | |
534 WaitableMessageLoopEvent event; | 679 WaitableMessageLoopEvent event; |
535 renderer_->Preroll(kNoTimestamp(), | 680 renderer_->Preroll(kNoTimestamp(), |
536 event.GetPipelineStatusCB()); | 681 event.GetPipelineStatusCB()); |
682 event.RunAndWaitForStatus(PIPELINE_OK); | |
537 | 683 |
538 event.RunAndWaitForStatus(PIPELINE_OK); | 684 // TODO(scherkus): We shouldn't display the next ready frame in a rebuffer |
685 // situation, see http://crbug.com/365516 | |
686 EXPECT_EQ(1u, scheduler_->scheduled_frames().size()); | |
539 | 687 |
540 Play(); | 688 Play(); |
541 | 689 |
542 Shutdown(); | 690 Shutdown(); |
543 } | 691 } |
544 | 692 |
545 // Verify that a late decoder response doesn't break invariants in the renderer. | 693 // Verify that a late decoder response doesn't break invariants in the renderer. |
546 TEST_F(VideoRendererImplTest, StopDuringOutstandingRead) { | 694 TEST_F(VideoRendererImplTest, StopDuringOutstandingRead) { |
547 Initialize(); | 695 Initialize(); |
548 QueueFrames("0 10 20 30"); | 696 QueueFrames("0 10 20 30"); |
549 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); | |
550 Preroll(0, PIPELINE_OK); | 697 Preroll(0, PIPELINE_OK); |
551 Play(); | 698 Play(); |
552 | 699 |
553 // Advance time a bit to trigger a Read(). | 700 scheduler_->DisplayFrames(base::TimeTicks()); |
554 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(10))); | 701 EXPECT_TRUE(pending_read()); |
555 AdvanceTimeInMs(10); | |
556 WaitForPendingRead(); | |
557 | 702 |
558 WaitableMessageLoopEvent event; | 703 WaitableMessageLoopEvent event; |
559 renderer_->Stop(event.GetClosure()); | 704 renderer_->Stop(event.GetClosure()); |
560 event.RunAndWait(); | 705 event.RunAndWait(); |
561 } | 706 } |
562 | 707 |
563 TEST_F(VideoRendererImplTest, AbortPendingRead_Playing) { | 708 TEST_F(VideoRendererImplTest, AbortPendingRead_Playing) { |
564 Initialize(); | 709 Initialize(); |
565 QueueFrames("0 10 20 30"); | 710 QueueFrames("0 10 20 30"); |
566 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); | |
567 Preroll(0, PIPELINE_OK); | 711 Preroll(0, PIPELINE_OK); |
568 Play(); | 712 Play(); |
569 | 713 |
570 // Advance time a bit to trigger a Read(). | 714 scheduler_->DisplayFrames(base::TimeTicks()); |
571 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(10))); | 715 EXPECT_TRUE(pending_read()); |
572 AdvanceTimeInMs(10); | |
573 WaitForPendingRead(); | |
574 QueueFrames("abort"); | 716 QueueFrames("abort"); |
575 SatisfyPendingRead(); | 717 SatisfyPendingRead(); |
576 | 718 |
577 Pause(); | 719 Pause(); |
578 Flush(); | 720 Flush(); |
579 QueueFrames("60 70 80 90"); | 721 QueueFrames("60 70 80 90"); |
580 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(60))); | |
581 Preroll(60, PIPELINE_OK); | 722 Preroll(60, PIPELINE_OK); |
582 Shutdown(); | 723 Shutdown(); |
583 } | 724 } |
584 | 725 |
585 TEST_F(VideoRendererImplTest, AbortPendingRead_Flush) { | 726 TEST_F(VideoRendererImplTest, AbortPendingRead_Flush) { |
586 Initialize(); | 727 Initialize(); |
587 QueueFrames("0 10 20 30"); | 728 QueueFrames("0 10 20 30"); |
588 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); | |
589 Preroll(0, PIPELINE_OK); | 729 Preroll(0, PIPELINE_OK); |
590 Play(); | 730 Play(); |
591 | 731 |
592 // Advance time a bit to trigger a Read(). | 732 scheduler_->DisplayFrames(base::TimeTicks()); |
593 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(10))); | 733 EXPECT_TRUE(pending_read()); |
594 AdvanceTimeInMs(10); | |
595 WaitForPendingRead(); | |
596 | 734 |
597 Pause(); | 735 Pause(); |
598 Flush(); | 736 Flush(); |
599 Shutdown(); | 737 Shutdown(); |
600 } | 738 } |
601 | 739 |
602 TEST_F(VideoRendererImplTest, AbortPendingRead_Preroll) { | 740 TEST_F(VideoRendererImplTest, AbortPendingRead_Preroll) { |
603 Initialize(); | 741 Initialize(); |
604 QueueFrames("0 10 abort"); | 742 QueueFrames("0 10 abort"); |
605 EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); | |
606 Preroll(0, PIPELINE_OK); | 743 Preroll(0, PIPELINE_OK); |
607 Shutdown(); | 744 Shutdown(); |
608 } | 745 } |
609 | 746 |
610 TEST_F(VideoRendererImplTest, VideoDecoder_InitFailure) { | 747 TEST_F(VideoRendererImplTest, VideoDecoder_InitFailure) { |
611 InSequence s; | |
612 | |
613 EXPECT_CALL(*decoder_, Initialize(_, _)) | 748 EXPECT_CALL(*decoder_, Initialize(_, _)) |
614 .WillOnce(RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED)); | 749 .WillOnce(RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED)); |
615 InitializeRenderer(DECODER_ERROR_NOT_SUPPORTED); | 750 InitializeRenderer(DECODER_ERROR_NOT_SUPPORTED); |
616 | 751 |
617 Stop(); | 752 Stop(); |
618 } | 753 } |
619 | 754 |
620 } // namespace media | 755 } // namespace media |
OLD | NEW |