diff --git a/include/libyuv/convert_from_argb.h b/include/libyuv/convert_from_argb.h index 0928bb53f..a394f8229 100644 --- a/include/libyuv/convert_from_argb.h +++ b/include/libyuv/convert_from_argb.h @@ -196,7 +196,7 @@ int ARGBToI444(const uint8_t* src_argb, int width, int height); -// RGB to I444 with matrix. See ArgbConstants at the top of this file for usage. +// ARGB to I444 with matrix. See ArgbConstants at the top of this file for usage. LIBYUV_API int ARGBToI444Matrix(const uint8_t* src_argb, int src_stride_argb, @@ -260,7 +260,7 @@ int ABGRToI422(const uint8_t* src_abgr, int width, int height); -// RGB to I444 with matrix. See ArgbConstants at the top of this file for usage. +// ARGB to I422 with matrix. See ArgbConstants at the top of this file for usage. LIBYUV_API int ARGBToI422Matrix(const uint8_t* src_argb, int src_stride_argb, @@ -408,7 +408,7 @@ int ARGBToNV12(const uint8_t* src_argb, int width, int height); -// RGB to NV12 with matrix. See ArgbConstants at the top of this file for usage. +// ARGB to NV12 with matrix. See ArgbConstants at the top of this file for usage. LIBYUV_API int ARGBToNV12Matrix(const uint8_t* src_argb, int src_stride_argb, @@ -420,7 +420,53 @@ int ARGBToNV12Matrix(const uint8_t* src_argb, int width, int height); -// RGB to NV21 with matrix. See ArgbConstants at the top of this file for usage. +// Convert ARGB To NV16. +LIBYUV_API +int ARGBToNV16(const uint8_t* src_argb, + int src_stride_argb, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + int width, + int height); + +// ARGB to NV16 with matrix. See ArgbConstants at the top of this file for usage. +LIBYUV_API +int ARGBToNV16Matrix(const uint8_t* src_argb, + int src_stride_argb, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + const struct ArgbConstants* argbconstants, + int width, + int height); + +// Convert ARGB To NV24. +LIBYUV_API +int ARGBToNV24(const uint8_t* src_argb, + int src_stride_argb, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + int width, + int height); + +// ARGB to NV24 with matrix. See ArgbConstants at the top of this file for usage. +LIBYUV_API +int ARGBToNV24Matrix(const uint8_t* src_argb, + int src_stride_argb, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + const struct ArgbConstants* argbconstants, + int width, + int height); + +// ARGB to NV21 with matrix. See ArgbConstants at the top of this file for usage. LIBYUV_API int ARGBToNV21Matrix(const uint8_t* src_argb, int src_stride_argb, diff --git a/source/convert_from_argb.cc b/source/convert_from_argb.cc index c8834a16a..f87c5c054 100644 --- a/source/convert_from_argb.cc +++ b/source/convert_from_argb.cc @@ -638,6 +638,498 @@ int ARGBToNV12Matrix(const uint8_t* src_argb, return 0; } +LIBYUV_API +int ARGBToNV16(const uint8_t* src_argb, + int src_stride_argb, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + int width, + int height) { + return ARGBToNV16Matrix(src_argb, src_stride_argb, dst_y, dst_stride_y, + dst_uv, dst_stride_uv, &kArgbI601Constants, width, + height); +} + +LIBYUV_API +int ARGBToNV16Matrix(const uint8_t* src_argb, + int src_stride_argb, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + const struct ArgbConstants* argbconstants, + int width, + int height) { + int y; + int halfwidth = (width >> 1) + (width & 1); + void (*ARGBToYMatrixRow)(const uint8_t* src_argb, uint8_t* dst_y, int width, + const struct ArgbConstants* c) = ARGBToYMatrixRow_C; + void (*ARGBToUVMatrixRow)(const uint8_t* src_argb, int src_stride_argb, + uint8_t* dst_u, uint8_t* dst_v, int width, + const struct ArgbConstants* c) = + ARGBToUVMatrixRow_C; + +#if defined(HAS_ARGBTOYMATRIXROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_Any_SSSE3; + if (IS_ALIGNED(width, 16)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_SSSE3; + } + } +#endif +#if defined(HAS_ARGBTOYMATRIXROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_Any_AVX2; + if (IS_ALIGNED(width, 32)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_AVX2; + } + } +#endif +#if defined(HAS_ARGBTOYMATRIXROW_AVX512BW) + if (TestCpuFlag(kCpuHasAVX512BW)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_Any_AVX512BW; + if (IS_ALIGNED(width, 64)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_AVX512BW; + } + } +#endif +#if defined(HAS_ARGBTOYMATRIXROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_Any_NEON; + if (IS_ALIGNED(width, 16)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_NEON; + } + } +#endif +#if defined(HAS_ARGBTOYMATRIXROW_NEON_DOTPROD) + if (TestCpuFlag(kCpuHasNeonDotProd)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_Any_NEON_DotProd; + if (IS_ALIGNED(width, 16)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_NEON_DotProd; + } + } +#endif +#if defined(HAS_ARGBTOYMATRIXROW_SVE2) + if (TestCpuFlag(kCpuHasSVE2)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_SVE2; + } +#endif +#if defined(HAS_ARGBTOYMATRIXROW_SME) + if (TestCpuFlag(kCpuHasSME)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_SME; + } +#endif +#if defined(HAS_ARGBTOYMATRIXROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_Any_LSX; + if (IS_ALIGNED(width, 16)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_LSX; + } + } +#endif +#if defined(HAS_ARGBTOYMATRIXROW_LASX) + if (TestCpuFlag(kCpuHasLASX)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_Any_LASX; + if (IS_ALIGNED(width, 32)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_LASX; + } + } +#endif +#if defined(HAS_ARGBTOYMATRIXROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_RVV; + } +#endif + +#if defined(HAS_ARGBTOUVMATRIXROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_NEON; + if (IS_ALIGNED(width, 16)) { + ARGBToUVMatrixRow = ARGBToUVMatrixRow_NEON; + } + } +#endif +#if defined(HAS_ARGBTOUVMATRIXROW_NEON_I8MM) + if (TestCpuFlag(kCpuHasNEON) && TestCpuFlag(kCpuHasNeonI8MM)) { + ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_NEON_I8MM; + if (IS_ALIGNED(width, 16)) { + ARGBToUVMatrixRow = ARGBToUVMatrixRow_NEON_I8MM; + } + } +#endif +#if defined(HAS_ARGBTOUVMATRIXROW_SVE2) + if (TestCpuFlag(kCpuHasSVE2)) { + if (IS_ALIGNED(width, 2)) { + ARGBToUVMatrixRow = ARGBToUVMatrixRow_SVE2; + } + } +#endif +#if defined(HAS_ARGBTOUVMATRIXROW_SME) + if (TestCpuFlag(kCpuHasSME)) { + if (IS_ALIGNED(width, 2)) { + ARGBToUVMatrixRow = ARGBToUVMatrixRow_SME; + } + } +#endif +#if defined(HAS_ARGBTOUVMATRIXROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_SSSE3; + if (IS_ALIGNED(width, 8)) { + ARGBToUVMatrixRow = ARGBToUVMatrixRow_SSSE3; + } + } +#endif +#if defined(HAS_ARGBTOUVMATRIXROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_AVX2; + if (IS_ALIGNED(width, 32)) { + ARGBToUVMatrixRow = ARGBToUVMatrixRow_AVX2; + } + } +#endif +#if defined(HAS_ARGBTOUVMATRIXROW_AVX512BW) + if (TestCpuFlag(kCpuHasAVX512BW)) { + ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_AVX512BW; + if (IS_ALIGNED(width, 64)) { + ARGBToUVMatrixRow = ARGBToUVMatrixRow_AVX512BW; + } + } +#endif +#if defined(HAS_ARGBTOUVMATRIXROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBToUVMatrixRow = ARGBToUVMatrixRow_RVV; + } +#endif + void (*MergeUVRow)(const uint8_t* src_u, const uint8_t* src_v, + uint8_t* dst_uv, int width) = MergeUVRow_C; + if (!src_argb || !dst_y || !dst_uv || !argbconstants || width <= 0 || + height == 0 || height == INT_MIN) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + src_argb = src_argb + (ptrdiff_t)(height - 1) * src_stride_argb; + src_stride_argb = -src_stride_argb; + } +#if defined(HAS_MERGEUVROW_SSE2) + if (TestCpuFlag(kCpuHasSSE2)) { + MergeUVRow = MergeUVRow_Any_SSE2; + if (IS_ALIGNED(halfwidth, 16)) { + MergeUVRow = MergeUVRow_SSE2; + } + } +#endif +#if defined(HAS_MERGEUVROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + MergeUVRow = MergeUVRow_Any_AVX2; + if (IS_ALIGNED(halfwidth, 32)) { + MergeUVRow = MergeUVRow_AVX2; + } + } +#endif +#if defined(HAS_MERGEUVROW_AVX512BW) + if (TestCpuFlag(kCpuHasAVX512BW)) { + MergeUVRow = MergeUVRow_Any_AVX512BW; + if (IS_ALIGNED(halfwidth, 32)) { + MergeUVRow = MergeUVRow_AVX512BW; + } + } +#endif +#if defined(HAS_MERGEUVROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + MergeUVRow = MergeUVRow_Any_NEON; + if (IS_ALIGNED(halfwidth, 16)) { + MergeUVRow = MergeUVRow_NEON; + } + } +#endif +#if defined(HAS_MERGEUVROW_SVE2) + if (TestCpuFlag(kCpuHasSVE2)) { + MergeUVRow = MergeUVRow_SVE2; + } +#endif +#if defined(HAS_MERGEUVROW_SME) + if (TestCpuFlag(kCpuHasSME)) { + MergeUVRow = MergeUVRow_SME; + } +#endif +#if defined(HAS_MERGEUVROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + MergeUVRow = MergeUVRow_Any_LSX; + if (IS_ALIGNED(halfwidth, 16)) { + MergeUVRow = MergeUVRow_LSX; + } + } +#endif +#if defined(HAS_MERGEUVROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + MergeUVRow = MergeUVRow_RVV; + } +#endif + + size_t row_size = (static_cast(halfwidth) + 31) & + ~static_cast(31); + if (row_size > SIZE_MAX / 2) { + return -1; + } + align_buffer_64(row_u, row_size * 2); + if (!row_u) + return 1; + uint8_t* row_v = row_u + row_size; + + for (y = 0; y < height; ++y) { + ARGBToUVMatrixRow(src_argb, 0, row_u, row_v, width, argbconstants); + ARGBToYMatrixRow(src_argb, dst_y, width, argbconstants); + MergeUVRow(row_u, row_v, dst_uv, halfwidth); + src_argb += src_stride_argb; + dst_y += dst_stride_y; + dst_uv += dst_stride_uv; + } + free_aligned_buffer_64(row_u); + return 0; +} + +LIBYUV_API +int ARGBToNV24(const uint8_t* src_argb, + int src_stride_argb, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + int width, + int height) { + return ARGBToNV24Matrix(src_argb, src_stride_argb, dst_y, dst_stride_y, + dst_uv, dst_stride_uv, &kArgbI601Constants, width, + height); +} + +LIBYUV_API +int ARGBToNV24Matrix(const uint8_t* src_argb, + int src_stride_argb, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + const struct ArgbConstants* argbconstants, + int width, + int height) { + int y; + void (*ARGBToYMatrixRow)(const uint8_t* src_argb, uint8_t* dst_y, int width, + const struct ArgbConstants* c) = ARGBToYMatrixRow_C; + void (*ARGBToUV444MatrixRow)( + const uint8_t* src_argb, uint8_t* dst_u, uint8_t* dst_v, int width, + const struct ArgbConstants* c) = ARGBToUV444MatrixRow_C; + +#if defined(HAS_ARGBTOYMATRIXROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_Any_SSSE3; + if (IS_ALIGNED(width, 16)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_SSSE3; + } + } +#endif +#if defined(HAS_ARGBTOYMATRIXROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_Any_AVX2; + if (IS_ALIGNED(width, 32)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_AVX2; + } + } +#endif +#if defined(HAS_ARGBTOYMATRIXROW_AVX512BW) + if (TestCpuFlag(kCpuHasAVX512BW)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_Any_AVX512BW; + if (IS_ALIGNED(width, 64)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_AVX512BW; + } + } +#endif +#if defined(HAS_ARGBTOYMATRIXROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_Any_NEON; + if (IS_ALIGNED(width, 16)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_NEON; + } + } +#endif +#if defined(HAS_ARGBTOYMATRIXROW_NEON_DOTPROD) + if (TestCpuFlag(kCpuHasNeonDotProd)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_Any_NEON_DotProd; + if (IS_ALIGNED(width, 16)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_NEON_DotProd; + } + } +#endif +#if defined(HAS_ARGBTOYMATRIXROW_SVE2) + if (TestCpuFlag(kCpuHasSVE2)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_SVE2; + } +#endif +#if defined(HAS_ARGBTOYMATRIXROW_SME) + if (TestCpuFlag(kCpuHasSME)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_SME; + } +#endif +#if defined(HAS_ARGBTOYMATRIXROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_Any_LSX; + if (IS_ALIGNED(width, 16)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_LSX; + } + } +#endif +#if defined(HAS_ARGBTOYMATRIXROW_LASX) + if (TestCpuFlag(kCpuHasLASX)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_Any_LASX; + if (IS_ALIGNED(width, 32)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_LASX; + } + } +#endif +#if defined(HAS_ARGBTOYMATRIXROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBToYMatrixRow = ARGBToYMatrixRow_RVV; + } +#endif + +#if defined(HAS_ARGBTOUV444MATRIXROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_Any_SSSE3; + if (IS_ALIGNED(width, 16)) { + ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_SSSE3; + } + } +#endif +#if defined(HAS_ARGBTOUV444MATRIXROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_Any_AVX2; + if (IS_ALIGNED(width, 32)) { + ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_AVX2; + } + } +#endif +#if defined(HAS_ARGBTOUV444MATRIXROW_AVX512BW) + if (TestCpuFlag(kCpuHasAVX512BW)) { + ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_Any_AVX512BW; + if (IS_ALIGNED(width, 64)) { + ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_AVX512BW; + } + } +#endif +#if defined(HAS_ARGBTOUV444MATRIXROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_Any_NEON; + if (IS_ALIGNED(width, 8)) { + ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_NEON; + } + } +#endif +#if defined(HAS_ARGBTOUV444MATRIXROW_NEON_I8MM) + if (TestCpuFlag(kCpuHasNeonI8MM)) { + ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_Any_NEON_I8MM; + if (IS_ALIGNED(width, 8)) { + ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_NEON_I8MM; + } + } +#endif +#if defined(HAS_ARGBTOUV444MATRIXROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_RVV; + } +#endif + void (*MergeUVRow)(const uint8_t* src_u, const uint8_t* src_v, + uint8_t* dst_uv, int width) = MergeUVRow_C; + if (!src_argb || !dst_y || !dst_uv || !argbconstants || width <= 0 || + height == 0 || height == INT_MIN) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + src_argb = src_argb + (ptrdiff_t)(height - 1) * src_stride_argb; + src_stride_argb = -src_stride_argb; + } +#if defined(HAS_MERGEUVROW_SSE2) + if (TestCpuFlag(kCpuHasSSE2)) { + MergeUVRow = MergeUVRow_Any_SSE2; + if (IS_ALIGNED(width, 16)) { + MergeUVRow = MergeUVRow_SSE2; + } + } +#endif +#if defined(HAS_MERGEUVROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + MergeUVRow = MergeUVRow_Any_AVX2; + if (IS_ALIGNED(width, 32)) { + MergeUVRow = MergeUVRow_AVX2; + } + } +#endif +#if defined(HAS_MERGEUVROW_AVX512BW) + if (TestCpuFlag(kCpuHasAVX512BW)) { + MergeUVRow = MergeUVRow_Any_AVX512BW; + if (IS_ALIGNED(width, 32)) { + MergeUVRow = MergeUVRow_AVX512BW; + } + } +#endif +#if defined(HAS_MERGEUVROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + MergeUVRow = MergeUVRow_Any_NEON; + if (IS_ALIGNED(width, 16)) { + MergeUVRow = MergeUVRow_NEON; + } + } +#endif +#if defined(HAS_MERGEUVROW_SVE2) + if (TestCpuFlag(kCpuHasSVE2)) { + MergeUVRow = MergeUVRow_SVE2; + } +#endif +#if defined(HAS_MERGEUVROW_SME) + if (TestCpuFlag(kCpuHasSME)) { + MergeUVRow = MergeUVRow_SME; + } +#endif +#if defined(HAS_MERGEUVROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + MergeUVRow = MergeUVRow_Any_LSX; + if (IS_ALIGNED(width, 16)) { + MergeUVRow = MergeUVRow_LSX; + } + } +#endif +#if defined(HAS_MERGEUVROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + MergeUVRow = MergeUVRow_RVV; + } +#endif + + size_t row_size = (static_cast(width) + 31) & + ~static_cast(31); + if (row_size > SIZE_MAX / 2) { + return -1; + } + align_buffer_64(row_u, row_size * 2); + if (!row_u) + return 1; + uint8_t* row_v = row_u + row_size; + + for (y = 0; y < height; ++y) { + ARGBToUV444MatrixRow(src_argb, row_u, row_v, width, argbconstants); + ARGBToYMatrixRow(src_argb, dst_y, width, argbconstants); + MergeUVRow(row_u, row_v, dst_uv, width); + src_argb += src_stride_argb; + dst_y += dst_stride_y; + dst_uv += dst_stride_uv; + } + free_aligned_buffer_64(row_u); + return 0; +} + LIBYUV_API int ARGBToNV21Matrix(const uint8_t* src_argb, int src_stride_argb, diff --git a/unit_test/convert_test.cc b/unit_test/convert_test.cc index 211b13d5d..fa7314cd7 100644 --- a/unit_test/convert_test.cc +++ b/unit_test/convert_test.cc @@ -834,6 +834,8 @@ TESTATOPLANARA(ARGB, 4, 1, I420Alpha, 2, 2) TESTATOBP(ARGB, 1, 4, NV12, 2, 2) TESTATOBP(ARGB, 1, 4, NV21, 2, 2) +TESTATOBP(ARGB, 1, 4, NV16, 2, 1) +TESTATOBP(ARGB, 1, 4, NV24, 1, 1) TESTATOBP(ABGR, 1, 4, NV12, 2, 2) TESTATOBP(ABGR, 1, 4, NV21, 2, 2) TESTATOBP(YUY2, 2, 4, NV12, 2, 2) @@ -841,6 +843,44 @@ TESTATOBP(UYVY, 2, 4, NV12, 2, 2) TESTATOBP(AYUV, 1, 4, NV12, 2, 2) TESTATOBP(AYUV, 1, 4, NV21, 2, 2) +// Matrix API with I601 constants matches the non-matrix wrapper. +#define TESTATOBPMATRIX(FMT_A, BPP_A, FMT_B, SUBSAMP_X, SUBSAMP_Y) \ + TEST_F(LibYUVConvertTest, Test##FMT_A##To##FMT_B##Matrix) { \ + const int kWidth = 16; \ + const int kHeight = 16; \ + const int kStrideUV = SUBSAMPLE(kWidth, SUBSAMP_X); \ + const int kHeightUV = SUBSAMPLE(kHeight, SUBSAMP_Y); \ + align_buffer_page_end(src_argb, kWidth * kHeight * BPP_A); \ + align_buffer_page_end(dst_y, kWidth * kHeight); \ + align_buffer_page_end(dst_uv, kStrideUV * 2 * kHeightUV); \ + align_buffer_page_end(ref_y, kWidth * kHeight); \ + align_buffer_page_end(ref_uv, kStrideUV * 2 * kHeightUV); \ + \ + MemRandomize(src_argb, kWidth * kHeight * BPP_A); \ + \ + FMT_A##To##FMT_B##Matrix(src_argb, kWidth * BPP_A, dst_y, kWidth, dst_uv, \ + kStrideUV * 2, &kArgbI601Constants, kWidth, \ + kHeight); \ + FMT_A##To##FMT_B(src_argb, kWidth * BPP_A, ref_y, kWidth, ref_uv, \ + kStrideUV * 2, kWidth, kHeight); \ + for (int i = 0; i < kWidth * kHeight; ++i) { \ + ASSERT_EQ(dst_y[i], ref_y[i]); \ + } \ + for (int i = 0; i < kStrideUV * 2 * kHeightUV; ++i) { \ + ASSERT_EQ(dst_uv[i], ref_uv[i]); \ + } \ + \ + free_aligned_buffer_page_end(src_argb); \ + free_aligned_buffer_page_end(dst_y); \ + free_aligned_buffer_page_end(dst_uv); \ + free_aligned_buffer_page_end(ref_y); \ + free_aligned_buffer_page_end(ref_uv); \ + } + +TESTATOBPMATRIX(ARGB, 4, NV12, 2, 2) +TESTATOBPMATRIX(ARGB, 4, NV16, 2, 1) +TESTATOBPMATRIX(ARGB, 4, NV24, 1, 1) + #if !defined(LEAN_TESTS) #ifdef HAVE_JPEG @@ -2420,37 +2460,6 @@ TEST_F(LibYUVConvertTest, TestRGB24ToNV12) { free_aligned_buffer_page_end(ref_uv); } -TEST_F(LibYUVConvertTest, TestARGBToNV12Matrix) { - const int kWidth = 16; - const int kHeight = 16; - align_buffer_page_end(src_argb, kWidth * kHeight * 4); - align_buffer_page_end(dst_y, kWidth * kHeight); - align_buffer_page_end(dst_uv, kWidth * kHeight / 2); - - MemRandomize(src_argb, kWidth * kHeight * 4); - - // BT.601 - ARGBToNV12Matrix(src_argb, kWidth * 4, dst_y, kWidth, dst_uv, kWidth, - &kArgbI601Constants, kWidth, kHeight); - // Verify against non-matrix version - align_buffer_page_end(ref_y, kWidth * kHeight); - align_buffer_page_end(ref_uv, kWidth * kHeight / 2); - ARGBToNV12(src_argb, kWidth * 4, ref_y, kWidth, ref_uv, kWidth, kWidth, - kHeight); - for (int i = 0; i < kWidth * kHeight; ++i) { - ASSERT_EQ(dst_y[i], ref_y[i]); - } - for (int i = 0; i < kWidth * kHeight / 2; ++i) { - ASSERT_EQ(dst_uv[i], ref_uv[i]); - } - - free_aligned_buffer_page_end(src_argb); - free_aligned_buffer_page_end(dst_y); - free_aligned_buffer_page_end(dst_uv); - free_aligned_buffer_page_end(ref_y); - free_aligned_buffer_page_end(ref_uv); -} - TEST_F(LibYUVConvertTest, TestABGRToNV12Matrix) { const int kWidth = 16; const int kHeight = 16;