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