10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 20529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 30529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// found in the LICENSE file. 40529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/message_loop/message_loop.h" 60529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/test/simple_test_tick_clock.h" 70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "media/base/test_helpers.h" 80529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "media/base/video_frame.h" 90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "media/filters/video_frame_scheduler_impl.h" 100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "testing/gmock/include/gmock/gmock.h" 110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "testing/gtest/include/gtest/gtest.h" 120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace media { 140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuusing testing::_; 165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// NOTE: millisecond-level resolution is used for times as real delayed tasks 180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// are posted. Don't use large values if you want to keep tests running fast. 190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass VideoFrameSchedulerImplTest : public testing::Test { 200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public: 210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VideoFrameSchedulerImplTest() 220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch : scheduler_(message_loop_.message_loop_proxy(), 230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Bind(&VideoFrameSchedulerImplTest::OnDisplay, 240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Unretained(this))), 250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch tick_clock_(new base::SimpleTestTickClock()) { 260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scheduler_.SetTickClockForTesting(scoped_ptr<base::TickClock>(tick_clock_)); 270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual ~VideoFrameSchedulerImplTest() {} 300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch MOCK_METHOD1(OnDisplay, void(const scoped_refptr<VideoFrame>&)); 320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch MOCK_METHOD2(OnFrameDone, 330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void(const scoped_refptr<VideoFrame>&, 340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VideoFrameScheduler::Reason)); 350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void Schedule(const scoped_refptr<VideoFrame>& frame, int64 target_ms) { 370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scheduler_.ScheduleVideoFrame( 380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch frame, 390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::TimeTicks() + base::TimeDelta::FromMilliseconds(target_ms), 400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Bind(&VideoFrameSchedulerImplTest::OnFrameDone, 410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Unretained(this))); 420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void RunUntilTimeHasElapsed(int64 ms) { 450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch WaitableMessageLoopEvent waiter; 460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch message_loop_.PostDelayedTask( 470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch FROM_HERE, waiter.GetClosure(), base::TimeDelta::FromMilliseconds(ms)); 480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch waiter.RunAndWait(); 490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void AdvanceTime(int64 ms) { 520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch tick_clock_->Advance(base::TimeDelta::FromMilliseconds(ms)); 530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void Reset() { 560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scheduler_.Reset(); 570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private: 600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::MessageLoop message_loop_; 610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VideoFrameSchedulerImpl scheduler_; 620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::SimpleTestTickClock* tick_clock_; // Owned by |scheduler_|. 630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DISALLOW_COPY_AND_ASSIGN(VideoFrameSchedulerImplTest); 650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}; 660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 670529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(VideoFrameSchedulerImplTest, ImmediateDisplay) { 680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_refptr<VideoFrame> frame = 690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VideoFrame::CreateBlackFrame(gfx::Size(8, 8)); 700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Schedule(frame, 0); 710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*this, OnDisplay(frame)); 730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*this, OnFrameDone(frame, VideoFrameScheduler::DISPLAYED)); 740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch RunUntilTimeHasElapsed(0); 750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 770529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(VideoFrameSchedulerImplTest, EventualDisplay) { 780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_refptr<VideoFrame> frame = 790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VideoFrame::CreateBlackFrame(gfx::Size(8, 8)); 800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Schedule(frame, 10); 810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Nothing should happen. 830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch RunUntilTimeHasElapsed(10); 840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Now we should get the frame. 860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*this, OnDisplay(frame)); 870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*this, OnFrameDone(frame, VideoFrameScheduler::DISPLAYED)); 880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch AdvanceTime(10); 890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch RunUntilTimeHasElapsed(10); 900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 920529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(VideoFrameSchedulerImplTest, DroppedFrame) { 930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_refptr<VideoFrame> dropped = 940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VideoFrame::CreateBlackFrame(gfx::Size(8, 8)); 950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_refptr<VideoFrame> displayed = 960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VideoFrame::CreateBlackFrame(gfx::Size(8, 8)); 970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Schedule(dropped, 10); 980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Schedule(displayed, 20); 990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // The frame past its deadline will get dropped. 1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*this, OnDisplay(displayed)); 1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*this, OnFrameDone(dropped, VideoFrameScheduler::DROPPED)); 1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*this, OnFrameDone(displayed, VideoFrameScheduler::DISPLAYED)); 1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch AdvanceTime(20); 1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch RunUntilTimeHasElapsed(20); 1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1080529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(VideoFrameSchedulerImplTest, SingleFrameLate) { 1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_refptr<VideoFrame> frame = 1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VideoFrame::CreateBlackFrame(gfx::Size(8, 8)); 1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Schedule(frame, 10); 1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Despite frame being late it should still get displayed as it's the only 1140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // one. 1150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*this, OnDisplay(frame)); 1160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*this, OnFrameDone(frame, VideoFrameScheduler::DISPLAYED)); 1170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch AdvanceTime(20); 1180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch RunUntilTimeHasElapsed(20); 1190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 1200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1210529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(VideoFrameSchedulerImplTest, ManyFramesLate) { 1220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_refptr<VideoFrame> dropped = 1230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VideoFrame::CreateBlackFrame(gfx::Size(8, 8)); 1240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_refptr<VideoFrame> displayed = 1250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VideoFrame::CreateBlackFrame(gfx::Size(8, 8)); 1260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Schedule(dropped, 10); 1270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Schedule(displayed, 20); 1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Despite both being late, the scheduler should always displays the latest 1300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // expired frame. 1310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*this, OnDisplay(displayed)); 1320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*this, OnFrameDone(dropped, VideoFrameScheduler::DROPPED)); 1330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*this, OnFrameDone(displayed, VideoFrameScheduler::DISPLAYED)); 1340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch AdvanceTime(30); 1350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch RunUntilTimeHasElapsed(30); 1360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 1370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1380529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(VideoFrameSchedulerImplTest, Reset) { 1390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_refptr<VideoFrame> frame = 1400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VideoFrame::CreateBlackFrame(gfx::Size(8, 8)); 1410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Schedule(frame, 10); 1420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Despite being on time, frame callback isn't run. 1445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_CALL(*this, OnFrameDone(_, _)).Times(0); 1450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch AdvanceTime(10); 1460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Reset(); 1470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch RunUntilTimeHasElapsed(10); 1480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} // namespace media 151