mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2026-02-16 23:29:52 +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
|
Name: libyuv
|
||||||
URL: http://code.google.com/p/libyuv/
|
URL: http://code.google.com/p/libyuv/
|
||||||
Version: 621
|
Version: 622
|
||||||
License: BSD
|
License: BSD
|
||||||
License File: LICENSE
|
License File: LICENSE
|
||||||
|
|
||||||
|
|||||||
@ -99,6 +99,14 @@ int ARGBToI420(const uint8* src_argb, int src_stride_argb,
|
|||||||
uint8* dst_v, int dst_stride_v,
|
uint8* dst_v, int dst_stride_v,
|
||||||
int width, int height);
|
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.
|
// Convert ARGB To I411.
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
int ARGBToI411(const uint8* src_argb, int src_stride_argb,
|
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,
|
uint8* dst_v, int dst_stride_v,
|
||||||
int width, int height);
|
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.
|
// Convert ARGB to I400.
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
int ARGBToI400(const uint8* src_argb, int src_stride_argb,
|
int ARGBToI400(const uint8* src_argb, int src_stride_argb,
|
||||||
|
|||||||
@ -55,6 +55,7 @@ extern "C" {
|
|||||||
#define HAS_ARGBTOUV444ROW_SSSE3
|
#define HAS_ARGBTOUV444ROW_SSSE3
|
||||||
#define HAS_ARGBTOUVROW_SSSE3
|
#define HAS_ARGBTOUVROW_SSSE3
|
||||||
#define HAS_ARGBTOYROW_SSSE3
|
#define HAS_ARGBTOYROW_SSSE3
|
||||||
|
#define HAS_ARGBTOYJROW_SSSE3
|
||||||
#define HAS_BGRATOUVROW_SSSE3
|
#define HAS_BGRATOUVROW_SSSE3
|
||||||
#define HAS_BGRATOYROW_SSSE3
|
#define HAS_BGRATOYROW_SSSE3
|
||||||
#define HAS_COPYROW_SSE2
|
#define HAS_COPYROW_SSE2
|
||||||
@ -203,6 +204,7 @@ extern "C" {
|
|||||||
#define HAS_ARGBTOUV444ROW_NEON
|
#define HAS_ARGBTOUV444ROW_NEON
|
||||||
#define HAS_ARGBTOUVROW_NEON
|
#define HAS_ARGBTOUVROW_NEON
|
||||||
#define HAS_ARGBTOYROW_NEON
|
#define HAS_ARGBTOYROW_NEON
|
||||||
|
#define HAS_ARGBTOYJROW_NEON
|
||||||
#define HAS_BGRATOUVROW_NEON
|
#define HAS_BGRATOUVROW_NEON
|
||||||
#define HAS_BGRATOYROW_NEON
|
#define HAS_BGRATOYROW_NEON
|
||||||
#define HAS_COPYROW_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_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_Any_AVX2(const uint8* src_argb, uint8* dst_y, int pix);
|
||||||
void ARGBToYRow_SSSE3(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 BGRAToYRow_SSSE3(const uint8* src_bgra, uint8* dst_y, int pix);
|
||||||
void ABGRToYRow_SSSE3(const uint8* src_abgr, 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 RGBAToYRow_SSSE3(const uint8* src_rgba, uint8* dst_y, int pix);
|
||||||
void RGB24ToYRow_SSSE3(const uint8* src_rgb24, 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 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 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 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 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 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 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 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 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,
|
void ARGBToUV444Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
|
||||||
int pix);
|
int pix);
|
||||||
void ARGBToUV422Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
|
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 ARGB1555ToYRow_NEON(const uint8* src_argb1555, uint8* dst_y, int pix);
|
||||||
void ARGB4444ToYRow_NEON(const uint8* src_argb4444, 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 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 BGRAToYRow_C(const uint8* src_bgra, uint8* dst_y, int pix);
|
||||||
void ABGRToYRow_C(const uint8* src_abgr, 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);
|
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 ARGB1555ToYRow_C(const uint8* src_argb1555, uint8* dst_y, int pix);
|
||||||
void ARGB4444ToYRow_C(const uint8* src_argb4444, 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 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 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 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 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 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 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 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 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 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);
|
void RGBAToYRow_Any_NEON(const uint8* src_rgba, uint8* dst_y, int pix);
|
||||||
|
|||||||
@ -11,6 +11,6 @@
|
|||||||
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
|
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
|
||||||
#define INCLUDE_LIBYUV_VERSION_H_
|
#define INCLUDE_LIBYUV_VERSION_H_
|
||||||
|
|
||||||
#define LIBYUV_VERSION 621
|
#define LIBYUV_VERSION 622
|
||||||
|
|
||||||
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
|
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
|
||||||
|
|||||||
@ -976,6 +976,126 @@ int ARGBToARGB4444(const uint8* src_argb, int src_stride_argb,
|
|||||||
return 0;
|
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
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
} // namespace libyuv
|
} // 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(YUY2ToYRow_Any_SSE2, YUY2ToYRow_Unaligned_SSE2, 2, 1, 16)
|
||||||
YANY(UYVYToYRow_Any_SSE2, UYVYToYRow_Unaligned_SSE2, 2, 1, 16)
|
YANY(UYVYToYRow_Any_SSE2, UYVYToYRow_Unaligned_SSE2, 2, 1, 16)
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAS_ARGBTOYJROW_SSSE3
|
||||||
|
YANY(ARGBToYJRow_Any_SSSE3, ARGBToYJRow_Unaligned_SSSE3, 4, 1, 16)
|
||||||
|
#endif
|
||||||
#ifdef HAS_ARGBTOYROW_NEON
|
#ifdef HAS_ARGBTOYROW_NEON
|
||||||
YANY(ARGBToYRow_Any_NEON, ARGBToYRow_NEON, 4, 1, 8)
|
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(BGRAToYRow_Any_NEON, BGRAToYRow_NEON, 4, 1, 8)
|
||||||
YANY(ABGRToYRow_Any_NEON, ABGRToYRow_NEON, 4, 1, 8)
|
YANY(ABGRToYRow_Any_NEON, ABGRToYRow_NEON, 4, 1, 8)
|
||||||
YANY(RGBAToYRow_Any_NEON, RGBAToYRow_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)
|
MAKEROWY(RAW, 0, 1, 2, 3)
|
||||||
#undef MAKEROWY
|
#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) {
|
void RGB565ToYRow_C(const uint8* src_rgb565, uint8* dst_y, int width) {
|
||||||
for (int x = 0; x < width; ++x) {
|
for (int x = 0; x < width; ++x) {
|
||||||
uint8 b = src_rgb565[0] & 0x1f;
|
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.
|
// 8x1 pixels.
|
||||||
void ARGBToUV444Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
|
void ARGBToUV444Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
|
||||||
int pix) {
|
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) {
|
void ARGBToYRow_Unaligned_SSSE3(const uint8* src_argb, uint8* dst_y, int pix) {
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"movdqa %4,%%xmm5 \n"
|
"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.
|
// 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
|
// 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,
|
// 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
|
#ifdef HAS_ARGBTOYROW_AVX2
|
||||||
// Convert 32 ARGB pixels (128 bytes) to 32 Y values.
|
// Convert 32 ARGB pixels (128 bytes) to 32 Y values.
|
||||||
__declspec(naked) __declspec(align(32))
|
__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))
|
__declspec(naked) __declspec(align(16))
|
||||||
void BGRAToYRow_SSSE3(const uint8* src_argb, uint8* dst_y, int pix) {
|
void BGRAToYRow_SSSE3(const uint8* src_argb, uint8* dst_y, int pix) {
|
||||||
__asm {
|
__asm {
|
||||||
|
|||||||
@ -686,6 +686,7 @@ TEST_F(libyuvTest, FMT_A##To##FMT_PLANAR##N) { \
|
|||||||
benchmark_width_, DIFF, _Opt, +, 0)
|
benchmark_width_, DIFF, _Opt, +, 0)
|
||||||
|
|
||||||
TESTATOPLANAR(ARGB, 4, I420, 2, 2, 4)
|
TESTATOPLANAR(ARGB, 4, I420, 2, 2, 4)
|
||||||
|
TESTATOPLANAR(ARGB, 4, J420, 2, 2, 4)
|
||||||
TESTATOPLANAR(BGRA, 4, I420, 2, 2, 4)
|
TESTATOPLANAR(BGRA, 4, I420, 2, 2, 4)
|
||||||
TESTATOPLANAR(ABGR, 4, I420, 2, 2, 4)
|
TESTATOPLANAR(ABGR, 4, I420, 2, 2, 4)
|
||||||
TESTATOPLANAR(RGBA, 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, YUY2, 2, 4, 1, 4)
|
||||||
TESTATOB(ARGB, 4, 4, 1, UYVY, 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, 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(BGRA, 4, 4, 1, ARGB, 4, 4, 1, 0)
|
||||||
TESTATOB(ABGR, 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)
|
TESTATOB(RGBA, 4, 4, 1, ARGB, 4, 4, 1, 0)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user