aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank Barchard <fbarchard@google.com>2020-04-17 00:01:14 -0700
committerCommit Bot <commit-bot@chromium.org>2020-04-17 09:16:46 +0000
commitd4c3f45eb672e7bd008cac3347f3e21c955cbf7d (patch)
tree1df47189e602bbb4543145ca7a22135318d1e468
parent27d846c57d07d13cee99a26e747067401712423a (diff)
downloadlibyuv-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.chromium2
-rw-r--r--include/libyuv/convert.h15
-rw-r--r--include/libyuv/convert_from_argb.h11
-rw-r--r--include/libyuv/row.h48
-rw-r--r--include/libyuv/version.h2
-rw-r--r--source/convert.cc40
-rw-r--r--source/rotate.cc22
-rw-r--r--source/row_common.cc8
-rw-r--r--source/row_gcc.cc12
-rw-r--r--source/row_mmi.cc8
-rw-r--r--source/row_msa.cc8
-rw-r--r--source/row_neon.cc8
-rw-r--r--source/row_neon64.cc8
-rw-r--r--source/row_win.cc12
-rw-r--r--unit_test/convert_test.cc1
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)