blob: e31f47207a3e096e96134a88c4c461d4c2526c43 [file] [log] [blame]
zijiehe90ea7362016-11-22 17:17:09 -08001/*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/desktop_capture/desktop_frame_rotation.h"
zijiehe90ea7362016-11-22 17:17:09 -080012
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "modules/desktop_capture/desktop_frame.h"
14#include "modules/desktop_capture/desktop_region.h"
15#include "modules/desktop_capture/test_utils.h"
16#include "test/gtest.h"
zijiehe90ea7362016-11-22 17:17:09 -080017
18namespace webrtc {
19
20namespace {
21
22// A DesktopFrame implementation which stores data in an external int array.
23class ArrayDesktopFrame : public DesktopFrame {
24 public:
25 ArrayDesktopFrame(DesktopSize size, uint32_t* data);
26 ~ArrayDesktopFrame() override;
27};
28
29ArrayDesktopFrame::ArrayDesktopFrame(DesktopSize size, uint32_t* data)
30 : DesktopFrame(size,
31 size.width() * kBytesPerPixel,
32 reinterpret_cast<uint8_t*>(data),
33 nullptr) {}
34
35ArrayDesktopFrame::~ArrayDesktopFrame() = default;
36
37} // namespace
38
39TEST(DesktopFrameRotationTest, CopyRect3x4) {
40 // A DesktopFrame of 4-pixel width by 3-pixel height.
41 static uint32_t frame_pixels[] = {
42 0, 1, 2, 3, //
43 4, 5, 6, 7, //
44 8, 9, 10, 11, //
45 };
46 ArrayDesktopFrame frame(DesktopSize(4, 3), frame_pixels);
47
48 {
49 BasicDesktopFrame target(DesktopSize(4, 3));
50 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
51 Rotation::CLOCK_WISE_0, DesktopVector(), &target);
52 ASSERT_TRUE(DesktopFrameDataEquals(frame, target));
53 }
54
55 // After Rotating clock-wise 90 degree
56 {
57 static uint32_t expected_pixels[] = {
58 8, 4, 0, //
59 9, 5, 1, //
60 10, 6, 2, //
61 11, 7, 3, //
62 };
63 ArrayDesktopFrame expected(DesktopSize(3, 4), expected_pixels);
64
65 BasicDesktopFrame target(DesktopSize(3, 4));
66 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
67 Rotation::CLOCK_WISE_90, DesktopVector(), &target);
68 ASSERT_TRUE(DesktopFrameDataEquals(target, expected));
69 }
70
71 // After Rotating clock-wise 180 degree
72 {
73 static uint32_t expected_pixels[] = {
74 11, 10, 9, 8, //
75 7, 6, 5, 4, //
76 3, 2, 1, 0, //
77 };
78 ArrayDesktopFrame expected(DesktopSize(4, 3), expected_pixels);
79
80 BasicDesktopFrame target(DesktopSize(4, 3));
81 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
82 Rotation::CLOCK_WISE_180, DesktopVector(), &target);
83 ASSERT_TRUE(DesktopFrameDataEquals(target, expected));
84 }
85
86 // After Rotating clock-wise 270 degree
87 {
88 static uint32_t expected_pixels[] = {
89 3, 7, 11, //
90 2, 6, 10, //
91 1, 5, 9, //
92 0, 4, 8, //
93 };
94 ArrayDesktopFrame expected(DesktopSize(3, 4), expected_pixels);
95
96 BasicDesktopFrame target(DesktopSize(3, 4));
97 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
98 Rotation::CLOCK_WISE_270, DesktopVector(), &target);
99 ASSERT_TRUE(DesktopFrameDataEquals(target, expected));
100 }
101}
102
103TEST(DesktopFrameRotationTest, CopyRect3x5) {
104 // A DesktopFrame of 5-pixel width by 3-pixel height.
105 static uint32_t frame_pixels[] = {
106 0, 1, 2, 3, 4, //
107 5, 6, 7, 8, 9, //
108 10, 11, 12, 13, 14, //
109 };
110 ArrayDesktopFrame frame(DesktopSize(5, 3), frame_pixels);
111
112 {
113 BasicDesktopFrame target(DesktopSize(5, 3));
114 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
115 Rotation::CLOCK_WISE_0, DesktopVector(), &target);
116 ASSERT_TRUE(DesktopFrameDataEquals(target, frame));
117 }
118
119 // After Rotating clock-wise 90 degree
120 {
121 static uint32_t expected_pixels[] = {
122 10, 5, 0, //
123 11, 6, 1, //
124 12, 7, 2, //
125 13, 8, 3, //
126 14, 9, 4, //
127 };
128 ArrayDesktopFrame expected(DesktopSize(3, 5), expected_pixels);
129
130 BasicDesktopFrame target(DesktopSize(3, 5));
131 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
132 Rotation::CLOCK_WISE_90, DesktopVector(), &target);
133 ASSERT_TRUE(DesktopFrameDataEquals(target, expected));
134 }
135
136 // After Rotating clock-wise 180 degree
137 {
138 static uint32_t expected_pixels[] {
139 14, 13, 12, 11, 10, //
140 9, 8, 7, 6, 5, //
141 4, 3, 2, 1, 0, //
142 };
143 ArrayDesktopFrame expected(DesktopSize(5, 3), expected_pixels);
144
145 BasicDesktopFrame target(DesktopSize(5, 3));
146 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
147 Rotation::CLOCK_WISE_180, DesktopVector(), &target);
148 ASSERT_TRUE(DesktopFrameDataEquals(target, expected));
149 }
150
151 // After Rotating clock-wise 270 degree
152 {
153 static uint32_t expected_pixels[] = {
154 4, 9, 14, //
155 3, 8, 13, //
156 2, 7, 12, //
157 1, 6, 11, //
158 0, 5, 10, //
159 };
160 ArrayDesktopFrame expected(DesktopSize(3, 5), expected_pixels);
161
162 BasicDesktopFrame target(DesktopSize(3, 5));
163 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
164 Rotation::CLOCK_WISE_270, DesktopVector(), &target);
165 ASSERT_TRUE(DesktopFrameDataEquals(target, expected));
166 }
167}
168
169TEST(DesktopFrameRotationTest, PartialCopyRect3x5) {
170 // A DesktopFrame of 5-pixel width by 3-pixel height.
171 static uint32_t frame_pixels[] = {
172 0, 1, 2, 3, 4, //
173 5, 6, 7, 8, 9, //
174 10, 11, 12, 13, 14, //
175 };
176 ArrayDesktopFrame frame(DesktopSize(5, 3), frame_pixels);
177
178 {
179 static uint32_t expected_pixels[] = {
180 0, 0, 0, 0, 0, //
181 0, 6, 7, 8, 0, //
182 0, 0, 0, 0, 0, //
183 };
184 ArrayDesktopFrame expected(DesktopSize(5, 3), expected_pixels);
185
186 BasicDesktopFrame target(DesktopSize(5, 3));
187 ClearDesktopFrame(&target);
188 RotateDesktopFrame(frame, DesktopRect::MakeXYWH(1, 1, 3, 1),
189 Rotation::CLOCK_WISE_0, DesktopVector(), &target);
190 ASSERT_TRUE(DesktopFrameDataEquals(target, expected));
191 }
192
193 {
194 static uint32_t expected_pixels[] = {
195 0, 1, 2, 3, 0, //
196 0, 6, 7, 8, 0, //
197 0, 0, 0, 0, 0, //
198 };
199 ArrayDesktopFrame expected(DesktopSize(5, 3), expected_pixels);
200
201 BasicDesktopFrame target(DesktopSize(5, 3));
202 ClearDesktopFrame(&target);
203 RotateDesktopFrame(frame, DesktopRect::MakeXYWH(1, 0, 3, 2),
204 Rotation::CLOCK_WISE_0, DesktopVector(), &target);
205 ASSERT_TRUE(DesktopFrameDataEquals(target, expected));
206 }
207
208 // After Rotating clock-wise 90 degree
209 {
210 static uint32_t expected_pixels[] = {
211 0, 0, 0, //
212 0, 6, 0, //
213 0, 7, 0, //
214 0, 8, 0, //
215 0, 0, 0, //
216 };
217 ArrayDesktopFrame expected(DesktopSize(3, 5), expected_pixels);
218
219 BasicDesktopFrame target(DesktopSize(3, 5));
220 ClearDesktopFrame(&target);
221 RotateDesktopFrame(frame, DesktopRect::MakeXYWH(1, 1, 3, 1),
222 Rotation::CLOCK_WISE_90, DesktopVector(), &target);
223 ASSERT_TRUE(DesktopFrameDataEquals(target, expected));
224 }
225
226 {
227 static uint32_t expected_pixels[] = {
228 0, 0, 0, //
229 11, 6, 0, //
230 12, 7, 0, //
231 13, 8, 0, //
232 0, 0, 0, //
233 };
234 ArrayDesktopFrame expected(DesktopSize(3, 5), expected_pixels);
235
236 BasicDesktopFrame target(DesktopSize(3, 5));
237 ClearDesktopFrame(&target);
238 RotateDesktopFrame(frame, DesktopRect::MakeXYWH(1, 1, 3, 2),
239 Rotation::CLOCK_WISE_90, DesktopVector(), &target);
240 ASSERT_TRUE(DesktopFrameDataEquals(target, expected));
241 }
242
243 // After Rotating clock-wise 180 degree
244 {
245 static uint32_t expected_pixels[] = {
246 0, 0, 0, 0, 0, //
247 0, 8, 7, 6, 0, //
248 0, 0, 0, 0, 0, //
249 };
250 ArrayDesktopFrame expected(DesktopSize(5, 3), expected_pixels);
251
252 BasicDesktopFrame target(DesktopSize(5, 3));
253 ClearDesktopFrame(&target);
254 RotateDesktopFrame(frame, DesktopRect::MakeXYWH(1, 1, 3, 1),
255 Rotation::CLOCK_WISE_180, DesktopVector(), &target);
256 ASSERT_TRUE(DesktopFrameDataEquals(target, expected));
257 }
258
259 {
260 static uint32_t expected_pixels[] = {
261 0, 13, 12, 11, 0, //
262 0, 8, 7, 6, 0, //
263 0, 0, 0, 0, 0, //
264 };
265 ArrayDesktopFrame expected(DesktopSize(5, 3), expected_pixels);
266
267 BasicDesktopFrame target(DesktopSize(5, 3));
268 ClearDesktopFrame(&target);
269 RotateDesktopFrame(frame, DesktopRect::MakeXYWH(1, 1, 3, 2),
270 Rotation::CLOCK_WISE_180, DesktopVector(), &target);
271 ASSERT_TRUE(DesktopFrameDataEquals(target, expected));
272 }
273
274 // After Rotating clock-wise 270 degree
275 {
276 static uint32_t expected_pixels[] = {
277 0, 0, 0, //
278 0, 8, 0, //
279 0, 7, 0, //
280 0, 6, 0, //
281 0, 0, 0, //
282 };
283 ArrayDesktopFrame expected(DesktopSize(3, 5), expected_pixels);
284
285 BasicDesktopFrame target(DesktopSize(3, 5));
286 ClearDesktopFrame(&target);
287 RotateDesktopFrame(frame, DesktopRect::MakeXYWH(1, 1, 3, 1),
288 Rotation::CLOCK_WISE_270, DesktopVector(), &target);
289 ASSERT_TRUE(DesktopFrameDataEquals(target, expected));
290 }
291
292 {
293 static uint32_t expected_pixels[] = {
294 0, 0, 0, //
295 3, 8, 0, //
296 2, 7, 0, //
297 1, 6, 0, //
298 0, 0, 0, //
299 };
300 ArrayDesktopFrame expected(DesktopSize(3, 5), expected_pixels);
301
302 BasicDesktopFrame target(DesktopSize(3, 5));
303 ClearDesktopFrame(&target);
304 RotateDesktopFrame(frame, DesktopRect::MakeXYWH(1, 0, 3, 2),
305 Rotation::CLOCK_WISE_270, DesktopVector(), &target);
306 ASSERT_TRUE(DesktopFrameDataEquals(target, expected));
307 }
308}
309
310TEST(DesktopFrameRotationTest, WithOffset) {
311 // A DesktopFrame of 4-pixel width by 3-pixel height.
312 static uint32_t frame_pixels[] = {
313 0, 1, 2, 3, //
314 4, 5, 6, 7, //
315 8, 9, 10, 11, //
316 };
317 ArrayDesktopFrame frame(DesktopSize(4, 3), frame_pixels);
318
319 {
320 static uint32_t expected_pixels[] = {
321 0, 0, 0, 0, 0, 0, 0, 0, //
322 0, 0, 1, 2, 3, 0, 0, 0, //
323 0, 4, 5, 6, 7, 0, 0, 0, //
324 0, 8, 9, 10, 11, 0, 0, 0, //
325 0, 0, 0, 0, 0, 0, 0, 0, //
326 0, 0, 0, 0, 0, 0, 0, 0, //
327 };
328 ArrayDesktopFrame expected(DesktopSize(8, 6), expected_pixels);
329
330 BasicDesktopFrame target(DesktopSize(8, 6));
331 ClearDesktopFrame(&target);
332 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
333 Rotation::CLOCK_WISE_0, DesktopVector(1, 1), &target);
334 ASSERT_TRUE(DesktopFrameDataEquals(target, expected));
335 target.mutable_updated_region()->Subtract(
336 DesktopRect::MakeOriginSize(DesktopVector(1, 1), frame.size()));
337 ASSERT_TRUE(target.updated_region().is_empty());
338 }
339
340 {
341 static uint32_t expected_pixels[] = {
342 0, 0, 0, 0, 0, 0, 0, 0, //
343 0, 11, 10, 9, 8, 0, 0, 0, //
344 0, 7, 6, 5, 4, 0, 0, 0, //
345 0, 3, 2, 1, 0, 0, 0, 0, //
346 0, 0, 0, 0, 0, 0, 0, 0, //
347 0, 0, 0, 0, 0, 0, 0, 0, //
348 };
349 ArrayDesktopFrame expected(DesktopSize(8, 6), expected_pixels);
350
351 BasicDesktopFrame target(DesktopSize(8, 6));
352 ClearDesktopFrame(&target);
353 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
354 Rotation::CLOCK_WISE_180, DesktopVector(1, 1), &target);
355 ASSERT_TRUE(DesktopFrameDataEquals(target, expected));
356 target.mutable_updated_region()->Subtract(
357 DesktopRect::MakeOriginSize(DesktopVector(1, 1), frame.size()));
358 ASSERT_TRUE(target.updated_region().is_empty());
359 }
360
361 {
362 static uint32_t expected_pixels[] = {
363 0, 0, 0, 0, 0, 0, //
364 0, 8, 4, 0, 0, 0, //
365 0, 9, 5, 1, 0, 0, //
366 0, 10, 6, 2, 0, 0, //
367 0, 11, 7, 3, 0, 0, //
368 0, 0, 0, 0, 0, 0, //
369 0, 0, 0, 0, 0, 0, //
370 0, 0, 0, 0, 0, 0, //
371 };
372 ArrayDesktopFrame expected(DesktopSize(6, 8), expected_pixels);
373
374 BasicDesktopFrame target(DesktopSize(6, 8));
375 ClearDesktopFrame(&target);
376 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
377 Rotation::CLOCK_WISE_90, DesktopVector(1, 1), &target);
378 ASSERT_TRUE(DesktopFrameDataEquals(target, expected));
379 target.mutable_updated_region()->Subtract(
380 DesktopRect::MakeXYWH(1, 1, 3, 4));
381 ASSERT_TRUE(target.updated_region().is_empty());
382 }
383
384 {
385 static uint32_t expected_pixels[] = {
386 0, 0, 0, 0, 0, 0, //
387 0, 3, 7, 11, 0, 0, //
388 0, 2, 6, 10, 0, 0, //
389 0, 1, 5, 9, 0, 0, //
390 0, 0, 4, 8, 0, 0, //
391 0, 0, 0, 0, 0, 0, //
392 0, 0, 0, 0, 0, 0, //
393 0, 0, 0, 0, 0, 0, //
394 };
395 ArrayDesktopFrame expected(DesktopSize(6, 8), expected_pixels);
396
397 BasicDesktopFrame target(DesktopSize(6, 8));
398 ClearDesktopFrame(&target);
399 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
400 Rotation::CLOCK_WISE_270, DesktopVector(1, 1), &target);
401 ASSERT_TRUE(DesktopFrameDataEquals(target, expected));
402 target.mutable_updated_region()->Subtract(
403 DesktopRect::MakeXYWH(1, 1, 3, 4));
404 ASSERT_TRUE(target.updated_region().is_empty());
405 }
406}
407
408// On a typical machine (Intel(R) Xeon(R) E5-1650 v3 @ 3.50GHz, with O2
409// optimization, the following case uses ~1.4s to finish. It means entirely
410// rotating one 2048 x 1536 frame, which is a large enough number to cover most
411// of desktop computer users, uses around 14ms.
412TEST(DesktopFrameRotationTest, DISABLED_PerformanceTest) {
413 BasicDesktopFrame frame(DesktopSize(2048, 1536));
414 BasicDesktopFrame target(DesktopSize(1536, 2048));
415 BasicDesktopFrame target2(DesktopSize(2048, 1536));
416 for (int i = 0; i < 100; i++) {
417 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
418 Rotation::CLOCK_WISE_90, DesktopVector(), &target);
419 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
420 Rotation::CLOCK_WISE_270, DesktopVector(), &target);
421 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
422 Rotation::CLOCK_WISE_0, DesktopVector(), &target2);
423 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
424 Rotation::CLOCK_WISE_180, DesktopVector(), &target2);
425 }
426}
427
428// On a typical machine (Intel(R) Xeon(R) E5-1650 v3 @ 3.50GHz, with O2
429// optimization, the following case uses ~6.7s to finish. It means entirely
430// rotating one 4096 x 3072 frame uses around 67ms.
431TEST(DesktopFrameRotationTest, DISABLED_PerformanceTestOnLargeScreen) {
432 BasicDesktopFrame frame(DesktopSize(4096, 3072));
433 BasicDesktopFrame target(DesktopSize(3072, 4096));
434 BasicDesktopFrame target2(DesktopSize(4096, 3072));
435 for (int i = 0; i < 100; i++) {
436 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
437 Rotation::CLOCK_WISE_90, DesktopVector(), &target);
438 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
439 Rotation::CLOCK_WISE_270, DesktopVector(), &target);
440 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
441 Rotation::CLOCK_WISE_0, DesktopVector(), &target2);
442 RotateDesktopFrame(frame, DesktopRect::MakeSize(frame.size()),
443 Rotation::CLOCK_WISE_180, DesktopVector(), &target2);
444 }
445}
446
447} // namespace webrtc