mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-07 17:26:49 +08:00
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>
This commit is contained in:
parent
27d846c57d
commit
d4c3f45eb6
@ -1,6 +1,6 @@
|
||||
Name: libyuv
|
||||
URL: http://code.google.com/p/libyuv/
|
||||
Version: 1748
|
||||
Version: 1749
|
||||
License: BSD
|
||||
License File: LICENSE
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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_
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user