Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(467)

Side by Side Diff: media/renderers/video_renderer_impl_unittest.cc

Issue 1955843002: Move Renderer permanent callbacks into RendererClient interface. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: updates media::Renderer subclasses Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
44 44
45 ACTION_P(RunClosure, closure) { 45 ACTION_P(RunClosure, closure) {
46 closure.Run(); 46 closure.Run();
47 } 47 }
48 48
49 MATCHER_P(HasTimestamp, ms, "") { 49 MATCHER_P(HasTimestamp, ms, "") {
50 *result_listener << "has timestamp " << arg->timestamp().InMilliseconds(); 50 *result_listener << "has timestamp " << arg->timestamp().InMilliseconds();
51 return arg->timestamp().InMilliseconds() == ms; 51 return arg->timestamp().InMilliseconds() == ms;
52 } 52 }
53 53
54 class VideoRendererImplTest 54 class VideoRendererImplTest : public testing::Test {
55 : public testing::Test {
56 public: 55 public:
57 VideoRendererImplTest() 56 VideoRendererImplTest()
58 : tick_clock_(new base::SimpleTestTickClock()), 57 : tick_clock_(new base::SimpleTestTickClock()),
59 decoder_(new NiceMock<MockVideoDecoder>()), 58 decoder_(new NiceMock<MockVideoDecoder>()),
60 demuxer_stream_(DemuxerStream::VIDEO) { 59 demuxer_stream_(DemuxerStream::VIDEO) {
61 ScopedVector<VideoDecoder> decoders; 60 ScopedVector<VideoDecoder> decoders;
62 decoders.push_back(decoder_); 61 decoders.push_back(decoder_);
63 62
64 null_video_sink_.reset(new NullVideoSink( 63 null_video_sink_.reset(new NullVideoSink(
65 false, base::TimeDelta::FromSecondsD(1.0 / 60), 64 false, base::TimeDelta::FromSecondsD(1.0 / 60),
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 } 112 }
114 113
115 void CallInitialize(const PipelineStatusCB& status_cb, 114 void CallInitialize(const PipelineStatusCB& status_cb,
116 bool low_delay, 115 bool low_delay,
117 bool expect_success) { 116 bool expect_success) {
118 if (low_delay) 117 if (low_delay)
119 demuxer_stream_.set_liveness(DemuxerStream::LIVENESS_LIVE); 118 demuxer_stream_.set_liveness(DemuxerStream::LIVENESS_LIVE);
120 EXPECT_CALL(*decoder_, Initialize(_, _, _, _, _)) 119 EXPECT_CALL(*decoder_, Initialize(_, _, _, _, _))
121 .WillOnce( 120 .WillOnce(
122 DoAll(SaveArg<4>(&output_cb_), RunCallback<3>(expect_success))); 121 DoAll(SaveArg<4>(&output_cb_), RunCallback<3>(expect_success)));
123 EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0); 122 EXPECT_CALL(mock_cb_, OnWaitingForDecryptionKey()).Times(0);
124 renderer_->Initialize( 123 renderer_->Initialize(&demuxer_stream_, nullptr, &mock_cb_,
125 &demuxer_stream_, status_cb, nullptr, 124 base::Bind(&WallClockTimeSource::GetWallClockTimes,
126 base::Bind(&VideoRendererImplTest::OnStatisticsUpdate, 125 base::Unretained(&time_source_)),
127 base::Unretained(this)), 126 status_cb);
128 base::Bind(&StrictMock<MockCB>::BufferingStateChange,
129 base::Unretained(&mock_cb_)),
130 ended_event_.GetClosure(), error_event_.GetPipelineStatusCB(),
131 base::Bind(&WallClockTimeSource::GetWallClockTimes,
132 base::Unretained(&time_source_)),
133 base::Bind(&VideoRendererImplTest::OnWaitingForDecryptionKey,
134 base::Unretained(this)));
135 } 127 }
136 128
137 void StartPlayingFrom(int milliseconds) { 129 void StartPlayingFrom(int milliseconds) {
138 SCOPED_TRACE(base::StringPrintf("StartPlayingFrom(%d)", milliseconds)); 130 SCOPED_TRACE(base::StringPrintf("StartPlayingFrom(%d)", milliseconds));
139 const base::TimeDelta media_time = 131 const base::TimeDelta media_time =
140 base::TimeDelta::FromMilliseconds(milliseconds); 132 base::TimeDelta::FromMilliseconds(milliseconds);
141 time_source_.SetMediaTime(media_time); 133 time_source_.SetMediaTime(media_time);
142 renderer_->StartPlayingFrom(media_time); 134 renderer_->StartPlayingFrom(media_time);
143 message_loop_.RunUntilIdle(); 135 message_loop_.RunUntilIdle();
144 } 136 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 CHECK(false) << "Unrecognized decoder buffer token: " << token; 190 CHECK(false) << "Unrecognized decoder buffer token: " << token;
199 } 191 }
200 } 192 }
201 193
202 bool IsReadPending() { 194 bool IsReadPending() {
203 return !decode_cb_.is_null(); 195 return !decode_cb_.is_null();
204 } 196 }
205 197
206 void WaitForError(PipelineStatus expected) { 198 void WaitForError(PipelineStatus expected) {
207 SCOPED_TRACE(base::StringPrintf("WaitForError(%d)", expected)); 199 SCOPED_TRACE(base::StringPrintf("WaitForError(%d)", expected));
208 error_event_.RunAndWaitForStatus(expected); 200
201 WaitableMessageLoopEvent event;
202 PipelineStatusCB error_cb = event.GetPipelineStatusCB();
203 EXPECT_CALL(mock_cb_, OnError(_))
204 .WillOnce(Invoke(&error_cb, &PipelineStatusCB::Run));
205 event.RunAndWaitForStatus(expected);
209 } 206 }
210 207
211 void WaitForEnded() { 208 void WaitForEnded() {
212 SCOPED_TRACE("WaitForEnded()"); 209 SCOPED_TRACE("WaitForEnded()");
213 ended_event_.RunAndWait(); 210
211 WaitableMessageLoopEvent event;
212 EXPECT_CALL(mock_cb_, OnEnded()).WillOnce(RunClosure(event.GetClosure()));
213 event.RunAndWait();
214 } 214 }
215 215
216 void WaitForPendingRead() { 216 void WaitForPendingRead() {
217 SCOPED_TRACE("WaitForPendingRead()"); 217 SCOPED_TRACE("WaitForPendingRead()");
218 if (!decode_cb_.is_null()) 218 if (!decode_cb_.is_null())
219 return; 219 return;
220 220
221 DCHECK(wait_for_pending_decode_cb_.is_null()); 221 DCHECK(wait_for_pending_decode_cb_.is_null());
222 222
223 WaitableMessageLoopEvent event; 223 WaitableMessageLoopEvent event;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 270
271 void AdvanceTimeInMs(int time_ms) { 271 void AdvanceTimeInMs(int time_ms) {
272 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); 272 DCHECK_EQ(&message_loop_, base::MessageLoop::current());
273 base::AutoLock l(lock_); 273 base::AutoLock l(lock_);
274 time_ += base::TimeDelta::FromMilliseconds(time_ms); 274 time_ += base::TimeDelta::FromMilliseconds(time_ms);
275 time_source_.StopTicking(); 275 time_source_.StopTicking();
276 time_source_.SetMediaTime(time_); 276 time_source_.SetMediaTime(time_);
277 time_source_.StartTicking(); 277 time_source_.StartTicking();
278 } 278 }
279 279
280 bool has_ended() const {
281 return ended_event_.is_signaled();
282 }
283
284 enum class UnderflowTestType { 280 enum class UnderflowTestType {
285 NORMAL, 281 NORMAL,
286 LOW_DELAY, 282 LOW_DELAY,
287 CANT_READ_WITHOUT_STALLING 283 CANT_READ_WITHOUT_STALLING
288 }; 284 };
289 void BasicUnderflowTest(UnderflowTestType type) { 285 void BasicUnderflowTest(UnderflowTestType type) {
290 InitializeWithLowDelay(type == UnderflowTestType::LOW_DELAY); 286 InitializeWithLowDelay(type == UnderflowTestType::LOW_DELAY);
291 if (type == UnderflowTestType::CANT_READ_WITHOUT_STALLING) 287 if (type == UnderflowTestType::CANT_READ_WITHOUT_STALLING)
292 ON_CALL(*decoder_, CanReadWithoutStalling()).WillByDefault(Return(false)); 288 ON_CALL(*decoder_, CanReadWithoutStalling()).WillByDefault(Return(false));
293 289
294 QueueFrames("0 30 60 90"); 290 QueueFrames("0 30 60 90");
295 291
296 { 292 {
297 WaitableMessageLoopEvent event; 293 WaitableMessageLoopEvent event;
298 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); 294 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0)));
299 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)) 295 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH))
300 .WillOnce(RunClosure(event.GetClosure())); 296 .WillOnce(RunClosure(event.GetClosure()));
297 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
301 StartPlayingFrom(0); 298 StartPlayingFrom(0);
302 event.RunAndWait(); 299 event.RunAndWait();
303 Mock::VerifyAndClearExpectations(&mock_cb_); 300 Mock::VerifyAndClearExpectations(&mock_cb_);
304 } 301 }
305 302
306 renderer_->OnTimeStateChanged(true); 303 renderer_->OnTimeStateChanged(true);
307 304
308 // Advance time slightly, but enough to exceed the duration of the last 305 // Advance time slightly, but enough to exceed the duration of the last
309 // frame. 306 // frame.
310 // Frames should be dropped and we should NOT signal having nothing. 307 // Frames should be dropped and we should NOT signal having nothing.
311 { 308 {
312 SCOPED_TRACE("Waiting for frame drops"); 309 SCOPED_TRACE("Waiting for frame drops");
313 WaitableMessageLoopEvent event; 310 WaitableMessageLoopEvent event;
314 311
315 // Note: Starting the TimeSource will cause the old VideoRendererImpl to 312 // Note: Starting the TimeSource will cause the old VideoRendererImpl to
316 // start rendering frames on its own thread, so the first frame may be 313 // start rendering frames on its own thread, so the first frame may be
317 // received. 314 // received.
318 time_source_.StartTicking(); 315 time_source_.StartTicking();
319 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(30))).Times(0); 316 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(30))).Times(0);
320 317
321 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(60))).Times(0); 318 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(60))).Times(0);
322 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(90))) 319 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(90)))
323 .WillOnce(RunClosure(event.GetClosure())); 320 .WillOnce(RunClosure(event.GetClosure()));
321 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
324 AdvanceTimeInMs(91); 322 AdvanceTimeInMs(91);
325 323
326 event.RunAndWait(); 324 event.RunAndWait();
327 Mock::VerifyAndClearExpectations(&mock_cb_); 325 Mock::VerifyAndClearExpectations(&mock_cb_);
328 } 326 }
329 327
330 // Advance time more. Now we should signal having nothing. And put 328 // Advance time more. Now we should signal having nothing. And put
331 // the last frame up for display. 329 // the last frame up for display.
332 { 330 {
333 SCOPED_TRACE("Waiting for BUFFERING_HAVE_NOTHING"); 331 SCOPED_TRACE("Waiting for BUFFERING_HAVE_NOTHING");
334 WaitableMessageLoopEvent event; 332 WaitableMessageLoopEvent event;
335 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_NOTHING)) 333 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING))
336 .WillOnce(RunClosure(event.GetClosure())); 334 .WillOnce(RunClosure(event.GetClosure()));
337 AdvanceTimeInMs(30); 335 AdvanceTimeInMs(30);
338 event.RunAndWait(); 336 event.RunAndWait();
339 Mock::VerifyAndClearExpectations(&mock_cb_); 337 Mock::VerifyAndClearExpectations(&mock_cb_);
340 } 338 }
341 339
342 // Simulate delayed buffering state callbacks. 340 // Simulate delayed buffering state callbacks.
343 renderer_->OnTimeStateChanged(false); 341 renderer_->OnTimeStateChanged(false);
344 renderer_->OnTimeStateChanged(true); 342 renderer_->OnTimeStateChanged(true);
345 343
346 // Receiving end of stream should signal having enough. 344 // Receiving end of stream should signal having enough.
347 { 345 {
348 SCOPED_TRACE("Waiting for BUFFERING_HAVE_ENOUGH"); 346 SCOPED_TRACE("Waiting for BUFFERING_HAVE_ENOUGH");
349 WaitableMessageLoopEvent event; 347 WaitableMessageLoopEvent event;
350 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)) 348 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH))
351 .WillOnce(RunClosure(event.GetClosure())); 349 .WillOnce(RunClosure(event.GetClosure()));
350 EXPECT_CALL(mock_cb_, OnEnded());
352 SatisfyPendingReadWithEndOfStream(); 351 SatisfyPendingReadWithEndOfStream();
353 event.RunAndWait(); 352 event.RunAndWait();
354 } 353 }
355 354
356 WaitForEnded();
357 Destroy(); 355 Destroy();
358 } 356 }
359 357
360 void UnderflowRecoveryTest(UnderflowTestType type) { 358 void UnderflowRecoveryTest(UnderflowTestType type) {
361 InitializeWithLowDelay(type == UnderflowTestType::LOW_DELAY); 359 InitializeWithLowDelay(type == UnderflowTestType::LOW_DELAY);
362 if (type == UnderflowTestType::CANT_READ_WITHOUT_STALLING) 360 if (type == UnderflowTestType::CANT_READ_WITHOUT_STALLING)
363 ON_CALL(*decoder_, CanReadWithoutStalling()).WillByDefault(Return(false)); 361 ON_CALL(*decoder_, CanReadWithoutStalling()).WillByDefault(Return(false));
364 362
365 QueueFrames("0 20 40 60"); 363 QueueFrames("0 20 40 60");
366 { 364 {
367 WaitableMessageLoopEvent event; 365 WaitableMessageLoopEvent event;
368 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); 366 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0)));
369 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)) 367 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH))
370 .WillOnce(RunClosure(event.GetClosure())); 368 .WillOnce(RunClosure(event.GetClosure()));
369 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
371 StartPlayingFrom(0); 370 StartPlayingFrom(0);
372 event.RunAndWait(); 371 event.RunAndWait();
373 Mock::VerifyAndClearExpectations(&mock_cb_); 372 Mock::VerifyAndClearExpectations(&mock_cb_);
374 } 373 }
375 374
376 renderer_->OnTimeStateChanged(true); 375 renderer_->OnTimeStateChanged(true);
377 time_source_.StartTicking(); 376 time_source_.StartTicking();
378 377
379 // Advance time, this should cause have nothing to be signaled. 378 // Advance time, this should cause have nothing to be signaled.
380 { 379 {
381 SCOPED_TRACE("Waiting for BUFFERING_HAVE_NOTHING"); 380 SCOPED_TRACE("Waiting for BUFFERING_HAVE_NOTHING");
382 WaitableMessageLoopEvent event; 381 WaitableMessageLoopEvent event;
383 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_NOTHING)) 382 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING))
384 .WillOnce(RunClosure(event.GetClosure())); 383 .WillOnce(RunClosure(event.GetClosure()));
385 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(20))).Times(1); 384 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(20))).Times(1);
385 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
386 AdvanceTimeInMs(20); 386 AdvanceTimeInMs(20);
387 event.RunAndWait(); 387 event.RunAndWait();
388 Mock::VerifyAndClearExpectations(&mock_cb_); 388 Mock::VerifyAndClearExpectations(&mock_cb_);
389 } 389 }
390 390
391 AdvanceTimeInMs(59); 391 AdvanceTimeInMs(59);
392 EXPECT_EQ(3u, renderer_->frames_queued_for_testing()); 392 EXPECT_EQ(3u, renderer_->frames_queued_for_testing());
393 time_source_.StopTicking(); 393 time_source_.StopTicking();
394 renderer_->OnTimeStateChanged(false); 394 renderer_->OnTimeStateChanged(false);
395 EXPECT_EQ(0u, renderer_->frames_queued_for_testing()); 395 EXPECT_EQ(0u, renderer_->frames_queued_for_testing());
396 ASSERT_TRUE(IsReadPending()); 396 ASSERT_TRUE(IsReadPending());
397 397
398 // Queue some frames, satisfy reads, and make sure expired frames are gone 398 // Queue some frames, satisfy reads, and make sure expired frames are gone
399 // when the renderer paints the first frame. 399 // when the renderer paints the first frame.
400 { 400 {
401 SCOPED_TRACE("Waiting for BUFFERING_HAVE_ENOUGH"); 401 SCOPED_TRACE("Waiting for BUFFERING_HAVE_ENOUGH");
402 WaitableMessageLoopEvent event; 402 WaitableMessageLoopEvent event;
403 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(80))).Times(1); 403 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(80))).Times(1);
404 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)) 404 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH))
405 .WillOnce(RunClosure(event.GetClosure())); 405 .WillOnce(RunClosure(event.GetClosure()));
406 if (type == UnderflowTestType::NORMAL) 406 if (type == UnderflowTestType::NORMAL)
407 QueueFrames("80 100 120 140 160"); 407 QueueFrames("80 100 120 140 160");
408 else 408 else
409 QueueFrames("40 60 80"); 409 QueueFrames("40 60 80");
410 SatisfyPendingRead(); 410 SatisfyPendingRead();
411 event.RunAndWait(); 411 event.RunAndWait();
412 } 412 }
413 413
414 Destroy(); 414 Destroy();
415 } 415 }
416 416
417 protected: 417 protected:
418 // Fixture members. 418 // Fixture members.
419 std::unique_ptr<VideoRendererImpl> renderer_; 419 std::unique_ptr<VideoRendererImpl> renderer_;
420 base::SimpleTestTickClock* tick_clock_; // Owned by |renderer_|. 420 base::SimpleTestTickClock* tick_clock_; // Owned by |renderer_|.
421 NiceMock<MockVideoDecoder>* decoder_; // Owned by |renderer_|. 421 NiceMock<MockVideoDecoder>* decoder_; // Owned by |renderer_|.
422 NiceMock<MockDemuxerStream> demuxer_stream_; 422 NiceMock<MockDemuxerStream> demuxer_stream_;
423 423
424 // Use StrictMock<T> to catch missing/extra callbacks. 424 // Use StrictMock<T> to catch missing/extra callbacks.
425 class MockCB { 425 class MockCB : public RendererClient {
426 public: 426 public:
427 MOCK_METHOD1(FrameReceived, void(const scoped_refptr<VideoFrame>&)); 427 MOCK_METHOD1(FrameReceived, void(const scoped_refptr<VideoFrame>&));
428 MOCK_METHOD1(BufferingStateChange, void(BufferingState)); 428
429 // RendererClient implementation.
430 MOCK_METHOD1(OnError, void(PipelineStatus));
431 MOCK_METHOD0(OnEnded, void());
432 MOCK_METHOD1(OnStatisticsUpdate, void(const PipelineStatistics&));
433 MOCK_METHOD1(OnBufferingStateChange, void(BufferingState));
434 MOCK_METHOD0(OnWaitingForDecryptionKey, void());
xhwang 2016/05/12 20:51:19 ditto about using MockRendererClient.
alokp 2016/05/12 21:46:51 Done. And also in renderer_impl_unittest.cc
429 }; 435 };
430 StrictMock<MockCB> mock_cb_; 436 StrictMock<MockCB> mock_cb_;
431 437
432 // Must be destroyed before |renderer_| since they share |tick_clock_|. 438 // Must be destroyed before |renderer_| since they share |tick_clock_|.
433 std::unique_ptr<NullVideoSink> null_video_sink_; 439 std::unique_ptr<NullVideoSink> null_video_sink_;
434 440
435 PipelineStatistics last_pipeline_statistics_;
436
437 WallClockTimeSource time_source_; 441 WallClockTimeSource time_source_;
438 442
439 base::MessageLoop message_loop_; 443 base::MessageLoop message_loop_;
440 444
441 private: 445 private:
442 void DecodeRequested(const scoped_refptr<DecoderBuffer>& buffer, 446 void DecodeRequested(const scoped_refptr<DecoderBuffer>& buffer,
443 const VideoDecoder::DecodeCB& decode_cb) { 447 const VideoDecoder::DecodeCB& decode_cb) {
444 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); 448 DCHECK_EQ(&message_loop_, base::MessageLoop::current());
445 CHECK(decode_cb_.is_null()); 449 CHECK(decode_cb_.is_null());
446 decode_cb_ = decode_cb; 450 decode_cb_ = decode_cb;
(...skipping 12 matching lines...) Expand all
459 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); 463 DCHECK_EQ(&message_loop_, base::MessageLoop::current());
460 decode_results_.clear(); 464 decode_results_.clear();
461 if (!decode_cb_.is_null()) { 465 if (!decode_cb_.is_null()) {
462 QueueFrames("abort"); 466 QueueFrames("abort");
463 SatisfyPendingRead(); 467 SatisfyPendingRead();
464 } 468 }
465 469
466 message_loop_.PostTask(FROM_HERE, callback); 470 message_loop_.PostTask(FROM_HERE, callback);
467 } 471 }
468 472
469 void OnStatisticsUpdate(const PipelineStatistics& stats) {
470 last_pipeline_statistics_ = stats;
471 }
472
473 MOCK_METHOD0(OnWaitingForDecryptionKey, void(void));
474
475 // Used to protect |time_|. 473 // Used to protect |time_|.
476 base::Lock lock_; 474 base::Lock lock_;
477 base::TimeDelta time_; 475 base::TimeDelta time_;
478 476
479 // Used for satisfying reads. 477 // Used for satisfying reads.
480 VideoDecoder::OutputCB output_cb_; 478 VideoDecoder::OutputCB output_cb_;
481 VideoDecoder::DecodeCB decode_cb_; 479 VideoDecoder::DecodeCB decode_cb_;
482 base::TimeDelta next_frame_timestamp_; 480 base::TimeDelta next_frame_timestamp_;
483 481
484 WaitableMessageLoopEvent error_event_;
485 WaitableMessageLoopEvent ended_event_;
486
487 // Run during DecodeRequested() to unblock WaitForPendingRead(). 482 // Run during DecodeRequested() to unblock WaitForPendingRead().
488 base::Closure wait_for_pending_decode_cb_; 483 base::Closure wait_for_pending_decode_cb_;
489 484
490 std::deque<std::pair<DecodeStatus, scoped_refptr<VideoFrame>>> 485 std::deque<std::pair<DecodeStatus, scoped_refptr<VideoFrame>>>
491 decode_results_; 486 decode_results_;
492 487
493 DISALLOW_COPY_AND_ASSIGN(VideoRendererImplTest); 488 DISALLOW_COPY_AND_ASSIGN(VideoRendererImplTest);
494 }; 489 };
495 490
496 TEST_F(VideoRendererImplTest, DoNothing) { 491 TEST_F(VideoRendererImplTest, DoNothing) {
497 // Test that creation and deletion doesn't depend on calls to Initialize() 492 // Test that creation and deletion doesn't depend on calls to Initialize()
498 // and/or Destroy(). 493 // and/or Destroy().
499 } 494 }
500 495
501 TEST_F(VideoRendererImplTest, DestroyWithoutInitialize) { 496 TEST_F(VideoRendererImplTest, DestroyWithoutInitialize) {
502 Destroy(); 497 Destroy();
503 } 498 }
504 499
505 TEST_F(VideoRendererImplTest, Initialize) { 500 TEST_F(VideoRendererImplTest, Initialize) {
506 Initialize(); 501 Initialize();
507 Destroy(); 502 Destroy();
508 } 503 }
509 504
510 TEST_F(VideoRendererImplTest, InitializeAndStartPlayingFrom) { 505 TEST_F(VideoRendererImplTest, InitializeAndStartPlayingFrom) {
511 Initialize(); 506 Initialize();
512 QueueFrames("0 10 20 30"); 507 QueueFrames("0 10 20 30");
513 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); 508 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0)));
514 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); 509 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
510 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
515 StartPlayingFrom(0); 511 StartPlayingFrom(0);
516 Destroy(); 512 Destroy();
517 } 513 }
518 514
519 TEST_F(VideoRendererImplTest, InitializeAndEndOfStream) { 515 TEST_F(VideoRendererImplTest, InitializeAndEndOfStream) {
520 Initialize(); 516 Initialize();
521 StartPlayingFrom(0); 517 StartPlayingFrom(0);
522 WaitForPendingRead(); 518 WaitForPendingRead();
523 { 519 {
524 SCOPED_TRACE("Waiting for BUFFERING_HAVE_ENOUGH"); 520 SCOPED_TRACE("Waiting for BUFFERING_HAVE_ENOUGH");
525 WaitableMessageLoopEvent event; 521 WaitableMessageLoopEvent event;
526 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)) 522 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH))
527 .WillOnce(RunClosure(event.GetClosure())); 523 .WillOnce(RunClosure(event.GetClosure()));
524 EXPECT_CALL(mock_cb_, OnEnded());
528 SatisfyPendingReadWithEndOfStream(); 525 SatisfyPendingReadWithEndOfStream();
529 event.RunAndWait(); 526 event.RunAndWait();
530 } 527 }
531 // Firing a time state changed to true should be ignored... 528 // Firing a time state changed to true should be ignored...
532 renderer_->OnTimeStateChanged(true); 529 renderer_->OnTimeStateChanged(true);
533 EXPECT_FALSE(null_video_sink_->is_started()); 530 EXPECT_FALSE(null_video_sink_->is_started());
534 Destroy(); 531 Destroy();
535 } 532 }
536 533
537 TEST_F(VideoRendererImplTest, DestroyWhileInitializing) { 534 TEST_F(VideoRendererImplTest, DestroyWhileInitializing) {
538 CallInitialize(NewExpectedStatusCB(PIPELINE_ERROR_ABORT), false, PIPELINE_OK); 535 CallInitialize(NewExpectedStatusCB(PIPELINE_ERROR_ABORT), false, PIPELINE_OK);
539 Destroy(); 536 Destroy();
540 } 537 }
541 538
542 TEST_F(VideoRendererImplTest, DestroyWhileFlushing) { 539 TEST_F(VideoRendererImplTest, DestroyWhileFlushing) {
543 Initialize(); 540 Initialize();
544 QueueFrames("0 10 20 30"); 541 QueueFrames("0 10 20 30");
545 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); 542 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0)));
546 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); 543 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
544 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
547 StartPlayingFrom(0); 545 StartPlayingFrom(0);
548 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_NOTHING));
549 renderer_->Flush(NewExpectedClosure()); 546 renderer_->Flush(NewExpectedClosure());
550 Destroy(); 547 Destroy();
551 } 548 }
552 549
553 TEST_F(VideoRendererImplTest, Play) { 550 TEST_F(VideoRendererImplTest, Play) {
554 Initialize(); 551 Initialize();
555 QueueFrames("0 10 20 30"); 552 QueueFrames("0 10 20 30");
556 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); 553 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0)));
557 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); 554 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
555 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
558 StartPlayingFrom(0); 556 StartPlayingFrom(0);
559 Destroy(); 557 Destroy();
560 } 558 }
561 559
562 TEST_F(VideoRendererImplTest, FlushWithNothingBuffered) { 560 TEST_F(VideoRendererImplTest, FlushWithNothingBuffered) {
563 Initialize(); 561 Initialize();
564 StartPlayingFrom(0); 562 StartPlayingFrom(0);
565 563
566 // We shouldn't expect a buffering state change since we never reached 564 // We shouldn't expect a buffering state change since we never reached
567 // BUFFERING_HAVE_ENOUGH. 565 // BUFFERING_HAVE_ENOUGH.
568 Flush(); 566 Flush();
569 Destroy(); 567 Destroy();
570 } 568 }
571 569
572 TEST_F(VideoRendererImplTest, DecodeError_Playing) { 570 TEST_F(VideoRendererImplTest, DecodeError_Playing) {
573 Initialize(); 571 Initialize();
574 QueueFrames("0 10 20 30"); 572 QueueFrames("0 10 20 30");
575 EXPECT_CALL(mock_cb_, FrameReceived(_)).Times(testing::AtLeast(1)); 573 EXPECT_CALL(mock_cb_, FrameReceived(_)).Times(testing::AtLeast(1));
576 574
577 // Consider the case that rendering is faster than we setup the test event. 575 // Consider the case that rendering is faster than we setup the test event.
578 // In that case, when we run out of the frames, BUFFERING_HAVE_NOTHING will 576 // In that case, when we run out of the frames, BUFFERING_HAVE_NOTHING will
579 // be called. 577 // be called.
580 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); 578 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
581 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_NOTHING)) 579 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING))
582 .Times(testing::AtMost(1)); 580 .Times(testing::AtMost(1));
581 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
583 582
584 StartPlayingFrom(0); 583 StartPlayingFrom(0);
585 renderer_->OnTimeStateChanged(true); 584 renderer_->OnTimeStateChanged(true);
586 time_source_.StartTicking(); 585 time_source_.StartTicking();
587 AdvanceTimeInMs(10); 586 AdvanceTimeInMs(10);
588 587
589 QueueFrames("error"); 588 QueueFrames("error");
590 SatisfyPendingRead(); 589 SatisfyPendingRead();
591 WaitForError(PIPELINE_ERROR_DECODE); 590 WaitForError(PIPELINE_ERROR_DECODE);
592 Destroy(); 591 Destroy();
593 } 592 }
594 593
595 TEST_F(VideoRendererImplTest, DecodeError_DuringStartPlayingFrom) { 594 TEST_F(VideoRendererImplTest, DecodeError_DuringStartPlayingFrom) {
596 Initialize(); 595 Initialize();
597 QueueFrames("error"); 596 QueueFrames("error");
597 EXPECT_CALL(mock_cb_, OnError(PIPELINE_ERROR_DECODE));
598 StartPlayingFrom(0); 598 StartPlayingFrom(0);
599 Destroy(); 599 Destroy();
600 } 600 }
601 601
602 TEST_F(VideoRendererImplTest, StartPlayingFrom_Exact) { 602 TEST_F(VideoRendererImplTest, StartPlayingFrom_Exact) {
603 Initialize(); 603 Initialize();
604 QueueFrames("50 60 70 80 90"); 604 QueueFrames("50 60 70 80 90");
605 605
606 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(60))); 606 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(60)));
607 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); 607 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
608 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
608 StartPlayingFrom(60); 609 StartPlayingFrom(60);
609 Destroy(); 610 Destroy();
610 } 611 }
611 612
612 TEST_F(VideoRendererImplTest, StartPlayingFrom_RightBefore) { 613 TEST_F(VideoRendererImplTest, StartPlayingFrom_RightBefore) {
613 Initialize(); 614 Initialize();
614 QueueFrames("50 60 70 80 90"); 615 QueueFrames("50 60 70 80 90");
615 616
616 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(50))); 617 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(50)));
617 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); 618 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
619 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
618 StartPlayingFrom(59); 620 StartPlayingFrom(59);
619 Destroy(); 621 Destroy();
620 } 622 }
621 623
622 TEST_F(VideoRendererImplTest, StartPlayingFrom_RightAfter) { 624 TEST_F(VideoRendererImplTest, StartPlayingFrom_RightAfter) {
623 Initialize(); 625 Initialize();
624 QueueFrames("50 60 70 80 90"); 626 QueueFrames("50 60 70 80 90");
625 627
626 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(60))); 628 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(60)));
627 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); 629 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
630 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
628 StartPlayingFrom(61); 631 StartPlayingFrom(61);
629 Destroy(); 632 Destroy();
630 } 633 }
631 634
632 TEST_F(VideoRendererImplTest, StartPlayingFrom_LowDelay) { 635 TEST_F(VideoRendererImplTest, StartPlayingFrom_LowDelay) {
633 // In low-delay mode only one frame is required to finish preroll. But frames 636 // In low-delay mode only one frame is required to finish preroll. But frames
634 // prior to the start time will not be used. 637 // prior to the start time will not be used.
635 InitializeWithLowDelay(true); 638 InitializeWithLowDelay(true);
636 QueueFrames("0 10"); 639 QueueFrames("0 10");
637 640
638 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(10))); 641 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(10)));
639 // Expect some amount of have enough/nothing due to only requiring one frame. 642 // Expect some amount of have enough/nothing due to only requiring one frame.
640 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)) 643 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH))
641 .Times(AnyNumber()); 644 .Times(AnyNumber());
642 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_NOTHING)) 645 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING))
643 .Times(AnyNumber()); 646 .Times(AnyNumber());
647 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
644 StartPlayingFrom(10); 648 StartPlayingFrom(10);
645 649
646 QueueFrames("20"); 650 QueueFrames("20");
647 SatisfyPendingRead(); 651 SatisfyPendingRead();
648 652
649 renderer_->OnTimeStateChanged(true); 653 renderer_->OnTimeStateChanged(true);
650 time_source_.StartTicking(); 654 time_source_.StartTicking();
651 655
652 WaitableMessageLoopEvent event; 656 WaitableMessageLoopEvent event;
653 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(20))) 657 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(20)))
654 .WillOnce(RunClosure(event.GetClosure())); 658 .WillOnce(RunClosure(event.GetClosure()));
655 AdvanceTimeInMs(20); 659 AdvanceTimeInMs(20);
656 event.RunAndWait(); 660 event.RunAndWait();
657 661
658 Destroy(); 662 Destroy();
659 } 663 }
660 664
661 // Verify that a late decoder response doesn't break invariants in the renderer. 665 // Verify that a late decoder response doesn't break invariants in the renderer.
662 TEST_F(VideoRendererImplTest, DestroyDuringOutstandingRead) { 666 TEST_F(VideoRendererImplTest, DestroyDuringOutstandingRead) {
663 Initialize(); 667 Initialize();
664 QueueFrames("0 10 20 30"); 668 QueueFrames("0 10 20 30");
665 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); 669 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0)));
666 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); 670 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
671 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
667 StartPlayingFrom(0); 672 StartPlayingFrom(0);
668 673
669 // Check that there is an outstanding Read() request. 674 // Check that there is an outstanding Read() request.
670 EXPECT_TRUE(IsReadPending()); 675 EXPECT_TRUE(IsReadPending());
671 676
672 Destroy(); 677 Destroy();
673 } 678 }
674 679
675 TEST_F(VideoRendererImplTest, VideoDecoder_InitFailure) { 680 TEST_F(VideoRendererImplTest, VideoDecoder_InitFailure) {
676 InitializeRenderer(false, false); 681 InitializeRenderer(false, false);
(...skipping 24 matching lines...) Expand all
701 UnderflowRecoveryTest(UnderflowTestType::CANT_READ_WITHOUT_STALLING); 706 UnderflowRecoveryTest(UnderflowTestType::CANT_READ_WITHOUT_STALLING);
702 } 707 }
703 708
704 // Verifies that the sink is stopped after rendering the first frame if 709 // Verifies that the sink is stopped after rendering the first frame if
705 // playback hasn't started. 710 // playback hasn't started.
706 TEST_F(VideoRendererImplTest, RenderingStopsAfterFirstFrame) { 711 TEST_F(VideoRendererImplTest, RenderingStopsAfterFirstFrame) {
707 InitializeWithLowDelay(true); 712 InitializeWithLowDelay(true);
708 QueueFrames("0"); 713 QueueFrames("0");
709 714
710 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); 715 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0)));
711 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); 716 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
717 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
718 EXPECT_CALL(mock_cb_, OnEnded()).Times(0);
712 719
713 { 720 {
714 SCOPED_TRACE("Waiting for sink to stop."); 721 SCOPED_TRACE("Waiting for sink to stop.");
715 WaitableMessageLoopEvent event; 722 WaitableMessageLoopEvent event;
716 723
717 null_video_sink_->set_background_render(true); 724 null_video_sink_->set_background_render(true);
718 null_video_sink_->set_stop_cb(event.GetClosure()); 725 null_video_sink_->set_stop_cb(event.GetClosure());
719 StartPlayingFrom(0); 726 StartPlayingFrom(0);
720 727
721 EXPECT_TRUE(IsReadPending()); 728 EXPECT_TRUE(IsReadPending());
722 SatisfyPendingReadWithEndOfStream(); 729 SatisfyPendingReadWithEndOfStream();
723 730
724 event.RunAndWait(); 731 event.RunAndWait();
725 } 732 }
726 733
727 EXPECT_FALSE(has_ended());
728 Destroy(); 734 Destroy();
729 } 735 }
730 736
731 // Verifies that the sink is stopped after rendering the first frame if 737 // Verifies that the sink is stopped after rendering the first frame if
732 // playback ha started. 738 // playback ha started.
733 TEST_F(VideoRendererImplTest, RenderingStopsAfterOneFrameWithEOS) { 739 TEST_F(VideoRendererImplTest, RenderingStopsAfterOneFrameWithEOS) {
734 InitializeWithLowDelay(true); 740 InitializeWithLowDelay(true);
735 QueueFrames("0"); 741 QueueFrames("0");
736 742
737 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); 743 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0)));
738 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); 744 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
745 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
739 746
740 { 747 {
741 SCOPED_TRACE("Waiting for sink to stop."); 748 SCOPED_TRACE("Waiting for sink to stop.");
742 WaitableMessageLoopEvent event; 749 WaitableMessageLoopEvent event;
743 750
744 null_video_sink_->set_stop_cb(event.GetClosure()); 751 null_video_sink_->set_stop_cb(event.GetClosure());
745 StartPlayingFrom(0); 752 StartPlayingFrom(0);
746 renderer_->OnTimeStateChanged(true); 753 renderer_->OnTimeStateChanged(true);
747 754
748 EXPECT_TRUE(IsReadPending()); 755 EXPECT_TRUE(IsReadPending());
749 SatisfyPendingReadWithEndOfStream(); 756 SatisfyPendingReadWithEndOfStream();
750 WaitForEnded(); 757 WaitForEnded();
751 758
752 renderer_->OnTimeStateChanged(false); 759 renderer_->OnTimeStateChanged(false);
753 event.RunAndWait(); 760 event.RunAndWait();
754 } 761 }
755 762
756 Destroy(); 763 Destroy();
757 } 764 }
758 765
759 // Tests the case where the video started and received a single Render() call, 766 // Tests the case where the video started and received a single Render() call,
760 // then the video was put into the background. 767 // then the video was put into the background.
761 TEST_F(VideoRendererImplTest, RenderingStartedThenStopped) { 768 TEST_F(VideoRendererImplTest, RenderingStartedThenStopped) {
762 Initialize(); 769 Initialize();
763 QueueFrames("0 30 60 90"); 770 QueueFrames("0 30 60 90");
764 771
765 // Start the sink and wait for the first callback. Set statistics to a non 772 // Start the sink and wait for the first callback. Set statistics to a non
766 // zero value, once we have some decoded frames they should be overwritten. 773 // zero value, once we have some decoded frames they should be overwritten.
767 last_pipeline_statistics_.video_frames_dropped = 1; 774 PipelineStatistics last_pipeline_statistics;
775 last_pipeline_statistics.video_frames_dropped = 1;
768 { 776 {
769 WaitableMessageLoopEvent event; 777 WaitableMessageLoopEvent event;
770 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); 778 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
771 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))) 779 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0)))
772 .WillOnce(RunClosure(event.GetClosure())); 780 .WillOnce(RunClosure(event.GetClosure()));
781 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_))
782 .WillRepeatedly(SaveArg<0>(&last_pipeline_statistics));
773 StartPlayingFrom(0); 783 StartPlayingFrom(0);
774 event.RunAndWait(); 784 event.RunAndWait();
775 Mock::VerifyAndClearExpectations(&mock_cb_); 785 Mock::VerifyAndClearExpectations(&mock_cb_);
776 EXPECT_EQ(0u, last_pipeline_statistics_.video_frames_dropped); 786 EXPECT_EQ(0u, last_pipeline_statistics.video_frames_dropped);
777 EXPECT_EQ(460800, last_pipeline_statistics_.video_memory_usage); 787 EXPECT_EQ(460800, last_pipeline_statistics.video_memory_usage);
778 } 788 }
779 789
780 // Consider the case that rendering is faster than we setup the test event. 790 // Consider the case that rendering is faster than we setup the test event.
781 // In that case, when we run out of the frames, BUFFERING_HAVE_NOTHING will 791 // In that case, when we run out of the frames, BUFFERING_HAVE_NOTHING will
782 // be called. And then during SatisfyPendingReadWithEndOfStream, 792 // be called. And then during SatisfyPendingReadWithEndOfStream,
783 // BUFFER_HAVE_ENOUGH will be called again. 793 // BUFFER_HAVE_ENOUGH will be called again.
784 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)) 794 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH))
785 .Times(testing::AtMost(1)); 795 .Times(testing::AtMost(1));
786 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_NOTHING)) 796 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING))
787 .Times(testing::AtMost(1)); 797 .Times(testing::AtMost(1));
788 renderer_->OnTimeStateChanged(true); 798 renderer_->OnTimeStateChanged(true);
789 time_source_.StartTicking(); 799 time_source_.StartTicking();
790 800
791 // Suspend all future callbacks and synthetically advance the media time, 801 // Suspend all future callbacks and synthetically advance the media time,
792 // because this is a background render, we won't underflow by waiting until 802 // because this is a background render, we won't underflow by waiting until
793 // a pending read is ready. 803 // a pending read is ready.
794 null_video_sink_->set_background_render(true); 804 null_video_sink_->set_background_render(true);
795 AdvanceTimeInMs(91); 805 AdvanceTimeInMs(91);
796 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(90))); 806 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(90)));
797 WaitForPendingRead(); 807 WaitForPendingRead();
798 SatisfyPendingReadWithEndOfStream(); 808 SatisfyPendingReadWithEndOfStream();
799 809
800 // If this wasn't background rendering mode, this would result in two frames 810 // If this wasn't background rendering mode, this would result in two frames
801 // being dropped, but since we set background render to true, none should be 811 // being dropped, but since we set background render to true, none should be
802 // reported 812 // reported
803 EXPECT_EQ(0u, last_pipeline_statistics_.video_frames_dropped); 813 EXPECT_EQ(0u, last_pipeline_statistics.video_frames_dropped);
804 EXPECT_EQ(4u, last_pipeline_statistics_.video_frames_decoded); 814 EXPECT_EQ(4u, last_pipeline_statistics.video_frames_decoded);
805 EXPECT_EQ(460800, last_pipeline_statistics_.video_memory_usage); 815 EXPECT_EQ(460800, last_pipeline_statistics.video_memory_usage);
806 816
807 AdvanceTimeInMs(30); 817 AdvanceTimeInMs(30);
808 WaitForEnded(); 818 WaitForEnded();
809 Destroy(); 819 Destroy();
810 } 820 }
811 821
812 TEST_F(VideoRendererImplTest, StartPlayingFromThenFlushThenEOS) { 822 TEST_F(VideoRendererImplTest, StartPlayingFromThenFlushThenEOS) {
813 Initialize(); 823 Initialize();
814 QueueFrames("0 30 60 90"); 824 QueueFrames("0 30 60 90");
815 825
816 WaitableMessageLoopEvent event; 826 WaitableMessageLoopEvent event;
817 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); 827 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0)));
818 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)) 828 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH))
819 .WillOnce(RunClosure(event.GetClosure())); 829 .WillOnce(RunClosure(event.GetClosure()));
830 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
820 StartPlayingFrom(0); 831 StartPlayingFrom(0);
821 event.RunAndWait(); 832 event.RunAndWait();
822 833
823 // Cycle ticking so that we get a non-null reference time. 834 // Cycle ticking so that we get a non-null reference time.
824 time_source_.StartTicking(); 835 time_source_.StartTicking();
825 time_source_.StopTicking(); 836 time_source_.StopTicking();
826 837
827 // Flush and simulate a seek past EOS, where some error prevents the decoder 838 // Flush and simulate a seek past EOS, where some error prevents the decoder
828 // from returning any frames. 839 // from returning any frames.
829 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_NOTHING)); 840 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
830 Flush(); 841 Flush();
831 842
832 StartPlayingFrom(200); 843 StartPlayingFrom(200);
833 WaitForPendingRead(); 844 WaitForPendingRead();
834 SatisfyPendingReadWithEndOfStream(); 845 SatisfyPendingReadWithEndOfStream();
835 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); 846 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
836 WaitForEnded(); 847 WaitForEnded();
837 Destroy(); 848 Destroy();
838 } 849 }
839 850
840 TEST_F(VideoRendererImplTest, FramesAreNotExpiredDuringPreroll) { 851 TEST_F(VideoRendererImplTest, FramesAreNotExpiredDuringPreroll) {
841 Initialize(); 852 Initialize();
842 // !CanReadWithoutStalling() puts the renderer in state BUFFERING_HAVE_ENOUGH 853 // !CanReadWithoutStalling() puts the renderer in state BUFFERING_HAVE_ENOUGH
843 // after the first frame. 854 // after the first frame.
844 ON_CALL(*decoder_, CanReadWithoutStalling()).WillByDefault(Return(false)); 855 ON_CALL(*decoder_, CanReadWithoutStalling()).WillByDefault(Return(false));
845 // Set background rendering to simulate the first couple of Render() calls 856 // Set background rendering to simulate the first couple of Render() calls
846 // by VFC. 857 // by VFC.
847 null_video_sink_->set_background_render(true); 858 null_video_sink_->set_background_render(true);
848 QueueFrames("0 10 20"); 859 QueueFrames("0 10 20");
849 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)) 860 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH))
850 .Times(testing::AtMost(1)); 861 .Times(testing::AtMost(1));
851 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); 862 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0)));
863 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
852 StartPlayingFrom(0); 864 StartPlayingFrom(0);
853 865
854 renderer_->OnTimeStateChanged(true); 866 renderer_->OnTimeStateChanged(true);
855 time_source_.StartTicking(); 867 time_source_.StartTicking();
856 868
857 WaitableMessageLoopEvent event; 869 WaitableMessageLoopEvent event;
858 // Frame "10" should not have been expired. 870 // Frame "10" should not have been expired.
859 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(10))) 871 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(10)))
860 .WillOnce(RunClosure(event.GetClosure())); 872 .WillOnce(RunClosure(event.GetClosure()));
861 AdvanceTimeInMs(10); 873 AdvanceTimeInMs(10);
(...skipping 12 matching lines...) Expand all
874 } 886 }
875 887
876 protected: 888 protected:
877 std::vector<base::Closure> frame_ready_cbs_; 889 std::vector<base::Closure> frame_ready_cbs_;
878 }; 890 };
879 891
880 TEST_F(VideoRendererImplAsyncAddFrameReadyTest, InitializeAndStartPlayingFrom) { 892 TEST_F(VideoRendererImplAsyncAddFrameReadyTest, InitializeAndStartPlayingFrom) {
881 Initialize(); 893 Initialize();
882 QueueFrames("0 10 20 30"); 894 QueueFrames("0 10 20 30");
883 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0))); 895 EXPECT_CALL(mock_cb_, FrameReceived(HasTimestamp(0)));
884 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); 896 EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
897 EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
885 StartPlayingFrom(0); 898 StartPlayingFrom(0);
886 ASSERT_EQ(1u, frame_ready_cbs_.size()); 899 ASSERT_EQ(1u, frame_ready_cbs_.size());
887 900
888 uint32_t frame_ready_index = 0; 901 uint32_t frame_ready_index = 0;
889 while (frame_ready_index < frame_ready_cbs_.size()) { 902 while (frame_ready_index < frame_ready_cbs_.size()) {
890 frame_ready_cbs_[frame_ready_index++].Run(); 903 frame_ready_cbs_[frame_ready_index++].Run();
891 message_loop_.RunUntilIdle(); 904 message_loop_.RunUntilIdle();
892 } 905 }
893 Destroy(); 906 Destroy();
894 } 907 }
895 908
896 TEST_F(VideoRendererImplAsyncAddFrameReadyTest, SequenceTokenDiscardOneFrame) { 909 TEST_F(VideoRendererImplAsyncAddFrameReadyTest, SequenceTokenDiscardOneFrame) {
897 Initialize(); 910 Initialize();
898 QueueFrames("0 10 20 30"); 911 QueueFrames("0 10 20 30");
899 StartPlayingFrom(0); 912 StartPlayingFrom(0);
900 Flush(); 913 Flush();
901 ASSERT_EQ(1u, frame_ready_cbs_.size()); 914 ASSERT_EQ(1u, frame_ready_cbs_.size());
902 // This frame will be discarded. 915 // This frame will be discarded.
903 frame_ready_cbs_.front().Run(); 916 frame_ready_cbs_.front().Run();
904 Destroy(); 917 Destroy();
905 } 918 }
906 919
907 } // namespace media 920 } // namespace media
OLDNEW
« media/renderers/audio_renderer_impl_unittest.cc ('K') | « media/renderers/video_renderer_impl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698