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
|
Name: libyuv
|
||||||
URL: http://code.google.com/p/libyuv/
|
URL: http://code.google.com/p/libyuv/
|
||||||
Version: 1801
|
Version: 1802
|
||||||
License: BSD
|
License: BSD
|
||||||
License File: LICENSE
|
License File: LICENSE
|
||||||
|
|
||||||
|
|||||||
@ -83,6 +83,26 @@ int NV12ToI420Rotate(const uint8_t* src_y,
|
|||||||
int height,
|
int height,
|
||||||
enum RotationMode mode);
|
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.
|
// Rotate a plane by 0, 90, 180, or 270.
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
int RotatePlane(const uint8_t* src,
|
int RotatePlane(const uint8_t* src,
|
||||||
@ -119,38 +139,50 @@ void RotatePlane270(const uint8_t* src,
|
|||||||
int height);
|
int height);
|
||||||
|
|
||||||
// Rotations for when U and V are interleaved.
|
// 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
|
// split the data into two buffers while
|
||||||
// rotating them. Deprecated.
|
// rotating them.
|
||||||
|
// width and height expected to be half size for NV12.
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
void RotateUV90(const uint8_t* src,
|
int SplitRotateUV(const uint8_t* src_uv,
|
||||||
int src_stride,
|
int src_stride_uv,
|
||||||
uint8_t* dst_a,
|
uint8_t* dst_u,
|
||||||
int dst_stride_a,
|
int dst_stride_u,
|
||||||
uint8_t* dst_b,
|
uint8_t* dst_v,
|
||||||
int dst_stride_b,
|
int dst_stride_v,
|
||||||
int width,
|
int width,
|
||||||
int height);
|
int height,
|
||||||
|
enum RotationMode mode);
|
||||||
|
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
void RotateUV180(const uint8_t* src,
|
void SplitRotateUV90(const uint8_t* src,
|
||||||
int src_stride,
|
int src_stride,
|
||||||
uint8_t* dst_a,
|
uint8_t* dst_a,
|
||||||
int dst_stride_a,
|
int dst_stride_a,
|
||||||
uint8_t* dst_b,
|
uint8_t* dst_b,
|
||||||
int dst_stride_b,
|
int dst_stride_b,
|
||||||
int width,
|
int width,
|
||||||
int height);
|
int height);
|
||||||
|
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
void RotateUV270(const uint8_t* src,
|
void SplitRotateUV180(const uint8_t* src,
|
||||||
int src_stride,
|
int src_stride,
|
||||||
uint8_t* dst_a,
|
uint8_t* dst_a,
|
||||||
int dst_stride_a,
|
int dst_stride_a,
|
||||||
uint8_t* dst_b,
|
uint8_t* dst_b,
|
||||||
int dst_stride_b,
|
int dst_stride_b,
|
||||||
int width,
|
int width,
|
||||||
int height);
|
int height);
|
||||||
|
|
||||||
|
LIBYUV_API
|
||||||
|
void SplitRotateUV270(const uint8_t* src,
|
||||||
|
int src_stride,
|
||||||
|
uint8_t* dst_a,
|
||||||
|
int dst_stride_a,
|
||||||
|
uint8_t* dst_b,
|
||||||
|
int dst_stride_b,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
|
||||||
// The 90 and 270 functions are based on transposes.
|
// The 90 and 270 functions are based on transposes.
|
||||||
// Doing a transpose with reversing the read/write
|
// Doing a transpose with reversing the read/write
|
||||||
@ -165,14 +197,14 @@ void TransposePlane(const uint8_t* src,
|
|||||||
int height);
|
int height);
|
||||||
|
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
void TransposeUV(const uint8_t* src,
|
void SplitTransposeUV(const uint8_t* src,
|
||||||
int src_stride,
|
int src_stride,
|
||||||
uint8_t* dst_a,
|
uint8_t* dst_a,
|
||||||
int dst_stride_a,
|
int dst_stride_a,
|
||||||
uint8_t* dst_b,
|
uint8_t* dst_b,
|
||||||
int dst_stride_b,
|
int dst_stride_b,
|
||||||
int width,
|
int width,
|
||||||
int height);
|
int height);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|||||||
@ -1099,15 +1099,15 @@ void RAWToUVRow_NEON(const uint8_t* src_raw,
|
|||||||
uint8_t* dst_v,
|
uint8_t* dst_v,
|
||||||
int width);
|
int width);
|
||||||
void RGB24ToUVJRow_NEON(const uint8_t* src_rgb24,
|
void RGB24ToUVJRow_NEON(const uint8_t* src_rgb24,
|
||||||
int src_stride_rgb24,
|
int src_stride_rgb24,
|
||||||
uint8_t* dst_u,
|
uint8_t* dst_u,
|
||||||
uint8_t* dst_v,
|
uint8_t* dst_v,
|
||||||
int width);
|
int width);
|
||||||
void RAWToUVJRow_NEON(const uint8_t* src_raw,
|
void RAWToUVJRow_NEON(const uint8_t* src_raw,
|
||||||
int src_stride_raw,
|
int src_stride_raw,
|
||||||
uint8_t* dst_u,
|
uint8_t* dst_u,
|
||||||
uint8_t* dst_v,
|
uint8_t* dst_v,
|
||||||
int width);
|
int width);
|
||||||
void RGB565ToUVRow_NEON(const uint8_t* src_rgb565,
|
void RGB565ToUVRow_NEON(const uint8_t* src_rgb565,
|
||||||
int src_stride_rgb565,
|
int src_stride_rgb565,
|
||||||
uint8_t* dst_u,
|
uint8_t* dst_u,
|
||||||
@ -1446,15 +1446,15 @@ void RAWToUVRow_Any_NEON(const uint8_t* src_ptr,
|
|||||||
uint8_t* dst_v,
|
uint8_t* dst_v,
|
||||||
int width);
|
int width);
|
||||||
void RGB24ToUVJRow_Any_NEON(const uint8_t* src_ptr,
|
void RGB24ToUVJRow_Any_NEON(const uint8_t* src_ptr,
|
||||||
int src_stride,
|
int src_stride,
|
||||||
uint8_t* dst_u,
|
uint8_t* dst_u,
|
||||||
uint8_t* dst_v,
|
uint8_t* dst_v,
|
||||||
int width);
|
int width);
|
||||||
void RAWToUVJRow_Any_NEON(const uint8_t* src_ptr,
|
void RAWToUVJRow_Any_NEON(const uint8_t* src_ptr,
|
||||||
int src_stride,
|
int src_stride,
|
||||||
uint8_t* dst_u,
|
uint8_t* dst_u,
|
||||||
uint8_t* dst_v,
|
uint8_t* dst_v,
|
||||||
int width);
|
int width);
|
||||||
void RGB565ToUVRow_Any_NEON(const uint8_t* src_ptr,
|
void RGB565ToUVRow_Any_NEON(const uint8_t* src_ptr,
|
||||||
int src_stride,
|
int src_stride,
|
||||||
uint8_t* dst_u,
|
uint8_t* dst_u,
|
||||||
@ -1601,15 +1601,15 @@ void RAWToUVRow_C(const uint8_t* src_rgb,
|
|||||||
uint8_t* dst_v,
|
uint8_t* dst_v,
|
||||||
int width);
|
int width);
|
||||||
void RGB24ToUVJRow_C(const uint8_t* src_rgb,
|
void RGB24ToUVJRow_C(const uint8_t* src_rgb,
|
||||||
int src_stride_rgb,
|
int src_stride_rgb,
|
||||||
uint8_t* dst_u,
|
uint8_t* dst_u,
|
||||||
uint8_t* dst_v,
|
uint8_t* dst_v,
|
||||||
int width);
|
int width);
|
||||||
void RAWToUVJRow_C(const uint8_t* src_rgb,
|
void RAWToUVJRow_C(const uint8_t* src_rgb,
|
||||||
int src_stride_rgb,
|
int src_stride_rgb,
|
||||||
uint8_t* dst_u,
|
uint8_t* dst_u,
|
||||||
uint8_t* dst_v,
|
uint8_t* dst_v,
|
||||||
int width);
|
int width);
|
||||||
void RGB565ToUVRow_C(const uint8_t* src_rgb565,
|
void RGB565ToUVRow_C(const uint8_t* src_rgb565,
|
||||||
int src_stride_rgb565,
|
int src_stride_rgb565,
|
||||||
uint8_t* dst_u,
|
uint8_t* dst_u,
|
||||||
|
|||||||
@ -11,6 +11,6 @@
|
|||||||
#ifndef INCLUDE_LIBYUV_VERSION_H_
|
#ifndef INCLUDE_LIBYUV_VERSION_H_
|
||||||
#define INCLUDE_LIBYUV_VERSION_H_
|
#define INCLUDE_LIBYUV_VERSION_H_
|
||||||
|
|
||||||
#define LIBYUV_VERSION 1801
|
#define LIBYUV_VERSION 1802
|
||||||
|
|
||||||
#endif // INCLUDE_LIBYUV_VERSION_H_
|
#endif // INCLUDE_LIBYUV_VERSION_H_
|
||||||
@ -1951,7 +1951,7 @@ int RGB24ToJ420(const uint8_t* src_rgb24,
|
|||||||
int y;
|
int y;
|
||||||
#if defined(HAS_RGB24TOYJROW)
|
#if defined(HAS_RGB24TOYJROW)
|
||||||
void (*RGB24ToUVJRow)(const uint8_t* src_rgb24, int src_stride_rgb24,
|
void (*RGB24ToUVJRow)(const uint8_t* src_rgb24, int src_stride_rgb24,
|
||||||
uint8_t* dst_u, uint8_t* dst_v, int width) =
|
uint8_t* dst_u, uint8_t* dst_v, int width) =
|
||||||
RGB24ToUVJRow_C;
|
RGB24ToUVJRow_C;
|
||||||
void (*RGB24ToYJRow)(const uint8_t* src_rgb24, uint8_t* dst_y, int width) =
|
void (*RGB24ToYJRow)(const uint8_t* src_rgb24, uint8_t* dst_y, int width) =
|
||||||
RGB24ToYJRow_C;
|
RGB24ToYJRow_C;
|
||||||
@ -1959,7 +1959,7 @@ int RGB24ToJ420(const uint8_t* src_rgb24,
|
|||||||
void (*RGB24ToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, int width) =
|
void (*RGB24ToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, int width) =
|
||||||
RGB24ToARGBRow_C;
|
RGB24ToARGBRow_C;
|
||||||
void (*ARGBToUVJRow)(const uint8_t* src_argb0, int src_stride_argb,
|
void (*ARGBToUVJRow)(const uint8_t* src_argb0, int src_stride_argb,
|
||||||
uint8_t* dst_u, uint8_t* dst_v, int width) =
|
uint8_t* dst_u, uint8_t* dst_v, int width) =
|
||||||
ARGBToUVJRow_C;
|
ARGBToUVJRow_C;
|
||||||
void (*ARGBToYJRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) =
|
void (*ARGBToYJRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) =
|
||||||
ARGBToYJRow_C;
|
ARGBToYJRow_C;
|
||||||
@ -2108,20 +2108,19 @@ int RGB24ToJ420(const uint8_t* src_rgb24,
|
|||||||
// Convert RAW to I420.
|
// Convert RAW to I420.
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
int RAWToI420(const uint8_t* src_raw,
|
int RAWToI420(const uint8_t* src_raw,
|
||||||
int src_stride_raw,
|
int src_stride_raw,
|
||||||
uint8_t* dst_y,
|
uint8_t* dst_y,
|
||||||
int dst_stride_y,
|
int dst_stride_y,
|
||||||
uint8_t* dst_u,
|
uint8_t* dst_u,
|
||||||
int dst_stride_u,
|
int dst_stride_u,
|
||||||
uint8_t* dst_v,
|
uint8_t* dst_v,
|
||||||
int dst_stride_v,
|
int dst_stride_v,
|
||||||
int width,
|
int width,
|
||||||
int height) {
|
int height) {
|
||||||
int y;
|
int y;
|
||||||
#if defined(HAS_RAWTOYROW)
|
#if defined(HAS_RAWTOYROW)
|
||||||
void (*RAWToUVRow)(const uint8_t* src_raw, int src_stride_raw,
|
void (*RAWToUVRow)(const uint8_t* src_raw, int src_stride_raw, uint8_t* dst_u,
|
||||||
uint8_t* dst_u, uint8_t* dst_v, int width) =
|
uint8_t* dst_v, int width) = RAWToUVRow_C;
|
||||||
RAWToUVRow_C;
|
|
||||||
void (*RAWToYRow)(const uint8_t* src_raw, uint8_t* dst_y, int width) =
|
void (*RAWToYRow)(const uint8_t* src_raw, uint8_t* dst_y, int width) =
|
||||||
RAWToYRow_C;
|
RAWToYRow_C;
|
||||||
#else
|
#else
|
||||||
@ -2277,19 +2276,19 @@ int RAWToI420(const uint8_t* src_raw,
|
|||||||
// Convert RAW to J420.
|
// Convert RAW to J420.
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
int RAWToJ420(const uint8_t* src_raw,
|
int RAWToJ420(const uint8_t* src_raw,
|
||||||
int src_stride_raw,
|
int src_stride_raw,
|
||||||
uint8_t* dst_y,
|
uint8_t* dst_y,
|
||||||
int dst_stride_y,
|
int dst_stride_y,
|
||||||
uint8_t* dst_u,
|
uint8_t* dst_u,
|
||||||
int dst_stride_u,
|
int dst_stride_u,
|
||||||
uint8_t* dst_v,
|
uint8_t* dst_v,
|
||||||
int dst_stride_v,
|
int dst_stride_v,
|
||||||
int width,
|
int width,
|
||||||
int height) {
|
int height) {
|
||||||
int y;
|
int y;
|
||||||
#if defined(HAS_RAWTOYJROW)
|
#if defined(HAS_RAWTOYJROW)
|
||||||
void (*RAWToUVJRow)(const uint8_t* src_raw, int src_stride_raw,
|
void (*RAWToUVJRow)(const uint8_t* src_raw, int src_stride_raw,
|
||||||
uint8_t* dst_u, uint8_t* dst_v, int width) =
|
uint8_t* dst_u, uint8_t* dst_v, int width) =
|
||||||
RAWToUVJRow_C;
|
RAWToUVJRow_C;
|
||||||
void (*RAWToYJRow)(const uint8_t* src_raw, uint8_t* dst_y, int width) =
|
void (*RAWToYJRow)(const uint8_t* src_raw, uint8_t* dst_y, int width) =
|
||||||
RAWToYJRow_C;
|
RAWToYJRow_C;
|
||||||
@ -2297,7 +2296,7 @@ int RAWToJ420(const uint8_t* src_raw,
|
|||||||
void (*RAWToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, int width) =
|
void (*RAWToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, int width) =
|
||||||
RAWToARGBRow_C;
|
RAWToARGBRow_C;
|
||||||
void (*ARGBToUVJRow)(const uint8_t* src_argb0, int src_stride_argb,
|
void (*ARGBToUVJRow)(const uint8_t* src_argb0, int src_stride_argb,
|
||||||
uint8_t* dst_u, uint8_t* dst_v, int width) =
|
uint8_t* dst_u, uint8_t* dst_v, int width) =
|
||||||
ARGBToUVJRow_C;
|
ARGBToUVJRow_C;
|
||||||
void (*ARGBToYJRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) =
|
void (*ARGBToYJRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) =
|
||||||
ARGBToYJRow_C;
|
ARGBToYJRow_C;
|
||||||
@ -3118,18 +3117,6 @@ int RAWToJ400(const uint8_t* src_raw,
|
|||||||
return 0;
|
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.
|
// Convert Android420 to I420.
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
int Android420ToI420(const uint8_t* src_y,
|
int Android420ToI420(const uint8_t* src_y,
|
||||||
@ -3147,58 +3134,10 @@ int Android420ToI420(const uint8_t* src_y,
|
|||||||
int dst_stride_v,
|
int dst_stride_v,
|
||||||
int width,
|
int width,
|
||||||
int height) {
|
int height) {
|
||||||
int y;
|
return Android420ToI420Rotate(src_y, src_stride_y, src_u, src_stride_u, src_v,
|
||||||
const ptrdiff_t vu_off = src_v - src_u;
|
src_stride_v, src_pixel_stride_uv, dst_y,
|
||||||
int halfwidth = (width + 1) >> 1;
|
dst_stride_y, dst_u, dst_stride_u, dst_v,
|
||||||
int halfheight = (height + 1) >> 1;
|
dst_stride_v, width, height, kRotate0);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
221
source/rotate.cc
221
source/rotate.cc
@ -221,14 +221,14 @@ void RotatePlane180(const uint8_t* src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
void TransposeUV(const uint8_t* src,
|
void SplitTransposeUV(const uint8_t* src,
|
||||||
int src_stride,
|
int src_stride,
|
||||||
uint8_t* dst_a,
|
uint8_t* dst_a,
|
||||||
int dst_stride_a,
|
int dst_stride_a,
|
||||||
uint8_t* dst_b,
|
uint8_t* dst_b,
|
||||||
int dst_stride_b,
|
int dst_stride_b,
|
||||||
int width,
|
int width,
|
||||||
int height) {
|
int height) {
|
||||||
int i = height;
|
int i = height;
|
||||||
#if defined(HAS_TRANSPOSEUVWX16_MSA)
|
#if defined(HAS_TRANSPOSEUVWX16_MSA)
|
||||||
void (*TransposeUVWx16)(const uint8_t* src, int src_stride, uint8_t* dst_a,
|
void (*TransposeUVWx16)(const uint8_t* src, int src_stride, uint8_t* dst_a,
|
||||||
@ -300,49 +300,49 @@ void TransposeUV(const uint8_t* src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
void RotateUV90(const uint8_t* src,
|
void SplitRotateUV90(const uint8_t* src,
|
||||||
int src_stride,
|
int src_stride,
|
||||||
uint8_t* dst_a,
|
uint8_t* dst_a,
|
||||||
int dst_stride_a,
|
int dst_stride_a,
|
||||||
uint8_t* dst_b,
|
uint8_t* dst_b,
|
||||||
int dst_stride_b,
|
int dst_stride_b,
|
||||||
int width,
|
int width,
|
||||||
int height) {
|
int height) {
|
||||||
src += src_stride * (height - 1);
|
src += src_stride * (height - 1);
|
||||||
src_stride = -src_stride;
|
src_stride = -src_stride;
|
||||||
|
|
||||||
TransposeUV(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b, width,
|
SplitTransposeUV(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b,
|
||||||
height);
|
width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
void RotateUV270(const uint8_t* src,
|
void SplitRotateUV270(const uint8_t* src,
|
||||||
int src_stride,
|
int src_stride,
|
||||||
uint8_t* dst_a,
|
uint8_t* dst_a,
|
||||||
int dst_stride_a,
|
int dst_stride_a,
|
||||||
uint8_t* dst_b,
|
uint8_t* dst_b,
|
||||||
int dst_stride_b,
|
int dst_stride_b,
|
||||||
int width,
|
int width,
|
||||||
int height) {
|
int height) {
|
||||||
dst_a += dst_stride_a * (width - 1);
|
dst_a += dst_stride_a * (width - 1);
|
||||||
dst_b += dst_stride_b * (width - 1);
|
dst_b += dst_stride_b * (width - 1);
|
||||||
dst_stride_a = -dst_stride_a;
|
dst_stride_a = -dst_stride_a;
|
||||||
dst_stride_b = -dst_stride_b;
|
dst_stride_b = -dst_stride_b;
|
||||||
|
|
||||||
TransposeUV(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b, width,
|
SplitTransposeUV(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b,
|
||||||
height);
|
width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rotate 180 is a horizontal and vertical flip.
|
// Rotate 180 is a horizontal and vertical flip.
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
void RotateUV180(const uint8_t* src,
|
void SplitRotateUV180(const uint8_t* src,
|
||||||
int src_stride,
|
int src_stride,
|
||||||
uint8_t* dst_a,
|
uint8_t* dst_a,
|
||||||
int dst_stride_a,
|
int dst_stride_a,
|
||||||
uint8_t* dst_b,
|
uint8_t* dst_b,
|
||||||
int dst_stride_b,
|
int dst_stride_b,
|
||||||
int width,
|
int width,
|
||||||
int height) {
|
int height) {
|
||||||
int i;
|
int i;
|
||||||
void (*MirrorSplitUVRow)(const uint8_t* src, uint8_t* dst_u, uint8_t* dst_v,
|
void (*MirrorSplitUVRow)(const uint8_t* src, uint8_t* dst_u, uint8_t* dst_v,
|
||||||
int width) = MirrorSplitUVRow_C;
|
int width) = MirrorSplitUVRow_C;
|
||||||
@ -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
|
LIBYUV_API
|
||||||
int RotatePlane(const uint8_t* src,
|
int RotatePlane(const uint8_t* src,
|
||||||
int src_stride,
|
int src_stride,
|
||||||
@ -584,18 +630,18 @@ int NV12ToI420Rotate(const uint8_t* src_y,
|
|||||||
width, height);
|
width, height);
|
||||||
case kRotate90:
|
case kRotate90:
|
||||||
RotatePlane90(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
|
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);
|
dst_stride_v, halfwidth, halfheight);
|
||||||
return 0;
|
return 0;
|
||||||
case kRotate270:
|
case kRotate270:
|
||||||
RotatePlane270(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
|
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);
|
dst_stride_v, halfwidth, halfheight);
|
||||||
return 0;
|
return 0;
|
||||||
case kRotate180:
|
case kRotate180:
|
||||||
RotatePlane180(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
|
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);
|
dst_stride_v, halfwidth, halfheight);
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -603,6 +649,97 @@ int NV12ToI420Rotate(const uint8_t* src_y,
|
|||||||
return -1;
|
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
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
} // namespace libyuv
|
} // namespace libyuv
|
||||||
|
|||||||
@ -1832,10 +1832,10 @@ void ARGBToUVJRow_NEON(const uint8_t* src_argb,
|
|||||||
|
|
||||||
// TODO(fbarchard): Subsample match C code.
|
// TODO(fbarchard): Subsample match C code.
|
||||||
void RGB24ToUVJRow_NEON(const uint8_t* src_rgb24,
|
void RGB24ToUVJRow_NEON(const uint8_t* src_rgb24,
|
||||||
int src_stride_rgb24,
|
int src_stride_rgb24,
|
||||||
uint8_t* dst_u,
|
uint8_t* dst_u,
|
||||||
uint8_t* dst_v,
|
uint8_t* dst_v,
|
||||||
int width) {
|
int width) {
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"add %1, %0, %1 \n" // src_stride + src_rgb24
|
"add %1, %0, %1 \n" // src_stride + src_rgb24
|
||||||
"vmov.s16 q10, #127 / 2 \n" // UB / VR 0.500 coefficient
|
"vmov.s16 q10, #127 / 2 \n" // UB / VR 0.500 coefficient
|
||||||
@ -1878,10 +1878,10 @@ void RGB24ToUVJRow_NEON(const uint8_t* src_rgb24,
|
|||||||
|
|
||||||
// TODO(fbarchard): Subsample match C code.
|
// TODO(fbarchard): Subsample match C code.
|
||||||
void RAWToUVJRow_NEON(const uint8_t* src_raw,
|
void RAWToUVJRow_NEON(const uint8_t* src_raw,
|
||||||
int src_stride_raw,
|
int src_stride_raw,
|
||||||
uint8_t* dst_u,
|
uint8_t* dst_u,
|
||||||
uint8_t* dst_v,
|
uint8_t* dst_v,
|
||||||
int width) {
|
int width) {
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"add %1, %0, %1 \n" // src_stride + src_raw
|
"add %1, %0, %1 \n" // src_stride + src_raw
|
||||||
"vmov.s16 q10, #127 / 2 \n" // UB / VR 0.500 coefficient
|
"vmov.s16 q10, #127 / 2 \n" // UB / VR 0.500 coefficient
|
||||||
|
|||||||
@ -2063,10 +2063,10 @@ void RGB24ToUVJRow_NEON(const uint8_t* src_rgb24,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RAWToUVJRow_NEON(const uint8_t* src_raw,
|
void RAWToUVJRow_NEON(const uint8_t* src_raw,
|
||||||
int src_stride_raw,
|
int src_stride_raw,
|
||||||
uint8_t* dst_u,
|
uint8_t* dst_u,
|
||||||
uint8_t* dst_v,
|
uint8_t* dst_v,
|
||||||
int width) {
|
int width) {
|
||||||
const uint8_t* src_raw_1 = src_raw + src_stride_raw;
|
const uint8_t* src_raw_1 = src_raw + src_stride_raw;
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"movi v20.8h, #63, lsl #0 \n" // UB/VR coeff (0.500) / 2
|
"movi v20.8h, #63, lsl #0 \n" // UB/VR coeff (0.500) / 2
|
||||||
|
|||||||
@ -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, I420, 1, 0, 0, 2, 2, I420, 2, 2)
|
||||||
TESTAPLANARTOP(Android420, NV12, 2, 0, 1, 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)
|
TESTAPLANARTOP(Android420, NV21, 2, 1, 0, 2, 2, I420, 2, 2)
|
||||||
|
#undef TESTAPLANARTOP
|
||||||
|
#undef TESTAPLANARTOPI
|
||||||
|
|
||||||
// wrapper to keep API the same
|
// wrapper to keep API the same
|
||||||
int I400ToNV21(const uint8_t* src_y,
|
int I400ToNV21(const uint8_t* src_y,
|
||||||
|
|||||||
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
namespace libyuv {
|
namespace libyuv {
|
||||||
|
|
||||||
|
#define SUBSAMPLE(v, a) ((((v) + (a)-1)) / (a))
|
||||||
|
|
||||||
static void I420TestRotate(int src_width,
|
static void I420TestRotate(int src_width,
|
||||||
int src_height,
|
int src_height,
|
||||||
int dst_width,
|
int dst_width,
|
||||||
@ -391,4 +393,119 @@ TEST_F(LibYUVRotateTest, NV12Rotate270_Invert) {
|
|||||||
disable_cpu_flags_, benchmark_cpu_info_);
|
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
|
} // namespace libyuv
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user