OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2010 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2010 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 // If we don't have a WebRtcVideoFrame, just skip all of these tests. | |
12 #if defined(HAVE_WEBRTC_VIDEO) | |
13 #include <limits.h> // For INT_MAX | 11 #include <limits.h> // For INT_MAX |
14 | 12 |
15 #include <memory> | |
16 #include <string> | 13 #include <string> |
17 #include <vector> | 14 #include <vector> |
18 | 15 |
19 #include "webrtc/base/gunit.h" | 16 #include "webrtc/base/gunit.h" |
20 #include "webrtc/base/logging.h" | 17 #include "webrtc/base/logging.h" |
21 #include "webrtc/base/sigslot.h" | |
22 #include "webrtc/media/base/fakevideocapturer.h" | 18 #include "webrtc/media/base/fakevideocapturer.h" |
23 #include "webrtc/media/base/mediachannel.h" | 19 #include "webrtc/media/base/mediachannel.h" |
24 #include "webrtc/media/base/testutils.h" | 20 #include "webrtc/media/base/testutils.h" |
25 #include "webrtc/media/base/videoadapter.h" | 21 #include "webrtc/media/base/videoadapter.h" |
26 | 22 |
27 namespace cricket { | 23 namespace cricket { |
28 | 24 |
29 namespace { | |
30 static const uint32_t kWaitTimeout = 3000U; // 3 seconds. | |
31 static const uint32_t kShortWaitTimeout = 1000U; // 1 second. | |
32 void UpdateCpuLoad(CoordinatedVideoAdapter* adapter, | |
33 int current_cpus, int max_cpus, float process_load, float system_load) { | |
34 adapter->set_cpu_load_min_samples(1); | |
35 adapter->OnCpuLoadUpdated(current_cpus, max_cpus, | |
36 process_load, system_load); | |
37 } | |
38 } | |
39 | |
40 class VideoAdapterTest : public testing::Test { | 25 class VideoAdapterTest : public testing::Test { |
41 public: | 26 public: |
42 virtual void SetUp() { | 27 virtual void SetUp() { |
43 capturer_.reset(new FakeVideoCapturer); | 28 capturer_.reset(new FakeVideoCapturer); |
44 capture_format_ = capturer_->GetSupportedFormats()->at(0); | 29 capture_format_ = capturer_->GetSupportedFormats()->at(0); |
45 capture_format_.interval = VideoFormat::FpsToInterval(50); | 30 capture_format_.interval = VideoFormat::FpsToInterval(50); |
46 adapter_.reset(new VideoAdapter()); | 31 adapter_.SetExpectedInputFrameInterval(capture_format_.interval); |
47 adapter_->SetInputFormat(capture_format_); | |
48 | 32 |
49 listener_.reset(new VideoCapturerListener(adapter_.get())); | 33 listener_.reset(new VideoCapturerListener(&adapter_)); |
50 capturer_->SignalFrameCaptured.connect( | 34 capturer_->SignalFrameCaptured.connect( |
51 listener_.get(), &VideoCapturerListener::OnFrameCaptured); | 35 listener_.get(), &VideoCapturerListener::OnFrameCaptured); |
52 } | 36 } |
53 | 37 |
54 virtual void TearDown() { | 38 virtual void TearDown() { |
55 // Explicitly disconnect the VideoCapturer before to avoid data races | 39 // Explicitly disconnect the VideoCapturer before to avoid data races |
56 // (frames delivered to VideoCapturerListener while it's being destructed). | 40 // (frames delivered to VideoCapturerListener while it's being destructed). |
57 capturer_->SignalFrameCaptured.disconnect_all(); | 41 capturer_->SignalFrameCaptured.disconnect_all(); |
58 } | 42 } |
59 | 43 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 | 95 |
112 private: | 96 private: |
113 rtc::CriticalSection crit_; | 97 rtc::CriticalSection crit_; |
114 VideoAdapter* video_adapter_; | 98 VideoAdapter* video_adapter_; |
115 VideoFormat adapted_format_; | 99 VideoFormat adapted_format_; |
116 int captured_frames_; | 100 int captured_frames_; |
117 int dropped_frames_; | 101 int dropped_frames_; |
118 bool last_adapt_was_no_op_; | 102 bool last_adapt_was_no_op_; |
119 }; | 103 }; |
120 | 104 |
121 class CpuAdapterListener: public sigslot::has_slots<> { | |
122 public: | |
123 CpuAdapterListener() : received_cpu_signal_(false) {} | |
124 void OnCpuAdaptationSignalled() { received_cpu_signal_ = true; } | |
125 bool received_cpu_signal() { return received_cpu_signal_; } | |
126 private: | |
127 bool received_cpu_signal_; | |
128 }; | |
129 | 105 |
130 void VerifyAdaptedResolution(const VideoCapturerListener::Stats& stats, | 106 void VerifyAdaptedResolution(const VideoCapturerListener::Stats& stats, |
131 int width, | 107 int width, |
132 int height) { | 108 int height) { |
133 EXPECT_EQ(width, stats.adapted_width); | 109 EXPECT_EQ(width, stats.adapted_width); |
134 EXPECT_EQ(height, stats.adapted_height); | 110 EXPECT_EQ(height, stats.adapted_height); |
135 } | 111 } |
136 | 112 |
137 std::unique_ptr<FakeVideoCapturer> capturer_; | 113 std::unique_ptr<FakeVideoCapturer> capturer_; |
138 std::unique_ptr<VideoAdapter> adapter_; | 114 VideoAdapter adapter_; |
139 std::unique_ptr<VideoCapturerListener> listener_; | 115 std::unique_ptr<VideoCapturerListener> listener_; |
140 VideoFormat capture_format_; | 116 VideoFormat capture_format_; |
141 }; | 117 }; |
142 | 118 |
143 | 119 // Do not adapt the frame rate or the resolution. Expect no frame drop and no |
144 // Test adapter remembers exact pixel count | |
145 TEST_F(VideoAdapterTest, AdaptNumPixels) { | |
146 adapter_->SetOutputNumPixels(123456); | |
147 EXPECT_EQ(123456, adapter_->GetOutputNumPixels()); | |
148 } | |
149 | |
150 // Test adapter is constructed but not activated. Expect no frame drop and no | |
151 // resolution change. | 120 // resolution change. |
152 TEST_F(VideoAdapterTest, AdaptInactive) { | 121 TEST_F(VideoAdapterTest, AdaptNothing) { |
153 // Output resolution is not set. | |
154 EXPECT_EQ(INT_MAX, adapter_->GetOutputNumPixels()); | |
155 | |
156 // Call Adapter with some frames. | |
157 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); | 122 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); |
158 for (int i = 0; i < 10; ++i) | 123 for (int i = 0; i < 10; ++i) |
159 capturer_->CaptureFrame(); | 124 capturer_->CaptureFrame(); |
160 | |
161 // Verify no frame drop and no resolution change. | |
162 VideoCapturerListener::Stats stats = listener_->GetStats(); | |
163 EXPECT_GE(stats.captured_frames, 10); | |
164 EXPECT_EQ(0, stats.dropped_frames); | |
165 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height); | |
166 } | |
167 | |
168 // Do not adapt the frame rate or the resolution. Expect no frame drop and no | |
169 // resolution change. | |
170 TEST_F(VideoAdapterTest, AdaptNothing) { | |
171 adapter_->SetOutputFormat(capture_format_); | |
172 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); | |
173 for (int i = 0; i < 10; ++i) | |
174 capturer_->CaptureFrame(); | |
175 | 125 |
176 // Verify no frame drop and no resolution change. | 126 // Verify no frame drop and no resolution change. |
177 VideoCapturerListener::Stats stats = listener_->GetStats(); | 127 VideoCapturerListener::Stats stats = listener_->GetStats(); |
178 EXPECT_GE(stats.captured_frames, 10); | 128 EXPECT_GE(stats.captured_frames, 10); |
179 EXPECT_EQ(0, stats.dropped_frames); | 129 EXPECT_EQ(0, stats.dropped_frames); |
180 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height); | 130 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height); |
181 EXPECT_TRUE(stats.last_adapt_was_no_op); | 131 EXPECT_TRUE(stats.last_adapt_was_no_op); |
182 } | 132 } |
183 | 133 |
184 TEST_F(VideoAdapterTest, AdaptZeroInterval) { | 134 TEST_F(VideoAdapterTest, AdaptZeroInterval) { |
185 VideoFormat format = capturer_->GetSupportedFormats()->at(0); | 135 VideoFormat format = capturer_->GetSupportedFormats()->at(0); |
186 format.interval = 0; | 136 format.interval = 0; |
187 adapter_->SetInputFormat(format); | 137 adapter_.OnOutputFormatRequest(format); |
188 adapter_->SetOutputFormat(format); | |
189 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); | 138 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); |
190 for (int i = 0; i < 10; ++i) | 139 for (int i = 0; i < 10; ++i) |
191 capturer_->CaptureFrame(); | 140 capturer_->CaptureFrame(); |
192 | 141 |
193 // Verify no crash and that frames aren't dropped. | 142 // Verify no crash and that frames aren't dropped. |
194 VideoCapturerListener::Stats stats = listener_->GetStats(); | 143 VideoCapturerListener::Stats stats = listener_->GetStats(); |
195 EXPECT_GE(stats.captured_frames, 10); | 144 EXPECT_GE(stats.captured_frames, 10); |
196 EXPECT_EQ(0, stats.dropped_frames); | 145 EXPECT_EQ(0, stats.dropped_frames); |
197 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height); | 146 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height); |
198 } | 147 } |
199 | 148 |
200 // Adapt the frame rate to be half of the capture rate at the beginning. Expect | 149 // Adapt the frame rate to be half of the capture rate at the beginning. Expect |
201 // the number of dropped frames to be half of the number the captured frames. | 150 // the number of dropped frames to be half of the number the captured frames. |
202 TEST_F(VideoAdapterTest, AdaptFramerate) { | 151 TEST_F(VideoAdapterTest, AdaptFramerate) { |
203 VideoFormat request_format = capture_format_; | 152 VideoFormat request_format = capture_format_; |
204 request_format.interval *= 2; | 153 request_format.interval *= 2; |
205 adapter_->SetOutputFormat(request_format); | 154 adapter_.OnOutputFormatRequest(request_format); |
206 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); | 155 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); |
207 for (int i = 0; i < 10; ++i) | 156 for (int i = 0; i < 10; ++i) |
208 capturer_->CaptureFrame(); | 157 capturer_->CaptureFrame(); |
209 | 158 |
210 // Verify frame drop and no resolution change. | 159 // Verify frame drop and no resolution change. |
211 VideoCapturerListener::Stats stats = listener_->GetStats(); | 160 VideoCapturerListener::Stats stats = listener_->GetStats(); |
212 EXPECT_GE(stats.captured_frames, 10); | 161 EXPECT_GE(stats.captured_frames, 10); |
213 EXPECT_EQ(stats.captured_frames / 2, stats.dropped_frames); | 162 EXPECT_EQ(stats.captured_frames / 2, stats.dropped_frames); |
214 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height); | 163 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height); |
215 } | 164 } |
216 | 165 |
217 // Adapt the frame rate to be half of the capture rate at the beginning. Expect | 166 // Adapt the frame rate to be half of the capture rate at the beginning. Expect |
218 // the number of dropped frames to be half of the number the captured frames. | 167 // the number of dropped frames to be half of the number the captured frames. |
219 TEST_F(VideoAdapterTest, AdaptFramerateVariable) { | 168 TEST_F(VideoAdapterTest, AdaptFramerateVariable) { |
220 VideoFormat request_format = capture_format_; | 169 VideoFormat request_format = capture_format_; |
221 request_format.interval = request_format.interval * 3 / 2; | 170 request_format.interval = request_format.interval * 3 / 2; |
222 adapter_->SetOutputFormat(request_format); | 171 adapter_.OnOutputFormatRequest(request_format); |
223 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); | 172 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); |
224 for (int i = 0; i < 30; ++i) | 173 for (int i = 0; i < 30; ++i) |
225 capturer_->CaptureFrame(); | 174 capturer_->CaptureFrame(); |
226 | 175 |
227 // Verify frame drop and no resolution change. | 176 // Verify frame drop and no resolution change. |
228 VideoCapturerListener::Stats stats = listener_->GetStats(); | 177 VideoCapturerListener::Stats stats = listener_->GetStats(); |
229 EXPECT_GE(stats.captured_frames, 30); | 178 EXPECT_GE(stats.captured_frames, 30); |
230 // Verify 2 / 3 kept (20) and 1 / 3 dropped (10). | 179 // Verify 2 / 3 kept (20) and 1 / 3 dropped (10). |
231 EXPECT_EQ(stats.captured_frames * 1 / 3, stats.dropped_frames); | 180 EXPECT_EQ(stats.captured_frames * 1 / 3, stats.dropped_frames); |
232 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height); | 181 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height); |
233 } | 182 } |
234 | 183 |
235 // Adapt the frame rate to be half of the capture rate after capturing no less | 184 // Adapt the frame rate to be half of the capture rate after capturing no less |
236 // than 10 frames. Expect no frame dropped before adaptation and frame dropped | 185 // than 10 frames. Expect no frame dropped before adaptation and frame dropped |
237 // after adaptation. | 186 // after adaptation. |
238 TEST_F(VideoAdapterTest, AdaptFramerateOntheFly) { | 187 TEST_F(VideoAdapterTest, AdaptFramerateOntheFly) { |
239 VideoFormat request_format = capture_format_; | 188 VideoFormat request_format = capture_format_; |
240 adapter_->SetOutputFormat(request_format); | 189 adapter_.OnOutputFormatRequest(request_format); |
241 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); | 190 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); |
242 for (int i = 0; i < 10; ++i) | 191 for (int i = 0; i < 10; ++i) |
243 capturer_->CaptureFrame(); | 192 capturer_->CaptureFrame(); |
244 | 193 |
245 // Verify no frame drop before adaptation. | 194 // Verify no frame drop before adaptation. |
246 EXPECT_EQ(0, listener_->GetStats().dropped_frames); | 195 EXPECT_EQ(0, listener_->GetStats().dropped_frames); |
247 | 196 |
248 // Adapat the frame rate. | 197 // Adapat the frame rate. |
249 request_format.interval *= 2; | 198 request_format.interval *= 2; |
250 adapter_->SetOutputFormat(request_format); | 199 adapter_.OnOutputFormatRequest(request_format); |
251 | 200 |
252 for (int i = 0; i < 20; ++i) | 201 for (int i = 0; i < 20; ++i) |
253 capturer_->CaptureFrame(); | 202 capturer_->CaptureFrame(); |
254 | 203 |
255 // Verify frame drop after adaptation. | 204 // Verify frame drop after adaptation. |
256 EXPECT_GT(listener_->GetStats().dropped_frames, 0); | 205 EXPECT_GT(listener_->GetStats().dropped_frames, 0); |
257 } | 206 } |
258 | 207 |
259 // Set a very high output pixel resolution. Expect no resolution change. | 208 // Set a very high output pixel resolution. Expect no resolution change. |
260 TEST_F(VideoAdapterTest, AdaptFrameResolutionHighLimit) { | 209 TEST_F(VideoAdapterTest, AdaptFrameResolutionHighLimit) { |
261 adapter_->SetOutputNumPixels(INT_MAX); | 210 VideoFormat output_format = capture_format_; |
262 VideoFormat adapted_format = adapter_->AdaptFrameResolution( | 211 output_format.width = 2560; |
| 212 output_format.height = 2560; |
| 213 adapter_.OnOutputFormatRequest(output_format); |
| 214 VideoFormat adapted_format = adapter_.AdaptFrameResolution( |
263 capture_format_.width, capture_format_.height); | 215 capture_format_.width, capture_format_.height); |
264 EXPECT_EQ(capture_format_.width, adapted_format.width); | 216 EXPECT_EQ(capture_format_.width, adapted_format.width); |
265 EXPECT_EQ(capture_format_.height, adapted_format.height); | 217 EXPECT_EQ(capture_format_.height, adapted_format.height); |
266 | |
267 adapter_->SetOutputNumPixels(987654321); | |
268 adapted_format = capture_format_, | |
269 adapter_->AdaptFrameResolution(capture_format_.width, capture_format_.height); | |
270 EXPECT_EQ(capture_format_.width, adapted_format.width); | |
271 EXPECT_EQ(capture_format_.height, adapted_format.height); | |
272 } | 218 } |
273 | 219 |
274 // Adapt the frame resolution to be the same as capture resolution. Expect no | 220 // Adapt the frame resolution to be the same as capture resolution. Expect no |
275 // resolution change. | 221 // resolution change. |
276 TEST_F(VideoAdapterTest, AdaptFrameResolutionIdentical) { | 222 TEST_F(VideoAdapterTest, AdaptFrameResolutionIdentical) { |
277 adapter_->SetOutputFormat(capture_format_); | 223 adapter_.OnOutputFormatRequest(capture_format_); |
278 const VideoFormat adapted_format = adapter_->AdaptFrameResolution( | 224 const VideoFormat adapted_format = adapter_.AdaptFrameResolution( |
279 capture_format_.width, capture_format_.height); | 225 capture_format_.width, capture_format_.height); |
280 EXPECT_EQ(capture_format_.width, adapted_format.width); | 226 EXPECT_EQ(capture_format_.width, adapted_format.width); |
281 EXPECT_EQ(capture_format_.height, adapted_format.height); | 227 EXPECT_EQ(capture_format_.height, adapted_format.height); |
282 } | 228 } |
283 | 229 |
284 // Adapt the frame resolution to be a quarter of the capture resolution. Expect | 230 // Adapt the frame resolution to be a quarter of the capture resolution. Expect |
285 // resolution change. | 231 // resolution change. |
286 TEST_F(VideoAdapterTest, AdaptFrameResolutionQuarter) { | 232 TEST_F(VideoAdapterTest, AdaptFrameResolutionQuarter) { |
287 VideoFormat request_format = capture_format_; | 233 VideoFormat request_format = capture_format_; |
288 request_format.width /= 2; | 234 request_format.width /= 2; |
289 request_format.height /= 2; | 235 request_format.height /= 2; |
290 adapter_->SetOutputFormat(request_format); | 236 adapter_.OnOutputFormatRequest(request_format); |
291 const VideoFormat adapted_format = adapter_->AdaptFrameResolution( | 237 const VideoFormat adapted_format = adapter_.AdaptFrameResolution( |
292 request_format.width, request_format.height); | 238 request_format.width, request_format.height); |
293 EXPECT_EQ(request_format.width, adapted_format.width); | 239 EXPECT_EQ(request_format.width, adapted_format.width); |
294 EXPECT_EQ(request_format.height, adapted_format.height); | 240 EXPECT_EQ(request_format.height, adapted_format.height); |
295 } | 241 } |
296 | 242 |
297 // Adapt the pixel resolution to 0. Expect frame drop. | 243 // Adapt the pixel resolution to 0. Expect frame drop. |
298 TEST_F(VideoAdapterTest, AdaptFrameResolutionDrop) { | 244 TEST_F(VideoAdapterTest, AdaptFrameResolutionDrop) { |
299 adapter_->SetOutputNumPixels(0); | 245 VideoFormat output_format = capture_format_; |
| 246 output_format.width = 0; |
| 247 output_format.height = 0; |
| 248 adapter_.OnOutputFormatRequest(output_format); |
300 EXPECT_TRUE( | 249 EXPECT_TRUE( |
301 adapter_->AdaptFrameResolution(capture_format_.width, | 250 adapter_ |
302 capture_format_.height).IsSize0x0()); | 251 .AdaptFrameResolution(capture_format_.width, capture_format_.height) |
| 252 .IsSize0x0()); |
303 } | 253 } |
304 | 254 |
305 // Adapt the frame resolution to be a quarter of the capture resolution at the | 255 // Adapt the frame resolution to be a quarter of the capture resolution at the |
306 // beginning. Expect resolution change. | 256 // beginning. Expect resolution change. |
307 TEST_F(VideoAdapterTest, AdaptResolution) { | 257 TEST_F(VideoAdapterTest, AdaptResolution) { |
308 VideoFormat request_format = capture_format_; | 258 VideoFormat request_format = capture_format_; |
309 request_format.width /= 2; | 259 request_format.width /= 2; |
310 request_format.height /= 2; | 260 request_format.height /= 2; |
311 adapter_->SetOutputFormat(request_format); | 261 adapter_.OnOutputFormatRequest(request_format); |
312 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); | 262 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); |
313 for (int i = 0; i < 10; ++i) | 263 for (int i = 0; i < 10; ++i) |
314 capturer_->CaptureFrame(); | 264 capturer_->CaptureFrame(); |
315 | 265 |
316 // Verify no frame drop and resolution change. | 266 // Verify no frame drop and resolution change. |
317 VideoCapturerListener::Stats stats = listener_->GetStats(); | 267 VideoCapturerListener::Stats stats = listener_->GetStats(); |
318 EXPECT_EQ(0, stats.dropped_frames); | 268 EXPECT_EQ(0, stats.dropped_frames); |
319 VerifyAdaptedResolution(stats, request_format.width, request_format.height); | 269 VerifyAdaptedResolution(stats, request_format.width, request_format.height); |
320 } | 270 } |
321 | 271 |
322 // Adapt the frame resolution to half width. Expect resolution change. | |
323 TEST_F(VideoAdapterTest, AdaptResolutionNarrow) { | |
324 VideoFormat request_format = capture_format_; | |
325 request_format.width /= 2; | |
326 adapter_->set_scale_third(true); | |
327 adapter_->SetOutputFormat(request_format); | |
328 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); | |
329 for (int i = 0; i < 10; ++i) | |
330 capturer_->CaptureFrame(); | |
331 | |
332 // Verify resolution change. | |
333 VerifyAdaptedResolution(listener_->GetStats(), | |
334 capture_format_.width * 2 / 3, | |
335 capture_format_.height * 2 / 3); | |
336 } | |
337 | |
338 // Adapt the frame resolution to half height. Expect resolution change. | |
339 TEST_F(VideoAdapterTest, AdaptResolutionWide) { | |
340 VideoFormat request_format = capture_format_; | |
341 request_format.height /= 2; | |
342 adapter_->set_scale_third(true); | |
343 adapter_->SetOutputFormat(request_format); | |
344 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); | |
345 for (int i = 0; i < 10; ++i) | |
346 capturer_->CaptureFrame(); | |
347 | |
348 // Verify resolution change. | |
349 VerifyAdaptedResolution(listener_->GetStats(), | |
350 capture_format_.width * 2 / 3, | |
351 capture_format_.height * 2 / 3); | |
352 } | |
353 | |
354 // Adapt the frame resolution to be a quarter of the capture resolution after | 272 // Adapt the frame resolution to be a quarter of the capture resolution after |
355 // capturing no less than 10 frames. Expect no resolution change before | 273 // capturing no less than 10 frames. Expect no resolution change before |
356 // adaptation and resolution change after adaptation. | 274 // adaptation and resolution change after adaptation. |
357 TEST_F(VideoAdapterTest, AdaptResolutionOnTheFly) { | 275 TEST_F(VideoAdapterTest, AdaptResolutionOnTheFly) { |
358 VideoFormat request_format = capture_format_; | 276 VideoFormat request_format = capture_format_; |
359 adapter_->SetOutputFormat(request_format); | 277 adapter_.OnOutputFormatRequest(request_format); |
360 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); | 278 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); |
361 for (int i = 0; i < 10; ++i) | 279 for (int i = 0; i < 10; ++i) |
362 capturer_->CaptureFrame(); | 280 capturer_->CaptureFrame(); |
363 | 281 |
364 // Verify no resolution change before adaptation. | 282 // Verify no resolution change before adaptation. |
365 VerifyAdaptedResolution( | 283 VerifyAdaptedResolution( |
366 listener_->GetStats(), request_format.width, request_format.height); | 284 listener_->GetStats(), request_format.width, request_format.height); |
367 | 285 |
368 // Adapt the frame resolution. | 286 // Adapt the frame resolution. |
369 request_format.width /= 2; | 287 request_format.width /= 2; |
370 request_format.height /= 2; | 288 request_format.height /= 2; |
371 adapter_->SetOutputFormat(request_format); | 289 adapter_.OnOutputFormatRequest(request_format); |
372 for (int i = 0; i < 10; ++i) | 290 for (int i = 0; i < 10; ++i) |
373 capturer_->CaptureFrame(); | 291 capturer_->CaptureFrame(); |
374 | 292 |
375 // Verify resolution change after adaptation. | 293 // Verify resolution change after adaptation. |
376 VerifyAdaptedResolution( | 294 VerifyAdaptedResolution( |
377 listener_->GetStats(), request_format.width, request_format.height); | 295 listener_->GetStats(), request_format.width, request_format.height); |
378 } | 296 } |
379 | 297 |
380 // Drop all frames. | 298 // Drop all frames. |
381 TEST_F(VideoAdapterTest, DropAllFrames) { | 299 TEST_F(VideoAdapterTest, DropAllFrames) { |
382 VideoFormat format; // with resolution 0x0. | 300 VideoFormat format; // with resolution 0x0. |
383 adapter_->SetOutputFormat(format); | 301 adapter_.OnOutputFormatRequest(format); |
384 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); | 302 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_)); |
385 for (int i = 0; i < 10; ++i) | 303 for (int i = 0; i < 10; ++i) |
386 capturer_->CaptureFrame(); | 304 capturer_->CaptureFrame(); |
387 | 305 |
388 // Verify all frames are dropped. | 306 // Verify all frames are dropped. |
389 VideoCapturerListener::Stats stats = listener_->GetStats(); | 307 VideoCapturerListener::Stats stats = listener_->GetStats(); |
390 EXPECT_GE(stats.captured_frames, 10); | 308 EXPECT_GE(stats.captured_frames, 10); |
391 EXPECT_EQ(stats.captured_frames, stats.dropped_frames); | 309 EXPECT_EQ(stats.captured_frames, stats.dropped_frames); |
392 } | 310 } |
393 | 311 |
394 TEST(CoordinatedVideoAdapterTest, TestCoordinatedWithoutCpuAdaptation) { | 312 TEST_F(VideoAdapterTest, TestOnOutputFormatRequest) { |
395 CoordinatedVideoAdapter adapter; | 313 VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), 0); |
396 adapter.set_cpu_adaptation(false); | 314 adapter_.SetExpectedInputFrameInterval(VideoFormat::FpsToInterval(30)); |
397 | 315 VideoFormat out_format = |
398 VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420); | 316 adapter_.AdaptFrameResolution(format.width, format.height); |
399 adapter.SetInputFormat(format); | 317 EXPECT_EQ(format, adapter_.input_format()); |
400 adapter.set_scale_third(true); | 318 EXPECT_EQ(format, out_format); |
401 EXPECT_EQ(format, adapter.input_format()); | 319 |
402 EXPECT_TRUE(adapter.output_format().IsSize0x0()); | 320 // Format request 640x400. |
403 | |
404 // Server format request 640x400. | |
405 format.height = 400; | 321 format.height = 400; |
406 adapter.OnOutputFormatRequest(format); | 322 adapter_.OnOutputFormatRequest(format); |
407 EXPECT_EQ(640, adapter.output_format().width); | 323 out_format = adapter_.AdaptFrameResolution(640, 400); |
408 EXPECT_EQ(400, adapter.output_format().height); | 324 EXPECT_EQ(640, out_format.width); |
409 | 325 EXPECT_EQ(400, out_format.height); |
410 // Server format request 1280x720, higher than input. Adapt nothing. | 326 |
| 327 // Request 1280x720, higher than input. Adapt nothing. |
411 format.width = 1280; | 328 format.width = 1280; |
412 format.height = 720; | 329 format.height = 720; |
413 adapter.OnOutputFormatRequest(format); | 330 adapter_.OnOutputFormatRequest(format); |
414 EXPECT_EQ(640, adapter.output_format().width); | 331 out_format = adapter_.AdaptFrameResolution(640, 400); |
415 EXPECT_EQ(400, adapter.output_format().height); | 332 EXPECT_EQ(640, out_format.width); |
416 | 333 EXPECT_EQ(400, out_format.height); |
417 // Cpu load is high, but cpu adaptation is disabled. Adapt nothing. | 334 |
418 adapter.OnCpuLoadUpdated(1, 1, 0.99f, 0.99f); | 335 // Request 0x0. |
419 EXPECT_EQ(640, adapter.output_format().width); | |
420 EXPECT_EQ(400, adapter.output_format().height); | |
421 | |
422 // Encoder resolution request: downgrade with different size. Adapt nothing. | |
423 adapter.OnEncoderResolutionRequest(320, 200, | |
424 CoordinatedVideoAdapter::DOWNGRADE); | |
425 EXPECT_EQ(640, adapter.output_format().width); | |
426 EXPECT_EQ(400, adapter.output_format().height); | |
427 | |
428 // Encoder resolution request: downgrade. | |
429 adapter.OnEncoderResolutionRequest(640, 400, | |
430 CoordinatedVideoAdapter::DOWNGRADE); | |
431 EXPECT_EQ(480, adapter.output_format().width); | |
432 EXPECT_EQ(300, adapter.output_format().height); | |
433 | |
434 // Encoder resolution request: downgrade. But GD off. Adapt nothing. | |
435 adapter.set_gd_adaptation(false); | |
436 adapter.OnEncoderResolutionRequest(480, 300, | |
437 CoordinatedVideoAdapter::DOWNGRADE); | |
438 EXPECT_EQ(480, adapter.output_format().width); | |
439 EXPECT_EQ(300, adapter.output_format().height); | |
440 adapter.set_gd_adaptation(true); | |
441 | |
442 // Encoder resolution request: downgrade. | |
443 adapter.OnEncoderResolutionRequest(480, 300, | |
444 CoordinatedVideoAdapter::DOWNGRADE); | |
445 EXPECT_EQ(320, adapter.output_format().width); | |
446 EXPECT_EQ(200, adapter.output_format().height); | |
447 | |
448 // Encoder resolution request: keep. Adapt nothing. | |
449 adapter.OnEncoderResolutionRequest(320, 200, | |
450 CoordinatedVideoAdapter::KEEP); | |
451 EXPECT_EQ(320, adapter.output_format().width); | |
452 EXPECT_EQ(200, adapter.output_format().height); | |
453 | |
454 // Encoder resolution request: upgrade. | |
455 adapter.OnEncoderResolutionRequest(320, 200, | |
456 CoordinatedVideoAdapter::UPGRADE); | |
457 EXPECT_EQ(480, adapter.output_format().width); | |
458 EXPECT_EQ(300, adapter.output_format().height); | |
459 | |
460 // Server format request 0x0. | |
461 format.width = 0; | 336 format.width = 0; |
462 format.height = 0; | 337 format.height = 0; |
463 adapter.OnOutputFormatRequest(format); | 338 adapter_.OnOutputFormatRequest(format); |
464 EXPECT_TRUE(adapter.output_format().IsSize0x0()); | 339 out_format = adapter_.AdaptFrameResolution(640, 400); |
465 | 340 EXPECT_TRUE(out_format.IsSize0x0()); |
466 // Server format request 320x200. | 341 |
| 342 // Request 320x200. |
467 format.width = 320; | 343 format.width = 320; |
468 format.height = 200; | 344 format.height = 200; |
469 adapter.OnOutputFormatRequest(format); | 345 adapter_.OnOutputFormatRequest(format); |
470 EXPECT_EQ(320, adapter.output_format().width); | 346 out_format = adapter_.AdaptFrameResolution(640, 400); |
471 EXPECT_EQ(200, adapter.output_format().height); | 347 EXPECT_EQ(320, out_format.width); |
472 | 348 EXPECT_EQ(200, out_format.height); |
473 // Server format request 160x100. But view disabled. Adapt nothing. | 349 |
474 adapter.set_view_adaptation(false); | 350 // Request resolution of 2 / 3. Expect adapt down. Scaling to 1/3 is not |
475 format.width = 160; | 351 // optimized and not allowed. |
476 format.height = 100; | |
477 adapter.OnOutputFormatRequest(format); | |
478 EXPECT_EQ(320, adapter.output_format().width); | |
479 EXPECT_EQ(200, adapter.output_format().height); | |
480 adapter.set_view_adaptation(true); | |
481 | |
482 // Enable View Switch. Expect adapt down. | |
483 adapter.set_view_switch(true); | |
484 format.width = 160; | |
485 format.height = 100; | |
486 adapter.OnOutputFormatRequest(format); | |
487 EXPECT_EQ(160, adapter.output_format().width); | |
488 EXPECT_EQ(100, adapter.output_format().height); | |
489 | |
490 // Encoder resolution request: upgrade. Adapt nothing. | |
491 adapter.OnEncoderResolutionRequest(160, 100, | |
492 CoordinatedVideoAdapter::UPGRADE); | |
493 EXPECT_EQ(160, adapter.output_format().width); | |
494 EXPECT_EQ(100, adapter.output_format().height); | |
495 | |
496 // Request View of 2 / 3. Expect adapt down. | |
497 adapter.set_view_switch(true); | |
498 format.width = (640 * 2 + 1) / 3; | 352 format.width = (640 * 2 + 1) / 3; |
499 format.height = (400 * 2 + 1) / 3; | 353 format.height = (400 * 2 + 1) / 3; |
500 adapter.OnOutputFormatRequest(format); | 354 adapter_.OnOutputFormatRequest(format); |
501 EXPECT_EQ((640 * 2 + 1) / 3, adapter.output_format().width); | 355 out_format = adapter_.AdaptFrameResolution(640, 400); |
502 EXPECT_EQ((400 * 2 + 1) / 3, adapter.output_format().height); | 356 EXPECT_EQ(320, out_format.width); |
503 | 357 EXPECT_EQ(200, out_format.height); |
504 | 358 |
505 // Request View of 3 / 8. Expect adapt down. | 359 // Request resolution of 3 / 8. Expect adapt down. |
506 adapter.set_view_switch(true); | |
507 format.width = 640 * 3 / 8; | 360 format.width = 640 * 3 / 8; |
508 format.height = 400 * 3 / 8; | 361 format.height = 400 * 3 / 8; |
509 adapter.OnOutputFormatRequest(format); | 362 adapter_.OnOutputFormatRequest(format); |
510 EXPECT_EQ(640 * 3 / 8, adapter.output_format().width); | 363 out_format = adapter_.AdaptFrameResolution(640, 400); |
511 EXPECT_EQ(400 * 3 / 8, adapter.output_format().height); | 364 EXPECT_EQ(640 * 3 / 8, out_format.width); |
512 | 365 EXPECT_EQ(400 * 3 / 8, out_format.height); |
513 // View Switch back up. Expect adapt. | 366 |
| 367 // Switch back up. Expect adapt. |
514 format.width = 320; | 368 format.width = 320; |
515 format.height = 200; | 369 format.height = 200; |
516 adapter.OnOutputFormatRequest(format); | 370 adapter_.OnOutputFormatRequest(format); |
517 EXPECT_EQ(320, adapter.output_format().width); | 371 out_format = adapter_.AdaptFrameResolution(640, 400); |
518 EXPECT_EQ(200, adapter.output_format().height); | 372 EXPECT_EQ(320, out_format.width); |
519 | 373 EXPECT_EQ(200, out_format.height); |
520 adapter.set_view_switch(false); | 374 |
521 | 375 // Format request 480x300. |
522 // Encoder resolution request: upgrade. Constrained by server request. | |
523 adapter.OnEncoderResolutionRequest(320, 200, | |
524 CoordinatedVideoAdapter::UPGRADE); | |
525 EXPECT_EQ(320, adapter.output_format().width); | |
526 EXPECT_EQ(200, adapter.output_format().height); | |
527 | |
528 // Server format request 480x300. | |
529 format.width = 480; | 376 format.width = 480; |
530 format.height = 300; | 377 format.height = 300; |
531 adapter.OnOutputFormatRequest(format); | 378 adapter_.OnOutputFormatRequest(format); |
532 EXPECT_EQ(480, adapter.output_format().width); | 379 out_format = adapter_.AdaptFrameResolution(640, 400); |
533 EXPECT_EQ(300, adapter.output_format().height); | 380 EXPECT_EQ(480, out_format.width); |
534 } | 381 EXPECT_EQ(300, out_format.height); |
535 | 382 } |
536 TEST(CoordinatedVideoAdapterTest, TestCoordinatedWithCpuAdaptation) { | 383 |
537 CoordinatedVideoAdapter adapter; | 384 TEST_F(VideoAdapterTest, TestViewRequestPlusCameraSwitch) { |
538 adapter.set_cpu_adaptation(true); | |
539 EXPECT_FALSE(adapter.cpu_smoothing()); | |
540 VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420); | |
541 adapter.SetInputFormat(format); | |
542 | |
543 // Server format request 640x400. | |
544 format.height = 400; | |
545 adapter.OnOutputFormatRequest(format); | |
546 EXPECT_EQ(640, adapter.output_format().width); | |
547 EXPECT_EQ(400, adapter.output_format().height); | |
548 | |
549 // Process load is medium, but system load is high. Downgrade. | |
550 UpdateCpuLoad(&adapter, 1, 1, 0.55f, 0.98f); | |
551 EXPECT_EQ(480, adapter.output_format().width); | |
552 EXPECT_EQ(300, adapter.output_format().height); | |
553 | |
554 // CPU high, but cpu adaptation disabled. Adapt nothing. | |
555 adapter.set_cpu_adaptation(false); | |
556 adapter.OnCpuLoadUpdated(1, 1, 0.55f, 0.98f); | |
557 EXPECT_EQ(480, adapter.output_format().width); | |
558 EXPECT_EQ(300, adapter.output_format().height); | |
559 adapter.set_cpu_adaptation(true); | |
560 | |
561 // System load is high, but time has not elaspsed. Adapt nothing. | |
562 adapter.set_cpu_load_min_samples(2); | |
563 adapter.OnCpuLoadUpdated(1, 1, 0.55f, 0.98f); | |
564 EXPECT_EQ(480, adapter.output_format().width); | |
565 EXPECT_EQ(300, adapter.output_format().height); | |
566 | |
567 // Process load is medium, but system load is high. Downgrade. | |
568 UpdateCpuLoad(&adapter, 1, 1, 0.55f, 0.98f); | |
569 EXPECT_EQ(320, adapter.output_format().width); | |
570 EXPECT_EQ(200, adapter.output_format().height); | |
571 | |
572 // Test reason for adapting is CPU. | |
573 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU, | |
574 adapter.adapt_reason()); | |
575 | |
576 // Server format request 320x200. Same as CPU. Do nothing. | |
577 format.width = 320; | |
578 format.height = 200; | |
579 adapter.OnOutputFormatRequest(format); | |
580 EXPECT_EQ(320, adapter.output_format().width); | |
581 EXPECT_EQ(200, adapter.output_format().height); | |
582 | |
583 // Test reason for adapting is CPU and VIEW. | |
584 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU + | |
585 CoordinatedVideoAdapter::ADAPTREASON_VIEW, | |
586 adapter.adapt_reason()); | |
587 | |
588 // Process load and system load are normal. Adapt nothing. | |
589 UpdateCpuLoad(&adapter, 1, 1, 0.5f, 0.8f); | |
590 EXPECT_EQ(320, adapter.output_format().width); | |
591 EXPECT_EQ(200, adapter.output_format().height); | |
592 | |
593 // Process load and system load are low, but view is still low. Adapt nothing. | |
594 UpdateCpuLoad(&adapter, 1, 1, 0.2f, 0.3f); | |
595 EXPECT_EQ(320, adapter.output_format().width); | |
596 EXPECT_EQ(200, adapter.output_format().height); | |
597 | |
598 // Test reason for adapting is VIEW. | |
599 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_VIEW, | |
600 adapter.adapt_reason()); | |
601 | |
602 // Server format request 640x400. Cpu is still low. Upgrade. | |
603 format.width = 640; | |
604 format.height = 400; | |
605 adapter.OnOutputFormatRequest(format); | |
606 EXPECT_EQ(480, adapter.output_format().width); | |
607 EXPECT_EQ(300, adapter.output_format().height); | |
608 | |
609 // Test reason for adapting is CPU. | |
610 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU, | |
611 adapter.adapt_reason()); | |
612 | |
613 // Encoder resolution request: downgrade. | |
614 adapter.OnEncoderResolutionRequest(480, 300, | |
615 CoordinatedVideoAdapter::DOWNGRADE); | |
616 EXPECT_EQ(320, adapter.output_format().width); | |
617 EXPECT_EQ(200, adapter.output_format().height); | |
618 | |
619 // Test reason for adapting is BANDWIDTH. | |
620 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH, | |
621 adapter.adapt_reason()); | |
622 | |
623 // Process load and system load are low. Constrained by GD. Adapt nothing | |
624 adapter.OnCpuLoadUpdated(1, 1, 0.2f, 0.3f); | |
625 EXPECT_EQ(320, adapter.output_format().width); | |
626 EXPECT_EQ(200, adapter.output_format().height); | |
627 | |
628 // Encoder resolution request: upgrade. | |
629 adapter.OnEncoderResolutionRequest(320, 200, | |
630 CoordinatedVideoAdapter::UPGRADE); | |
631 EXPECT_EQ(480, adapter.output_format().width); | |
632 EXPECT_EQ(300, adapter.output_format().height); | |
633 | |
634 // Encoder resolution request: upgrade. Constrained by CPU. | |
635 adapter.OnEncoderResolutionRequest(480, 300, | |
636 CoordinatedVideoAdapter::UPGRADE); | |
637 EXPECT_EQ(480, adapter.output_format().width); | |
638 EXPECT_EQ(300, adapter.output_format().height); | |
639 | |
640 // Server format request 640x400. Constrained by CPU. | |
641 format.width = 640; | |
642 format.height = 400; | |
643 adapter.OnOutputFormatRequest(format); | |
644 EXPECT_EQ(480, adapter.output_format().width); | |
645 EXPECT_EQ(300, adapter.output_format().height); | |
646 } | |
647 | |
648 TEST(CoordinatedVideoAdapterTest, TestCoordinatedWithCpuRequest) { | |
649 CoordinatedVideoAdapter adapter; | |
650 adapter.set_cpu_adaptation(true); | |
651 EXPECT_FALSE(adapter.cpu_smoothing()); | |
652 VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420); | |
653 adapter.SetInputFormat(format); | |
654 | |
655 // Server format request 640x400. | |
656 format.height = 400; | |
657 adapter.OnOutputFormatRequest(format); | |
658 EXPECT_EQ(640, adapter.output_format().width); | |
659 EXPECT_EQ(400, adapter.output_format().height); | |
660 | |
661 // CPU resolution request: downgrade. Adapt down. | |
662 adapter.OnCpuResolutionRequest(CoordinatedVideoAdapter::DOWNGRADE); | |
663 EXPECT_EQ(480, adapter.output_format().width); | |
664 EXPECT_EQ(300, adapter.output_format().height); | |
665 | |
666 // CPU resolution request: keep. Do nothing. | |
667 adapter.OnCpuResolutionRequest(CoordinatedVideoAdapter::KEEP); | |
668 EXPECT_EQ(480, adapter.output_format().width); | |
669 EXPECT_EQ(300, adapter.output_format().height); | |
670 | |
671 // CPU resolution request: downgrade, but cpu adaptation disabled. | |
672 // Adapt nothing. | |
673 adapter.set_cpu_adaptation(false); | |
674 adapter.OnCpuResolutionRequest(CoordinatedVideoAdapter::DOWNGRADE); | |
675 EXPECT_EQ(480, adapter.output_format().width); | |
676 EXPECT_EQ(300, adapter.output_format().height); | |
677 | |
678 // CPU resolution request: downgrade. Adapt down. | |
679 adapter.set_cpu_adaptation(true); | |
680 adapter.OnCpuResolutionRequest(CoordinatedVideoAdapter::DOWNGRADE); | |
681 EXPECT_EQ(320, adapter.output_format().width); | |
682 EXPECT_EQ(200, adapter.output_format().height); | |
683 | |
684 // Test reason for adapting is CPU. | |
685 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU, | |
686 adapter.adapt_reason()); | |
687 | |
688 // CPU resolution request: downgrade, but already at minimum. Do nothing. | |
689 adapter.OnCpuResolutionRequest(CoordinatedVideoAdapter::DOWNGRADE); | |
690 EXPECT_EQ(320, adapter.output_format().width); | |
691 EXPECT_EQ(200, adapter.output_format().height); | |
692 | |
693 // Server format request 320x200. Same as CPU. Do nothing. | |
694 format.width = 320; | |
695 format.height = 200; | |
696 adapter.OnOutputFormatRequest(format); | |
697 EXPECT_EQ(320, adapter.output_format().width); | |
698 EXPECT_EQ(200, adapter.output_format().height); | |
699 | |
700 // Test reason for adapting is CPU and VIEW. | |
701 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU + | |
702 CoordinatedVideoAdapter::ADAPTREASON_VIEW, | |
703 adapter.adapt_reason()); | |
704 | |
705 // CPU resolution request: upgrade, but view request still low. Do nothing. | |
706 adapter.OnCpuResolutionRequest(CoordinatedVideoAdapter::UPGRADE); | |
707 EXPECT_EQ(320, adapter.output_format().width); | |
708 EXPECT_EQ(200, adapter.output_format().height); | |
709 | |
710 // Test reason for adapting is VIEW. | |
711 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_VIEW, | |
712 adapter.adapt_reason()); | |
713 | |
714 // Server format request 640x400. Cpu is still low. Upgrade. | |
715 format.width = 640; | |
716 format.height = 400; | |
717 adapter.OnOutputFormatRequest(format); | |
718 EXPECT_EQ(480, adapter.output_format().width); | |
719 EXPECT_EQ(300, adapter.output_format().height); | |
720 | |
721 // Test reason for adapting is CPU. | |
722 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU, | |
723 adapter.adapt_reason()); | |
724 | |
725 // Encoder resolution request: downgrade. | |
726 adapter.OnEncoderResolutionRequest(480, 300, | |
727 CoordinatedVideoAdapter::DOWNGRADE); | |
728 EXPECT_EQ(320, adapter.output_format().width); | |
729 EXPECT_EQ(200, adapter.output_format().height); | |
730 | |
731 // Test reason for adapting is BANDWIDTH. | |
732 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH, | |
733 adapter.adapt_reason()); | |
734 | |
735 // Process load and system load are low. Constrained by GD. Adapt nothing | |
736 adapter.OnCpuLoadUpdated(1, 1, 0.2f, 0.3f); | |
737 EXPECT_EQ(320, adapter.output_format().width); | |
738 EXPECT_EQ(200, adapter.output_format().height); | |
739 | |
740 // Encoder resolution request: upgrade. | |
741 adapter.OnEncoderResolutionRequest(320, 200, | |
742 CoordinatedVideoAdapter::UPGRADE); | |
743 EXPECT_EQ(480, adapter.output_format().width); | |
744 EXPECT_EQ(300, adapter.output_format().height); | |
745 | |
746 // Encoder resolution request: upgrade. Constrained by CPU. | |
747 adapter.OnEncoderResolutionRequest(480, 300, | |
748 CoordinatedVideoAdapter::UPGRADE); | |
749 EXPECT_EQ(480, adapter.output_format().width); | |
750 EXPECT_EQ(300, adapter.output_format().height); | |
751 | |
752 // Server format request 640x400. Constrained by CPU. | |
753 format.width = 640; | |
754 format.height = 400; | |
755 adapter.OnOutputFormatRequest(format); | |
756 EXPECT_EQ(480, adapter.output_format().width); | |
757 EXPECT_EQ(300, adapter.output_format().height); | |
758 } | |
759 | |
760 TEST(CoordinatedVideoAdapterTest, TestViewRequestPlusCameraSwitch) { | |
761 CoordinatedVideoAdapter adapter; | |
762 adapter.set_view_switch(true); | |
763 | |
764 // Start at HD. | 385 // Start at HD. |
765 VideoFormat format(1280, 720, VideoFormat::FpsToInterval(30), FOURCC_I420); | 386 VideoFormat format(1280, 720, VideoFormat::FpsToInterval(30), 0); |
766 adapter.SetInputFormat(format); | 387 adapter_.SetExpectedInputFrameInterval(VideoFormat::FpsToInterval(30)); |
767 EXPECT_EQ(format, adapter.input_format()); | 388 VideoFormat out_format = |
768 EXPECT_TRUE(adapter.output_format().IsSize0x0()); | 389 adapter_.AdaptFrameResolution(format.width, format.height); |
769 | 390 EXPECT_EQ(format, adapter_.input_format()); |
770 // View request for VGA. | 391 EXPECT_EQ(out_format, adapter_.input_format()); |
| 392 |
| 393 // Format request for VGA. |
771 format.width = 640; | 394 format.width = 640; |
772 format.height = 360; | 395 format.height = 360; |
773 adapter.OnOutputFormatRequest(format); | 396 adapter_.OnOutputFormatRequest(format); |
774 EXPECT_EQ(640, adapter.output_format().width); | 397 out_format = adapter_.AdaptFrameResolution(1280, 720); |
775 EXPECT_EQ(360, adapter.output_format().height); | 398 EXPECT_EQ(640, out_format.width); |
776 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_VIEW, adapter.adapt_reason()); | 399 EXPECT_EQ(360, out_format.height); |
777 | 400 |
778 // Now, the camera reopens at VGA. | 401 // Now, the camera reopens at VGA. |
779 // Both the frame and the output format should be 640x360. | 402 // Both the frame and the output format should be 640x360. |
780 const VideoFormat out_format = adapter.AdaptFrameResolution(640, 360); | 403 out_format = adapter_.AdaptFrameResolution(640, 360); |
781 EXPECT_EQ(640, out_format.width); | 404 EXPECT_EQ(640, out_format.width); |
782 EXPECT_EQ(360, out_format.height); | 405 EXPECT_EQ(360, out_format.height); |
783 // At this point, the view is no longer adapted, since the input has resized | |
784 // small enough to fit the last view request. | |
785 EXPECT_EQ(0, adapter.adapt_reason()); | |
786 | 406 |
787 // And another view request comes in for 640x360, which should have no | 407 // And another view request comes in for 640x360, which should have no |
788 // real impact. | 408 // real impact. |
789 adapter.OnOutputFormatRequest(format); | 409 adapter_.OnOutputFormatRequest(format); |
790 EXPECT_EQ(640, adapter.output_format().width); | 410 out_format = adapter_.AdaptFrameResolution(640, 360); |
791 EXPECT_EQ(360, adapter.output_format().height); | 411 EXPECT_EQ(640, out_format.width); |
792 EXPECT_EQ(0, adapter.adapt_reason()); | 412 EXPECT_EQ(360, out_format.height); |
793 } | 413 } |
794 | 414 |
795 TEST(CoordinatedVideoAdapterTest, TestVGAWidth) { | 415 TEST_F(VideoAdapterTest, TestVGAWidth) { |
796 CoordinatedVideoAdapter adapter; | 416 // Reqeuested Output format is 640x360. |
797 adapter.set_view_switch(true); | 417 VideoFormat format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420); |
798 | 418 adapter_.SetExpectedInputFrameInterval(VideoFormat::FpsToInterval(30)); |
799 // Start at 640x480, for cameras that don't support 640x360. | 419 adapter_.OnOutputFormatRequest(format); |
800 VideoFormat format(640, 480, VideoFormat::FpsToInterval(30), FOURCC_I420); | 420 |
801 adapter.SetInputFormat(format); | 421 VideoFormat out_format = adapter_.AdaptFrameResolution(640, 480); |
802 EXPECT_EQ(format, adapter.input_format()); | |
803 EXPECT_TRUE(adapter.output_format().IsSize0x0()); | |
804 | |
805 // Output format is 640x360, though. | |
806 format.width = 640; | |
807 format.height = 360; | |
808 adapter.SetOutputFormat(format); | |
809 | |
810 // And also a view request comes for 640x360. | |
811 adapter.OnOutputFormatRequest(format); | |
812 // At this point, we have to adapt down to something lower. | 422 // At this point, we have to adapt down to something lower. |
813 EXPECT_EQ(480, adapter.output_format().width); | 423 EXPECT_EQ(480, out_format.width); |
814 EXPECT_EQ(360, adapter.output_format().height); | 424 EXPECT_EQ(360, out_format.height); |
815 | 425 |
816 // But if frames come in at 640x360, we shouldn't adapt them down. | 426 // But if frames come in at 640x360, we shouldn't adapt them down. |
817 // Fake a 640x360 frame. | 427 out_format = adapter_.AdaptFrameResolution(640, 360); |
818 VideoFormat out_format = adapter.AdaptFrameResolution(640, 360); | 428 EXPECT_EQ(640, out_format.width); |
819 EXPECT_EQ(640, out_format.width); | 429 EXPECT_EQ(360, out_format.height); |
820 EXPECT_EQ(360, out_format.height); | 430 |
821 | 431 out_format = adapter_.AdaptFrameResolution(640, 480); |
822 // Similarly, no-op adapt requests for other reasons shouldn't change | 432 EXPECT_EQ(480, out_format.width); |
823 // adaptation state (before a previous bug, the previous EXPECTs would | 433 EXPECT_EQ(360, out_format.height); |
824 // fail and the following would succeed, as the no-op CPU request would | 434 } |
825 // fix the adaptation state). | 435 |
826 adapter.set_cpu_adaptation(true); | 436 TEST_F(VideoAdapterTest, TestOnResolutionRequestInSmallSteps) { |
827 UpdateCpuLoad(&adapter, 1, 1, 0.7f, 0.7f); | 437 VideoFormat out_format = adapter_.AdaptFrameResolution(1280, 720); |
828 out_format = adapter.AdaptFrameResolution(640, 360); | 438 EXPECT_EQ(1280, out_format.width); |
829 | 439 EXPECT_EQ(720, out_format.height); |
830 EXPECT_EQ(640, out_format.width); | 440 |
831 EXPECT_EQ(360, out_format.height); | 441 // Adapt down one step. |
832 } | 442 adapter_.OnResolutionRequest(rtc::Optional<int>(1280 * 720 - 1), |
833 | 443 rtc::Optional<int>()); |
834 // When adapting resolution for CPU or GD, the quantity of pixels that the | 444 out_format = adapter_.AdaptFrameResolution(1280, 720); |
835 // request is based on is reduced to half or double, and then an actual | 445 EXPECT_EQ(960, out_format.width); |
836 // resolution is snapped to, rounding to the closest actual resolution. | 446 EXPECT_EQ(540, out_format.height); |
837 // This works well for some tolerance to 3/4, odd widths and aspect ratios | 447 |
838 // that dont exactly match, but is not best behavior for ViewRequests which | 448 // Adapt down one step more. |
839 // need to be be strictly respected to avoid going over the resolution budget | 449 adapter_.OnResolutionRequest(rtc::Optional<int>(960 * 540 - 1), |
840 // given to the codec - 854x480 total pixels. | 450 rtc::Optional<int>()); |
841 // ViewRequest must find a lower resolution. | 451 out_format = adapter_.AdaptFrameResolution(1280, 720); |
842 TEST(CoordinatedVideoAdapterTest, TestCoordinatedViewRequestDown) { | 452 EXPECT_EQ(640, out_format.width); |
843 CoordinatedVideoAdapter adapter; | 453 EXPECT_EQ(360, out_format.height); |
844 adapter.set_cpu_adaptation(false); | 454 |
845 | 455 // Adapt down one step more. |
846 VideoFormat format(960, 540, VideoFormat::FpsToInterval(30), FOURCC_I420); | 456 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1), |
847 adapter.SetInputFormat(format); | 457 rtc::Optional<int>()); |
848 adapter.set_scale_third(true); | 458 out_format = adapter_.AdaptFrameResolution(1280, 720); |
849 EXPECT_EQ(format, adapter.input_format()); | 459 EXPECT_EQ(480, out_format.width); |
850 EXPECT_TRUE(adapter.output_format().IsSize0x0()); | 460 EXPECT_EQ(270, out_format.height); |
851 | 461 |
852 // Server format request 640x400. Expect HVGA. | 462 // Adapt up one step. |
853 format.width = 640; | 463 adapter_.OnResolutionRequest(rtc::Optional<int>(), |
854 format.height = 400; | 464 rtc::Optional<int>(480 * 270)); |
855 adapter.OnOutputFormatRequest(format); | 465 out_format = adapter_.AdaptFrameResolution(1280, 720); |
856 EXPECT_EQ(640, adapter.output_format().width); | 466 EXPECT_EQ(640, out_format.width); |
857 EXPECT_EQ(360, adapter.output_format().height); | 467 EXPECT_EQ(360, out_format.height); |
858 | 468 |
859 // Test reason for adapting is VIEW. | 469 // Adapt up one step more. |
860 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_VIEW, adapter.adapt_reason()); | 470 adapter_.OnResolutionRequest(rtc::Optional<int>(), |
861 } | 471 rtc::Optional<int>(640 * 360)); |
862 | 472 out_format = adapter_.AdaptFrameResolution(1280, 720); |
863 // Test that we downgrade video for cpu up to two times. | 473 EXPECT_EQ(960, out_format.width); |
864 TEST(CoordinatedVideoAdapterTest, TestCpuDowngradeTimes) { | 474 EXPECT_EQ(540, out_format.height); |
865 CoordinatedVideoAdapter adapter; | 475 |
866 adapter.set_cpu_adaptation(true); | 476 // Adapt up one step more. |
867 EXPECT_FALSE(adapter.cpu_smoothing()); | 477 adapter_.OnResolutionRequest(rtc::Optional<int>(), |
868 VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420); | 478 rtc::Optional<int>(960 * 720)); |
869 adapter.SetInputFormat(format); | 479 out_format = adapter_.AdaptFrameResolution(1280, 720); |
870 | 480 EXPECT_EQ(1280, out_format.width); |
871 // Server format request 640x400. | 481 EXPECT_EQ(720, out_format.height); |
872 format.height = 400; | 482 } |
873 adapter.OnOutputFormatRequest(format); | 483 |
874 EXPECT_EQ(640, adapter.output_format().width); | 484 TEST_F(VideoAdapterTest, TestOnResolutionRequestMaxZero) { |
875 EXPECT_EQ(400, adapter.output_format().height); | 485 VideoFormat out_format = adapter_.AdaptFrameResolution(1280, 720); |
876 | 486 EXPECT_EQ(1280, out_format.width); |
877 // Process load and system load are low. Do not change the cpu desired format | 487 EXPECT_EQ(720, out_format.height); |
878 // and do not adapt. | 488 |
879 adapter.OnCpuLoadUpdated(1, 1, 0.2f, 0.3f); | 489 adapter_.OnResolutionRequest(rtc::Optional<int>(0), rtc::Optional<int>()); |
880 EXPECT_EQ(640, adapter.output_format().width); | 490 out_format = adapter_.AdaptFrameResolution(1280, 720); |
881 EXPECT_EQ(400, adapter.output_format().height); | 491 EXPECT_EQ(0, out_format.width); |
882 | 492 EXPECT_EQ(0, out_format.height); |
883 // System load is high. Downgrade. | 493 } |
884 UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); | 494 |
885 EXPECT_EQ(480, adapter.output_format().width); | 495 TEST_F(VideoAdapterTest, TestOnResolutionRequestInLargeSteps) { |
886 EXPECT_EQ(300, adapter.output_format().height); | 496 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1), |
887 | 497 rtc::Optional<int>()); |
888 // System load is high. Downgrade again. | 498 VideoFormat out_format = adapter_.AdaptFrameResolution(1280, 720); |
889 UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); | 499 EXPECT_EQ(480, out_format.width); |
890 EXPECT_EQ(320, adapter.output_format().width); | 500 EXPECT_EQ(270, out_format.height); |
891 EXPECT_EQ(200, adapter.output_format().height); | 501 |
892 | 502 adapter_.OnResolutionRequest(rtc::Optional<int>(), |
893 // System load is still high. Do not downgrade any more. | 503 rtc::Optional<int>(960 * 720)); |
894 UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); | 504 out_format = adapter_.AdaptFrameResolution(1280, 720); |
895 EXPECT_EQ(320, adapter.output_format().width); | 505 EXPECT_EQ(1280, out_format.width); |
896 EXPECT_EQ(200, adapter.output_format().height); | 506 EXPECT_EQ(720, out_format.height); |
897 | 507 } |
898 // Process load and system load are low. Upgrade. | 508 |
899 UpdateCpuLoad(&adapter, 1, 1, 0.2f, 0.3f); | 509 TEST_F(VideoAdapterTest, TestOnOutputFormatRequestCapsMaxResolution) { |
900 EXPECT_EQ(480, adapter.output_format().width); | 510 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1), |
901 EXPECT_EQ(300, adapter.output_format().height); | 511 rtc::Optional<int>()); |
902 | 512 VideoFormat out_format = adapter_.AdaptFrameResolution(1280, 720); |
903 // System load is high. Downgrade. | 513 EXPECT_EQ(480, out_format.width); |
904 UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); | 514 EXPECT_EQ(270, out_format.height); |
905 EXPECT_EQ(320, adapter.output_format().width); | 515 |
906 EXPECT_EQ(200, adapter.output_format().height); | 516 VideoFormat new_format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420); |
907 | 517 adapter_.SetExpectedInputFrameInterval(VideoFormat::FpsToInterval(30)); |
908 // System load is still high. Do not downgrade any more. | 518 adapter_.OnOutputFormatRequest(new_format); |
909 UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); | 519 out_format = adapter_.AdaptFrameResolution(1280, 720); |
910 EXPECT_EQ(320, adapter.output_format().width); | 520 EXPECT_EQ(480, out_format.width); |
911 EXPECT_EQ(200, adapter.output_format().height); | 521 EXPECT_EQ(270, out_format.height); |
912 } | 522 |
913 | 523 adapter_.OnResolutionRequest(rtc::Optional<int>(), |
914 // Test that we respect CPU adapter threshold values. | 524 rtc::Optional<int>(960 * 720)); |
915 TEST(CoordinatedVideoAdapterTest, TestAdapterCpuThreshold) { | 525 out_format = adapter_.AdaptFrameResolution(1280, 720); |
916 CoordinatedVideoAdapter adapter; | 526 EXPECT_EQ(640, out_format.width); |
917 adapter.set_cpu_adaptation(true); | 527 EXPECT_EQ(360, out_format.height); |
918 EXPECT_FALSE(adapter.cpu_smoothing()); | 528 } |
919 VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420); | 529 |
920 adapter.SetInputFormat(format); | 530 TEST_F(VideoAdapterTest, TestOnResolutionRequestReset) { |
921 | 531 VideoFormat out_format = adapter_.AdaptFrameResolution(1280, 720); |
922 // Server format request 640x400. | 532 EXPECT_EQ(1280, out_format.width); |
923 format.height = 400; | 533 EXPECT_EQ(720, out_format.height); |
924 adapter.OnOutputFormatRequest(format); | 534 |
925 EXPECT_EQ(640, adapter.output_format().width); | 535 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1), |
926 EXPECT_EQ(400, adapter.output_format().height); | 536 rtc::Optional<int>()); |
927 | 537 out_format = adapter_.AdaptFrameResolution(1280, 720); |
928 // Process load and system load are low. Do not change the cpu desired format | 538 EXPECT_EQ(480, out_format.width); |
929 // and do not adapt. | 539 EXPECT_EQ(270, out_format.height); |
930 adapter.OnCpuLoadUpdated(1, 1, 0.2f, 0.3f); | 540 |
931 EXPECT_EQ(640, adapter.output_format().width); | 541 adapter_.OnResolutionRequest(rtc::Optional<int>(), rtc::Optional<int>()); |
932 EXPECT_EQ(400, adapter.output_format().height); | 542 out_format = adapter_.AdaptFrameResolution(1280, 720); |
933 | 543 EXPECT_EQ(1280, out_format.width); |
934 // System load is high. Downgrade. | 544 EXPECT_EQ(720, out_format.height); |
935 UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); | |
936 EXPECT_EQ(480, adapter.output_format().width); | |
937 EXPECT_EQ(300, adapter.output_format().height); | |
938 | |
939 // Test reason for adapting is CPU. | |
940 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU, adapter.adapt_reason()); | |
941 | |
942 // System load is high. Normally downgrade but threshold is high. Do nothing. | |
943 adapter.set_high_system_threshold(0.98f); // Set threshold high. | |
944 UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); | |
945 EXPECT_EQ(480, adapter.output_format().width); | |
946 EXPECT_EQ(300, adapter.output_format().height); | |
947 | |
948 // System load is medium. Normally do nothing, threshold is low. Adapt down. | |
949 adapter.set_high_system_threshold(0.75f); // Set threshold low. | |
950 UpdateCpuLoad(&adapter, 1, 1, 0.8f, 0.8f); | |
951 EXPECT_EQ(320, adapter.output_format().width); | |
952 EXPECT_EQ(200, adapter.output_format().height); | |
953 } | |
954 | |
955 | |
956 // Test that for an upgrade cpu request, we actually upgrade the desired format; | |
957 // for a downgrade request, we downgrade from the output format. | |
958 TEST(CoordinatedVideoAdapterTest, TestRealCpuUpgrade) { | |
959 CoordinatedVideoAdapter adapter; | |
960 adapter.set_cpu_adaptation(true); | |
961 adapter.set_cpu_smoothing(true); | |
962 VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420); | |
963 adapter.SetInputFormat(format); | |
964 | |
965 // Server format request 640x400. | |
966 format.width = 640; | |
967 format.height = 400; | |
968 adapter.OnOutputFormatRequest(format); | |
969 EXPECT_EQ(640, adapter.output_format().width); | |
970 EXPECT_EQ(400, adapter.output_format().height); | |
971 | |
972 // Process load and system load are low. Do not change the cpu desired format | |
973 // and do not adapt. | |
974 UpdateCpuLoad(&adapter, 1, 1, 0.2f, 0.3f); | |
975 EXPECT_EQ(640, adapter.output_format().width); | |
976 EXPECT_EQ(400, adapter.output_format().height); | |
977 | |
978 // Server format request 320x200. | |
979 format.width = 320; | |
980 format.height = 200; | |
981 adapter.OnOutputFormatRequest(format); | |
982 EXPECT_EQ(320, adapter.output_format().width); | |
983 EXPECT_EQ(200, adapter.output_format().height); | |
984 | |
985 // Process load and system load are low. Do not change the cpu desired format | |
986 // and do not adapt. | |
987 UpdateCpuLoad(&adapter, 1, 1, 0.2f, 0.3f); | |
988 EXPECT_EQ(320, adapter.output_format().width); | |
989 EXPECT_EQ(200, adapter.output_format().height); | |
990 | |
991 // Server format request 640x400. Set to 640x400 immediately. | |
992 format.width = 640; | |
993 format.height = 400; | |
994 adapter.OnOutputFormatRequest(format); | |
995 EXPECT_EQ(640, adapter.output_format().width); | |
996 EXPECT_EQ(400, adapter.output_format().height); | |
997 | |
998 // Server format request 320x200. | |
999 format.width = 320; | |
1000 format.height = 200; | |
1001 adapter.OnOutputFormatRequest(format); | |
1002 EXPECT_EQ(320, adapter.output_format().width); | |
1003 EXPECT_EQ(200, adapter.output_format().height); | |
1004 | |
1005 // Process load is high, but system is not. Do not change the cpu desired | |
1006 // format and do not adapt. | |
1007 for (size_t i = 0; i < 10; ++i) { | |
1008 UpdateCpuLoad(&adapter, 1, 1, 0.75f, 0.8f); | |
1009 } | |
1010 EXPECT_EQ(320, adapter.output_format().width); | |
1011 EXPECT_EQ(200, adapter.output_format().height); | |
1012 } | |
1013 | |
1014 // Test that for an upgrade encoder request, we actually upgrade the desired | |
1015 // format; for a downgrade request, we downgrade from the output format. | |
1016 TEST(CoordinatedVideoAdapterTest, TestRealEncoderUpgrade) { | |
1017 CoordinatedVideoAdapter adapter; | |
1018 adapter.set_cpu_adaptation(true); | |
1019 adapter.set_cpu_smoothing(true); | |
1020 VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420); | |
1021 adapter.SetInputFormat(format); | |
1022 | |
1023 // Server format request 640x400. | |
1024 format.width = 640; | |
1025 format.height = 400; | |
1026 adapter.OnOutputFormatRequest(format); | |
1027 EXPECT_EQ(640, adapter.output_format().width); | |
1028 EXPECT_EQ(400, adapter.output_format().height); | |
1029 | |
1030 // Encoder resolution request. Do not change the encoder desired format and | |
1031 // do not adapt. | |
1032 adapter.OnEncoderResolutionRequest(640, 400, | |
1033 CoordinatedVideoAdapter::UPGRADE); | |
1034 EXPECT_EQ(640, adapter.output_format().width); | |
1035 EXPECT_EQ(400, adapter.output_format().height); | |
1036 | |
1037 // Server format request 320x200. | |
1038 format.width = 320; | |
1039 format.height = 200; | |
1040 adapter.OnOutputFormatRequest(format); | |
1041 EXPECT_EQ(320, adapter.output_format().width); | |
1042 EXPECT_EQ(200, adapter.output_format().height); | |
1043 | |
1044 // Encoder resolution request. Do not change the encoder desired format and | |
1045 // do not adapt. | |
1046 adapter.OnEncoderResolutionRequest(320, 200, | |
1047 CoordinatedVideoAdapter::UPGRADE); | |
1048 EXPECT_EQ(320, adapter.output_format().width); | |
1049 EXPECT_EQ(200, adapter.output_format().height); | |
1050 | |
1051 // Server format request 640x400. Set to 640x400 immediately. | |
1052 format.width = 640; | |
1053 format.height = 400; | |
1054 adapter.OnOutputFormatRequest(format); | |
1055 EXPECT_EQ(480, adapter.output_format().width); | |
1056 EXPECT_EQ(300, adapter.output_format().height); | |
1057 | |
1058 // Test reason for adapting is BANDWIDTH. | |
1059 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH, | |
1060 adapter.adapt_reason()); | |
1061 | |
1062 // Server format request 320x200. | |
1063 format.width = 320; | |
1064 format.height = 200; | |
1065 adapter.OnOutputFormatRequest(format); | |
1066 EXPECT_EQ(320, adapter.output_format().width); | |
1067 EXPECT_EQ(200, adapter.output_format().height); | |
1068 | |
1069 // Encoder resolution request. Downgrade from 320x200. | |
1070 adapter.OnEncoderResolutionRequest(320, 200, | |
1071 CoordinatedVideoAdapter::DOWNGRADE); | |
1072 EXPECT_EQ(240, adapter.output_format().width); | |
1073 EXPECT_EQ(150, adapter.output_format().height); | |
1074 } | |
1075 | |
1076 TEST(CoordinatedVideoAdapterTest, TestNormalizeOutputFormat) { | |
1077 CoordinatedVideoAdapter adapter; | |
1078 // The input format is 640x360 and the output is limited to 16:9. | |
1079 VideoFormat format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420); | |
1080 adapter.SetInputFormat(format); | |
1081 | |
1082 format.width = 320; | |
1083 format.height = 180; | |
1084 format.interval = VideoFormat::FpsToInterval(15); | |
1085 adapter.OnOutputFormatRequest(format); | |
1086 EXPECT_EQ(320, adapter.output_format().width); | |
1087 EXPECT_EQ(180, adapter.output_format().height); | |
1088 EXPECT_EQ(VideoFormat::FpsToInterval(15), adapter.output_format().interval); | |
1089 | |
1090 format.width = 320; | |
1091 format.height = 200; | |
1092 format.interval = VideoFormat::FpsToInterval(40); | |
1093 adapter.OnOutputFormatRequest(format); | |
1094 EXPECT_EQ(320, adapter.output_format().width); | |
1095 EXPECT_EQ(180, adapter.output_format().height); | |
1096 EXPECT_EQ(VideoFormat::FpsToInterval(30), adapter.output_format().interval); | |
1097 | |
1098 // Test reason for adapting is VIEW. Should work even with normalization. | |
1099 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_VIEW, | |
1100 adapter.adapt_reason()); | |
1101 | |
1102 format.width = 320; | |
1103 format.height = 240; | |
1104 adapter.OnOutputFormatRequest(format); | |
1105 EXPECT_EQ(320, adapter.output_format().width); | |
1106 EXPECT_EQ(180, adapter.output_format().height); | |
1107 | |
1108 // The input format is 640x480 and the output will be 4:3. | |
1109 format.width = 640; | |
1110 format.height = 480; | |
1111 adapter.SetInputFormat(format); | |
1112 EXPECT_EQ(320, adapter.output_format().width); | |
1113 EXPECT_EQ(240, adapter.output_format().height); | |
1114 | |
1115 format.width = 320; | |
1116 format.height = 240; | |
1117 adapter.OnOutputFormatRequest(format); | |
1118 EXPECT_EQ(320, adapter.output_format().width); | |
1119 EXPECT_EQ(240, adapter.output_format().height); | |
1120 | |
1121 // The input format is initialized after the output. At that time, the output | |
1122 // height is adjusted. | |
1123 format.width = 0; | |
1124 format.height = 0; | |
1125 adapter.SetInputFormat(format); | |
1126 | |
1127 format.width = 320; | |
1128 format.height = 240; | |
1129 format.interval = VideoFormat::FpsToInterval(30); | |
1130 adapter.OnOutputFormatRequest(format); | |
1131 EXPECT_EQ(320, adapter.output_format().width); | |
1132 EXPECT_EQ(240, adapter.output_format().height); | |
1133 EXPECT_EQ(VideoFormat::FpsToInterval(30), adapter.output_format().interval); | |
1134 | |
1135 format.width = 640; | |
1136 format.height = 480; | |
1137 format.interval = VideoFormat::FpsToInterval(15); | |
1138 adapter.SetInputFormat(format); | |
1139 EXPECT_EQ(320, adapter.output_format().width); | |
1140 EXPECT_EQ(240, adapter.output_format().height); | |
1141 EXPECT_EQ(VideoFormat::FpsToInterval(15), adapter.output_format().interval); | |
1142 } | |
1143 | |
1144 // Test that we downgrade video for cpu up to two times. | |
1145 TEST_F(VideoAdapterTest, CpuDowngradeAndSignal) { | |
1146 CoordinatedVideoAdapter adapter; | |
1147 CpuAdapterListener cpu_listener; | |
1148 adapter.SignalCpuAdaptationUnable.connect( | |
1149 &cpu_listener, &CpuAdapterListener::OnCpuAdaptationSignalled); | |
1150 | |
1151 adapter.set_cpu_adaptation(true); | |
1152 EXPECT_FALSE(adapter.cpu_smoothing()); | |
1153 VideoFormat format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420); | |
1154 adapter.SetInputFormat(format); | |
1155 adapter.OnOutputFormatRequest(format); | |
1156 | |
1157 // System load is high. Downgrade. | |
1158 UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); | |
1159 | |
1160 // System load is high. Downgrade again. | |
1161 UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); | |
1162 | |
1163 // System load is still high. Do not downgrade any more. Ensure we have not | |
1164 // signalled until after the cpu warning though. | |
1165 EXPECT_TRUE(!cpu_listener.received_cpu_signal()); | |
1166 UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); | |
1167 EXPECT_TRUE_WAIT(cpu_listener.received_cpu_signal(), kWaitTimeout); | |
1168 } | |
1169 | |
1170 // Test that we downgrade video for cpu up to two times. | |
1171 TEST_F(VideoAdapterTest, CpuDowngradeAndDontSignal) { | |
1172 CoordinatedVideoAdapter adapter; | |
1173 CpuAdapterListener cpu_listener; | |
1174 adapter.SignalCpuAdaptationUnable.connect( | |
1175 &cpu_listener, &CpuAdapterListener::OnCpuAdaptationSignalled); | |
1176 | |
1177 adapter.set_cpu_adaptation(true); | |
1178 adapter.set_cpu_smoothing(true); | |
1179 VideoFormat format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420); | |
1180 adapter.SetInputFormat(format); | |
1181 adapter.OnOutputFormatRequest(format); | |
1182 | |
1183 // System load is high. Downgrade. | |
1184 UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); | |
1185 | |
1186 // System load is high, process is not, Do not downgrade again. | |
1187 UpdateCpuLoad(&adapter, 1, 1, 0.25f, 0.95f); | |
1188 | |
1189 // System load is high, process is not, Do not downgrade again and do not | |
1190 // signal. | |
1191 adapter.set_cpu_adaptation(false); | |
1192 UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); | |
1193 rtc::Thread::Current()->ProcessMessages(kShortWaitTimeout); | |
1194 EXPECT_TRUE(!cpu_listener.received_cpu_signal()); | |
1195 adapter.set_cpu_adaptation(true); | |
1196 } | |
1197 | |
1198 // Test that we require enough time before we downgrade. | |
1199 TEST_F(VideoAdapterTest, CpuMinTimeRequirement) { | |
1200 CoordinatedVideoAdapter adapter; | |
1201 CpuAdapterListener cpu_listener; | |
1202 adapter.SignalCpuAdaptationUnable.connect( | |
1203 &cpu_listener, &CpuAdapterListener::OnCpuAdaptationSignalled); | |
1204 | |
1205 adapter.set_cpu_adaptation(true); | |
1206 adapter.set_cpu_smoothing(true); | |
1207 VideoFormat format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420); | |
1208 adapter.SetInputFormat(format); | |
1209 adapter.OnOutputFormatRequest(format); | |
1210 | |
1211 EXPECT_EQ(3, adapter.cpu_load_min_samples()); | |
1212 adapter.set_cpu_load_min_samples(5); | |
1213 | |
1214 for (size_t i = 0; i < 4; ++i) { | |
1215 adapter.OnCpuLoadUpdated(1, 1, 1.0f, 1.0f); | |
1216 EXPECT_EQ(640, adapter.output_format().width); | |
1217 EXPECT_EQ(360, adapter.output_format().height); | |
1218 } | |
1219 // The computed cpu load should now be around 93.5%, with the coefficient of | |
1220 // 0.4 and a seed value of 0.5. That should be high enough to adapt, but it | |
1221 // isn't enough samples, so we shouldn't have adapted on any of the previous | |
1222 // samples. | |
1223 | |
1224 // One more sample is enough, though, once enough time has passed. | |
1225 adapter.OnCpuLoadUpdated(1, 1, 1.0f, 1.0f); | |
1226 EXPECT_EQ(480, adapter.output_format().width); | |
1227 EXPECT_EQ(270, adapter.output_format().height); | |
1228 | |
1229 // Now the cpu is lower, but we still need enough samples to upgrade. | |
1230 for (size_t i = 0; i < 4; ++i) { | |
1231 adapter.OnCpuLoadUpdated(1, 1, 0.1f, 0.1f); | |
1232 EXPECT_EQ(480, adapter.output_format().width); | |
1233 EXPECT_EQ(270, adapter.output_format().height); | |
1234 } | |
1235 | |
1236 // One more sample is enough, once time has elapsed. | |
1237 adapter.OnCpuLoadUpdated(1, 1, 1.0f, 1.0f); | |
1238 EXPECT_EQ(640, adapter.output_format().width); | |
1239 EXPECT_EQ(360, adapter.output_format().height); | |
1240 } | |
1241 | |
1242 TEST_F(VideoAdapterTest, CpuIgnoresSpikes) { | |
1243 CoordinatedVideoAdapter adapter; | |
1244 CpuAdapterListener cpu_listener; | |
1245 adapter.SignalCpuAdaptationUnable.connect( | |
1246 &cpu_listener, &CpuAdapterListener::OnCpuAdaptationSignalled); | |
1247 | |
1248 adapter.set_cpu_adaptation(true); | |
1249 adapter.set_cpu_smoothing(true); | |
1250 VideoFormat format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420); | |
1251 adapter.SetInputFormat(format); | |
1252 adapter.OnOutputFormatRequest(format); | |
1253 | |
1254 // System load is high. Downgrade. | |
1255 for (size_t i = 0; i < 5; ++i) { | |
1256 UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f); | |
1257 } | |
1258 EXPECT_EQ(480, adapter.output_format().width); | |
1259 EXPECT_EQ(270, adapter.output_format().height); | |
1260 | |
1261 // Now we're in a state where we could upgrade or downgrade, so get to a | |
1262 // steady state of about 75% cpu usage. | |
1263 for (size_t i = 0; i < 5; ++i) { | |
1264 UpdateCpuLoad(&adapter, 1, 1, 0.75f, 0.75f); | |
1265 EXPECT_EQ(480, adapter.output_format().width); | |
1266 EXPECT_EQ(270, adapter.output_format().height); | |
1267 } | |
1268 | |
1269 // Now, the cpu spikes for two samples, but then goes back to | |
1270 // normal. This shouldn't cause adaptation. | |
1271 UpdateCpuLoad(&adapter, 1, 1, 0.90f, 0.90f); | |
1272 UpdateCpuLoad(&adapter, 1, 1, 0.90f, 0.90f); | |
1273 EXPECT_EQ(480, adapter.output_format().width); | |
1274 EXPECT_EQ(270, adapter.output_format().height); | |
1275 // Back to the steady state for awhile. | |
1276 for (size_t i = 0; i < 5; ++i) { | |
1277 UpdateCpuLoad(&adapter, 1, 1, 0.75, 0.75); | |
1278 EXPECT_EQ(480, adapter.output_format().width); | |
1279 EXPECT_EQ(270, adapter.output_format().height); | |
1280 } | |
1281 | |
1282 // Now, system cpu usage is starting to drop down. But it takes a bit before | |
1283 // it gets all the way there. | |
1284 for (size_t i = 0; i < 10; ++i) { | |
1285 UpdateCpuLoad(&adapter, 1, 1, 0.5f, 0.5f); | |
1286 } | |
1287 EXPECT_EQ(640, adapter.output_format().width); | |
1288 EXPECT_EQ(360, adapter.output_format().height); | |
1289 } | 545 } |
1290 | 546 |
1291 } // namespace cricket | 547 } // namespace cricket |
1292 #endif // HAVE_WEBRTC_VIDEO | |
OLD | NEW |