diff options
author | Frank Barchard <fbarchard@google.com> | 2020-04-17 00:01:14 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-04-17 09:16:46 +0000 |
commit | d4c3f45eb672e7bd008cac3347f3e21c955cbf7d (patch) | |
tree | 1df47189e602bbb4543145ca7a22135318d1e468 | |
parent | 27d846c57d07d13cee99a26e747067401712423a (diff) | |
download | libyuv-d4c3f45eb672e7bd008cac3347f3e21c955cbf7d.tar.gz |
libyuv r1749 upstream for I444ToNV12
Bug: libyuv:858
Change-Id: Iacf70938ace6258e5bbd397cd78414f1025474c5
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/2154331
Reviewed-by: Frank Barchard <fbarchard@chromium.org>
Reviewed-by: Mirko Bonadei <mbonadei@chromium.org>
Commit-Queue: Frank Barchard <fbarchard@chromium.org>
-rw-r--r-- | README.chromium | 2 | ||||
-rw-r--r-- | include/libyuv/convert.h | 15 | ||||
-rw-r--r-- | include/libyuv/convert_from_argb.h | 11 | ||||
-rw-r--r-- | include/libyuv/row.h | 48 | ||||
-rw-r--r-- | include/libyuv/version.h | 2 | ||||
-rw-r--r-- | source/convert.cc | 40 | ||||
-rw-r--r-- | source/rotate.cc | 22 | ||||
-rw-r--r-- | source/row_common.cc | 8 | ||||
-rw-r--r-- | source/row_gcc.cc | 12 | ||||
-rw-r--r-- | source/row_mmi.cc | 8 | ||||
-rw-r--r-- | source/row_msa.cc | 8 | ||||
-rw-r--r-- | source/row_neon.cc | 8 | ||||
-rw-r--r-- | source/row_neon64.cc | 8 | ||||
-rw-r--r-- | source/row_win.cc | 12 | ||||
-rw-r--r-- | unit_test/convert_test.cc | 1 |
15 files changed, 125 insertions, 80 deletions
diff --git a/README.chromium b/README.chromium index f24f37bb..994c4fcb 100644 --- a/README.chromium +++ b/README.chromium @@ -1,6 +1,6 @@ Name: libyuv URL: http://code.google.com/p/libyuv/ -Version: 1748 +Version: 1749 License: BSD License File: LICENSE diff --git a/include/libyuv/convert.h b/include/libyuv/convert.h index f05a928b..b1bb5424 100644 --- a/include/libyuv/convert.h +++ b/include/libyuv/convert.h @@ -42,6 +42,21 @@ int I444ToI420(const uint8_t* src_y, int width, int height); +// Convert I444 to NV12. +LIBYUV_API +int I444ToNV12(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + int width, + int height); + // Convert I444 to NV21. LIBYUV_API int I444ToNV21(const uint8_t* src_y, diff --git a/include/libyuv/convert_from_argb.h b/include/libyuv/convert_from_argb.h index 05718244..158730ca 100644 --- a/include/libyuv/convert_from_argb.h +++ b/include/libyuv/convert_from_argb.h @@ -281,17 +281,6 @@ int ABGRToNV21(const uint8_t* src_abgr, int width, int height); -// Convert ARGB To NV21. -LIBYUV_API -int ARGBToNV21(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_vu, - int dst_stride_vu, - int width, - int height); - // Convert ARGB To YUY2. LIBYUV_API int ARGBToYUY2(const uint8_t* src_argb, diff --git a/include/libyuv/row.h b/include/libyuv/row.h index 1e177a61..45db1b91 100644 --- a/include/libyuv/row.h +++ b/include/libyuv/row.h @@ -112,7 +112,7 @@ extern "C" { #define HAS_J422TOARGBROW_SSSE3 #define HAS_MERGEUVROW_SSE2 #define HAS_MIRRORROW_SSSE3 -#define HAS_MIRRORUVROW_SSSE3 +#define HAS_MIRRORSPLITUVROW_SSSE3 #define HAS_NV12TOARGBROW_SSSE3 #define HAS_NV12TORGB24ROW_SSSE3 #define HAS_NV12TORGB565ROW_SSSE3 @@ -367,7 +367,7 @@ extern "C" { #define HAS_J400TOARGBROW_NEON #define HAS_MERGEUVROW_NEON #define HAS_MIRRORROW_NEON -#define HAS_MIRRORUVROW_NEON +#define HAS_MIRRORSPLITUVROW_NEON #define HAS_NV12TOARGBROW_NEON #define HAS_NV12TORGB24ROW_NEON #define HAS_NV12TORGB565ROW_NEON @@ -480,7 +480,7 @@ extern "C" { #define HAS_J400TOARGBROW_MSA #define HAS_MERGEUVROW_MSA #define HAS_MIRRORROW_MSA -#define HAS_MIRRORUVROW_MSA +#define HAS_MIRRORSPLITUVROW_MSA #define HAS_NV12TOARGBROW_MSA #define HAS_NV12TORGB565ROW_MSA #define HAS_NV21TOARGBROW_MSA @@ -563,7 +563,7 @@ extern "C" { #define HAS_MERGERGBROW_MMI #define HAS_MERGEUVROW_MMI #define HAS_MIRRORROW_MMI -#define HAS_MIRRORUVROW_MMI +#define HAS_MIRRORSPLITUVROW_MMI #define HAS_RAWTOARGBROW_MMI #define HAS_RAWTORGB24ROW_MMI #define HAS_RAWTOUVROW_MMI @@ -1573,26 +1573,26 @@ void MirrorRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void MirrorRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void MirrorRow_Any_MMI(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void MirrorUVRow_SSSE3(const uint8_t* src, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void MirrorUVRow_NEON(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void MirrorUVRow_MSA(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void MirrorUVRow_MMI(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void MirrorUVRow_C(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width); +void MirrorSplitUVRow_SSSE3(const uint8_t* src, + uint8_t* dst_u, + uint8_t* dst_v, + int width); +void MirrorSplitUVRow_NEON(const uint8_t* src_uv, + uint8_t* dst_u, + uint8_t* dst_v, + int width); +void MirrorSplitUVRow_MSA(const uint8_t* src_uv, + uint8_t* dst_u, + uint8_t* dst_v, + int width); +void MirrorSplitUVRow_MMI(const uint8_t* src_uv, + uint8_t* dst_u, + uint8_t* dst_v, + int width); +void MirrorSplitUVRow_C(const uint8_t* src_uv, + uint8_t* dst_u, + uint8_t* dst_v, + int width); void ARGBMirrorRow_AVX2(const uint8_t* src, uint8_t* dst, int width); void ARGBMirrorRow_SSE2(const uint8_t* src, uint8_t* dst, int width); diff --git a/include/libyuv/version.h b/include/libyuv/version.h index 6e30190b..d8d586dc 100644 --- a/include/libyuv/version.h +++ b/include/libyuv/version.h @@ -11,6 +11,6 @@ #ifndef INCLUDE_LIBYUV_VERSION_H_ #define INCLUDE_LIBYUV_VERSION_H_ -#define LIBYUV_VERSION 1748 +#define LIBYUV_VERSION 1749 #endif // INCLUDE_LIBYUV_VERSION_H_ diff --git a/source/convert.cc b/source/convert.cc index 3a03e456..0645debc 100644 --- a/source/convert.cc +++ b/source/convert.cc @@ -498,6 +498,46 @@ int I400ToI420(const uint8_t* src_y, return 0; } +// TODO(fbarchard): Implement row conversion. +LIBYUV_API +int I444ToNV12(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + int width, + int height) { + int halfwidth = (width + 1) >> 1; + int halfheight = (height + 1) >> 1; + // Negative height means invert the image. + if (height < 0) { + height = -height; + halfheight = (height + 1) >> 1; + src_y = src_y + (height - 1) * src_stride_y; + src_u = src_u + (height - 1) * src_stride_u; + src_v = src_v + (height - 1) * src_stride_v; + src_stride_y = -src_stride_y; + src_stride_u = -src_stride_u; + src_stride_v = -src_stride_v; + } + // Allocate u and v buffers + align_buffer_64(plane_u, halfwidth * halfheight * 2); + uint8_t* plane_v = plane_u + halfwidth * halfheight; + + I444ToI420(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, + dst_y, dst_stride_y, plane_u, halfwidth, plane_v, halfwidth, width, + height); + MergeUVPlane(plane_u, halfwidth, plane_v, halfwidth, dst_uv, dst_stride_uv, + halfwidth, halfheight); + free_aligned_buffer_64(plane_u); + return 0; +} + // I400 is greyscale typically used in MJPG LIBYUV_API int I400ToNV21(const uint8_t* src_y, diff --git a/source/rotate.cc b/source/rotate.cc index cea835d1..57618791 100644 --- a/source/rotate.cc +++ b/source/rotate.cc @@ -340,26 +340,26 @@ void RotateUV180(const uint8_t* src, int width, int height) { int i; - void (*MirrorUVRow)(const uint8_t* src, uint8_t* dst_u, uint8_t* dst_v, - int width) = MirrorUVRow_C; -#if defined(HAS_MIRRORUVROW_NEON) + void (*MirrorSplitUVRow)(const uint8_t* src, uint8_t* dst_u, uint8_t* dst_v, + int width) = MirrorSplitUVRow_C; +#if defined(HAS_MIRRORSPLITUVROW_NEON) if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { - MirrorUVRow = MirrorUVRow_NEON; + MirrorSplitUVRow = MirrorSplitUVRow_NEON; } #endif -#if defined(HAS_MIRRORUVROW_SSSE3) +#if defined(HAS_MIRRORSPLITUVROW_SSSE3) if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 16)) { - MirrorUVRow = MirrorUVRow_SSSE3; + MirrorSplitUVRow = MirrorSplitUVRow_SSSE3; } #endif -#if defined(HAS_MIRRORUVROW_MSA) +#if defined(HAS_MIRRORSPLITUVROW_MSA) if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 32)) { - MirrorUVRow = MirrorUVRow_MSA; + MirrorSplitUVRow = MirrorSplitUVRow_MSA; } #endif -#if defined(HAS_MIRRORUVROW_MMI) +#if defined(HAS_MIRRORSPLITUVROW_MMI) if (TestCpuFlag(kCpuHasMMI) && IS_ALIGNED(width, 8)) { - MirrorUVRow = MirrorUVRow_MMI; + MirrorSplitUVRow = MirrorSplitUVRow_MMI; } #endif @@ -367,7 +367,7 @@ void RotateUV180(const uint8_t* src, dst_b += dst_stride_b * (height - 1); for (i = 0; i < height; ++i) { - MirrorUVRow(src, dst_a, dst_b, width); + MirrorSplitUVRow(src, dst_a, dst_b, width); src += src_stride; dst_a -= dst_stride_a; dst_b -= dst_stride_b; diff --git a/source/row_common.cc b/source/row_common.cc index 800e2201..026845b9 100644 --- a/source/row_common.cc +++ b/source/row_common.cc @@ -2167,10 +2167,10 @@ void MirrorRow_C(const uint8_t* src, uint8_t* dst, int width) { } } -void MirrorUVRow_C(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { +void MirrorSplitUVRow_C(const uint8_t* src_uv, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { int x; src_uv += (width - 1) << 1; for (x = 0; x < width - 1; x += 2) { diff --git a/source/row_gcc.cc b/source/row_gcc.cc index d8480d56..9e7b9e5e 100644 --- a/source/row_gcc.cc +++ b/source/row_gcc.cc @@ -3229,14 +3229,14 @@ void MirrorRow_AVX2(const uint8_t* src, uint8_t* dst, int width) { } #endif // HAS_MIRRORROW_AVX2 -#ifdef HAS_MIRRORUVROW_SSSE3 +#ifdef HAS_MIRRORSPLITUVROW_SSSE3 // Shuffle table for reversing the bytes of UV channels. static const uvec8 kShuffleMirrorUV = {14u, 12u, 10u, 8u, 6u, 4u, 2u, 0u, 15u, 13u, 11u, 9u, 7u, 5u, 3u, 1u}; -void MirrorUVRow_SSSE3(const uint8_t* src, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { +void MirrorSplitUVRow_SSSE3(const uint8_t* src, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { intptr_t temp_width = (intptr_t)(width); asm volatile( "movdqa %4,%%xmm1 \n" @@ -3260,7 +3260,7 @@ void MirrorUVRow_SSSE3(const uint8_t* src, : "m"(kShuffleMirrorUV) // %4 : "memory", "cc", "xmm0", "xmm1"); } -#endif // HAS_MIRRORUVROW_SSSE3 +#endif // HAS_MIRRORSPLITUVROW_SSSE3 #ifdef HAS_RGB24MIRRORROW_SSSE3 diff --git a/source/row_mmi.cc b/source/row_mmi.cc index f778d25e..9ecafaa2 100644 --- a/source/row_mmi.cc +++ b/source/row_mmi.cc @@ -4914,10 +4914,10 @@ void MirrorRow_MMI(const uint8_t* src, uint8_t* dst, int width) { : "memory"); } -void MirrorUVRow_MMI(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { +void MirrorSplitUVRow_MMI(const uint8_t* src_uv, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { uint64_t src0, src1, dest0, dest1; const uint64_t mask0 = 0x00ff00ff00ff00ffULL; const uint64_t mask1 = 0x1b; diff --git a/source/row_msa.cc b/source/row_msa.cc index 5c0239a3..1e410fb6 100644 --- a/source/row_msa.cc +++ b/source/row_msa.cc @@ -3315,10 +3315,10 @@ void SetRow_MSA(uint8_t* dst, uint8_t v8, int width) { } } -void MirrorUVRow_MSA(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { +void MirrorSplitUVRow_MSA(const uint8_t* src_uv, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { int x; v16u8 src0, src1, src2, src3; v16u8 dst0, dst1, dst2, dst3; diff --git a/source/row_neon.cc b/source/row_neon.cc index eecec291..f358bd36 100644 --- a/source/row_neon.cc +++ b/source/row_neon.cc @@ -701,10 +701,10 @@ void MirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width) { : "cc", "memory", "q0", "q1", "q2"); } -void MirrorUVRow_NEON(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { +void MirrorSplitUVRow_NEON(const uint8_t* src_uv, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { asm volatile( // Start at end of source row. "mov r12, #-16 \n" diff --git a/source/row_neon64.cc b/source/row_neon64.cc index 6e1bdf14..b57147bb 100644 --- a/source/row_neon64.cc +++ b/source/row_neon64.cc @@ -765,10 +765,10 @@ void MirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width) { : "cc", "memory", "v0", "v1", "v2", "v3"); } -void MirrorUVRow_NEON(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { +void MirrorSplitUVRow_NEON(const uint8_t* src_uv, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { asm volatile( // Start at end of source row. "add %0, %0, %w3, sxtw #1 \n" diff --git a/source/row_win.cc b/source/row_win.cc index f976d402..fdb111e8 100644 --- a/source/row_win.cc +++ b/source/row_win.cc @@ -3045,15 +3045,15 @@ __declspec(naked) void MirrorRow_AVX2(const uint8_t* src, } #endif // HAS_MIRRORROW_AVX2 -#ifdef HAS_MIRRORUVROW_SSSE3 +#ifdef HAS_MIRRORSPLITUVROW_SSSE3 // Shuffle table for reversing the bytes of UV channels. static const uvec8 kShuffleMirrorUV = {14u, 12u, 10u, 8u, 6u, 4u, 2u, 0u, 15u, 13u, 11u, 9u, 7u, 5u, 3u, 1u}; -__declspec(naked) void MirrorUVRow_SSSE3(const uint8_t* src, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { +__declspec(naked) void MirrorSplitUVRow_SSSE3(const uint8_t* src, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { __asm { push edi mov eax, [esp + 4 + 4] // src @@ -3078,7 +3078,7 @@ __declspec(naked) void MirrorUVRow_SSSE3(const uint8_t* src, ret } } -#endif // HAS_MIRRORUVROW_SSSE3 +#endif // HAS_MIRRORSPLITUVROW_SSSE3 #ifdef HAS_ARGBMIRRORROW_SSE2 __declspec(naked) void ARGBMirrorRow_SSE2(const uint8_t* src, diff --git a/unit_test/convert_test.cc b/unit_test/convert_test.cc index f66b2b84..6765ebfa 100644 --- a/unit_test/convert_test.cc +++ b/unit_test/convert_test.cc @@ -400,6 +400,7 @@ int I400ToNV21(const uint8_t* src_y, TESTPLANARTOBP(I420, 2, 2, NV12, 2, 2) TESTPLANARTOBP(I420, 2, 2, NV21, 2, 2) TESTPLANARTOBP(I422, 2, 1, NV21, 2, 2) +TESTPLANARTOBP(I444, 1, 1, NV12, 2, 2) TESTPLANARTOBP(I444, 1, 1, NV21, 2, 2) TESTPLANARTOBP(I400, 2, 2, NV21, 2, 2) |