diff --git a/source/planar_functions.cc b/source/planar_functions.cc index 3489c9711..ab911e172 100644 --- a/source/planar_functions.cc +++ b/source/planar_functions.cc @@ -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. diff --git a/source/row_common.cc b/source/row_common.cc index c2f418925..7b72e91f5 100644 --- a/source/row_common.cc +++ b/source/row_common.cc @@ -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) { diff --git a/unit_test/convert_test.cc b/unit_test/convert_test.cc index 5c95d9312..5b7474e9f 100644 --- a/unit_test/convert_test.cc +++ b/unit_test/convert_test.cc @@ -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(dst_y_c[i * kWidth + j]) - \ - static_cast(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(dst_u_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \ - static_cast( \ - 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(dst_v_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \ - static_cast( \ - 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(dst_y_c[i * kWidth + j]) - \ - static_cast(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( \ - dst_uv_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) * 2 + j]) - \ - static_cast( \ - 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(dst_y_c[i * kWidth + j]) - \ - static_cast(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( \ - dst_uv_c[i * 2 * SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \ - static_cast( \ - 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(dst_y_c[i * kWidth + j]) - \ - static_cast(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(dst_u_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \ - static_cast( \ - 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(dst_v_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \ - static_cast( \ - 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(dst_argb_c[i + OFF]) - \ - static_cast(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(dst_argb32_c[i * kWidth * 4 + j]) - \ - static_cast(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(dst_y_c[i * kWidth + j]), \ - static_cast(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(dst_u_c[i * kStrideUV + j]), \ - static_cast(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(dst_v_c[i * kStrideUV + j]), \ - static_cast(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(dst_y_c[i * kWidth + j]), \ - static_cast(dst_y_opt[i * kWidth + j]), DIFF); \ + EXPECT_EQ(static_cast(dst_y_c[i * kWidth + j]), \ + static_cast(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(dst_y_c[i * kWidth + j]) - \ - static_cast(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(dst_uv_c[i * kStrideUV * 2 + j]) - \ - static_cast(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(dst_argb_c[i]) - \ - static_cast(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(dst_argb_c[i]) - \ - static_cast(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(dst_argb_c[i]) - \ - static_cast(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(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(dst_argb_c[i + DOFF]) - \ - static_cast(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) {