mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-06 16:56:55 +08:00
Android420ToI420Rotate function to convert with rotation
- adapted from Android420ToI420, adding a rotation parameter - SplitRotateUV added to rotate and split the UV channel of NV12 or NV21 - rename RotateUV functions to SplitRotateUV Bug: b/203549508 Change-Id: I6774da5fb5908fdf1fc12393f0001f41bbda9851 Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/3251282 Reviewed-by: richard winterton <rrwinterton@gmail.com> Commit-Queue: Frank Barchard <fbarchard@chromium.org>
This commit is contained in:
parent
b179f1847a
commit
fa043c7a64
@ -1,6 +1,6 @@
|
||||
Name: libyuv
|
||||
URL: http://code.google.com/p/libyuv/
|
||||
Version: 1801
|
||||
Version: 1802
|
||||
License: BSD
|
||||
License File: LICENSE
|
||||
|
||||
|
||||
@ -83,6 +83,26 @@ int NV12ToI420Rotate(const uint8_t* src_y,
|
||||
int height,
|
||||
enum RotationMode mode);
|
||||
|
||||
// Convert Android420 to I420 with rotation.
|
||||
// "rotation" can be 0, 90, 180 or 270.
|
||||
LIBYUV_API
|
||||
int Android420ToI420Rotate(const uint8_t* src_y,
|
||||
int src_stride_y,
|
||||
const uint8_t* src_u,
|
||||
int src_stride_u,
|
||||
const uint8_t* src_v,
|
||||
int src_stride_v,
|
||||
int src_pixel_stride_uv,
|
||||
uint8_t* dst_y,
|
||||
int dst_stride_y,
|
||||
uint8_t* dst_u,
|
||||
int dst_stride_u,
|
||||
uint8_t* dst_v,
|
||||
int dst_stride_v,
|
||||
int width,
|
||||
int height,
|
||||
enum RotationMode rotation);
|
||||
|
||||
// Rotate a plane by 0, 90, 180, or 270.
|
||||
LIBYUV_API
|
||||
int RotatePlane(const uint8_t* src,
|
||||
@ -119,11 +139,23 @@ void RotatePlane270(const uint8_t* src,
|
||||
int height);
|
||||
|
||||
// Rotations for when U and V are interleaved.
|
||||
// These functions take one input pointer and
|
||||
// These functions take one UV input pointer and
|
||||
// split the data into two buffers while
|
||||
// rotating them. Deprecated.
|
||||
// rotating them.
|
||||
// width and height expected to be half size for NV12.
|
||||
LIBYUV_API
|
||||
void RotateUV90(const uint8_t* src,
|
||||
int SplitRotateUV(const uint8_t* src_uv,
|
||||
int src_stride_uv,
|
||||
uint8_t* dst_u,
|
||||
int dst_stride_u,
|
||||
uint8_t* dst_v,
|
||||
int dst_stride_v,
|
||||
int width,
|
||||
int height,
|
||||
enum RotationMode mode);
|
||||
|
||||
LIBYUV_API
|
||||
void SplitRotateUV90(const uint8_t* src,
|
||||
int src_stride,
|
||||
uint8_t* dst_a,
|
||||
int dst_stride_a,
|
||||
@ -133,7 +165,7 @@ void RotateUV90(const uint8_t* src,
|
||||
int height);
|
||||
|
||||
LIBYUV_API
|
||||
void RotateUV180(const uint8_t* src,
|
||||
void SplitRotateUV180(const uint8_t* src,
|
||||
int src_stride,
|
||||
uint8_t* dst_a,
|
||||
int dst_stride_a,
|
||||
@ -143,7 +175,7 @@ void RotateUV180(const uint8_t* src,
|
||||
int height);
|
||||
|
||||
LIBYUV_API
|
||||
void RotateUV270(const uint8_t* src,
|
||||
void SplitRotateUV270(const uint8_t* src,
|
||||
int src_stride,
|
||||
uint8_t* dst_a,
|
||||
int dst_stride_a,
|
||||
@ -165,7 +197,7 @@ void TransposePlane(const uint8_t* src,
|
||||
int height);
|
||||
|
||||
LIBYUV_API
|
||||
void TransposeUV(const uint8_t* src,
|
||||
void SplitTransposeUV(const uint8_t* src,
|
||||
int src_stride,
|
||||
uint8_t* dst_a,
|
||||
int dst_stride_a,
|
||||
|
||||
@ -11,6 +11,6 @@
|
||||
#ifndef INCLUDE_LIBYUV_VERSION_H_
|
||||
#define INCLUDE_LIBYUV_VERSION_H_
|
||||
|
||||
#define LIBYUV_VERSION 1801
|
||||
#define LIBYUV_VERSION 1802
|
||||
|
||||
#endif // INCLUDE_LIBYUV_VERSION_H_
|
||||
@ -2119,9 +2119,8 @@ int RAWToI420(const uint8_t* src_raw,
|
||||
int height) {
|
||||
int y;
|
||||
#if defined(HAS_RAWTOYROW)
|
||||
void (*RAWToUVRow)(const uint8_t* src_raw, int src_stride_raw,
|
||||
uint8_t* dst_u, uint8_t* dst_v, int width) =
|
||||
RAWToUVRow_C;
|
||||
void (*RAWToUVRow)(const uint8_t* src_raw, int src_stride_raw, uint8_t* dst_u,
|
||||
uint8_t* dst_v, int width) = RAWToUVRow_C;
|
||||
void (*RAWToYRow)(const uint8_t* src_raw, uint8_t* dst_y, int width) =
|
||||
RAWToYRow_C;
|
||||
#else
|
||||
@ -3118,18 +3117,6 @@ int RAWToJ400(const uint8_t* src_raw,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SplitPixels(const uint8_t* src_u,
|
||||
int src_pixel_stride_uv,
|
||||
uint8_t* dst_u,
|
||||
int width) {
|
||||
int i;
|
||||
for (i = 0; i < width; ++i) {
|
||||
*dst_u = *src_u;
|
||||
++dst_u;
|
||||
src_u += src_pixel_stride_uv;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert Android420 to I420.
|
||||
LIBYUV_API
|
||||
int Android420ToI420(const uint8_t* src_y,
|
||||
@ -3147,58 +3134,10 @@ int Android420ToI420(const uint8_t* src_y,
|
||||
int dst_stride_v,
|
||||
int width,
|
||||
int height) {
|
||||
int y;
|
||||
const ptrdiff_t vu_off = src_v - src_u;
|
||||
int halfwidth = (width + 1) >> 1;
|
||||
int halfheight = (height + 1) >> 1;
|
||||
if (!src_u || !src_v || !dst_u || !dst_v || width <= 0 || height == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Negative height means invert the image.
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
halfheight = (height + 1) >> 1;
|
||||
src_y = src_y + (height - 1) * src_stride_y;
|
||||
src_u = src_u + (halfheight - 1) * src_stride_u;
|
||||
src_v = src_v + (halfheight - 1) * src_stride_v;
|
||||
src_stride_y = -src_stride_y;
|
||||
src_stride_u = -src_stride_u;
|
||||
src_stride_v = -src_stride_v;
|
||||
}
|
||||
|
||||
if (dst_y) {
|
||||
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
|
||||
}
|
||||
|
||||
// Copy UV planes as is - I420
|
||||
if (src_pixel_stride_uv == 1) {
|
||||
CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, halfheight);
|
||||
CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, halfheight);
|
||||
return 0;
|
||||
// Split UV planes - NV21
|
||||
}
|
||||
if (src_pixel_stride_uv == 2 && vu_off == -1 &&
|
||||
src_stride_u == src_stride_v) {
|
||||
SplitUVPlane(src_v, src_stride_v, dst_v, dst_stride_v, dst_u, dst_stride_u,
|
||||
halfwidth, halfheight);
|
||||
return 0;
|
||||
// Split UV planes - NV12
|
||||
}
|
||||
if (src_pixel_stride_uv == 2 && vu_off == 1 && src_stride_u == src_stride_v) {
|
||||
SplitUVPlane(src_u, src_stride_u, dst_u, dst_stride_u, dst_v, dst_stride_v,
|
||||
halfwidth, halfheight);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (y = 0; y < halfheight; ++y) {
|
||||
SplitPixels(src_u, src_pixel_stride_uv, dst_u, halfwidth);
|
||||
SplitPixels(src_v, src_pixel_stride_uv, dst_v, halfwidth);
|
||||
src_u += src_stride_u;
|
||||
src_v += src_stride_v;
|
||||
dst_u += dst_stride_u;
|
||||
dst_v += dst_stride_v;
|
||||
}
|
||||
return 0;
|
||||
return Android420ToI420Rotate(src_y, src_stride_y, src_u, src_stride_u, src_v,
|
||||
src_stride_v, src_pixel_stride_uv, dst_y,
|
||||
dst_stride_y, dst_u, dst_stride_u, dst_v,
|
||||
dst_stride_v, width, height, kRotate0);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
159
source/rotate.cc
159
source/rotate.cc
@ -221,7 +221,7 @@ void RotatePlane180(const uint8_t* src,
|
||||
}
|
||||
|
||||
LIBYUV_API
|
||||
void TransposeUV(const uint8_t* src,
|
||||
void SplitTransposeUV(const uint8_t* src,
|
||||
int src_stride,
|
||||
uint8_t* dst_a,
|
||||
int dst_stride_a,
|
||||
@ -300,7 +300,7 @@ void TransposeUV(const uint8_t* src,
|
||||
}
|
||||
|
||||
LIBYUV_API
|
||||
void RotateUV90(const uint8_t* src,
|
||||
void SplitRotateUV90(const uint8_t* src,
|
||||
int src_stride,
|
||||
uint8_t* dst_a,
|
||||
int dst_stride_a,
|
||||
@ -311,12 +311,12 @@ void RotateUV90(const uint8_t* src,
|
||||
src += src_stride * (height - 1);
|
||||
src_stride = -src_stride;
|
||||
|
||||
TransposeUV(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b, width,
|
||||
height);
|
||||
SplitTransposeUV(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b,
|
||||
width, height);
|
||||
}
|
||||
|
||||
LIBYUV_API
|
||||
void RotateUV270(const uint8_t* src,
|
||||
void SplitRotateUV270(const uint8_t* src,
|
||||
int src_stride,
|
||||
uint8_t* dst_a,
|
||||
int dst_stride_a,
|
||||
@ -329,13 +329,13 @@ void RotateUV270(const uint8_t* src,
|
||||
dst_stride_a = -dst_stride_a;
|
||||
dst_stride_b = -dst_stride_b;
|
||||
|
||||
TransposeUV(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b, width,
|
||||
height);
|
||||
SplitTransposeUV(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b,
|
||||
width, height);
|
||||
}
|
||||
|
||||
// Rotate 180 is a horizontal and vertical flip.
|
||||
LIBYUV_API
|
||||
void RotateUV180(const uint8_t* src,
|
||||
void SplitRotateUV180(const uint8_t* src,
|
||||
int src_stride,
|
||||
uint8_t* dst_a,
|
||||
int dst_stride_a,
|
||||
@ -378,6 +378,52 @@ void RotateUV180(const uint8_t* src,
|
||||
}
|
||||
}
|
||||
|
||||
// Rotate UV and split into planar.
|
||||
// width and height expected to be half size for NV12
|
||||
LIBYUV_API
|
||||
int SplitRotateUV(const uint8_t* src_uv,
|
||||
int src_stride_uv,
|
||||
uint8_t* dst_u,
|
||||
int dst_stride_u,
|
||||
uint8_t* dst_v,
|
||||
int dst_stride_v,
|
||||
int width,
|
||||
int height,
|
||||
enum RotationMode mode) {
|
||||
if (!src_uv || width <= 0 || height == 0 || !dst_u || !dst_v) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Negative height means invert the image.
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
src_uv = src_uv + (height - 1) * src_stride_uv;
|
||||
src_stride_uv = -src_stride_uv;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case kRotate0:
|
||||
SplitUVPlane(src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v,
|
||||
dst_stride_v, width, height);
|
||||
return 0;
|
||||
case kRotate90:
|
||||
SplitRotateUV90(src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v,
|
||||
dst_stride_v, width, height);
|
||||
return 0;
|
||||
case kRotate270:
|
||||
SplitRotateUV270(src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v,
|
||||
dst_stride_v, width, height);
|
||||
return 0;
|
||||
case kRotate180:
|
||||
SplitRotateUV180(src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v,
|
||||
dst_stride_v, width, height);
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
LIBYUV_API
|
||||
int RotatePlane(const uint8_t* src,
|
||||
int src_stride,
|
||||
@ -584,17 +630,17 @@ int NV12ToI420Rotate(const uint8_t* src_y,
|
||||
width, height);
|
||||
case kRotate90:
|
||||
RotatePlane90(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
|
||||
RotateUV90(src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v,
|
||||
SplitRotateUV90(src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v,
|
||||
dst_stride_v, halfwidth, halfheight);
|
||||
return 0;
|
||||
case kRotate270:
|
||||
RotatePlane270(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
|
||||
RotateUV270(src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v,
|
||||
SplitRotateUV270(src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v,
|
||||
dst_stride_v, halfwidth, halfheight);
|
||||
return 0;
|
||||
case kRotate180:
|
||||
RotatePlane180(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
|
||||
RotateUV180(src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v,
|
||||
SplitRotateUV180(src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v,
|
||||
dst_stride_v, halfwidth, halfheight);
|
||||
return 0;
|
||||
default:
|
||||
@ -603,6 +649,97 @@ int NV12ToI420Rotate(const uint8_t* src_y,
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void SplitPixels(const uint8_t* src_u,
|
||||
int src_pixel_stride_uv,
|
||||
uint8_t* dst_u,
|
||||
int width) {
|
||||
int i;
|
||||
for (i = 0; i < width; ++i) {
|
||||
*dst_u = *src_u;
|
||||
++dst_u;
|
||||
src_u += src_pixel_stride_uv;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert Android420 to I420 with Rotate
|
||||
LIBYUV_API
|
||||
int Android420ToI420Rotate(const uint8_t* src_y,
|
||||
int src_stride_y,
|
||||
const uint8_t* src_u,
|
||||
int src_stride_u,
|
||||
const uint8_t* src_v,
|
||||
int src_stride_v,
|
||||
int src_pixel_stride_uv,
|
||||
uint8_t* dst_y,
|
||||
int dst_stride_y,
|
||||
uint8_t* dst_u,
|
||||
int dst_stride_u,
|
||||
uint8_t* dst_v,
|
||||
int dst_stride_v,
|
||||
int width,
|
||||
int height,
|
||||
enum RotationMode rotation) {
|
||||
int y;
|
||||
const ptrdiff_t vu_off = src_v - src_u;
|
||||
int halfwidth = (width + 1) >> 1;
|
||||
int halfheight = (height + 1) >> 1;
|
||||
if (!src_u || !src_v || !dst_u || !dst_v || width <= 0 || height == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Negative height means invert the image.
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
halfheight = (height + 1) >> 1;
|
||||
src_y = src_y + (height - 1) * src_stride_y;
|
||||
src_u = src_u + (halfheight - 1) * src_stride_u;
|
||||
src_v = src_v + (halfheight - 1) * src_stride_v;
|
||||
src_stride_y = -src_stride_y;
|
||||
src_stride_u = -src_stride_u;
|
||||
src_stride_v = -src_stride_v;
|
||||
}
|
||||
|
||||
if (dst_y) {
|
||||
RotatePlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height,
|
||||
rotation);
|
||||
}
|
||||
|
||||
// Copy UV planes - I420
|
||||
if (src_pixel_stride_uv == 1) {
|
||||
RotatePlane(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, halfheight,
|
||||
rotation);
|
||||
RotatePlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, halfheight,
|
||||
rotation);
|
||||
return 0;
|
||||
}
|
||||
// Split UV planes - NV21
|
||||
if (src_pixel_stride_uv == 2 && vu_off == -1 &&
|
||||
src_stride_u == src_stride_v) {
|
||||
SplitRotateUV(src_v, src_stride_v, dst_v, dst_stride_v, dst_u, dst_stride_u,
|
||||
halfwidth, halfheight, rotation);
|
||||
return 0;
|
||||
}
|
||||
// Split UV planes - NV12
|
||||
if (src_pixel_stride_uv == 2 && vu_off == 1 && src_stride_u == src_stride_v) {
|
||||
SplitRotateUV(src_u, src_stride_u, dst_u, dst_stride_u, dst_v, dst_stride_v,
|
||||
halfwidth, halfheight, rotation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rotation == 0) {
|
||||
for (y = 0; y < halfheight; ++y) {
|
||||
SplitPixels(src_u, src_pixel_stride_uv, dst_u, halfwidth);
|
||||
SplitPixels(src_v, src_pixel_stride_uv, dst_v, halfwidth);
|
||||
src_u += src_stride_u;
|
||||
src_v += src_stride_v;
|
||||
dst_u += dst_stride_u;
|
||||
dst_v += dst_stride_v;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// unsupported type and/or rotation.
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
} // namespace libyuv
|
||||
|
||||
@ -290,6 +290,8 @@ TESTPLANARTOP(I412, uint16_t, 2, 1, 1, I444, uint8_t, 1, 1, 1, 12)
|
||||
TESTAPLANARTOP(Android420, I420, 1, 0, 0, 2, 2, I420, 2, 2)
|
||||
TESTAPLANARTOP(Android420, NV12, 2, 0, 1, 2, 2, I420, 2, 2)
|
||||
TESTAPLANARTOP(Android420, NV21, 2, 1, 0, 2, 2, I420, 2, 2)
|
||||
#undef TESTAPLANARTOP
|
||||
#undef TESTAPLANARTOPI
|
||||
|
||||
// wrapper to keep API the same
|
||||
int I400ToNV21(const uint8_t* src_y,
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
|
||||
namespace libyuv {
|
||||
|
||||
#define SUBSAMPLE(v, a) ((((v) + (a)-1)) / (a))
|
||||
|
||||
static void I420TestRotate(int src_width,
|
||||
int src_height,
|
||||
int dst_width,
|
||||
@ -391,4 +393,119 @@ TEST_F(LibYUVRotateTest, NV12Rotate270_Invert) {
|
||||
disable_cpu_flags_, benchmark_cpu_info_);
|
||||
}
|
||||
|
||||
// Test Android 420 to I420 Rotate
|
||||
#define TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X, \
|
||||
SRC_SUBSAMP_Y, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
|
||||
W1280, N, NEG, OFF, PN, OFF_U, OFF_V, ROT) \
|
||||
TEST_F(LibYUVRotateTest, \
|
||||
SRC_FMT_PLANAR##To##FMT_PLANAR##Rotate##ROT##To##PN##N) { \
|
||||
const int kWidth = W1280; \
|
||||
const int kHeight = benchmark_height_; \
|
||||
const int kSizeUV = \
|
||||
SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); \
|
||||
align_buffer_page_end(src_y, kWidth* kHeight + OFF); \
|
||||
align_buffer_page_end(src_uv, \
|
||||
kSizeUV*((PIXEL_STRIDE == 3) ? 3 : 2) + OFF); \
|
||||
align_buffer_page_end(dst_y_c, kWidth* kHeight); \
|
||||
align_buffer_page_end(dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X) * \
|
||||
SUBSAMPLE(kHeight, SUBSAMP_Y)); \
|
||||
align_buffer_page_end(dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X) * \
|
||||
SUBSAMPLE(kHeight, SUBSAMP_Y)); \
|
||||
align_buffer_page_end(dst_y_opt, kWidth* kHeight); \
|
||||
align_buffer_page_end(dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X) * \
|
||||
SUBSAMPLE(kHeight, SUBSAMP_Y)); \
|
||||
align_buffer_page_end(dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X) * \
|
||||
SUBSAMPLE(kHeight, SUBSAMP_Y)); \
|
||||
uint8_t* src_u = src_uv + OFF_U; \
|
||||
uint8_t* src_v = src_uv + (PIXEL_STRIDE == 1 ? kSizeUV : OFF_V); \
|
||||
int src_stride_uv = SUBSAMPLE(kWidth, SUBSAMP_X) * PIXEL_STRIDE; \
|
||||
for (int i = 0; i < kHeight; ++i) \
|
||||
for (int j = 0; j < kWidth; ++j) \
|
||||
src_y[i * kWidth + j + OFF] = (fastrand() & 0xff); \
|
||||
for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) { \
|
||||
for (int j = 0; j < SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) { \
|
||||
src_u[(i * src_stride_uv) + j * PIXEL_STRIDE + OFF] = \
|
||||
(fastrand() & 0xff); \
|
||||
src_v[(i * src_stride_uv) + j * PIXEL_STRIDE + OFF] = \
|
||||
(fastrand() & 0xff); \
|
||||
} \
|
||||
} \
|
||||
memset(dst_y_c, 1, kWidth* kHeight); \
|
||||
memset(dst_u_c, 2, \
|
||||
SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \
|
||||
memset(dst_v_c, 3, \
|
||||
SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \
|
||||
memset(dst_y_opt, 101, kWidth* kHeight); \
|
||||
memset(dst_u_opt, 102, \
|
||||
SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \
|
||||
memset(dst_v_opt, 103, \
|
||||
SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \
|
||||
MaskCpuFlags(disable_cpu_flags_); \
|
||||
SRC_FMT_PLANAR##To##FMT_PLANAR##Rotate( \
|
||||
src_y + OFF, kWidth, src_u + OFF, SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \
|
||||
src_v + OFF, SUBSAMPLE(kWidth, SRC_SUBSAMP_X), PIXEL_STRIDE, dst_y_c, \
|
||||
kWidth, dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X), dst_v_c, \
|
||||
SUBSAMPLE(kWidth, SUBSAMP_X), kWidth, NEG kHeight, \
|
||||
(libyuv::RotationMode)ROT); \
|
||||
MaskCpuFlags(benchmark_cpu_info_); \
|
||||
for (int i = 0; i < benchmark_iterations_; ++i) { \
|
||||
SRC_FMT_PLANAR##To##FMT_PLANAR##Rotate( \
|
||||
src_y + OFF, kWidth, src_u + OFF, SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \
|
||||
src_v + OFF, SUBSAMPLE(kWidth, SRC_SUBSAMP_X), PIXEL_STRIDE, \
|
||||
dst_y_opt, kWidth, dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \
|
||||
dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X), kWidth, NEG kHeight, \
|
||||
(libyuv::RotationMode)ROT); \
|
||||
} \
|
||||
for (int i = 0; i < kHeight; ++i) { \
|
||||
for (int j = 0; j < kWidth; ++j) { \
|
||||
EXPECT_EQ(dst_y_c[i * kWidth + j], dst_y_opt[i * kWidth + j]); \
|
||||
} \
|
||||
} \
|
||||
for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
|
||||
for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \
|
||||
EXPECT_EQ(dst_u_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j], \
|
||||
dst_u_opt[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]); \
|
||||
} \
|
||||
} \
|
||||
for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
|
||||
for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \
|
||||
EXPECT_EQ(dst_v_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j], \
|
||||
dst_v_opt[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]); \
|
||||
} \
|
||||
} \
|
||||
free_aligned_buffer_page_end(dst_y_c); \
|
||||
free_aligned_buffer_page_end(dst_u_c); \
|
||||
free_aligned_buffer_page_end(dst_v_c); \
|
||||
free_aligned_buffer_page_end(dst_y_opt); \
|
||||
free_aligned_buffer_page_end(dst_u_opt); \
|
||||
free_aligned_buffer_page_end(dst_v_opt); \
|
||||
free_aligned_buffer_page_end(src_y); \
|
||||
free_aligned_buffer_page_end(src_uv); \
|
||||
}
|
||||
|
||||
#define TESTAPLANARTOP(SRC_FMT_PLANAR, PN, PIXEL_STRIDE, OFF_U, OFF_V, \
|
||||
SRC_SUBSAMP_X, SRC_SUBSAMP_Y, FMT_PLANAR, SUBSAMP_X, \
|
||||
SUBSAMP_Y) \
|
||||
TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
|
||||
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, benchmark_width_ + 1, \
|
||||
_Any, +, 0, PN, OFF_U, OFF_V, 0) \
|
||||
TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
|
||||
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, benchmark_width_, \
|
||||
_Unaligned, +, 2, PN, OFF_U, OFF_V, 0) \
|
||||
TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
|
||||
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, benchmark_width_, _Invert, \
|
||||
-, 0, PN, OFF_U, OFF_V, 0) \
|
||||
TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
|
||||
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, benchmark_width_, _Opt, +, \
|
||||
0, PN, OFF_U, OFF_V, 0) \
|
||||
TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
|
||||
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, benchmark_width_, _Opt, +, \
|
||||
0, PN, OFF_U, OFF_V, 180)
|
||||
|
||||
TESTAPLANARTOP(Android420, I420, 1, 0, 0, 2, 2, I420, 2, 2)
|
||||
TESTAPLANARTOP(Android420, NV12, 2, 0, 1, 2, 2, I420, 2, 2)
|
||||
TESTAPLANARTOP(Android420, NV21, 2, 1, 0, 2, 2, I420, 2, 2)
|
||||
#undef TESTAPLANARTOP
|
||||
#undef TESTAPLANARTOPI
|
||||
|
||||
} // namespace libyuv
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user