mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-07 17:26:49 +08:00
ARGBToJ420 and ARGBToJ400 - Full range YUV Jpeg style.
BUG=159 TEST=*J4* Review URL: https://webrtc-codereview.appspot.com/1243004 git-svn-id: http://libyuv.googlecode.com/svn/trunk@622 16f28f9a-4ce2-e073-06de-1de4eb20be90
This commit is contained in:
parent
036d06c5c5
commit
cfaa66c041
@ -1,6 +1,6 @@
|
||||
Name: libyuv
|
||||
URL: http://code.google.com/p/libyuv/
|
||||
Version: 621
|
||||
Version: 622
|
||||
License: BSD
|
||||
License File: LICENSE
|
||||
|
||||
|
||||
@ -99,6 +99,14 @@ int ARGBToI420(const uint8* src_argb, int src_stride_argb,
|
||||
uint8* dst_v, int dst_stride_v,
|
||||
int width, int height);
|
||||
|
||||
// Convert ARGB to J420. (JPeg full range I420).
|
||||
LIBYUV_API
|
||||
int ARGBToJ420(const uint8* src_argb, int src_stride_argb,
|
||||
uint8* dst_yj, int dst_stride_yj,
|
||||
uint8* dst_u, int dst_stride_u,
|
||||
uint8* dst_v, int dst_stride_v,
|
||||
int width, int height);
|
||||
|
||||
// Convert ARGB To I411.
|
||||
LIBYUV_API
|
||||
int ARGBToI411(const uint8* src_argb, int src_stride_argb,
|
||||
@ -107,6 +115,12 @@ int ARGBToI411(const uint8* src_argb, int src_stride_argb,
|
||||
uint8* dst_v, int dst_stride_v,
|
||||
int width, int height);
|
||||
|
||||
// Convert ARGB to J400. (JPeg full range).
|
||||
LIBYUV_API
|
||||
int ARGBToJ400(const uint8* src_argb, int src_stride_argb,
|
||||
uint8* dst_yj, int dst_stride_yj,
|
||||
int width, int height);
|
||||
|
||||
// Convert ARGB to I400.
|
||||
LIBYUV_API
|
||||
int ARGBToI400(const uint8* src_argb, int src_stride_argb,
|
||||
|
||||
@ -55,6 +55,7 @@ extern "C" {
|
||||
#define HAS_ARGBTOUV444ROW_SSSE3
|
||||
#define HAS_ARGBTOUVROW_SSSE3
|
||||
#define HAS_ARGBTOYROW_SSSE3
|
||||
#define HAS_ARGBTOYJROW_SSSE3
|
||||
#define HAS_BGRATOUVROW_SSSE3
|
||||
#define HAS_BGRATOYROW_SSSE3
|
||||
#define HAS_COPYROW_SSE2
|
||||
@ -203,6 +204,7 @@ extern "C" {
|
||||
#define HAS_ARGBTOUV444ROW_NEON
|
||||
#define HAS_ARGBTOUVROW_NEON
|
||||
#define HAS_ARGBTOYROW_NEON
|
||||
#define HAS_ARGBTOYJROW_NEON
|
||||
#define HAS_BGRATOUVROW_NEON
|
||||
#define HAS_BGRATOYROW_NEON
|
||||
#define HAS_COPYROW_NEON
|
||||
@ -398,18 +400,21 @@ void UYVYToARGBRow_NEON(const uint8* src_uyvy,
|
||||
void ARGBToYRow_AVX2(const uint8* src_argb, uint8* dst_y, int pix);
|
||||
void ARGBToYRow_Any_AVX2(const uint8* src_argb, uint8* dst_y, int pix);
|
||||
void ARGBToYRow_SSSE3(const uint8* src_argb, uint8* dst_y, int pix);
|
||||
void ARGBToYJRow_SSSE3(const uint8* src_argb, uint8* dst_y, int pix);
|
||||
void BGRAToYRow_SSSE3(const uint8* src_bgra, uint8* dst_y, int pix);
|
||||
void ABGRToYRow_SSSE3(const uint8* src_abgr, uint8* dst_y, int pix);
|
||||
void RGBAToYRow_SSSE3(const uint8* src_rgba, uint8* dst_y, int pix);
|
||||
void RGB24ToYRow_SSSE3(const uint8* src_rgb24, uint8* dst_y, int pix);
|
||||
void RAWToYRow_SSSE3(const uint8* src_raw, uint8* dst_y, int pix);
|
||||
void ARGBToYRow_Unaligned_SSSE3(const uint8* src_argb, uint8* dst_y, int pix);
|
||||
void ARGBToYJRow_Unaligned_SSSE3(const uint8* src_argb, uint8* dst_y, int pix);
|
||||
void BGRAToYRow_Unaligned_SSSE3(const uint8* src_bgra, uint8* dst_y, int pix);
|
||||
void ABGRToYRow_Unaligned_SSSE3(const uint8* src_abgr, uint8* dst_y, int pix);
|
||||
void RGBAToYRow_Unaligned_SSSE3(const uint8* src_rgba, uint8* dst_y, int pix);
|
||||
void RGB24ToYRow_Unaligned_SSSE3(const uint8* src_rgb24, uint8* dst_y, int pix);
|
||||
void RAWToYRow_Unaligned_SSSE3(const uint8* src_raw, uint8* dst_y, int pix);
|
||||
void ARGBToYRow_NEON(const uint8* src_argb, uint8* dst_y, int pix);
|
||||
void ARGBToYJRow_NEON(const uint8* src_argb, uint8* dst_y, int pix);
|
||||
void ARGBToUV444Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
|
||||
int pix);
|
||||
void ARGBToUV422Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
|
||||
@ -443,6 +448,7 @@ void RGB565ToYRow_NEON(const uint8* src_rgb565, uint8* dst_y, int pix);
|
||||
void ARGB1555ToYRow_NEON(const uint8* src_argb1555, uint8* dst_y, int pix);
|
||||
void ARGB4444ToYRow_NEON(const uint8* src_argb4444, uint8* dst_y, int pix);
|
||||
void ARGBToYRow_C(const uint8* src_argb, uint8* dst_y, int pix);
|
||||
void ARGBToYJRow_C(const uint8* src_argb, uint8* dst_y, int pix);
|
||||
void BGRAToYRow_C(const uint8* src_bgra, uint8* dst_y, int pix);
|
||||
void ABGRToYRow_C(const uint8* src_abgr, uint8* dst_y, int pix);
|
||||
void RGBAToYRow_C(const uint8* src_rgba, uint8* dst_y, int pix);
|
||||
@ -452,12 +458,14 @@ void RGB565ToYRow_C(const uint8* src_rgb565, uint8* dst_y, int pix);
|
||||
void ARGB1555ToYRow_C(const uint8* src_argb1555, uint8* dst_y, int pix);
|
||||
void ARGB4444ToYRow_C(const uint8* src_argb4444, uint8* dst_y, int pix);
|
||||
void ARGBToYRow_Any_SSSE3(const uint8* src_argb, uint8* dst_y, int pix);
|
||||
void ARGBToYJRow_Any_SSSE3(const uint8* src_argb, uint8* dst_y, int pix);
|
||||
void BGRAToYRow_Any_SSSE3(const uint8* src_bgra, uint8* dst_y, int pix);
|
||||
void ABGRToYRow_Any_SSSE3(const uint8* src_abgr, uint8* dst_y, int pix);
|
||||
void RGBAToYRow_Any_SSSE3(const uint8* src_rgba, uint8* dst_y, int pix);
|
||||
void RGB24ToYRow_Any_SSSE3(const uint8* src_rgb24, uint8* dst_y, int pix);
|
||||
void RAWToYRow_Any_SSSE3(const uint8* src_raw, uint8* dst_y, int pix);
|
||||
void ARGBToYRow_Any_NEON(const uint8* src_argb, uint8* dst_y, int pix);
|
||||
void ARGBToYJRow_Any_NEON(const uint8* src_argb, uint8* dst_y, int pix);
|
||||
void BGRAToYRow_Any_NEON(const uint8* src_bgra, uint8* dst_y, int pix);
|
||||
void ABGRToYRow_Any_NEON(const uint8* src_abgr, uint8* dst_y, int pix);
|
||||
void RGBAToYRow_Any_NEON(const uint8* src_rgba, uint8* dst_y, int pix);
|
||||
|
||||
@ -11,6 +11,6 @@
|
||||
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
|
||||
#define INCLUDE_LIBYUV_VERSION_H_
|
||||
|
||||
#define LIBYUV_VERSION 621
|
||||
#define LIBYUV_VERSION 622
|
||||
|
||||
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
|
||||
|
||||
@ -976,6 +976,126 @@ int ARGBToARGB4444(const uint8* src_argb, int src_stride_argb,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert ARGB to J420. (JPeg full range I420).
|
||||
LIBYUV_API
|
||||
int ARGBToJ420(const uint8* src_argb, int src_stride_argb,
|
||||
uint8* dst_yj, int dst_stride_yj,
|
||||
uint8* dst_u, int dst_stride_u,
|
||||
uint8* dst_v, int dst_stride_v,
|
||||
int width, int height) {
|
||||
if (!src_argb ||
|
||||
!dst_yj || !dst_u || !dst_v ||
|
||||
width <= 0 || height == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Negative height means invert the image.
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
src_argb = src_argb + (height - 1) * src_stride_argb;
|
||||
src_stride_argb = -src_stride_argb;
|
||||
}
|
||||
void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb,
|
||||
uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C;
|
||||
void (*ARGBToYJRow)(const uint8* src_argb, uint8* dst_yj, int pix) =
|
||||
ARGBToYJRow_C;
|
||||
#if defined(HAS_ARGBTOYJROW_SSSE3)
|
||||
if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) {
|
||||
ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
|
||||
ARGBToYJRow = ARGBToYJRow_Any_SSSE3;
|
||||
if (IS_ALIGNED(width, 16)) {
|
||||
ARGBToUVRow = ARGBToUVRow_Unaligned_SSSE3;
|
||||
ARGBToYJRow = ARGBToYJRow_Unaligned_SSSE3;
|
||||
if (IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) {
|
||||
ARGBToUVRow = ARGBToUVRow_SSSE3;
|
||||
if (IS_ALIGNED(dst_yj, 16) && IS_ALIGNED(dst_stride_yj, 16)) {
|
||||
ARGBToYJRow = ARGBToYJRow_SSSE3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_ARGBTOYJROW_NEON)
|
||||
if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
|
||||
ARGBToYJRow = ARGBToYJRow_Any_NEON;
|
||||
if (IS_ALIGNED(width, 8)) {
|
||||
ARGBToYJRow = ARGBToYJRow_NEON;
|
||||
}
|
||||
if (width >= 16) {
|
||||
ARGBToUVRow = ARGBToUVRow_Any_NEON;
|
||||
if (IS_ALIGNED(width, 16)) {
|
||||
ARGBToUVRow = ARGBToUVRow_NEON;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int y = 0; y < height - 1; y += 2) {
|
||||
ARGBToUVRow(src_argb, src_stride_argb, dst_u, dst_v, width);
|
||||
ARGBToYJRow(src_argb, dst_yj, width);
|
||||
ARGBToYJRow(src_argb + src_stride_argb, dst_yj + dst_stride_yj, width);
|
||||
src_argb += src_stride_argb * 2;
|
||||
dst_yj += dst_stride_yj * 2;
|
||||
dst_u += dst_stride_u;
|
||||
dst_v += dst_stride_v;
|
||||
}
|
||||
if (height & 1) {
|
||||
ARGBToUVRow(src_argb, 0, dst_u, dst_v, width);
|
||||
ARGBToYJRow(src_argb, dst_yj, width);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert ARGB to J400.
|
||||
LIBYUV_API
|
||||
int ARGBToJ400(const uint8* src_argb, int src_stride_argb,
|
||||
uint8* dst_yj, int dst_stride_yj,
|
||||
int width, int height) {
|
||||
if (!src_argb || !dst_yj || width <= 0 || height == 0) {
|
||||
return -1;
|
||||
}
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
src_argb = src_argb + (height - 1) * src_stride_argb;
|
||||
src_stride_argb = -src_stride_argb;
|
||||
}
|
||||
// Coalesce contiguous rows.
|
||||
if (src_stride_argb == width * 4 &&
|
||||
dst_stride_yj == width) {
|
||||
return ARGBToI400(src_argb, 0,
|
||||
dst_yj, 0,
|
||||
width * height, 1);
|
||||
}
|
||||
void (*ARGBToYJRow)(const uint8* src_argb, uint8* dst_yj, int pix) =
|
||||
ARGBToYJRow_C;
|
||||
#if defined(HAS_ARGBTOYJROW_SSSE3)
|
||||
if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) {
|
||||
ARGBToYJRow = ARGBToYJRow_Any_SSSE3;
|
||||
if (IS_ALIGNED(width, 16)) {
|
||||
ARGBToYJRow = ARGBToYJRow_Unaligned_SSSE3;
|
||||
if (IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16) &&
|
||||
IS_ALIGNED(dst_yj, 16) && IS_ALIGNED(dst_stride_yj, 16)) {
|
||||
ARGBToYJRow = ARGBToYJRow_SSSE3;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_ARGBTOYJROW_NEON)
|
||||
if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
|
||||
ARGBToYJRow = ARGBToYJRow_Any_NEON;
|
||||
if (IS_ALIGNED(width, 8)) {
|
||||
ARGBToYJRow = ARGBToYJRow_NEON;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
ARGBToYJRow(src_argb, dst_yj, width);
|
||||
src_argb += src_stride_argb;
|
||||
dst_yj += dst_stride_yj;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
} // namespace libyuv
|
||||
|
||||
@ -215,8 +215,12 @@ YANY(RGBAToYRow_Any_SSSE3, RGBAToYRow_Unaligned_SSSE3, 4, 1, 16)
|
||||
YANY(YUY2ToYRow_Any_SSE2, YUY2ToYRow_Unaligned_SSE2, 2, 1, 16)
|
||||
YANY(UYVYToYRow_Any_SSE2, UYVYToYRow_Unaligned_SSE2, 2, 1, 16)
|
||||
#endif
|
||||
#ifdef HAS_ARGBTOYJROW_SSSE3
|
||||
YANY(ARGBToYJRow_Any_SSSE3, ARGBToYJRow_Unaligned_SSSE3, 4, 1, 16)
|
||||
#endif
|
||||
#ifdef HAS_ARGBTOYROW_NEON
|
||||
YANY(ARGBToYRow_Any_NEON, ARGBToYRow_NEON, 4, 1, 8)
|
||||
YANY(ARGBToYJRow_Any_NEON, ARGBToYJRow_NEON, 4, 1, 8)
|
||||
YANY(BGRAToYRow_Any_NEON, BGRAToYRow_NEON, 4, 1, 8)
|
||||
YANY(ABGRToYRow_Any_NEON, ABGRToYRow_NEON, 4, 1, 8)
|
||||
YANY(RGBAToYRow_Any_NEON, RGBAToYRow_NEON, 4, 1, 8)
|
||||
|
||||
@ -256,6 +256,22 @@ MAKEROWY(RGB24, 2, 1, 0, 3)
|
||||
MAKEROWY(RAW, 0, 1, 2, 3)
|
||||
#undef MAKEROWY
|
||||
|
||||
static __inline int RGBToYJ(uint8 r, uint8 g, uint8 b) {
|
||||
return (66 * r + 129 * g + 25 * b + 0x0080) >> 8;
|
||||
}
|
||||
|
||||
#define MAKEROWYJ(NAME, R, G, B, BPP) \
|
||||
void NAME ## ToYJRow_C(const uint8* src_argb0, uint8* dst_y, int width) { \
|
||||
for (int x = 0; x < width; ++x) { \
|
||||
dst_y[0] = RGBToYJ(src_argb0[R], src_argb0[G], src_argb0[B]); \
|
||||
src_argb0 += BPP; \
|
||||
dst_y += 1; \
|
||||
} \
|
||||
} \
|
||||
|
||||
MAKEROWYJ(ARGB, 2, 1, 0, 4)
|
||||
#undef MAKEROWYJ
|
||||
|
||||
void RGB565ToYRow_C(const uint8* src_rgb565, uint8* dst_y, int width) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
uint8 b = src_rgb565[0] & 0x1f;
|
||||
|
||||
@ -1336,6 +1336,29 @@ void ARGBToYRow_NEON(const uint8* src_argb, uint8* dst_y, int pix) {
|
||||
);
|
||||
}
|
||||
|
||||
void ARGBToYJRow_NEON(const uint8* src_argb, uint8* dst_y, int pix) {
|
||||
asm volatile (
|
||||
"vmov.u8 d24, #13 \n" // B * 0.1016 coefficient
|
||||
"vmov.u8 d25, #65 \n" // G * 0.5078 coefficient
|
||||
"vmov.u8 d26, #33 \n" // R * 0.2578 coefficient
|
||||
".p2align 2 \n"
|
||||
"1: \n"
|
||||
"vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels.
|
||||
"subs %2, %2, #8 \n" // 8 processed per loop.
|
||||
"vmull.u8 q2, d0, d24 \n" // B
|
||||
"vmlal.u8 q2, d1, d25 \n" // G
|
||||
"vmlal.u8 q2, d2, d26 \n" // R
|
||||
"vqrshrun.s16 d0, q2, #7 \n" // 16 bit to 8 bit Y
|
||||
"vst1.8 {d0}, [%1]! \n" // store 8 pixels Y.
|
||||
"bgt 1b \n"
|
||||
: "+r"(src_argb), // %0
|
||||
"+r"(dst_y), // %1
|
||||
"+r"(pix) // %2
|
||||
:
|
||||
: "cc", "memory", "q0", "q1", "q2", "q12", "q13"
|
||||
);
|
||||
}
|
||||
|
||||
// 8x1 pixels.
|
||||
void ARGBToUV444Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
|
||||
int pix) {
|
||||
|
||||
@ -642,6 +642,40 @@ void ARGBToYRow_SSSE3(const uint8* src_argb, uint8* dst_y, int pix) {
|
||||
);
|
||||
}
|
||||
|
||||
void ARGBToYJRow_SSSE3(const uint8* src_argb, uint8* dst_y, int pix) {
|
||||
asm volatile (
|
||||
"movdqa %3,%%xmm4 \n"
|
||||
".p2align 4 \n"
|
||||
"1: \n"
|
||||
"movdqa (%0),%%xmm0 \n"
|
||||
"movdqa 0x10(%0),%%xmm1 \n"
|
||||
"movdqa 0x20(%0),%%xmm2 \n"
|
||||
"movdqa 0x30(%0),%%xmm3 \n"
|
||||
"pmaddubsw %%xmm4,%%xmm0 \n"
|
||||
"pmaddubsw %%xmm4,%%xmm1 \n"
|
||||
"pmaddubsw %%xmm4,%%xmm2 \n"
|
||||
"pmaddubsw %%xmm4,%%xmm3 \n"
|
||||
"lea 0x40(%0),%0 \n"
|
||||
"phaddw %%xmm1,%%xmm0 \n"
|
||||
"phaddw %%xmm3,%%xmm2 \n"
|
||||
"psrlw $0x7,%%xmm0 \n"
|
||||
"psrlw $0x7,%%xmm2 \n"
|
||||
"packuswb %%xmm2,%%xmm0 \n"
|
||||
"sub $0x10,%2 \n"
|
||||
"movdqa %%xmm0,(%1) \n"
|
||||
"lea 0x10(%1),%1 \n"
|
||||
"jg 1b \n"
|
||||
: "+r"(src_argb), // %0
|
||||
"+r"(dst_y), // %1
|
||||
"+r"(pix) // %2
|
||||
: "m"(kARGBToY) // %3
|
||||
: "memory", "cc"
|
||||
#if defined(__SSE2__)
|
||||
, "xmm0", "xmm1", "xmm2", "xmm3", "xmm4"
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
void ARGBToYRow_Unaligned_SSSE3(const uint8* src_argb, uint8* dst_y, int pix) {
|
||||
asm volatile (
|
||||
"movdqa %4,%%xmm5 \n"
|
||||
@ -679,6 +713,39 @@ void ARGBToYRow_Unaligned_SSSE3(const uint8* src_argb, uint8* dst_y, int pix) {
|
||||
);
|
||||
}
|
||||
|
||||
void ARGBToYJRow_Unaligned_SSSE3(const uint8* src_argb, uint8* dst_y, int pix) {
|
||||
asm volatile (
|
||||
"movdqa %3,%%xmm4 \n"
|
||||
".p2align 4 \n"
|
||||
"1: \n"
|
||||
"movdqu (%0),%%xmm0 \n"
|
||||
"movdqu 0x10(%0),%%xmm1 \n"
|
||||
"movdqu 0x20(%0),%%xmm2 \n"
|
||||
"movdqu 0x30(%0),%%xmm3 \n"
|
||||
"pmaddubsw %%xmm4,%%xmm0 \n"
|
||||
"pmaddubsw %%xmm4,%%xmm1 \n"
|
||||
"pmaddubsw %%xmm4,%%xmm2 \n"
|
||||
"pmaddubsw %%xmm4,%%xmm3 \n"
|
||||
"lea 0x40(%0),%0 \n"
|
||||
"phaddw %%xmm1,%%xmm0 \n"
|
||||
"phaddw %%xmm3,%%xmm2 \n"
|
||||
"psrlw $0x7,%%xmm0 \n"
|
||||
"psrlw $0x7,%%xmm2 \n"
|
||||
"packuswb %%xmm2,%%xmm0 \n"
|
||||
"sub $0x10,%2 \n"
|
||||
"movdqu %%xmm0,(%1) \n"
|
||||
"lea 0x10(%1),%1 \n"
|
||||
"jg 1b \n"
|
||||
: "+r"(src_argb), // %0
|
||||
"+r"(dst_y), // %1
|
||||
"+r"(pix) // %2
|
||||
: "m"(kARGBToY) // %3
|
||||
: "memory", "cc"
|
||||
#if defined(__SSE2__)
|
||||
, "xmm0", "xmm1", "xmm2", "xmm3", "xmm4"
|
||||
#endif
|
||||
);
|
||||
}
|
||||
// TODO(fbarchard): pass xmm constants to single block of assembly.
|
||||
// fpic on GCC 4.2 for OSX runs out of GPR registers. "m" effectively takes
|
||||
// 3 registers - ebx, ebp and eax. "m" can be passed with 3 normal registers,
|
||||
|
||||
@ -664,6 +664,39 @@ void ARGBToYRow_SSSE3(const uint8* src_argb, uint8* dst_y, int pix) {
|
||||
}
|
||||
}
|
||||
|
||||
// Convert 16 ARGB pixels (64 bytes) to 16 Y values.
|
||||
__declspec(naked) __declspec(align(16))
|
||||
void ARGBToYJRow_SSSE3(const uint8* src_argb, uint8* dst_y, int pix) {
|
||||
__asm {
|
||||
mov eax, [esp + 4] /* src_argb */
|
||||
mov edx, [esp + 8] /* dst_y */
|
||||
mov ecx, [esp + 12] /* pix */
|
||||
movdqa xmm4, kARGBToY
|
||||
|
||||
align 16
|
||||
convertloop:
|
||||
movdqa xmm0, [eax]
|
||||
movdqa xmm1, [eax + 16]
|
||||
movdqa xmm2, [eax + 32]
|
||||
movdqa xmm3, [eax + 48]
|
||||
pmaddubsw xmm0, xmm4
|
||||
pmaddubsw xmm1, xmm4
|
||||
pmaddubsw xmm2, xmm4
|
||||
pmaddubsw xmm3, xmm4
|
||||
lea eax, [eax + 64]
|
||||
phaddw xmm0, xmm1
|
||||
phaddw xmm2, xmm3
|
||||
psrlw xmm0, 7
|
||||
psrlw xmm2, 7
|
||||
packuswb xmm0, xmm2
|
||||
sub ecx, 16
|
||||
movdqa [edx], xmm0
|
||||
lea edx, [edx + 16]
|
||||
jg convertloop
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAS_ARGBTOYROW_AVX2
|
||||
// Convert 32 ARGB pixels (128 bytes) to 32 Y values.
|
||||
__declspec(naked) __declspec(align(32))
|
||||
@ -737,6 +770,38 @@ void ARGBToYRow_Unaligned_SSSE3(const uint8* src_argb, uint8* dst_y, int pix) {
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(naked) __declspec(align(16))
|
||||
void ARGBToYJRow_Unaligned_SSSE3(const uint8* src_argb, uint8* dst_y, int pix) {
|
||||
__asm {
|
||||
mov eax, [esp + 4] /* src_argb */
|
||||
mov edx, [esp + 8] /* dst_y */
|
||||
mov ecx, [esp + 12] /* pix */
|
||||
movdqa xmm4, kARGBToY
|
||||
|
||||
align 16
|
||||
convertloop:
|
||||
movdqu xmm0, [eax]
|
||||
movdqu xmm1, [eax + 16]
|
||||
movdqu xmm2, [eax + 32]
|
||||
movdqu xmm3, [eax + 48]
|
||||
pmaddubsw xmm0, xmm4
|
||||
pmaddubsw xmm1, xmm4
|
||||
pmaddubsw xmm2, xmm4
|
||||
pmaddubsw xmm3, xmm4
|
||||
lea eax, [eax + 64]
|
||||
phaddw xmm0, xmm1
|
||||
phaddw xmm2, xmm3
|
||||
psrlw xmm0, 7
|
||||
psrlw xmm2, 7
|
||||
packuswb xmm0, xmm2
|
||||
sub ecx, 16
|
||||
movdqu [edx], xmm0
|
||||
lea edx, [edx + 16]
|
||||
jg convertloop
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(naked) __declspec(align(16))
|
||||
void BGRAToYRow_SSSE3(const uint8* src_argb, uint8* dst_y, int pix) {
|
||||
__asm {
|
||||
|
||||
@ -686,6 +686,7 @@ TEST_F(libyuvTest, FMT_A##To##FMT_PLANAR##N) { \
|
||||
benchmark_width_, DIFF, _Opt, +, 0)
|
||||
|
||||
TESTATOPLANAR(ARGB, 4, I420, 2, 2, 4)
|
||||
TESTATOPLANAR(ARGB, 4, J420, 2, 2, 4)
|
||||
TESTATOPLANAR(BGRA, 4, I420, 2, 2, 4)
|
||||
TESTATOPLANAR(ABGR, 4, I420, 2, 2, 4)
|
||||
TESTATOPLANAR(RGBA, 4, I420, 2, 2, 4)
|
||||
@ -902,6 +903,7 @@ TESTATOB(ARGB, 4, 4, 1, BayerGRBG, 1, 2, 2, 0)
|
||||
TESTATOB(ARGB, 4, 4, 1, YUY2, 2, 4, 1, 4)
|
||||
TESTATOB(ARGB, 4, 4, 1, UYVY, 2, 4, 1, 4)
|
||||
TESTATOB(ARGB, 4, 4, 1, I400, 1, 1, 1, 2)
|
||||
TESTATOB(ARGB, 4, 4, 1, J400, 1, 1, 1, 2)
|
||||
TESTATOB(BGRA, 4, 4, 1, ARGB, 4, 4, 1, 0)
|
||||
TESTATOB(ABGR, 4, 4, 1, ARGB, 4, 4, 1, 0)
|
||||
TESTATOB(RGBA, 4, 4, 1, ARGB, 4, 4, 1, 0)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user