ARGBToJ420 and ARGBAttenuate make C match SIMD

Bug: libyuv:447
Change-Id: Ie1dd4a20fb8d5c96231dcfee9f8a0ac2edfb9bd8
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/2185629
Commit-Queue: Frank Barchard <fbarchard@chromium.org>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
This commit is contained in:
Frank Barchard 2020-05-06 15:28:31 -07:00 committed by Commit Bot
parent 0b8bb60f2e
commit 6cd1ffb1b8
3 changed files with 228 additions and 354 deletions

View File

@ -1186,8 +1186,7 @@ int NV12Mirror(const uint8_t* src_y,
int height) {
int halfwidth = (width + 1) >> 1;
int halfheight = (height + 1) >> 1;
if (!src_y || !src_uv || !dst_uv || width <= 0 ||
height == 0) {
if (!src_y || !src_uv || !dst_uv || width <= 0 || height == 0) {
return -1;
}
// Negative height means invert the image.

View File

@ -426,6 +426,8 @@ static __inline int RGBToY(uint8_t r, uint8_t g, uint8_t b) {
}
#endif
#define AVGB(a, b) (((a) + (b) + 1) >> 1)
#ifdef LIBYUV_RGBTOU_TRUNCATE
static __inline int RGBToU(uint8_t r, uint8_t g, uint8_t b) {
return (112 * b - 74 * g - 38 * r + 0x8000) >> 8;
@ -434,6 +436,7 @@ static __inline int RGBToV(uint8_t r, uint8_t g, uint8_t b) {
return (112 * r - 94 * g - 18 * b + 0x8000) >> 8;
}
#else
// TODO(fbarchard): Add rounding to SIMD and use this
static __inline int RGBToU(uint8_t r, uint8_t g, uint8_t b) {
return (112 * b - 74 * g - 38 * r + 0x8080) >> 8;
}
@ -451,11 +454,10 @@ static __inline int RGB2xToV(uint16_t r, uint16_t g, uint16_t b) {
}
#endif
#define AVGB(a, b) (((a) + (b) + 1) >> 1)
// ARGBToY_C and ARGBToUV_C
// Intel version mimic SSE/AVX which does 2 pavgb
#if LIBYUV_ARGBTOUV_PAVGB
#define MAKEROWY(NAME, R, G, B, BPP) \
void NAME##ToYRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width) { \
int x; \
@ -578,14 +580,25 @@ static __inline int RGBToYJ(uint8_t r, uint8_t g, uint8_t b) {
}
#endif
#if defined(LIBYUV_ARGBTOUV_PAVGB)
static __inline int RGBToUJ(uint8_t r, uint8_t g, uint8_t b) {
return (127 * b - 84 * g - 43 * r + 0x8080) >> 8;
}
static __inline int RGBToVJ(uint8_t r, uint8_t g, uint8_t b) {
return (127 * r - 107 * g - 20 * b + 0x8080) >> 8;
}
#else
static __inline int RGB2xToUJ(uint16_t r, uint16_t g, uint16_t b) {
return ((127 / 2) * b - (84 / 2) * g - (43 / 2) * r + 0x8080) >> 8;
}
static __inline int RGB2xToVJ(uint16_t r, uint16_t g, uint16_t b) {
return ((127 / 2) * r - (107 / 2) * g - (20 / 2) * b + 0x8080) >> 8;
}
#endif
// ARGBToYJ_C and ARGBToUVJ_C
// Intel version mimic SSE/AVX which does 2 pavgb
#if LIBYUV_ARGBTOUV_PAVGB
#define MAKEROWYJ(NAME, R, G, B, BPP) \
void NAME##ToYJRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width) { \
int x; \
@ -621,6 +634,48 @@ static __inline int RGBToVJ(uint8_t r, uint8_t g, uint8_t b) {
dst_v[0] = RGBToVJ(ar, ag, ab); \
} \
}
#else
// ARM version does sum / 2 then multiply by 2x smaller coefficients
#define MAKEROWYJ(NAME, R, G, B, BPP) \
void NAME##ToYJRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width) { \
int x; \
for (x = 0; x < width; ++x) { \
dst_y[0] = RGBToYJ(src_argb0[R], src_argb0[G], src_argb0[B]); \
src_argb0 += BPP; \
dst_y += 1; \
} \
} \
void NAME##ToUVJRow_C(const uint8_t* src_rgb0, int src_stride_rgb, \
uint8_t* dst_u, uint8_t* dst_v, int width) { \
const uint8_t* src_rgb1 = src_rgb0 + src_stride_rgb; \
int x; \
for (x = 0; x < width - 1; x += 2) { \
uint16_t ab = (src_rgb0[B] + src_rgb0[B + BPP] + src_rgb1[B] + \
src_rgb1[B + BPP] + 1) >> \
1; \
uint16_t ag = (src_rgb0[G] + src_rgb0[G + BPP] + src_rgb1[G] + \
src_rgb1[G + BPP] + 1) >> \
1; \
uint16_t ar = (src_rgb0[R] + src_rgb0[R + BPP] + src_rgb1[R] + \
src_rgb1[R + BPP] + 1) >> \
1; \
dst_u[0] = RGB2xToUJ(ar, ag, ab); \
dst_v[0] = RGB2xToVJ(ar, ag, ab); \
src_rgb0 += BPP * 2; \
src_rgb1 += BPP * 2; \
dst_u += 1; \
dst_v += 1; \
} \
if (width & 1) { \
uint16_t ab = (src_rgb0[B] + src_rgb1[B]); \
uint16_t ag = (src_rgb0[G] + src_rgb1[G]); \
uint16_t ar = (src_rgb0[R] + src_rgb1[R]); \
dst_u[0] = RGB2xToUJ(ar, ag, ab); \
dst_v[0] = RGB2xToVJ(ar, ag, ab); \
} \
}
#endif
MAKEROWYJ(ARGB, 2, 1, 0, 4)
MAKEROWYJ(RGBA, 3, 2, 1, 4)
@ -2602,10 +2657,14 @@ void BlendPlaneRow_C(const uint8_t* src0,
}
#undef UBLEND
#if defined(__aarch64__) || defined(__arm__)
#define ATTENUATE(f, a) (f * a + 128) >> 8
#else
// This code mimics the SSSE3 version for better testability.
#define ATTENUATE(f, a) (a | (a << 8)) * (f | (f << 8)) >> 24
#endif
// Multiply source RGB by alpha and store to destination.
// This code mimics the SSSE3 version for better testability.
void ARGBAttenuateRow_C(const uint8_t* src_argb, uint8_t* dst_argb, int width) {
int i;
for (i = 0; i < width - 1; i += 2) {

View File

@ -31,19 +31,10 @@
#include "libyuv/row.h" /* For ARGBToAR30Row_AVX2 */
#endif
#if defined(__arm__) || defined(__aarch64__)
// arm version subsamples by summing 4 pixels, rounding divide by 2, then
// multiplying by matrix with 2x smaller coefficients which are rounded
// to nearest integer.
#define ARM_YUV_ERROR 4
#else
#define ARM_YUV_ERROR 0
#endif
// Some functions fail on big endian. Enable these tests on all cpus except
// PowerPC, but they are not optimized so disabled by default.
#if !defined(__powerpc__) && defined(ENABLE_SLOW_TESTS)
#define INTEL_TEST 1
#define LITTLE_ENDIAN_ONLY_TEST 1
#endif
namespace libyuv {
@ -225,41 +216,23 @@ TESTPLANARTOP(H420, uint8_t, 1, 2, 2, H010, uint16_t, 2, 2, 2)
dst_y_opt, kWidth, dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \
dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X), kWidth, NEG kHeight); \
} \
int max_diff = 0; \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth; ++j) { \
int abs_diff = abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \
static_cast<int>(dst_y_opt[i * kWidth + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
EXPECT_EQ(dst_y_c[i * kWidth + j], dst_y_opt[i * kWidth + j]); \
} \
} \
EXPECT_EQ(0, max_diff); \
for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \
int abs_diff = abs( \
static_cast<int>(dst_u_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \
static_cast<int>( \
dst_u_opt[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
EXPECT_EQ(dst_u_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j], \
dst_u_opt[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]); \
} \
} \
EXPECT_LE(max_diff, 0); \
for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \
int abs_diff = abs( \
static_cast<int>(dst_v_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \
static_cast<int>( \
dst_v_opt[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
EXPECT_EQ(dst_v_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j], \
dst_v_opt[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]); \
} \
} \
EXPECT_LE(max_diff, 3); \
free_aligned_buffer_page_end(dst_y_c); \
free_aligned_buffer_page_end(dst_u_c); \
free_aligned_buffer_page_end(dst_v_c); \
@ -354,30 +327,17 @@ int I400ToNV21(const uint8_t* src_y,
src_v + OFF, SUBSAMPLE(kWidth, SRC_SUBSAMP_X), dst_y_opt, kWidth, \
dst_uv_opt, SUBSAMPLE(kWidth, SUBSAMP_X) * 2, kWidth, NEG kHeight); \
} \
int max_diff = 0; \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth; ++j) { \
int abs_diff = abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \
static_cast<int>(dst_y_opt[i * kWidth + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
EXPECT_EQ(dst_y_c[i * kWidth + j], dst_y_opt[i * kWidth + j]); \
} \
} \
EXPECT_LE(max_diff, 1); \
for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X) * 2; ++j) { \
int abs_diff = \
abs(static_cast<int>( \
dst_uv_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) * 2 + j]) - \
static_cast<int>( \
dst_uv_opt[i * SUBSAMPLE(kWidth, SUBSAMP_X) * 2 + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
EXPECT_EQ(dst_uv_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) * 2 + j], \
dst_uv_opt[i * SUBSAMPLE(kWidth, SUBSAMP_X) * 2 + j]); \
} \
} \
EXPECT_LE(max_diff, 1); \
free_aligned_buffer_page_end(dst_y_c); \
free_aligned_buffer_page_end(dst_uv_c); \
free_aligned_buffer_page_end(dst_y_opt); \
@ -449,32 +409,19 @@ TESTPLANARTOBP(I400, 2, 2, NV21, 2, 2)
kWidth, dst_uv_opt, 2 * SUBSAMPLE(kWidth, SUBSAMP_X), kWidth, \
NEG kHeight); \
} \
int max_diff = 0; \
if (DOY) { \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth; ++j) { \
int abs_diff = abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \
static_cast<int>(dst_y_opt[i * kWidth + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
EXPECT_EQ(dst_y_c[i * kWidth + j], dst_y_opt[i * kWidth + j]); \
} \
} \
EXPECT_LE(max_diff, 1); \
} \
for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
for (int j = 0; j < 2 * SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \
int abs_diff = \
abs(static_cast<int>( \
dst_uv_c[i * 2 * SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \
static_cast<int>( \
dst_uv_opt[i * 2 * SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
EXPECT_EQ(dst_uv_c[i * 2 * SUBSAMPLE(kWidth, SUBSAMP_X) + j], \
dst_uv_opt[i * 2 * SUBSAMPLE(kWidth, SUBSAMP_X) + j]); \
} \
} \
EXPECT_LE(max_diff, 1); \
free_aligned_buffer_page_end(dst_y_c); \
free_aligned_buffer_page_end(dst_uv_c); \
free_aligned_buffer_page_end(dst_y_opt); \
@ -553,43 +500,25 @@ TESTBIPLANARTOBP(NV12, 2, 2, NV12Mirror, 2, 2)
kWidth, dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X), dst_v_opt, \
SUBSAMPLE(kWidth, SUBSAMP_X), kWidth, NEG kHeight); \
} \
int max_diff = 0; \
if (DOY) { \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth; ++j) { \
int abs_diff = abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \
static_cast<int>(dst_y_opt[i * kWidth + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
EXPECT_EQ(dst_y_c[i * kWidth + j], dst_y_opt[i * kWidth + j]); \
} \
} \
EXPECT_LE(max_diff, 1); \
} \
for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \
int abs_diff = abs( \
static_cast<int>(dst_u_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \
static_cast<int>( \
dst_u_opt[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
EXPECT_EQ(dst_u_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j], \
dst_u_opt[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]); \
} \
} \
EXPECT_LE(max_diff, 1); \
for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \
int abs_diff = abs( \
static_cast<int>(dst_v_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \
static_cast<int>( \
dst_v_opt[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
EXPECT_EQ(dst_v_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j], \
dst_v_opt[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]); \
} \
} \
EXPECT_LE(max_diff, 1); \
free_aligned_buffer_page_end(dst_y_c); \
free_aligned_buffer_page_end(dst_u_c); \
free_aligned_buffer_page_end(dst_v_c); \
@ -694,7 +623,7 @@ TESTPLANARTOB(J420, 2, 2, RAW, 3, 3, 1)
TESTPLANARTOB(J420, 2, 2, RGB24, 3, 3, 1)
TESTPLANARTOB(H420, 2, 2, RAW, 3, 3, 1)
TESTPLANARTOB(H420, 2, 2, RGB24, 3, 3, 1)
#ifdef INTEL_TEST
#ifdef LITTLE_ENDIAN_ONLY_TEST
TESTPLANARTOB(I420, 2, 2, RGB565, 2, 2, 1)
TESTPLANARTOB(J420, 2, 2, RGB565, 2, 2, 1)
TESTPLANARTOB(H420, 2, 2, RGB565, 2, 2, 1)
@ -726,13 +655,13 @@ TESTPLANARTOB(I422, 2, 1, YUY2, 2, 4, 1)
TESTPLANARTOB(I422, 2, 1, UYVY, 2, 4, 1)
TESTPLANARTOB(I420, 2, 2, I400, 1, 1, 1)
TESTPLANARTOB(J420, 2, 2, J400, 1, 1, 1)
#ifdef INTEL_TEST
#ifdef LITTLE_ENDIAN_ONLY_TEST
TESTPLANARTOB(I420, 2, 2, AR30, 4, 4, 1)
TESTPLANARTOB(H420, 2, 2, AR30, 4, 4, 1)
#endif
#define TESTQPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
YALIGN, W1280, DIFF, N, NEG, OFF, ATTEN) \
YALIGN, W1280, N, NEG, OFF, ATTEN) \
TEST_F(LibYUVConvertTest, FMT_PLANAR##To##FMT_B##N) { \
const int kWidth = ((W1280) > 0) ? (W1280) : 1; \
const int kHeight = ALIGNINT(benchmark_height_, YALIGN); \
@ -767,15 +696,9 @@ TESTPLANARTOB(H420, 2, 2, AR30, 4, 4, 1)
dst_argb_opt + OFF, kStrideB, kWidth, NEG kHeight, \
ATTEN); \
} \
int max_diff = 0; \
for (int i = 0; i < kWidth * BPP_B * kHeight; ++i) { \
int abs_diff = abs(static_cast<int>(dst_argb_c[i + OFF]) - \
static_cast<int>(dst_argb_opt[i + OFF])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
EXPECT_EQ(dst_argb_c[i + OFF], dst_argb_opt[i + OFF]); \
} \
EXPECT_LE(max_diff, DIFF); \
free_aligned_buffer_page_end(src_y); \
free_aligned_buffer_page_end(src_u); \
free_aligned_buffer_page_end(src_v); \
@ -785,23 +708,23 @@ TESTPLANARTOB(H420, 2, 2, AR30, 4, 4, 1)
}
#define TESTQPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
YALIGN, DIFF) \
YALIGN) \
TESTQPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
YALIGN, benchmark_width_ - 4, DIFF, _Any, +, 0, 0) \
YALIGN, benchmark_width_ - 4, _Any, +, 0, 0) \
TESTQPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
YALIGN, benchmark_width_, DIFF, _Unaligned, +, 1, 0) \
YALIGN, benchmark_width_, _Unaligned, +, 1, 0) \
TESTQPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
YALIGN, benchmark_width_, DIFF, _Invert, -, 0, 0) \
YALIGN, benchmark_width_, _Invert, -, 0, 0) \
TESTQPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
YALIGN, benchmark_width_, DIFF, _Opt, +, 0, 0) \
YALIGN, benchmark_width_, _Opt, +, 0, 0) \
TESTQPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
YALIGN, benchmark_width_, DIFF, _Premult, +, 0, 1)
YALIGN, benchmark_width_, _Premult, +, 0, 1)
TESTQPLANARTOB(I420Alpha, 2, 2, ARGB, 4, 4, 1, 2)
TESTQPLANARTOB(I420Alpha, 2, 2, ABGR, 4, 4, 1, 2)
TESTQPLANARTOB(I420Alpha, 2, 2, ARGB, 4, 4, 1)
TESTQPLANARTOB(I420Alpha, 2, 2, ABGR, 4, 4, 1)
#define TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, FMT_C, \
BPP_B, W1280, DIFF, N, NEG, OFF) \
BPP_B, W1280, N, NEG, OFF) \
TEST_F(LibYUVConvertTest, FMT_PLANAR##To##FMT_B##N) { \
const int kWidth = ((W1280) > 0) ? (W1280) : 1; \
const int kHeight = benchmark_height_; \
@ -840,18 +763,12 @@ TESTQPLANARTOB(I420Alpha, 2, 2, ABGR, 4, 4, 1, 2)
kHeight); \
FMT_C##ToARGB(dst_argb_opt, kStrideB, dst_argb32_opt, kWidth * 4, kWidth, \
kHeight); \
int max_diff = 0; \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth * 4; ++j) { \
int abs_diff = \
abs(static_cast<int>(dst_argb32_c[i * kWidth * 4 + j]) - \
static_cast<int>(dst_argb32_opt[i * kWidth * 4 + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
EXPECT_EQ(dst_argb32_c[i * kWidth * 4 + j], \
dst_argb32_opt[i * kWidth * 4 + j]); \
} \
} \
EXPECT_LE(max_diff, DIFF); \
free_aligned_buffer_page_end(src_y); \
free_aligned_buffer_page_end(src_uv); \
free_aligned_buffer_page_end(dst_argb_c); \
@ -860,93 +777,29 @@ TESTQPLANARTOB(I420Alpha, 2, 2, ABGR, 4, 4, 1, 2)
free_aligned_buffer_page_end(dst_argb32_opt); \
}
#define TESTBIPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, FMT_C, BPP_B, \
DIFF) \
#define TESTBIPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, FMT_C, BPP_B) \
TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, FMT_C, BPP_B, \
benchmark_width_ - 4, DIFF, _Any, +, 0) \
benchmark_width_ - 4, _Any, +, 0) \
TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, FMT_C, BPP_B, \
benchmark_width_, DIFF, _Unaligned, +, 1) \
benchmark_width_, _Unaligned, +, 1) \
TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, FMT_C, BPP_B, \
benchmark_width_, DIFF, _Invert, -, 0) \
benchmark_width_, _Invert, -, 0) \
TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, FMT_C, BPP_B, \
benchmark_width_, DIFF, _Opt, +, 0)
benchmark_width_, _Opt, +, 0)
TESTBIPLANARTOB(NV12, 2, 2, ARGB, ARGB, 4, 2)
TESTBIPLANARTOB(NV21, 2, 2, ARGB, ARGB, 4, 2)
TESTBIPLANARTOB(NV12, 2, 2, ABGR, ABGR, 4, 2)
TESTBIPLANARTOB(NV21, 2, 2, ABGR, ABGR, 4, 2)
TESTBIPLANARTOB(NV12, 2, 2, RGB24, RGB24, 3, 2)
TESTBIPLANARTOB(NV21, 2, 2, RGB24, RGB24, 3, 2)
TESTBIPLANARTOB(NV12, 2, 2, RAW, RAW, 3, 2)
TESTBIPLANARTOB(NV21, 2, 2, RAW, RAW, 3, 2)
#ifdef INTEL_TEST
TESTBIPLANARTOB(NV12, 2, 2, RGB565, RGB565, 2, 9)
TESTBIPLANARTOB(NV12, 2, 2, ARGB, ARGB, 4)
TESTBIPLANARTOB(NV21, 2, 2, ARGB, ARGB, 4)
TESTBIPLANARTOB(NV12, 2, 2, ABGR, ABGR, 4)
TESTBIPLANARTOB(NV21, 2, 2, ABGR, ABGR, 4)
TESTBIPLANARTOB(NV12, 2, 2, RGB24, RGB24, 3)
TESTBIPLANARTOB(NV21, 2, 2, RGB24, RGB24, 3)
TESTBIPLANARTOB(NV12, 2, 2, RAW, RAW, 3)
TESTBIPLANARTOB(NV21, 2, 2, RAW, RAW, 3)
TESTBIPLANARTOB(NV21, 2, 2, YUV24, RAW, 3)
#ifdef LITTLE_ENDIAN_ONLY_TEST
TESTBIPLANARTOB(NV12, 2, 2, RGB565, RGB565, 2)
#endif
TESTBIPLANARTOB(NV21, 2, 2, YUV24, RAW, 3, 2)
#ifdef DO_THREE_PLANES
// Do 3 allocations for yuv. conventional but slower.
#define TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
W1280, DIFF, N, NEG, OFF) \
TEST_F(LibYUVConvertTest, FMT_A##To##FMT_PLANAR##N) { \
const int kWidth = ((W1280) > 0) ? (W1280) : 1; \
const int kHeight = ALIGNINT(benchmark_height_, YALIGN); \
const int kStrideUV = SUBSAMPLE(kWidth, SUBSAMP_X); \
const int kStride = (kStrideUV * SUBSAMP_X * 8 * BPP_A + 7) / 8; \
align_buffer_page_end(src_argb, kStride* kHeight + OFF); \
align_buffer_page_end(dst_y_c, kWidth* kHeight); \
align_buffer_page_end(dst_u_c, kStrideUV* SUBSAMPLE(kHeight, SUBSAMP_Y)); \
align_buffer_page_end(dst_v_c, kStrideUV* SUBSAMPLE(kHeight, SUBSAMP_Y)); \
align_buffer_page_end(dst_y_opt, kWidth* kHeight); \
align_buffer_page_end(dst_u_opt, \
kStrideUV* SUBSAMPLE(kHeight, SUBSAMP_Y)); \
align_buffer_page_end(dst_v_opt, \
kStrideUV* SUBSAMPLE(kHeight, SUBSAMP_Y)); \
memset(dst_y_c, 1, kWidth* kHeight); \
memset(dst_u_c, 2, kStrideUV* SUBSAMPLE(kHeight, SUBSAMP_Y)); \
memset(dst_v_c, 3, kStrideUV* SUBSAMPLE(kHeight, SUBSAMP_Y)); \
memset(dst_y_opt, 101, kWidth* kHeight); \
memset(dst_u_opt, 102, kStrideUV* SUBSAMPLE(kHeight, SUBSAMP_Y)); \
memset(dst_v_opt, 103, kStrideUV* SUBSAMPLE(kHeight, SUBSAMP_Y)); \
for (int i = 0; i < kHeight; ++i) \
for (int j = 0; j < kStride; ++j) \
src_argb[(i * kStride) + j + OFF] = (fastrand() & 0xff); \
MaskCpuFlags(disable_cpu_flags_); \
FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, dst_y_c, kWidth, dst_u_c, \
kStrideUV, dst_v_c, kStrideUV, kWidth, NEG kHeight); \
MaskCpuFlags(benchmark_cpu_info_); \
for (int i = 0; i < benchmark_iterations_; ++i) { \
FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, dst_y_opt, kWidth, \
dst_u_opt, kStrideUV, dst_v_opt, kStrideUV, \
kWidth, NEG kHeight); \
} \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth; ++j) { \
EXPECT_NEAR(static_cast<int>(dst_y_c[i * kWidth + j]), \
static_cast<int>(dst_y_opt[i * kWidth + j]), DIFF); \
} \
} \
for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
for (int j = 0; j < kStrideUV; ++j) { \
EXPECT_NEAR(static_cast<int>(dst_u_c[i * kStrideUV + j]), \
static_cast<int>(dst_u_opt[i * kStrideUV + j]), DIFF); \
} \
} \
for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
for (int j = 0; j < kStrideUV; ++j) { \
EXPECT_NEAR(static_cast<int>(dst_v_c[i * kStrideUV + j]), \
static_cast<int>(dst_v_opt[i * kStrideUV + j]), DIFF); \
} \
} \
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_argb); \
}
#else
#define TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
W1280, DIFF, N, NEG, OFF) \
TEST_F(LibYUVConvertTest, FMT_A##To##FMT_PLANAR##N) { \
@ -980,8 +833,8 @@ TESTBIPLANARTOB(NV21, 2, 2, YUV24, RAW, 3, 2)
} \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth; ++j) { \
EXPECT_NEAR(static_cast<int>(dst_y_c[i * kWidth + j]), \
static_cast<int>(dst_y_opt[i * kWidth + j]), DIFF); \
EXPECT_EQ(static_cast<int>(dst_y_c[i * kWidth + j]), \
static_cast<int>(dst_y_opt[i * kWidth + j])); \
} \
} \
for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y) * 2; ++i) { \
@ -996,7 +849,6 @@ TESTBIPLANARTOB(NV21, 2, 2, YUV24, RAW, 3, 2)
free_aligned_buffer_page_end(dst_uv_opt); \
free_aligned_buffer_page_end(src_argb); \
}
#endif
#define TESTATOPLANAR(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
DIFF) \
@ -1013,10 +865,10 @@ TESTATOPLANAR(ABGR, 4, 1, I420, 2, 2, 0)
TESTATOPLANAR(ARGB, 4, 1, I420, 2, 2, 0)
TESTATOPLANAR(ARGB, 4, 1, I422, 2, 1, 0)
TESTATOPLANAR(ARGB, 4, 1, I444, 1, 1, 0)
TESTATOPLANAR(ARGB, 4, 1, J420, 2, 2, ARM_YUV_ERROR)
TESTATOPLANAR(ARGB, 4, 1, J422, 2, 1, ARM_YUV_ERROR)
#ifdef INTEL_TEST
TESTATOPLANAR(ARGB1555, 2, 1, I420, 2, 2, 15)
TESTATOPLANAR(ARGB, 4, 1, J420, 2, 2, 0)
TESTATOPLANAR(ARGB, 4, 1, J422, 2, 1, 0)
#ifdef LITTLE_ENDIAN_ONLY_TEST
TESTATOPLANAR(ARGB1555, 2, 1, I420, 2, 2, 9)
TESTATOPLANAR(ARGB4444, 2, 1, I420, 2, 2, 17)
TESTATOPLANAR(RGB565, 2, 1, I420, 2, 2, 5)
#endif
@ -1025,7 +877,7 @@ TESTATOPLANAR(I400, 1, 1, I420, 2, 2, 0)
TESTATOPLANAR(J400, 1, 1, J420, 2, 2, 0)
TESTATOPLANAR(RAW, 3, 1, I420, 2, 2, 0)
TESTATOPLANAR(RGB24, 3, 1, I420, 2, 2, 0)
TESTATOPLANAR(RGB24, 3, 1, J420, 2, 2, ARM_YUV_ERROR)
TESTATOPLANAR(RGB24, 3, 1, J420, 2, 2, 0)
TESTATOPLANAR(RGBA, 4, 1, I420, 2, 2, 0)
TESTATOPLANAR(UYVY, 2, 1, I420, 2, 2, 0)
TESTATOPLANAR(UYVY, 2, 1, I422, 2, 1, 0)
@ -1061,28 +913,17 @@ TESTATOPLANAR(YUY2, 2, 1, I422, 2, 1, 0)
FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, dst_y_opt, kWidth, \
dst_uv_opt, kStrideUV * 2, kWidth, NEG kHeight); \
} \
int max_diff = 0; \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth; ++j) { \
int abs_diff = abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \
static_cast<int>(dst_y_opt[i * kWidth + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
EXPECT_EQ(dst_y_c[i * kWidth + j], dst_y_opt[i * kWidth + j]); \
} \
} \
EXPECT_LE(max_diff, 0); \
for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
for (int j = 0; j < kStrideUV * 2; ++j) { \
int abs_diff = \
abs(static_cast<int>(dst_uv_c[i * kStrideUV * 2 + j]) - \
static_cast<int>(dst_uv_opt[i * kStrideUV * 2 + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
EXPECT_EQ(dst_uv_c[i * kStrideUV * 2 + j], \
dst_uv_opt[i * kStrideUV * 2 + j]); \
} \
} \
EXPECT_LE(max_diff, 0); \
free_aligned_buffer_page_end(dst_y_c); \
free_aligned_buffer_page_end(dst_uv_c); \
free_aligned_buffer_page_end(dst_y_opt); \
@ -1110,7 +951,7 @@ TESTATOBIPLANAR(AYUV, 1, 4, NV12, 2, 2)
TESTATOBIPLANAR(AYUV, 1, 4, NV21, 2, 2)
#define TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, FMT_B, BPP_B, STRIDE_B, \
HEIGHT_B, W1280, DIFF, N, NEG, OFF) \
HEIGHT_B, W1280, N, NEG, OFF) \
TEST_F(LibYUVConvertTest, FMT_A##To##FMT_B##N) { \
const int kWidth = ((W1280) > 0) ? (W1280) : 1; \
const int kHeight = benchmark_height_; \
@ -1136,22 +977,16 @@ TESTATOBIPLANAR(AYUV, 1, 4, NV21, 2, 2)
FMT_A##To##FMT_B(src_argb + OFF, kStrideA, dst_argb_opt, kStrideB, \
kWidth, NEG kHeight); \
} \
int max_diff = 0; \
for (int i = 0; i < kStrideB * kHeightB; ++i) { \
int abs_diff = abs(static_cast<int>(dst_argb_c[i]) - \
static_cast<int>(dst_argb_opt[i])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
EXPECT_EQ(dst_argb_c[i], dst_argb_opt[i]); \
} \
EXPECT_LE(max_diff, DIFF); \
free_aligned_buffer_page_end(src_argb); \
free_aligned_buffer_page_end(dst_argb_c); \
free_aligned_buffer_page_end(dst_argb_opt); \
}
#define TESTATOBRANDOM(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, FMT_B, BPP_B, \
STRIDE_B, HEIGHT_B, DIFF) \
STRIDE_B, HEIGHT_B) \
TEST_F(LibYUVConvertTest, FMT_A##To##FMT_B##_Random) { \
for (int times = 0; times < benchmark_iterations_; ++times) { \
const int kWidth = (fastrand() & 63) + 1; \
@ -1177,7 +1012,7 @@ TESTATOBIPLANAR(AYUV, 1, 4, NV21, 2, 2)
FMT_A##To##FMT_B(src_argb, kStrideA, dst_argb_opt, kStrideB, kWidth, \
kHeight); \
for (int i = 0; i < kStrideB * kHeightB; ++i) { \
EXPECT_NEAR(dst_argb_c[i], dst_argb_opt[i], DIFF); \
EXPECT_EQ(dst_argb_c[i], dst_argb_opt[i]); \
} \
free_aligned_buffer_page_end(src_argb); \
free_aligned_buffer_page_end(dst_argb_c); \
@ -1186,78 +1021,77 @@ TESTATOBIPLANAR(AYUV, 1, 4, NV21, 2, 2)
}
#define TESTATOB(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, FMT_B, BPP_B, STRIDE_B, \
HEIGHT_B, DIFF) \
HEIGHT_B) \
TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, FMT_B, BPP_B, STRIDE_B, \
HEIGHT_B, benchmark_width_ - 4, DIFF, _Any, +, 0) \
HEIGHT_B, benchmark_width_ - 4, _Any, +, 0) \
TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, FMT_B, BPP_B, STRIDE_B, \
HEIGHT_B, benchmark_width_, DIFF, _Unaligned, +, 1) \
HEIGHT_B, benchmark_width_, _Unaligned, +, 1) \
TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, FMT_B, BPP_B, STRIDE_B, \
HEIGHT_B, benchmark_width_, DIFF, _Invert, -, 0) \
HEIGHT_B, benchmark_width_, _Invert, -, 0) \
TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, FMT_B, BPP_B, STRIDE_B, \
HEIGHT_B, benchmark_width_, DIFF, _Opt, +, 0) \
HEIGHT_B, benchmark_width_, _Opt, +, 0) \
TESTATOBRANDOM(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, FMT_B, BPP_B, STRIDE_B, \
HEIGHT_B, DIFF)
HEIGHT_B)
// TODO(fbarchard): make ARM version of C code that matches NEON.
TESTATOB(AB30, 4, 4, 1, ABGR, 4, 4, 1, 0)
TESTATOB(AB30, 4, 4, 1, ARGB, 4, 4, 1, 0)
#ifdef INTEL_TEST
TESTATOB(ABGR, 4, 4, 1, AR30, 4, 4, 1, 0)
TESTATOB(AB30, 4, 4, 1, ABGR, 4, 4, 1)
TESTATOB(AB30, 4, 4, 1, ARGB, 4, 4, 1)
#ifdef LITTLE_ENDIAN_ONLY_TEST
TESTATOB(ABGR, 4, 4, 1, AR30, 4, 4, 1)
#endif
TESTATOB(ABGR, 4, 4, 1, ARGB, 4, 4, 1, 0)
#ifdef INTEL_TEST
TESTATOB(AR30, 4, 4, 1, AB30, 4, 4, 1, 0)
TESTATOB(ABGR, 4, 4, 1, ARGB, 4, 4, 1)
#ifdef LITTLE_ENDIAN_ONLY_TEST
TESTATOB(AR30, 4, 4, 1, AB30, 4, 4, 1)
#endif
TESTATOB(AR30, 4, 4, 1, ABGR, 4, 4, 1, 0)
#ifdef INTEL_TEST
TESTATOB(AR30, 4, 4, 1, AR30, 4, 4, 1, 0)
TESTATOB(AR30, 4, 4, 1, ARGB, 4, 4, 1, 0)
TESTATOB(AR30, 4, 4, 1, ABGR, 4, 4, 1)
#ifdef LITTLE_ENDIAN_ONLY_TEST
TESTATOB(AR30, 4, 4, 1, AR30, 4, 4, 1)
TESTATOB(AR30, 4, 4, 1, ARGB, 4, 4, 1)
#endif
TESTATOB(ARGB, 4, 4, 1, ABGR, 4, 4, 1, 0)
#ifdef INTEL_TEST
TESTATOB(ARGB, 4, 4, 1, AR30, 4, 4, 1, 0)
TESTATOB(ARGB, 4, 4, 1, ABGR, 4, 4, 1)
#ifdef LITTLE_ENDIAN_ONLY_TEST
TESTATOB(ARGB, 4, 4, 1, AR30, 4, 4, 1)
#endif
TESTATOB(ARGB, 4, 4, 1, ARGB, 4, 4, 1, 0)
TESTATOB(ARGB, 4, 4, 1, ARGB1555, 2, 2, 1, 0)
TESTATOB(ARGB, 4, 4, 1, ARGB4444, 2, 2, 1, 0)
TESTATOB(ARGB, 4, 4, 1, ARGBMirror, 4, 4, 1, 0)
TESTATOB(ARGB, 4, 4, 1, BGRA, 4, 4, 1, 0)
TESTATOB(ARGB, 4, 4, 1, I400, 1, 1, 1, 0)
TESTATOB(ARGB, 4, 4, 1, J400, 1, 1, 1, 0)
TESTATOB(RGBA, 4, 4, 1, J400, 1, 1, 1, 0)
TESTATOB(ARGB, 4, 4, 1, RAW, 3, 3, 1, 0)
TESTATOB(ARGB, 4, 4, 1, RGB24, 3, 3, 1, 0)
#ifdef INTEL_TEST
TESTATOB(ARGB, 4, 4, 1, RGB565, 2, 2, 1, 0)
TESTATOB(ARGB, 4, 4, 1, ARGB, 4, 4, 1)
TESTATOB(ARGB, 4, 4, 1, ARGB1555, 2, 2, 1)
TESTATOB(ARGB, 4, 4, 1, ARGB4444, 2, 2, 1)
TESTATOB(ARGB, 4, 4, 1, ARGBMirror, 4, 4, 1)
TESTATOB(ARGB, 4, 4, 1, BGRA, 4, 4, 1)
TESTATOB(ARGB, 4, 4, 1, I400, 1, 1, 1)
TESTATOB(ARGB, 4, 4, 1, J400, 1, 1, 1)
TESTATOB(RGBA, 4, 4, 1, J400, 1, 1, 1)
TESTATOB(ARGB, 4, 4, 1, RAW, 3, 3, 1)
TESTATOB(ARGB, 4, 4, 1, RGB24, 3, 3, 1)
#ifdef LITTLE_ENDIAN_ONLY_TEST
TESTATOB(ARGB, 4, 4, 1, RGB565, 2, 2, 1)
#endif
TESTATOB(ARGB, 4, 4, 1, RGBA, 4, 4, 1, 0)
TESTATOB(ARGB, 4, 4, 1, UYVY, 2, 4, 1, 4)
TESTATOB(ARGB, 4, 4, 1, YUY2, 2, 4, 1, 4)
TESTATOB(ARGB1555, 2, 2, 1, ARGB, 4, 4, 1, 0)
TESTATOB(ARGB4444, 2, 2, 1, ARGB, 4, 4, 1, 0)
TESTATOB(BGRA, 4, 4, 1, ARGB, 4, 4, 1, 0)
TESTATOB(I400, 1, 1, 1, ARGB, 4, 4, 1, 0)
TESTATOB(I400, 1, 1, 1, I400, 1, 1, 1, 0)
TESTATOB(I400, 1, 1, 1, I400Mirror, 1, 1, 1, 0)
TESTATOB(J400, 1, 1, 1, ARGB, 4, 4, 1, 0)
TESTATOB(J400, 1, 1, 1, J400, 1, 1, 1, 0)
TESTATOB(RAW, 3, 3, 1, ARGB, 4, 4, 1, 0)
TESTATOB(RAW, 3, 3, 1, RGBA, 4, 4, 1, 0)
TESTATOB(RAW, 3, 3, 1, RGB24, 3, 3, 1, 0)
TESTATOB(RGB24, 3, 3, 1, ARGB, 4, 4, 1, 0)
TESTATOB(RGB24, 3, 3, 1, J400, 1, 1, 1, 0)
TESTATOB(RGB24, 3, 3, 1, RGB24Mirror, 3, 3, 1, 0)
TESTATOB(RAW, 3, 3, 1, J400, 1, 1, 1, 0)
#ifdef INTEL_TEST
TESTATOB(RGB565, 2, 2, 1, ARGB, 4, 4, 1, 0)
TESTATOB(ARGB, 4, 4, 1, RGBA, 4, 4, 1)
TESTATOB(ARGB, 4, 4, 1, UYVY, 2, 4, 1)
TESTATOB(ARGB, 4, 4, 1, YUY2, 2, 4, 1) // 4
TESTATOB(ARGB1555, 2, 2, 1, ARGB, 4, 4, 1)
TESTATOB(ARGB4444, 2, 2, 1, ARGB, 4, 4, 1)
TESTATOB(BGRA, 4, 4, 1, ARGB, 4, 4, 1)
TESTATOB(I400, 1, 1, 1, ARGB, 4, 4, 1)
TESTATOB(I400, 1, 1, 1, I400, 1, 1, 1)
TESTATOB(I400, 1, 1, 1, I400Mirror, 1, 1, 1)
TESTATOB(J400, 1, 1, 1, ARGB, 4, 4, 1)
TESTATOB(J400, 1, 1, 1, J400, 1, 1, 1)
TESTATOB(RAW, 3, 3, 1, ARGB, 4, 4, 1)
TESTATOB(RAW, 3, 3, 1, RGBA, 4, 4, 1)
TESTATOB(RAW, 3, 3, 1, RGB24, 3, 3, 1)
TESTATOB(RGB24, 3, 3, 1, ARGB, 4, 4, 1)
TESTATOB(RGB24, 3, 3, 1, J400, 1, 1, 1)
TESTATOB(RGB24, 3, 3, 1, RGB24Mirror, 3, 3, 1)
TESTATOB(RAW, 3, 3, 1, J400, 1, 1, 1)
#ifdef LITTLE_ENDIAN_ONLY_TEST
TESTATOB(RGB565, 2, 2, 1, ARGB, 4, 4, 1)
#endif
TESTATOB(RGBA, 4, 4, 1, ARGB, 4, 4, 1, 0)
TESTATOB(UYVY, 2, 4, 1, ARGB, 4, 4, 1, ARM_YUV_ERROR)
TESTATOB(YUY2, 2, 4, 1, ARGB, 4, 4, 1, ARM_YUV_ERROR)
TESTATOB(YUY2, 2, 4, 1, Y, 1, 1, 1, 0)
TESTATOB(RGBA, 4, 4, 1, ARGB, 4, 4, 1)
TESTATOB(UYVY, 2, 4, 1, ARGB, 4, 4, 1)
TESTATOB(YUY2, 2, 4, 1, ARGB, 4, 4, 1)
TESTATOB(YUY2, 2, 4, 1, Y, 1, 1, 1)
#define TESTATOBDI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, FMT_B, BPP_B, STRIDE_B, \
HEIGHT_B, W1280, DIFF, N, NEG, OFF) \
HEIGHT_B, W1280, N, NEG, OFF) \
TEST_F(LibYUVConvertTest, FMT_A##To##FMT_B##Dither##N) { \
const int kWidth = ((W1280) > 0) ? (W1280) : 1; \
const int kHeight = benchmark_height_; \
@ -1283,22 +1117,16 @@ TESTATOB(YUY2, 2, 4, 1, Y, 1, 1, 1, 0)
FMT_A##To##FMT_B##Dither(src_argb + OFF, kStrideA, dst_argb_opt, \
kStrideB, NULL, kWidth, NEG kHeight); \
} \
int max_diff = 0; \
for (int i = 0; i < kStrideB * kHeightB; ++i) { \
int abs_diff = abs(static_cast<int>(dst_argb_c[i]) - \
static_cast<int>(dst_argb_opt[i])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
EXPECT_EQ(dst_argb_c[i], dst_argb_opt[i]); \
} \
EXPECT_LE(max_diff, DIFF); \
free_aligned_buffer_page_end(src_argb); \
free_aligned_buffer_page_end(dst_argb_c); \
free_aligned_buffer_page_end(dst_argb_opt); \
}
#define TESTATOBDRANDOM(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, FMT_B, BPP_B, \
STRIDE_B, HEIGHT_B, DIFF) \
STRIDE_B, HEIGHT_B) \
TEST_F(LibYUVConvertTest, FMT_A##To##FMT_B##Dither_Random) { \
for (int times = 0; times < benchmark_iterations_; ++times) { \
const int kWidth = (fastrand() & 63) + 1; \
@ -1323,15 +1151,9 @@ TESTATOB(YUY2, 2, 4, 1, Y, 1, 1, 1, 0)
MaskCpuFlags(benchmark_cpu_info_); \
FMT_A##To##FMT_B##Dither(src_argb, kStrideA, dst_argb_opt, kStrideB, \
NULL, kWidth, kHeight); \
int max_diff = 0; \
for (int i = 0; i < kStrideB * kHeightB; ++i) { \
int abs_diff = abs(static_cast<int>(dst_argb_c[i]) - \
static_cast<int>(dst_argb_opt[i])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
EXPECT_EQ(dst_argb_c[i], dst_argb_opt[i]); \
} \
EXPECT_LE(max_diff, DIFF); \
free_aligned_buffer_page_end(src_argb); \
free_aligned_buffer_page_end(dst_argb_c); \
free_aligned_buffer_page_end(dst_argb_opt); \
@ -1339,20 +1161,20 @@ TESTATOB(YUY2, 2, 4, 1, Y, 1, 1, 1, 0)
}
#define TESTATOBD(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, FMT_B, BPP_B, STRIDE_B, \
HEIGHT_B, DIFF) \
HEIGHT_B) \
TESTATOBDI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, FMT_B, BPP_B, STRIDE_B, \
HEIGHT_B, benchmark_width_ - 4, DIFF, _Any, +, 0) \
HEIGHT_B, benchmark_width_ - 4, _Any, +, 0) \
TESTATOBDI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, FMT_B, BPP_B, STRIDE_B, \
HEIGHT_B, benchmark_width_, DIFF, _Unaligned, +, 1) \
HEIGHT_B, benchmark_width_, _Unaligned, +, 1) \
TESTATOBDI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, FMT_B, BPP_B, STRIDE_B, \
HEIGHT_B, benchmark_width_, DIFF, _Invert, -, 0) \
HEIGHT_B, benchmark_width_, _Invert, -, 0) \
TESTATOBDI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, FMT_B, BPP_B, STRIDE_B, \
HEIGHT_B, benchmark_width_, DIFF, _Opt, +, 0) \
HEIGHT_B, benchmark_width_, _Opt, +, 0) \
TESTATOBDRANDOM(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, FMT_B, BPP_B, STRIDE_B, \
HEIGHT_B, DIFF)
HEIGHT_B)
#ifdef INTEL_TEST
TESTATOBD(ARGB, 4, 4, 1, RGB565, 2, 2, 1, 0)
#ifdef LITTLE_ENDIAN_ONLY_TEST
TESTATOBD(ARGB, 4, 4, 1, RGB565, 2, 2, 1)
#endif
#define TESTSYMI(FMT_ATOB, BPP_A, STRIDE_A, HEIGHT_A, W1280, N, NEG, OFF) \
@ -2450,7 +2272,7 @@ TEST_F(LibYUVConvertTest, TestDither) {
TESTPLANARTOBID(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
YALIGN, benchmark_width_, DIFF, _Opt, +, 0, FMT_C, BPP_C)
#ifdef INTEL_TEST
#ifdef LITTLE_ENDIAN_ONLY_TEST
TESTPLANARTOBD(I420, 2, 2, RGB565, 2, 2, 1, 9, ARGB, 4)
#endif
#define TESTPTOB(NAME, UYVYTOI420, UYVYTONV12) \
@ -2594,7 +2416,7 @@ TESTPLANARTOE(H420, 2, 2, RAW, 1, 3, RGB24, 3)
TESTPLANARTOE(H420, 2, 2, RGB24, 1, 3, RAW, 3)
TESTPLANARTOE(H420, 2, 2, ARGB, 1, 4, RAW, 3)
TESTPLANARTOE(H420, 2, 2, RAW, 1, 3, ARGB, 4)
#ifdef INTEL_TEST
#ifdef LITTLE_ENDIAN_ONLY_TEST
TESTPLANARTOE(I420, 2, 2, ARGB, 1, 4, RGB565, 2)
TESTPLANARTOE(I420, 2, 2, ARGB, 1, 4, ARGB1555, 2)
TESTPLANARTOE(I420, 2, 2, ARGB, 1, 4, ARGB4444, 2)
@ -2741,7 +2563,7 @@ TESTQPLANARTOE(I420Alpha, 2, 2, ABGR, 1, 4, ARGB, 4)
_Opt, +, 0, FMT_C, BPP_C)
// Caveat: Destination needs to be 4 bytes
#ifdef INTEL_TEST
#ifdef LITTLE_ENDIAN_ONLY_TEST
TESTPLANETOE(ARGB, 1, 4, AR30, 1, 4, ARGB, 4)
TESTPLANETOE(ABGR, 1, 4, AR30, 1, 4, ABGR, 4)
TESTPLANETOE(AR30, 1, 4, ARGB, 1, 4, ABGR, 4)
@ -2857,7 +2679,7 @@ TEST_F(LibYUVConvertTest, ABGRToAR30Row_Opt) {
// TODO(fbarchard): Fix clamping issue affected by U channel.
#define TESTPLANAR16TOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \
ALIGN, YALIGN, W1280, DIFF, N, NEG, SOFF, DOFF) \
ALIGN, YALIGN, W1280, N, NEG, SOFF, DOFF) \
TEST_F(LibYUVConvertTest, FMT_PLANAR##To##FMT_B##N) { \
const int kWidth = ((W1280) > 0) ? (W1280) : 1; \
const int kHeight = ALIGNINT(benchmark_height_, YALIGN); \
@ -2893,15 +2715,9 @@ TEST_F(LibYUVConvertTest, ABGRToAR30Row_Opt) {
reinterpret_cast<uint16_t*>(src_v + SOFF), kStrideUV, \
dst_argb_opt + DOFF, kStrideB, kWidth, NEG kHeight); \
} \
int max_diff = 0; \
for (int i = 0; i < kWidth * BPP_B * kHeight; ++i) { \
int abs_diff = abs(static_cast<int>(dst_argb_c[i + DOFF]) - \
static_cast<int>(dst_argb_opt[i + DOFF])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
EXPECT_EQ(dst_argb_c[i + DOFF], dst_argb_opt[i + DOFF]); \
} \
EXPECT_LE(max_diff, DIFF); \
free_aligned_buffer_page_end(src_y); \
free_aligned_buffer_page_end(src_u); \
free_aligned_buffer_page_end(src_v); \
@ -2910,41 +2726,41 @@ TEST_F(LibYUVConvertTest, ABGRToAR30Row_Opt) {
}
#define TESTPLANAR16TOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
YALIGN, DIFF) \
YALIGN) \
TESTPLANAR16TOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
YALIGN, benchmark_width_ - 4, DIFF, _Any, +, 0, 0) \
YALIGN, benchmark_width_ - 4, _Any, +, 0, 0) \
TESTPLANAR16TOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
YALIGN, benchmark_width_, DIFF, _Unaligned, +, 1, 1) \
YALIGN, benchmark_width_, _Unaligned, +, 1, 1) \
TESTPLANAR16TOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
YALIGN, benchmark_width_, DIFF, _Invert, -, 0, 0) \
YALIGN, benchmark_width_, _Invert, -, 0, 0) \
TESTPLANAR16TOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
YALIGN, benchmark_width_, DIFF, _Opt, +, 0, 0)
YALIGN, benchmark_width_, _Opt, +, 0, 0)
TESTPLANAR16TOB(I010, 2, 2, ARGB, 4, 4, 1, 2)
TESTPLANAR16TOB(I010, 2, 2, ABGR, 4, 4, 1, 2)
TESTPLANAR16TOB(H010, 2, 2, ARGB, 4, 4, 1, 2)
TESTPLANAR16TOB(H010, 2, 2, ABGR, 4, 4, 1, 2)
TESTPLANAR16TOB(U010, 2, 2, ARGB, 4, 4, 1, 2)
TESTPLANAR16TOB(U010, 2, 2, ABGR, 4, 4, 1, 2)
TESTPLANAR16TOB(I210, 2, 1, ARGB, 4, 4, 1, 2)
TESTPLANAR16TOB(I210, 2, 1, ABGR, 4, 4, 1, 2)
TESTPLANAR16TOB(H210, 2, 1, ARGB, 4, 4, 1, 2)
TESTPLANAR16TOB(H210, 2, 1, ABGR, 4, 4, 1, 2)
TESTPLANAR16TOB(U210, 2, 1, ARGB, 4, 4, 1, 2)
TESTPLANAR16TOB(U210, 2, 1, ABGR, 4, 4, 1, 2)
#ifdef INTEL_TEST
TESTPLANAR16TOB(I010, 2, 2, AR30, 4, 4, 1, 2)
TESTPLANAR16TOB(I010, 2, 2, AB30, 4, 4, 1, 2)
TESTPLANAR16TOB(H010, 2, 2, AR30, 4, 4, 1, 2)
TESTPLANAR16TOB(H010, 2, 2, AB30, 4, 4, 1, 2)
TESTPLANAR16TOB(U010, 2, 2, AR30, 4, 4, 1, 2)
TESTPLANAR16TOB(U010, 2, 2, AB30, 4, 4, 1, 2)
TESTPLANAR16TOB(I210, 2, 1, AR30, 4, 4, 1, 2)
TESTPLANAR16TOB(I210, 2, 1, AB30, 4, 4, 1, 2)
TESTPLANAR16TOB(H210, 2, 1, AR30, 4, 4, 1, 2)
TESTPLANAR16TOB(H210, 2, 1, AB30, 4, 4, 1, 2)
TESTPLANAR16TOB(U210, 2, 1, AR30, 4, 4, 1, 2)
TESTPLANAR16TOB(U210, 2, 1, AB30, 4, 4, 1, 2)
TESTPLANAR16TOB(I010, 2, 2, ARGB, 4, 4, 1)
TESTPLANAR16TOB(I010, 2, 2, ABGR, 4, 4, 1)
TESTPLANAR16TOB(H010, 2, 2, ARGB, 4, 4, 1)
TESTPLANAR16TOB(H010, 2, 2, ABGR, 4, 4, 1)
TESTPLANAR16TOB(U010, 2, 2, ARGB, 4, 4, 1)
TESTPLANAR16TOB(U010, 2, 2, ABGR, 4, 4, 1)
TESTPLANAR16TOB(I210, 2, 1, ARGB, 4, 4, 1)
TESTPLANAR16TOB(I210, 2, 1, ABGR, 4, 4, 1)
TESTPLANAR16TOB(H210, 2, 1, ARGB, 4, 4, 1)
TESTPLANAR16TOB(H210, 2, 1, ABGR, 4, 4, 1)
TESTPLANAR16TOB(U210, 2, 1, ARGB, 4, 4, 1)
TESTPLANAR16TOB(U210, 2, 1, ABGR, 4, 4, 1)
#ifdef LITTLE_ENDIAN_ONLY_TEST
TESTPLANAR16TOB(I010, 2, 2, AR30, 4, 4, 1)
TESTPLANAR16TOB(I010, 2, 2, AB30, 4, 4, 1)
TESTPLANAR16TOB(H010, 2, 2, AR30, 4, 4, 1)
TESTPLANAR16TOB(H010, 2, 2, AB30, 4, 4, 1)
TESTPLANAR16TOB(U010, 2, 2, AR30, 4, 4, 1)
TESTPLANAR16TOB(U010, 2, 2, AB30, 4, 4, 1)
TESTPLANAR16TOB(I210, 2, 1, AR30, 4, 4, 1)
TESTPLANAR16TOB(I210, 2, 1, AB30, 4, 4, 1)
TESTPLANAR16TOB(H210, 2, 1, AR30, 4, 4, 1)
TESTPLANAR16TOB(H210, 2, 1, AB30, 4, 4, 1)
TESTPLANAR16TOB(U210, 2, 1, AR30, 4, 4, 1)
TESTPLANAR16TOB(U210, 2, 1, AB30, 4, 4, 1)
#endif
static int Clamp(int y) {