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" |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
13 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
14 #include "base/synchronization/lock.h" | 14 #include "base/synchronization/lock.h" |
15 #include "base/timer/timer.h" | 15 #include "base/timer/timer.h" |
16 #include "media/base/data_buffer.h" | 16 #include "media/base/data_buffer.h" |
17 #include "media/base/gmock_callback_support.h" | 17 #include "media/base/gmock_callback_support.h" |
18 #include "media/base/limits.h" | 18 #include "media/base/limits.h" |
19 #include "media/base/mock_filters.h" | 19 #include "media/base/mock_filters.h" |
20 #include "media/base/test_helpers.h" | 20 #include "media/base/test_helpers.h" |
21 #include "media/base/video_frame.h" | 21 #include "media/base/video_frame.h" |
| 22 #include "media/filters/clockless_video_frame_scheduler.h" |
| 23 #include "media/filters/video_frame_scheduler_impl.h" |
22 #include "media/filters/video_renderer_impl.h" | 24 #include "media/filters/video_renderer_impl.h" |
23 #include "testing/gtest/include/gtest/gtest.h" | 25 #include "testing/gtest/include/gtest/gtest.h" |
24 | 26 |
25 using ::testing::_; | 27 using ::testing::_; |
26 using ::testing::AnyNumber; | 28 using ::testing::AnyNumber; |
27 using ::testing::InSequence; | 29 using ::testing::InSequence; |
28 using ::testing::Invoke; | 30 using ::testing::Invoke; |
29 using ::testing::NiceMock; | 31 using ::testing::NiceMock; |
30 using ::testing::NotNull; | 32 using ::testing::NotNull; |
31 using ::testing::Return; | 33 using ::testing::Return; |
32 using ::testing::StrictMock; | 34 using ::testing::StrictMock; |
33 | 35 |
34 namespace media { | 36 namespace media { |
35 | 37 |
36 static const int kFrameDurationInMs = 10; | 38 static const int kFrameDurationInMs = 10; |
37 static const int kVideoDurationInMs = kFrameDurationInMs * 100; | 39 static const int kVideoDurationInMs = kFrameDurationInMs * 100; |
38 | 40 |
39 class VideoRendererImplTest : public ::testing::Test { | 41 class VideoRendererImplTest : public ::testing::Test { |
40 public: | 42 public: |
41 VideoRendererImplTest() | 43 VideoRendererImplTest() |
42 : decoder_(new MockVideoDecoder()), | 44 : decoder_(new MockVideoDecoder()), |
43 demuxer_stream_(DemuxerStream::VIDEO) { | 45 demuxer_stream_(DemuxerStream::VIDEO) { |
44 ScopedVector<VideoDecoder> decoders; | 46 ScopedVector<VideoDecoder> decoders; |
45 decoders.push_back(decoder_); | 47 decoders.push_back(decoder_); |
46 | 48 |
47 renderer_.reset(new VideoRendererImpl( | 49 renderer_.reset(new VideoRendererImpl( |
48 message_loop_.message_loop_proxy(), | 50 message_loop_.message_loop_proxy(), |
| 51 scoped_ptr<VideoFrameScheduler>( |
| 52 #if 1 |
| 53 new ClocklessVideoFrameScheduler(base::Bind( |
| 54 &VideoRendererImplTest::OnPaint, base::Unretained(this)))), |
| 55 #else |
| 56 new VideoFrameSchedulerImpl( |
| 57 message_loop_.message_loop_proxy(), |
| 58 base::Bind(&VideoRendererImplTest::OnPaint, |
| 59 base::Unretained(this)))), |
| 60 #endif |
49 decoders.Pass(), | 61 decoders.Pass(), |
50 media::SetDecryptorReadyCB(), | 62 media::SetDecryptorReadyCB())); |
51 base::Bind(&VideoRendererImplTest::OnPaint, base::Unretained(this)), | |
52 true)); | |
53 | 63 |
54 demuxer_stream_.set_video_decoder_config(TestVideoConfig::Normal()); | 64 demuxer_stream_.set_video_decoder_config(TestVideoConfig::Normal()); |
55 | 65 |
56 // We expect these to be called but we don't care how/when. | 66 // We expect these to be called but we don't care how/when. |
57 EXPECT_CALL(demuxer_stream_, Read(_)) | 67 EXPECT_CALL(demuxer_stream_, Read(_)) |
58 .WillRepeatedly(RunCallback<0>(DemuxerStream::kOk, | 68 .WillRepeatedly(RunCallback<0>(DemuxerStream::kOk, |
59 DecoderBuffer::CreateEOSBuffer())); | 69 DecoderBuffer::CreateEOSBuffer())); |
60 EXPECT_CALL(*decoder_, Stop()) | 70 EXPECT_CALL(*decoder_, Stop()) |
61 .WillRepeatedly(Invoke(this, &VideoRendererImplTest::StopRequested)); | 71 .WillRepeatedly(Invoke(this, &VideoRendererImplTest::StopRequested)); |
62 EXPECT_CALL(statistics_cb_object_, OnStatistics(_)) | 72 EXPECT_CALL(statistics_cb_object_, OnStatistics(_)) |
(...skipping 19 matching lines...) Expand all Loading... |
82 .WillRepeatedly(Invoke(this, &VideoRendererImplTest::FrameRequested)); | 92 .WillRepeatedly(Invoke(this, &VideoRendererImplTest::FrameRequested)); |
83 | 93 |
84 EXPECT_CALL(*decoder_, Reset(_)) | 94 EXPECT_CALL(*decoder_, Reset(_)) |
85 .WillRepeatedly(Invoke(this, &VideoRendererImplTest::FlushRequested)); | 95 .WillRepeatedly(Invoke(this, &VideoRendererImplTest::FlushRequested)); |
86 | 96 |
87 InSequence s; | 97 InSequence s; |
88 | 98 |
89 EXPECT_CALL(*decoder_, Initialize(_, _)) | 99 EXPECT_CALL(*decoder_, Initialize(_, _)) |
90 .WillOnce(RunCallback<1>(PIPELINE_OK)); | 100 .WillOnce(RunCallback<1>(PIPELINE_OK)); |
91 | 101 |
92 // Set playback rate before anything else happens. | |
93 renderer_->SetPlaybackRate(1.0f); | |
94 | |
95 // Initialize, we shouldn't have any reads. | 102 // Initialize, we shouldn't have any reads. |
96 InitializeRenderer(PIPELINE_OK); | 103 InitializeRenderer(PIPELINE_OK); |
97 | 104 |
98 // Start prerolling. | 105 // Start prerolling. |
99 QueuePrerollFrames(0); | 106 QueuePrerollFrames(0); |
100 Preroll(0, PIPELINE_OK); | 107 Preroll(0, PIPELINE_OK); |
101 } | 108 } |
102 | 109 |
103 void InitializeRenderer(PipelineStatus expected) { | 110 void InitializeRenderer(PipelineStatus expected) { |
104 SCOPED_TRACE(base::StringPrintf("InitializeRenderer(%d)", expected)); | 111 SCOPED_TRACE(base::StringPrintf("InitializeRenderer(%d)", expected)); |
(...skipping 10 matching lines...) Expand all Loading... |
115 base::Unretained(&statistics_cb_object_)), | 122 base::Unretained(&statistics_cb_object_)), |
116 base::Bind(&VideoRendererImplTest::OnTimeUpdate, | 123 base::Bind(&VideoRendererImplTest::OnTimeUpdate, |
117 base::Unretained(this)), | 124 base::Unretained(this)), |
118 ended_event_.GetClosure(), | 125 ended_event_.GetClosure(), |
119 error_event_.GetPipelineStatusCB(), | 126 error_event_.GetPipelineStatusCB(), |
120 base::Bind(&VideoRendererImplTest::GetTime, base::Unretained(this)), | 127 base::Bind(&VideoRendererImplTest::GetTime, base::Unretained(this)), |
121 base::Bind(&VideoRendererImplTest::GetDuration, | 128 base::Bind(&VideoRendererImplTest::GetDuration, |
122 base::Unretained(this))); | 129 base::Unretained(this))); |
123 } | 130 } |
124 | 131 |
| 132 void SetPlaybackRate(float playback_rate) { |
| 133 SCOPED_TRACE(base::StringPrintf("SetPlaybackRate(%f)", playback_rate)); |
| 134 renderer_->SetPlaybackRate(playback_rate); |
| 135 } |
| 136 |
125 void Play() { | 137 void Play() { |
126 SCOPED_TRACE("Play()"); | 138 SCOPED_TRACE("Play()"); |
127 WaitableMessageLoopEvent event; | 139 WaitableMessageLoopEvent event; |
128 renderer_->Play(event.GetClosure()); | 140 renderer_->Play(event.GetClosure()); |
129 event.RunAndWait(); | 141 event.RunAndWait(); |
130 } | 142 } |
131 | 143 |
132 void Preroll(int timestamp_ms, PipelineStatus expected) { | 144 void Preroll(int timestamp_ms, PipelineStatus expected) { |
133 SCOPED_TRACE(base::StringPrintf("Preroll(%d, %d)", timestamp_ms, expected)); | 145 SCOPED_TRACE(base::StringPrintf("Preroll(%d, %d)", timestamp_ms, expected)); |
134 WaitableMessageLoopEvent event; | 146 WaitableMessageLoopEvent event; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 QueueNextFrame(); | 221 QueueNextFrame(); |
210 } | 222 } |
211 | 223 |
212 // Queue the frame at |timestamp| plus additional ones for prerolling. | 224 // Queue the frame at |timestamp| plus additional ones for prerolling. |
213 for (int i = 0; i < limits::kMaxVideoFrames; ++i) { | 225 for (int i = 0; i < limits::kMaxVideoFrames; ++i) { |
214 QueueNextFrame(); | 226 QueueNextFrame(); |
215 } | 227 } |
216 } | 228 } |
217 | 229 |
218 void ResetCurrentFrame() { | 230 void ResetCurrentFrame() { |
219 base::AutoLock l(lock_); | |
220 current_frame_ = NULL; | 231 current_frame_ = NULL; |
221 } | 232 } |
222 | 233 |
223 scoped_refptr<VideoFrame> GetCurrentFrame() { | 234 scoped_refptr<VideoFrame> GetCurrentFrame() { |
224 base::AutoLock l(lock_); | |
225 return current_frame_; | 235 return current_frame_; |
226 } | 236 } |
227 | 237 |
228 int GetCurrentTimestampInMs() { | 238 int GetCurrentTimestampInMs() { |
229 scoped_refptr<VideoFrame> frame = GetCurrentFrame(); | 239 scoped_refptr<VideoFrame> frame = GetCurrentFrame(); |
230 if (!frame.get()) | 240 if (!current_frame_) |
231 return -1; | 241 return -1; |
232 return frame->timestamp().InMilliseconds(); | 242 return current_frame_->timestamp().InMilliseconds(); |
233 } | 243 } |
234 | 244 |
235 void WaitForError(PipelineStatus expected) { | 245 void WaitForError(PipelineStatus expected) { |
236 SCOPED_TRACE(base::StringPrintf("WaitForError(%d)", expected)); | 246 SCOPED_TRACE(base::StringPrintf("WaitForError(%d)", expected)); |
237 error_event_.RunAndWaitForStatus(expected); | 247 error_event_.RunAndWaitForStatus(expected); |
238 } | 248 } |
239 | 249 |
240 void WaitForEnded() { | 250 void WaitForEnded() { |
241 SCOPED_TRACE("WaitForEnded()"); | 251 SCOPED_TRACE("WaitForEnded()"); |
242 ended_event_.RunAndWait(); | 252 ended_event_.RunAndWait(); |
(...skipping 18 matching lines...) Expand all Loading... |
261 CHECK(!read_cb_.is_null()); | 271 CHECK(!read_cb_.is_null()); |
262 CHECK(!decode_results_.empty()); | 272 CHECK(!decode_results_.empty()); |
263 | 273 |
264 base::Closure closure = base::Bind( | 274 base::Closure closure = base::Bind( |
265 read_cb_, decode_results_.front().first, | 275 read_cb_, decode_results_.front().first, |
266 decode_results_.front().second); | 276 decode_results_.front().second); |
267 | 277 |
268 read_cb_.Reset(); | 278 read_cb_.Reset(); |
269 decode_results_.pop_front(); | 279 decode_results_.pop_front(); |
270 | 280 |
| 281 LOG(ERROR) << __FUNCTION__; |
| 282 |
271 message_loop_.PostTask(FROM_HERE, closure); | 283 message_loop_.PostTask(FROM_HERE, closure); |
272 } | 284 } |
273 | 285 |
274 void AdvanceTimeInMs(int time_ms) { | 286 void AdvanceTimeInMs(int time_ms) { |
275 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); | 287 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); |
276 base::AutoLock l(lock_); | |
277 time_ += base::TimeDelta::FromMilliseconds(time_ms); | 288 time_ += base::TimeDelta::FromMilliseconds(time_ms); |
278 DCHECK_LE(time_.InMicroseconds(), duration_.InMicroseconds()); | 289 DCHECK_LE(time_.InMicroseconds(), duration_.InMicroseconds()); |
279 } | 290 } |
280 | 291 |
281 protected: | 292 protected: |
282 // Fixture members. | 293 // Fixture members. |
283 scoped_ptr<VideoRendererImpl> renderer_; | 294 scoped_ptr<VideoRendererImpl> renderer_; |
284 MockVideoDecoder* decoder_; // Owned by |renderer_|. | 295 MockVideoDecoder* decoder_; // Owned by |renderer_|. |
285 NiceMock<MockDemuxerStream> demuxer_stream_; | 296 NiceMock<MockDemuxerStream> demuxer_stream_; |
286 MockStatisticsCB statistics_cb_object_; | 297 MockStatisticsCB statistics_cb_object_; |
287 | 298 |
288 private: | 299 private: |
289 base::TimeDelta GetTime() { | 300 base::TimeDelta GetTime() { |
290 base::AutoLock l(lock_); | |
291 return time_; | 301 return time_; |
292 } | 302 } |
293 | 303 |
294 base::TimeDelta GetDuration() { | 304 base::TimeDelta GetDuration() { |
295 return duration_; | 305 return duration_; |
296 } | 306 } |
297 | 307 |
298 void OnPaint(const scoped_refptr<VideoFrame>& frame) { | 308 void OnPaint(const scoped_refptr<VideoFrame>& frame) { |
299 base::AutoLock l(lock_); | 309 LOG(ERROR) << __FUNCTION__ << " ts=" << frame->timestamp().InMicroseconds(); |
300 current_frame_ = frame; | 310 current_frame_ = frame; |
301 } | 311 } |
302 | 312 |
303 void FrameRequested(const scoped_refptr<DecoderBuffer>& buffer, | 313 void FrameRequested(const scoped_refptr<DecoderBuffer>& buffer, |
304 const VideoDecoder::DecodeCB& read_cb) { | 314 const VideoDecoder::DecodeCB& read_cb) { |
| 315 LOG(ERROR) << __FUNCTION__; |
305 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); | 316 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); |
306 CHECK(read_cb_.is_null()); | 317 CHECK(read_cb_.is_null()); |
307 read_cb_ = read_cb; | 318 read_cb_ = read_cb; |
308 | 319 |
309 // Wake up WaitForPendingRead() if needed. | 320 // Wake up WaitForPendingRead() if needed. |
310 if (!wait_for_pending_read_cb_.is_null()) | 321 if (!wait_for_pending_read_cb_.is_null()) |
311 base::ResetAndReturn(&wait_for_pending_read_cb_).Run(); | 322 base::ResetAndReturn(&wait_for_pending_read_cb_).Run(); |
312 | 323 |
313 if (decode_results_.empty()) | 324 if (decode_results_.empty()) |
314 return; | 325 return; |
(...skipping 16 matching lines...) Expand all Loading... |
331 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); | 342 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); |
332 decode_results_.clear(); | 343 decode_results_.clear(); |
333 if (!read_cb_.is_null()) { | 344 if (!read_cb_.is_null()) { |
334 QueueAbortedRead(); | 345 QueueAbortedRead(); |
335 SatisfyPendingRead(); | 346 SatisfyPendingRead(); |
336 } | 347 } |
337 } | 348 } |
338 | 349 |
339 base::MessageLoop message_loop_; | 350 base::MessageLoop message_loop_; |
340 | 351 |
341 // Used to protect |time_| and |current_frame_|. | |
342 base::Lock lock_; | |
343 base::TimeDelta time_; | 352 base::TimeDelta time_; |
344 scoped_refptr<VideoFrame> current_frame_; | 353 scoped_refptr<VideoFrame> current_frame_; |
345 | 354 |
346 // Used for satisfying reads. | 355 // Used for satisfying reads. |
347 VideoDecoder::DecodeCB read_cb_; | 356 VideoDecoder::DecodeCB read_cb_; |
348 base::TimeDelta next_frame_timestamp_; | 357 base::TimeDelta next_frame_timestamp_; |
349 base::TimeDelta duration_; | 358 base::TimeDelta duration_; |
350 | 359 |
351 WaitableMessageLoopEvent error_event_; | 360 WaitableMessageLoopEvent error_event_; |
352 WaitableMessageLoopEvent ended_event_; | 361 WaitableMessageLoopEvent ended_event_; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 } | 408 } |
400 | 409 |
401 TEST_F(VideoRendererImplTest, Play) { | 410 TEST_F(VideoRendererImplTest, Play) { |
402 Initialize(); | 411 Initialize(); |
403 Play(); | 412 Play(); |
404 Shutdown(); | 413 Shutdown(); |
405 } | 414 } |
406 | 415 |
407 TEST_F(VideoRendererImplTest, EndOfStream_DefaultFrameDuration) { | 416 TEST_F(VideoRendererImplTest, EndOfStream_DefaultFrameDuration) { |
408 Initialize(); | 417 Initialize(); |
| 418 SetPlaybackRate(1.0); // Can't reach end of stream with zero playback rate. |
409 Play(); | 419 Play(); |
410 | 420 |
411 // Verify that the ended callback fires when the default last frame duration | 421 // Verify that the ended callback fires when the default last frame duration |
412 // has elapsed. | 422 // has elapsed. |
413 int end_timestamp = kFrameDurationInMs * limits::kMaxVideoFrames + | 423 int end_timestamp = kFrameDurationInMs * limits::kMaxVideoFrames + |
414 VideoRendererImpl::kMaxLastFrameDuration().InMilliseconds(); | 424 VideoRendererImpl::kMaxLastFrameDuration().InMilliseconds(); |
415 EXPECT_LT(end_timestamp, kVideoDurationInMs); | 425 EXPECT_LT(end_timestamp, kVideoDurationInMs); |
416 | 426 |
417 QueueEndOfStream(); | 427 QueueEndOfStream(); |
418 AdvanceTimeInMs(end_timestamp); | 428 AdvanceTimeInMs(end_timestamp); |
419 WaitForEnded(); | 429 WaitForEnded(); |
420 | 430 |
421 Shutdown(); | 431 Shutdown(); |
422 } | 432 } |
423 | 433 |
424 TEST_F(VideoRendererImplTest, EndOfStream_ClipDuration) { | 434 TEST_F(VideoRendererImplTest, EndOfStream_ClipDuration) { |
425 int duration = kVideoDurationInMs + kFrameDurationInMs / 2; | 435 int duration = kVideoDurationInMs + kFrameDurationInMs / 2; |
426 InitializeWithDuration(duration); | 436 InitializeWithDuration(duration); |
| 437 SetPlaybackRate(1.0); // Can't reach end of stream with zero playback rate. |
427 Play(); | 438 Play(); |
428 | 439 |
429 // Render all frames except for the last |limits::kMaxVideoFrames| frames | 440 // Render all frames except for the last |limits::kMaxVideoFrames| frames |
430 // and deliver all the frames between the start and |duration|. The preroll | 441 // and deliver all the frames between the start and |duration|. The preroll |
431 // inside Initialize() makes this a little confusing, but |timestamp| is | 442 // inside Initialize() makes this a little confusing, but |timestamp| is |
432 // the current render time and QueueNextFrame() delivers a frame with a | 443 // the current render time and QueueNextFrame() delivers a frame with a |
433 // timestamp that is |timestamp| + limits::kMaxVideoFrames * | 444 // timestamp that is |timestamp| + limits::kMaxVideoFrames * |
434 // kFrameDurationInMs. | 445 // kFrameDurationInMs. |
435 int timestamp = kFrameDurationInMs; | 446 int timestamp = kFrameDurationInMs; |
436 int end_timestamp = duration - limits::kMaxVideoFrames * kFrameDurationInMs; | 447 int end_timestamp = duration - limits::kMaxVideoFrames * kFrameDurationInMs; |
437 for (; timestamp < end_timestamp; timestamp += kFrameDurationInMs) { | 448 for (; timestamp < end_timestamp; timestamp += kFrameDurationInMs) { |
438 QueueNextFrame(); | 449 QueueNextFrame(); |
439 } | 450 } |
440 | 451 |
441 // Queue the end of stream frame and wait for the last frame to be rendered. | 452 // Queue the end of stream frame and wait for the last frame to be rendered. |
442 QueueEndOfStream(); | 453 QueueEndOfStream(); |
| 454 SatisfyPendingRead(); |
443 AdvanceTimeInMs(duration); | 455 AdvanceTimeInMs(duration); |
444 WaitForEnded(); | 456 WaitForEnded(); |
445 | 457 |
446 Shutdown(); | 458 Shutdown(); |
447 } | 459 } |
448 | 460 |
449 TEST_F(VideoRendererImplTest, DecodeError_Playing) { | 461 TEST_F(VideoRendererImplTest, DecodeError_Playing) { |
450 Initialize(); | 462 Initialize(); |
| 463 SetPlaybackRate(1.0); |
451 Play(); | 464 Play(); |
452 | 465 |
453 QueueDecodeError(); | 466 QueueDecodeError(); |
454 AdvanceTimeInMs(kVideoDurationInMs); | 467 SatisfyPendingRead(); |
| 468 // AdvanceTimeInMs(kVideoDurationInMs); |
455 WaitForError(PIPELINE_ERROR_DECODE); | 469 WaitForError(PIPELINE_ERROR_DECODE); |
456 Shutdown(); | 470 Shutdown(); |
457 } | 471 } |
458 | 472 |
459 TEST_F(VideoRendererImplTest, DecodeError_DuringPreroll) { | 473 TEST_F(VideoRendererImplTest, DecodeError_DuringPreroll) { |
460 Initialize(); | 474 Initialize(); |
461 Pause(); | 475 Pause(); |
462 Flush(); | 476 Flush(); |
463 | 477 |
464 QueueDecodeError(); | 478 QueueDecodeError(); |
(...skipping 29 matching lines...) Expand all Loading... |
494 Flush(); | 508 Flush(); |
495 QueuePrerollFrames(kFrameDurationInMs * 6); | 509 QueuePrerollFrames(kFrameDurationInMs * 6); |
496 | 510 |
497 Preroll(kFrameDurationInMs * 6 + 1, PIPELINE_OK); | 511 Preroll(kFrameDurationInMs * 6 + 1, PIPELINE_OK); |
498 EXPECT_EQ(kFrameDurationInMs * 6, GetCurrentTimestampInMs()); | 512 EXPECT_EQ(kFrameDurationInMs * 6, GetCurrentTimestampInMs()); |
499 Shutdown(); | 513 Shutdown(); |
500 } | 514 } |
501 | 515 |
502 TEST_F(VideoRendererImplTest, PlayAfterPreroll) { | 516 TEST_F(VideoRendererImplTest, PlayAfterPreroll) { |
503 Initialize(); | 517 Initialize(); |
| 518 SetPlaybackRate(1.0); |
504 Pause(); | 519 Pause(); |
505 Flush(); | 520 Flush(); |
506 QueuePrerollFrames(kFrameDurationInMs * 4); | 521 QueuePrerollFrames(kFrameDurationInMs * 4); |
507 | 522 |
508 Preroll(kFrameDurationInMs * 4, PIPELINE_OK); | 523 Preroll(kFrameDurationInMs * 4, PIPELINE_OK); |
509 EXPECT_EQ(kFrameDurationInMs * 4, GetCurrentTimestampInMs()); | 524 EXPECT_EQ(kFrameDurationInMs * 4, GetCurrentTimestampInMs()); |
510 | 525 |
511 Play(); | 526 Play(); |
512 // Advance time past prerolled time to trigger a Read(). | 527 // Advance time past prerolled time to trigger a Read(). |
513 AdvanceTimeInMs(5 * kFrameDurationInMs); | 528 AdvanceTimeInMs(5 * kFrameDurationInMs); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 // preroll even after the first frame is painted. | 566 // preroll even after the first frame is painted. |
552 QueueNextFrame(); | 567 QueueNextFrame(); |
553 Play(); | 568 Play(); |
554 | 569 |
555 // Simulate a Pause/Preroll/Play rebuffer sequence. | 570 // Simulate a Pause/Preroll/Play rebuffer sequence. |
556 Pause(); | 571 Pause(); |
557 | 572 |
558 WaitableMessageLoopEvent event; | 573 WaitableMessageLoopEvent event; |
559 renderer_->Preroll(kNoTimestamp(), | 574 renderer_->Preroll(kNoTimestamp(), |
560 event.GetPipelineStatusCB()); | 575 event.GetPipelineStatusCB()); |
561 | 576 SatisfyPendingRead(); |
562 event.RunAndWaitForStatus(PIPELINE_OK); | 577 event.RunAndWaitForStatus(PIPELINE_OK); |
563 | 578 |
564 Play(); | 579 Play(); |
565 | 580 |
566 Shutdown(); | 581 Shutdown(); |
567 } | 582 } |
568 | 583 |
569 TEST_F(VideoRendererImplTest, GetCurrentFrame_Initialized) { | 584 TEST_F(VideoRendererImplTest, GetCurrentFrame_Initialized) { |
570 Initialize(); | 585 Initialize(); |
571 EXPECT_TRUE(GetCurrentFrame().get()); // Due to prerolling. | 586 EXPECT_TRUE(GetCurrentFrame().get()); // Due to prerolling. |
(...skipping 23 matching lines...) Expand all Loading... |
595 // Frame shouldn't be updated. | 610 // Frame shouldn't be updated. |
596 ResetCurrentFrame(); | 611 ResetCurrentFrame(); |
597 Flush(); | 612 Flush(); |
598 EXPECT_FALSE(GetCurrentFrame().get()); | 613 EXPECT_FALSE(GetCurrentFrame().get()); |
599 | 614 |
600 Shutdown(); | 615 Shutdown(); |
601 } | 616 } |
602 | 617 |
603 TEST_F(VideoRendererImplTest, GetCurrentFrame_EndOfStream) { | 618 TEST_F(VideoRendererImplTest, GetCurrentFrame_EndOfStream) { |
604 Initialize(); | 619 Initialize(); |
| 620 SetPlaybackRate(1.0); // Can't reach end of stream with zero playback rate. |
605 Play(); | 621 Play(); |
606 Pause(); | 622 Pause(); |
607 Flush(); | 623 Flush(); |
608 | 624 |
609 // Preroll only end of stream frames. | 625 // Preroll only end of stream frames. |
610 QueueEndOfStream(); | 626 QueueEndOfStream(); |
611 | 627 |
612 // Frame shouldn't be updated. | 628 // Frame shouldn't be updated. |
613 ResetCurrentFrame(); | 629 ResetCurrentFrame(); |
614 Preroll(0, PIPELINE_OK); | 630 Preroll(0, PIPELINE_OK); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 InSequence s; | 717 InSequence s; |
702 | 718 |
703 EXPECT_CALL(*decoder_, Initialize(_, _)) | 719 EXPECT_CALL(*decoder_, Initialize(_, _)) |
704 .WillOnce(RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED)); | 720 .WillOnce(RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED)); |
705 InitializeRenderer(DECODER_ERROR_NOT_SUPPORTED); | 721 InitializeRenderer(DECODER_ERROR_NOT_SUPPORTED); |
706 | 722 |
707 Stop(); | 723 Stop(); |
708 } | 724 } |
709 | 725 |
710 } // namespace media | 726 } // namespace media |
OLD | NEW |