Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 40 buffer->MutableDataV()[x + y * chroma_width] = | 40 buffer->MutableDataV()[x + y * chroma_width] = |
| 41 255 * y / (chroma_height - 1); | 41 255 * y / (chroma_height - 1); |
| 42 } | 42 } |
| 43 } | 43 } |
| 44 return buffer; | 44 return buffer; |
| 45 } | 45 } |
| 46 | 46 |
| 47 // The offsets and sizes describe the rectangle extracted from the | 47 // The offsets and sizes describe the rectangle extracted from the |
| 48 // original (gradient) frame, in relative coordinates where the | 48 // original (gradient) frame, in relative coordinates where the |
| 49 // original frame correspond to the unit square, 0.0 <= x, y < 1.0. | 49 // original frame correspond to the unit square, 0.0 <= x, y < 1.0. |
| 50 void CheckCrop(webrtc::VideoFrameBuffer* frame, | 50 void CheckCrop(const webrtc::VideoFrameBuffer& frame, |
| 51 double offset_x, | 51 double offset_x, |
| 52 double offset_y, | 52 double offset_y, |
| 53 double rel_width, | 53 double rel_width, |
| 54 double rel_height) { | 54 double rel_height) { |
| 55 int width = frame->width(); | 55 int width = frame.width(); |
| 56 int height = frame->height(); | 56 int height = frame.height(); |
| 57 // Check that pixel values in the corners match the gradient used | 57 // Check that pixel values in the corners match the gradient used |
| 58 // for initialization. | 58 // for initialization. |
| 59 for (int i = 0; i < 2; i++) { | 59 for (int i = 0; i < 2; i++) { |
| 60 for (int j = 0; j < 2; j++) { | 60 for (int j = 0; j < 2; j++) { |
| 61 // Pixel coordinates of the corner. | 61 // Pixel coordinates of the corner. |
| 62 int x = i * (width - 1); | 62 int x = i * (width - 1); |
| 63 int y = j * (height - 1); | 63 int y = j * (height - 1); |
| 64 // Relative coordinates, range 0.0 - 1.0 correspond to the | 64 // Relative coordinates, range 0.0 - 1.0 correspond to the |
| 65 // size of the uncropped input frame. | 65 // size of the uncropped input frame. |
| 66 double orig_x = offset_x + i * rel_width; | 66 double orig_x = offset_x + i * rel_width; |
| 67 double orig_y = offset_y + j * rel_height; | 67 double orig_y = offset_y + j * rel_height; |
| 68 | 68 |
| 69 EXPECT_NEAR(frame->DataY()[x + y * frame->StrideY()] / 256.0, | 69 EXPECT_NEAR(frame.DataY()[x + y * frame.StrideY()] / 256.0, |
| 70 (orig_x + orig_y) / 2, 0.02); | 70 (orig_x + orig_y) / 2, 0.02); |
| 71 EXPECT_NEAR(frame->DataU()[x / 2 + (y / 2) * frame->StrideU()] / 256.0, | 71 EXPECT_NEAR(frame.DataU()[x / 2 + (y / 2) * frame.StrideU()] / 256.0, |
| 72 orig_x, 0.02); | 72 orig_x, 0.02); |
| 73 EXPECT_NEAR(frame->DataV()[x / 2 + (y / 2) * frame->StrideV()] / 256.0, | 73 EXPECT_NEAR(frame.DataV()[x / 2 + (y / 2) * frame.StrideV()] / 256.0, |
| 74 orig_y, 0.02); | 74 orig_y, 0.02); |
| 75 } | 75 } |
| 76 } | 76 } |
| 77 } | 77 } |
| 78 | 78 |
| 79 void CheckRotate(int width, int height, webrtc::VideoRotation rotation, | |
| 80 const webrtc::VideoFrameBuffer& rotated) { | |
| 81 int rotated_width = width; | |
| 82 int rotated_height = height; | |
| 83 | |
| 84 if (rotation == kVideoRotation_90 || rotation == kVideoRotation_270) { | |
| 85 std::swap(rotated_width, rotated_height); | |
| 86 } | |
| 87 EXPECT_EQ(rotated_width, rotated.width()); | |
| 88 EXPECT_EQ(rotated_height, rotated.height()); | |
| 89 | |
| 90 // Clock-wise order (with 0,0 at top-left) | |
| 91 const struct { int x; int y; } corners[] = { | |
| 92 { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } | |
| 93 }; | |
| 94 // Corresponding corner colors of the frame produced by CreateGradient. | |
| 95 const struct { int y; int u; int v; } colors[] = { | |
| 96 {0, 0, 0}, { 127, 255, 0}, { 255, 255, 255 }, {127, 0, 255} | |
| 97 }; | |
| 98 int corner_offset = static_cast<int>(rotation) / 90; | |
| 99 | |
| 100 for (int i = 0; i < 4; i++) { | |
| 101 int j = (i + corner_offset) % 4; | |
| 102 int x = corners[j].x * (rotated_width - 1); | |
| 103 int y = corners[j].y * (rotated_height - 1); | |
| 104 EXPECT_EQ(colors[i].y, rotated.DataY()[x + y * rotated.StrideY()]); | |
| 105 EXPECT_EQ(colors[i].u, | |
| 106 rotated.DataU()[(x / 2) + (y / 2) * rotated.StrideU()]); | |
| 107 EXPECT_EQ(colors[i].v, | |
| 108 rotated.DataV()[(x / 2) + (y / 2) * rotated.StrideV()]); | |
| 109 } | |
| 110 } | |
| 111 | |
| 79 } // namespace | 112 } // namespace |
| 80 | 113 |
| 81 TEST(TestVideoFrame, InitialValues) { | 114 TEST(TestVideoFrame, InitialValues) { |
| 82 VideoFrame frame; | 115 VideoFrame frame; |
| 83 EXPECT_TRUE(frame.IsZeroSize()); | 116 EXPECT_TRUE(frame.IsZeroSize()); |
| 84 EXPECT_EQ(kVideoRotation_0, frame.rotation()); | 117 EXPECT_EQ(kVideoRotation_0, frame.rotation()); |
| 85 } | 118 } |
| 86 | 119 |
| 87 TEST(TestVideoFrame, CopiesInitialFrameWithoutCrashing) { | 120 TEST(TestVideoFrame, CopiesInitialFrameWithoutCrashing) { |
| 88 VideoFrame frame; | 121 VideoFrame frame; |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 253 } | 286 } |
| 254 | 287 |
| 255 TEST(TestI420FrameBuffer, Scale) { | 288 TEST(TestI420FrameBuffer, Scale) { |
| 256 rtc::scoped_refptr<I420Buffer> buf = CreateGradient(200, 100); | 289 rtc::scoped_refptr<I420Buffer> buf = CreateGradient(200, 100); |
| 257 | 290 |
| 258 // Pure scaling, no cropping. | 291 // Pure scaling, no cropping. |
| 259 rtc::scoped_refptr<I420Buffer> scaled_buffer( | 292 rtc::scoped_refptr<I420Buffer> scaled_buffer( |
| 260 I420Buffer::Create(150, 75)); | 293 I420Buffer::Create(150, 75)); |
| 261 | 294 |
| 262 scaled_buffer->ScaleFrom(buf); | 295 scaled_buffer->ScaleFrom(buf); |
| 263 CheckCrop(scaled_buffer, 0.0, 0.0, 1.0, 1.0); | 296 CheckCrop(*scaled_buffer, 0.0, 0.0, 1.0, 1.0); |
| 264 } | 297 } |
| 265 | 298 |
| 266 TEST(TestI420FrameBuffer, CropXCenter) { | 299 TEST(TestI420FrameBuffer, CropXCenter) { |
| 267 rtc::scoped_refptr<I420Buffer> buf = CreateGradient(200, 100); | 300 rtc::scoped_refptr<I420Buffer> buf = CreateGradient(200, 100); |
| 268 | 301 |
| 269 // Pure center cropping, no scaling. | 302 // Pure center cropping, no scaling. |
| 270 rtc::scoped_refptr<I420Buffer> scaled_buffer( | 303 rtc::scoped_refptr<I420Buffer> scaled_buffer( |
| 271 I420Buffer::Create(100, 100)); | 304 I420Buffer::Create(100, 100)); |
| 272 | 305 |
| 273 scaled_buffer->CropAndScaleFrom(buf, 50, 0, 100, 100); | 306 scaled_buffer->CropAndScaleFrom(buf, 50, 0, 100, 100); |
| 274 CheckCrop(scaled_buffer, 0.25, 0.0, 0.5, 1.0); | 307 CheckCrop(*scaled_buffer, 0.25, 0.0, 0.5, 1.0); |
| 275 } | 308 } |
| 276 | 309 |
| 277 TEST(TestI420FrameBuffer, CropXNotCenter) { | 310 TEST(TestI420FrameBuffer, CropXNotCenter) { |
| 278 rtc::scoped_refptr<I420Buffer> buf = CreateGradient(200, 100); | 311 rtc::scoped_refptr<I420Buffer> buf = CreateGradient(200, 100); |
| 279 | 312 |
| 280 // Non-center cropping, no scaling. | 313 // Non-center cropping, no scaling. |
| 281 rtc::scoped_refptr<I420Buffer> scaled_buffer( | 314 rtc::scoped_refptr<I420Buffer> scaled_buffer( |
| 282 I420Buffer::Create(100, 100)); | 315 I420Buffer::Create(100, 100)); |
| 283 | 316 |
| 284 scaled_buffer->CropAndScaleFrom(buf, 25, 0, 100, 100); | 317 scaled_buffer->CropAndScaleFrom(buf, 25, 0, 100, 100); |
| 285 CheckCrop(scaled_buffer, 0.125, 0.0, 0.5, 1.0); | 318 CheckCrop(*scaled_buffer, 0.125, 0.0, 0.5, 1.0); |
| 286 } | 319 } |
| 287 | 320 |
| 288 TEST(TestI420FrameBuffer, CropYCenter) { | 321 TEST(TestI420FrameBuffer, CropYCenter) { |
| 289 rtc::scoped_refptr<I420Buffer> buf = CreateGradient(100, 200); | 322 rtc::scoped_refptr<I420Buffer> buf = CreateGradient(100, 200); |
| 290 | 323 |
| 291 // Pure center cropping, no scaling. | 324 // Pure center cropping, no scaling. |
| 292 rtc::scoped_refptr<I420Buffer> scaled_buffer( | 325 rtc::scoped_refptr<I420Buffer> scaled_buffer( |
| 293 I420Buffer::Create(100, 100)); | 326 I420Buffer::Create(100, 100)); |
| 294 | 327 |
| 295 scaled_buffer->CropAndScaleFrom(buf, 0, 50, 100, 100); | 328 scaled_buffer->CropAndScaleFrom(buf, 0, 50, 100, 100); |
| 296 CheckCrop(scaled_buffer, 0.0, 0.25, 1.0, 0.5); | 329 CheckCrop(*scaled_buffer, 0.0, 0.25, 1.0, 0.5); |
| 297 } | 330 } |
| 298 | 331 |
| 299 TEST(TestI420FrameBuffer, CropYNotCenter) { | 332 TEST(TestI420FrameBuffer, CropYNotCenter) { |
| 300 rtc::scoped_refptr<I420Buffer> buf = CreateGradient(100, 200); | 333 rtc::scoped_refptr<I420Buffer> buf = CreateGradient(100, 200); |
| 301 | 334 |
| 302 // Non-center cropping, no scaling. | 335 // Non-center cropping, no scaling. |
| 303 rtc::scoped_refptr<I420Buffer> scaled_buffer( | 336 rtc::scoped_refptr<I420Buffer> scaled_buffer( |
| 304 I420Buffer::Create(100, 100)); | 337 I420Buffer::Create(100, 100)); |
| 305 | 338 |
| 306 scaled_buffer->CropAndScaleFrom(buf, 0, 25, 100, 100); | 339 scaled_buffer->CropAndScaleFrom(buf, 0, 25, 100, 100); |
| 307 CheckCrop(scaled_buffer, 0.0, 0.125, 1.0, 0.5); | 340 CheckCrop(*scaled_buffer, 0.0, 0.125, 1.0, 0.5); |
| 308 } | 341 } |
| 309 | 342 |
| 310 TEST(TestI420FrameBuffer, CropAndScale16x9) { | 343 TEST(TestI420FrameBuffer, CropAndScale16x9) { |
| 311 rtc::scoped_refptr<I420Buffer> buf = CreateGradient(640, 480); | 344 rtc::scoped_refptr<I420Buffer> buf = CreateGradient(640, 480); |
| 312 | 345 |
| 313 // Center crop to 640 x 360 (16/9 aspect), then scale down by 2. | 346 // Center crop to 640 x 360 (16/9 aspect), then scale down by 2. |
| 314 rtc::scoped_refptr<I420Buffer> scaled_buffer( | 347 rtc::scoped_refptr<I420Buffer> scaled_buffer( |
| 315 I420Buffer::Create(320, 180)); | 348 I420Buffer::Create(320, 180)); |
| 316 | 349 |
| 317 scaled_buffer->CropAndScaleFrom(buf); | 350 scaled_buffer->CropAndScaleFrom(buf); |
| 318 CheckCrop(scaled_buffer, 0.0, 0.125, 1.0, 0.75); | 351 CheckCrop(*scaled_buffer, 0.0, 0.125, 1.0, 0.75); |
| 352 } | |
| 353 | |
| 354 TEST(TestI420FrameBuffer, Rotate_0) { | |
|
magjed_webrtc
2016/10/13 22:35:11
Can you turn this into a parameterized test (TEST_
nisse-webrtc
2016/10/18 09:34:21
Done.
| |
| 355 rtc::scoped_refptr<VideoFrameBuffer> buffer = CreateGradient(640, 480); | |
| 356 rtc::scoped_refptr<VideoFrameBuffer> rotated_buffer = | |
| 357 I420Buffer::Rotate(buffer, kVideoRotation_0); | |
| 358 CheckRotate(640, 480, kVideoRotation_0, *rotated_buffer); | |
| 359 } | |
| 360 | |
| 361 TEST(TestI420FrameBuffer, Rotate_90) { | |
| 362 rtc::scoped_refptr<VideoFrameBuffer> buffer = CreateGradient(640, 480); | |
| 363 rtc::scoped_refptr<VideoFrameBuffer> rotated_buffer = | |
| 364 I420Buffer::Rotate(buffer, kVideoRotation_90); | |
| 365 CheckRotate(640, 480, kVideoRotation_90, *rotated_buffer); | |
| 366 } | |
| 367 TEST(TestI420FrameBuffer, Rotate_180) { | |
| 368 rtc::scoped_refptr<VideoFrameBuffer> buffer = CreateGradient(640, 480); | |
| 369 rtc::scoped_refptr<VideoFrameBuffer> rotated_buffer = | |
| 370 I420Buffer::Rotate(buffer, kVideoRotation_180); | |
| 371 CheckRotate(640, 480, kVideoRotation_180, *rotated_buffer); | |
| 372 } | |
| 373 TEST(TestI420FrameBuffer, Rotate_270) { | |
| 374 rtc::scoped_refptr<VideoFrameBuffer> buffer = CreateGradient(640, 480); | |
| 375 rtc::scoped_refptr<VideoFrameBuffer> rotated_buffer = | |
| 376 I420Buffer::Rotate(buffer, kVideoRotation_270); | |
| 377 CheckRotate(640, 480, kVideoRotation_270, *rotated_buffer); | |
| 319 } | 378 } |
| 320 | 379 |
| 321 } // namespace webrtc | 380 } // namespace webrtc |
| OLD | NEW |