OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "remoting/host/capture_scheduler.h" | |
6 | |
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" | |
12 | |
13 namespace remoting { | |
14 | |
15 static const int kTestInputs[] = { 100, 50, 30, 20, 10, 30, 60, 80 }; | |
16 static const int kMinumumFrameIntervalMs = 50; | |
17 | |
18 class CaptureSchedulerTest : public testing::Test { | |
19 public: | |
20 CaptureSchedulerTest() : capture_called_(false) {} | |
21 | |
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_)); | |
31 scheduler_->Start(); | |
32 } | |
33 | |
34 void DoCapture() { | |
35 capture_called_ = true; | |
36 } | |
37 | |
38 void CheckCaptureCalled() { | |
39 EXPECT_TRUE(capture_called_); | |
40 capture_called_ = false; | |
41 } | |
42 | |
43 void SimulateSingleFrameCapture( | |
44 base::TimeDelta capture_delay, | |
45 base::TimeDelta encode_delay, | |
46 base::TimeDelta expected_delay_between_frames) { | |
47 capture_timer_->Fire(); | |
48 CheckCaptureCalled(); | |
49 tick_clock_->Advance(capture_delay); | |
50 scheduler_->OnCaptureCompleted(); | |
51 | |
52 VideoPacket packet; | |
53 packet.set_encode_time_ms(encode_delay.InMilliseconds()); | |
54 scheduler_->OnFrameEncoded(&packet); | |
55 | |
56 scheduler_->OnFrameSent(); | |
57 | |
58 scoped_ptr<VideoAck> ack(new VideoAck()); | |
59 ack->set_frame_id(packet.frame_id()); | |
60 scheduler_->ProcessVideoAck(ack.Pass()); | |
61 | |
62 EXPECT_TRUE(capture_timer_->IsRunning()); | |
63 EXPECT_EQ(std::max(base::TimeDelta(), | |
64 expected_delay_between_frames - capture_delay), | |
65 capture_timer_->GetCurrentDelay()); | |
66 } | |
67 | |
68 protected: | |
69 base::MessageLoop message_loop_; | |
70 | |
71 scoped_ptr<CaptureScheduler> scheduler_; | |
72 | |
73 // Owned by |scheduler_|. | |
74 base::SimpleTestTickClock* tick_clock_; | |
75 base::MockTimer* capture_timer_; | |
76 | |
77 bool capture_called_; | |
78 }; | |
79 | |
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. | |
86 }; | |
87 | |
88 for (size_t i = 0; i < arraysize(kTestResults); ++i) { | |
89 for (size_t j = 0; j < arraysize(kTestInputs); ++j) { | |
90 InitScheduler(); | |
91 scheduler_->SetNumOfProcessorsForTest(1 << i); | |
92 | |
93 SimulateSingleFrameCapture( | |
94 base::TimeDelta::FromMilliseconds(kTestInputs[j]), | |
95 base::TimeDelta::FromMilliseconds(kTestInputs[j]), | |
96 base::TimeDelta::FromMilliseconds(kTestResults[i][j])); | |
97 } | |
98 } | |
99 } | |
100 | |
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. | |
107 }; | |
108 | |
109 for (size_t i = 0; i < arraysize(kTestResults); ++i) { | |
110 for (size_t j = 0; j < arraysize(kTestInputs); ++j) { | |
111 InitScheduler(); | |
112 scheduler_->SetNumOfProcessorsForTest(1 << i); | |
113 | |
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])); | |
119 } | |
120 } | |
121 } | |
122 | |
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. | |
129 }; | |
130 | |
131 for (size_t i = 0; i < arraysize(kTestResults); ++i) { | |
132 InitScheduler(); | |
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])); | |
140 } | |
141 } | |
142 } | |
143 | |
144 // Verify that we never have more than 2 encoding frames. | |
145 TEST_F(CaptureSchedulerTest, MaximumEncodingFrames) { | |
146 InitScheduler(); | |
147 | |
148 // Process the first frame to let the scheduler know that receiver supports | |
149 // ACKs. | |
150 SimulateSingleFrameCapture( | |
151 base::TimeDelta(), base::TimeDelta(), | |
152 base::TimeDelta::FromMilliseconds(kMinumumFrameIntervalMs)); | |
153 | |
154 capture_timer_->Fire(); | |
155 CheckCaptureCalled(); | |
156 scheduler_->OnCaptureCompleted(); | |
157 | |
158 capture_timer_->Fire(); | |
159 CheckCaptureCalled(); | |
160 scheduler_->OnCaptureCompleted(); | |
161 | |
162 EXPECT_FALSE(capture_timer_->IsRunning()); | |
163 VideoPacket packet; | |
164 scheduler_->OnFrameEncoded(&packet); | |
165 EXPECT_TRUE(capture_timer_->IsRunning()); | |
166 } | |
167 | |
168 // Verify that the scheduler doesn't exceed maximum number of pending frames. | |
169 TEST_F(CaptureSchedulerTest, MaximumPendingFrames) { | |
170 InitScheduler(); | |
171 | |
172 // Process the first frame to let the scheduler know that receiver supports | |
173 // ACKs. | |
174 SimulateSingleFrameCapture( | |
175 base::TimeDelta(), base::TimeDelta(), | |
176 base::TimeDelta::FromMilliseconds(kMinumumFrameIntervalMs)); | |
177 | |
178 // Queue some frames until the sender is blocked. | |
179 while (capture_timer_->IsRunning()) { | |
180 capture_timer_->Fire(); | |
181 CheckCaptureCalled(); | |
182 scheduler_->OnCaptureCompleted(); | |
183 VideoPacket packet; | |
184 scheduler_->OnFrameEncoded(&packet); | |
185 scheduler_->OnFrameSent(); | |
186 } | |
187 | |
188 // Next frame should be scheduled, once one of the queued frames is | |
189 // acknowledged. | |
190 EXPECT_FALSE(capture_timer_->IsRunning()); | |
191 scheduler_->ProcessVideoAck(make_scoped_ptr(new VideoAck())); | |
192 EXPECT_TRUE(capture_timer_->IsRunning()); | |
193 } | |
194 | |
195 } // namespace remoting | |
OLD | NEW |