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
3 // found in the LICENSE file.
5 #include "remoting/host/capture_scheduler.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/test/simple_test_tick_clock.h"
9 #include "base/timer/mock_timer.h"
10 #include "remoting/proto/video.pb.h"
11 #include "testing/gtest/include/gtest/gtest.h"
15 static const int kTestInputs
[] = { 100, 50, 30, 20, 10, 30, 60, 80 };
16 static const int kMinumumFrameIntervalMs
= 50;
18 class CaptureSchedulerTest
: public testing::Test
{
20 CaptureSchedulerTest() : capture_called_(false) {}
22 void InitScheduler() {
23 scheduler_
.reset(new CaptureScheduler(
24 base::Bind(&CaptureSchedulerTest::DoCapture
, base::Unretained(this))));
25 scheduler_
->set_minimum_interval(
26 base::TimeDelta::FromMilliseconds(kMinumumFrameIntervalMs
));
27 tick_clock_
= new base::SimpleTestTickClock();
28 scheduler_
->SetTickClockForTest(make_scoped_ptr(tick_clock_
));
29 capture_timer_
= new base::MockTimer(false, false);
30 scheduler_
->SetTimerForTest(make_scoped_ptr(capture_timer_
));
35 capture_called_
= true;
38 void CheckCaptureCalled() {
39 EXPECT_TRUE(capture_called_
);
40 capture_called_
= false;
43 void SimulateSingleFrameCapture(
44 base::TimeDelta capture_delay
,
45 base::TimeDelta encode_delay
,
46 base::TimeDelta expected_delay_between_frames
) {
47 capture_timer_
->Fire();
49 tick_clock_
->Advance(capture_delay
);
50 scheduler_
->OnCaptureCompleted();
53 packet
.set_encode_time_ms(encode_delay
.InMilliseconds());
54 scheduler_
->OnFrameEncoded(&packet
);
56 scheduler_
->OnFrameSent();
58 scoped_ptr
<VideoAck
> ack(new VideoAck());
59 ack
->set_frame_id(packet
.frame_id());
60 scheduler_
->ProcessVideoAck(ack
.Pass());
62 EXPECT_TRUE(capture_timer_
->IsRunning());
63 EXPECT_EQ(std::max(base::TimeDelta(),
64 expected_delay_between_frames
- capture_delay
),
65 capture_timer_
->GetCurrentDelay());
69 base::MessageLoop message_loop_
;
71 scoped_ptr
<CaptureScheduler
> scheduler_
;
73 // Owned by |scheduler_|.
74 base::SimpleTestTickClock
* tick_clock_
;
75 base::MockTimer
* capture_timer_
;
80 TEST_F(CaptureSchedulerTest
, SingleSampleSameTimes
) {
81 const int kTestResults
[][arraysize(kTestInputs
)] = {
82 { 400, 200, 120, 80, 50, 120, 240, 320 }, // One core.
83 { 200, 100, 60, 50, 50, 60, 120, 160 }, // Two cores.
84 { 100, 50, 50, 50, 50, 50, 60, 80 }, // Four cores.
85 { 50, 50, 50, 50, 50, 50, 50, 50 } // Eight cores.
88 for (size_t i
= 0; i
< arraysize(kTestResults
); ++i
) {
89 for (size_t j
= 0; j
< arraysize(kTestInputs
); ++j
) {
91 scheduler_
->SetNumOfProcessorsForTest(1 << i
);
93 SimulateSingleFrameCapture(
94 base::TimeDelta::FromMilliseconds(kTestInputs
[j
]),
95 base::TimeDelta::FromMilliseconds(kTestInputs
[j
]),
96 base::TimeDelta::FromMilliseconds(kTestResults
[i
][j
]));
101 TEST_F(CaptureSchedulerTest
, SingleSampleDifferentTimes
) {
102 const int kTestResults
[][arraysize(kTestInputs
)] = {
103 { 360, 220, 120, 60, 60, 120, 220, 360 }, // One core.
104 { 180, 110, 60, 50, 50, 60, 110, 180 }, // Two cores.
105 { 90, 55, 50, 50, 50, 50, 55, 90 }, // Four cores.
106 { 50, 50, 50, 50, 50, 50, 50, 50 } // Eight cores.
109 for (size_t i
= 0; i
< arraysize(kTestResults
); ++i
) {
110 for (size_t j
= 0; j
< arraysize(kTestInputs
); ++j
) {
112 scheduler_
->SetNumOfProcessorsForTest(1 << i
);
114 SimulateSingleFrameCapture(
115 base::TimeDelta::FromMilliseconds(kTestInputs
[j
]),
116 base::TimeDelta::FromMilliseconds(
117 kTestInputs
[arraysize(kTestInputs
) - 1 - j
]),
118 base::TimeDelta::FromMilliseconds(kTestResults
[i
][j
]));
123 TEST_F(CaptureSchedulerTest
, RollingAverageDifferentTimes
) {
124 const int kTestResults
[][arraysize(kTestInputs
)] = {
125 { 360, 290, 233, 133, 80, 80, 133, 233 }, // One core.
126 { 180, 145, 116, 66, 50, 50, 66, 116 }, // Two cores.
127 { 90, 72, 58, 50, 50, 50, 50, 58 }, // Four cores.
128 { 50, 50, 50, 50, 50, 50, 50, 50 } // Eight cores.
131 for (size_t i
= 0; i
< arraysize(kTestResults
); ++i
) {
133 scheduler_
->SetNumOfProcessorsForTest(1 << i
);
134 for (size_t j
= 0; j
< arraysize(kTestInputs
); ++j
) {
135 SimulateSingleFrameCapture(
136 base::TimeDelta::FromMilliseconds(kTestInputs
[j
]),
137 base::TimeDelta::FromMilliseconds(
138 kTestInputs
[arraysize(kTestInputs
) - 1 - j
]),
139 base::TimeDelta::FromMilliseconds(kTestResults
[i
][j
]));
144 // Verify that we never have more than 2 encoding frames.
145 TEST_F(CaptureSchedulerTest
, MaximumEncodingFrames
) {
148 // Process the first frame to let the scheduler know that receiver supports
150 SimulateSingleFrameCapture(
151 base::TimeDelta(), base::TimeDelta(),
152 base::TimeDelta::FromMilliseconds(kMinumumFrameIntervalMs
));
154 capture_timer_
->Fire();
155 CheckCaptureCalled();
156 scheduler_
->OnCaptureCompleted();
158 capture_timer_
->Fire();
159 CheckCaptureCalled();
160 scheduler_
->OnCaptureCompleted();
162 EXPECT_FALSE(capture_timer_
->IsRunning());
164 scheduler_
->OnFrameEncoded(&packet
);
165 EXPECT_TRUE(capture_timer_
->IsRunning());
168 // Verify that the scheduler doesn't exceed maximum number of pending frames.
169 TEST_F(CaptureSchedulerTest
, MaximumPendingFrames
) {
172 // Process the first frame to let the scheduler know that receiver supports
174 SimulateSingleFrameCapture(
175 base::TimeDelta(), base::TimeDelta(),
176 base::TimeDelta::FromMilliseconds(kMinumumFrameIntervalMs
));
178 // Queue some frames until the sender is blocked.
179 while (capture_timer_
->IsRunning()) {
180 capture_timer_
->Fire();
181 CheckCaptureCalled();
182 scheduler_
->OnCaptureCompleted();
184 scheduler_
->OnFrameEncoded(&packet
);
185 scheduler_
->OnFrameSent();
188 // Next frame should be scheduled, once one of the queued frames is
190 EXPECT_FALSE(capture_timer_
->IsRunning());
191 scheduler_
->ProcessVideoAck(make_scoped_ptr(new VideoAck()));
192 EXPECT_TRUE(capture_timer_
->IsRunning());
195 // Verify that the scheduler doesn't exceed maximum number of pending frames
196 // when acks are not supported.
197 TEST_F(CaptureSchedulerTest
, MaximumPendingFramesNoAcks
) {
200 // Queue some frames until the sender is blocked.
201 while (capture_timer_
->IsRunning()) {
202 capture_timer_
->Fire();
203 CheckCaptureCalled();
204 scheduler_
->OnCaptureCompleted();
206 scheduler_
->OnFrameEncoded(&packet
);
209 // Next frame should be scheduled, once one of the queued frames is sent.
210 EXPECT_FALSE(capture_timer_
->IsRunning());
211 scheduler_
->OnFrameSent();
212 EXPECT_TRUE(capture_timer_
->IsRunning());
214 } // namespace remoting