Commit b95dbf24 authored by fbarchard@google.com's avatar fbarchard@google.com

check pointer of last pixel and last pixel + 64 are in the same page.

BUG=none
TEST=none
Review URL: https://webrtc-codereview.appspot.com/387006

git-svn-id: http://libyuv.googlecode.com/svn/trunk@170 16f28f9a-4ce2-e073-06de-1de4eb20be90
parent 567244c0
Name: libyuv Name: libyuv
URL: http://code.google.com/p/libyuv/ URL: http://code.google.com/p/libyuv/
Version: 169 Version: 170
License: BSD License: BSD
License File: LICENSE License File: LICENSE
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_ #ifndef INCLUDE_LIBYUV_VERSION_H_
#define INCLUDE_LIBYUV_VERSION_H_ #define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 169 #define LIBYUV_VERSION 170
#endif // INCLUDE_LIBYUV_VERSION_H_ #endif // INCLUDE_LIBYUV_VERSION_H_
...@@ -346,531 +346,635 @@ int RGB24ToARGB(const uint8* src_frame, int src_stride_frame, ...@@ -346,531 +346,635 @@ int RGB24ToARGB(const uint8* src_frame, int src_stride_frame,
return 0; return 0;
} }
int ARGBToI420(const uint8* src_frame, int src_stride_frame, // Test if over reading on source is safe.
// TODO(fbarchard): Find more efficient solution to safely do odd sizes.
// Macros to control read policy, from slowest to fastest:
// READSAFE_NEVER - disables read ahead on systems with strict memory reads
// READSAFE_ODDHEIGHT - last row of odd height done with C.
// This policy assumes that the caller handles the last row of an odd height
// image using C.
// READSAFE_PAGE - enable read ahead within same page.
// A page is 4096 bytes. When reading ahead, if the last pixel is near the
// end the page, and a read spans the page into the next page, a memory
// exception can occur if that page has not been allocated, or is a guard
// page. This setting ensures the overread is within the same page.
// READSAFE_ALWAYS - enables read ahead on systems without memory exceptions
// or where buffers are padded by 64 bytes.
#define READSAFE_ODDHEIGHT
static bool TestReadSafe(const uint8* src_yuy2, int src_stride_yuy2,
int width, int height, int bpp, int overread) {
if (width > kMaxStride) {
return false;
}
#if defined(READSAFE_ALWAYS)
return true;
#elif defined(READSAFE_NEVER)
return false;
#elif defined(READSAFE_ODDHEIGHT)
if (src_stride_yuy2 >= 0 && (height & 1) && width * bpp >= overread) {
return true;
}
return false;
#elif defined(READSAFE_PAGE)
if (src_stride_yuy2 >= 0) {
src_yuy2 += (height - 1) * src_stride_yuy2;
}
uintptr_t last_adr = (uintptr_t)(src_yuy2) + width * bpp - 1;
uintptr_t last_read_adr = last_adr + overread - 1;
if (((last_adr ^ last_read_adr) & ~4095) == 0) {
return true;
}
return false;
#endif
}
// Convert YUY2 to I420.
int YUY2ToI420(const uint8* src_yuy2, int src_stride_yuy2,
uint8* dst_y, int dst_stride_y, uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u, uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v, uint8* dst_v, int dst_stride_v,
int width, int height) { int width, int height) {
// Negative height means invert the image.
if (height < 0) { if (height < 0) {
height = -height; height = -height;
src_frame = src_frame + (height - 1) * src_stride_frame; src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2;
src_stride_frame = -src_stride_frame; src_stride_yuy2 = -src_stride_yuy2;
}
void (*YUY2ToUVRow)(const uint8* src_yuy2, int src_stride_yuy2,
uint8* dst_u, uint8* dst_v, int pix);
void (*YUY2ToYRow)(const uint8* src_yuy2,
uint8* dst_y, int pix);
YUY2ToYRow = YUY2ToYRow_C;
YUY2ToUVRow = YUY2ToUVRow_C;
#if defined(HAS_YUY2TOYROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
if (TestReadSafe(src_yuy2, src_stride_yuy2, width, height, 2, 32)) {
YUY2ToUVRow = YUY2ToUVRow_Any_SSE2;
YUY2ToYRow = YUY2ToYRow_Any_SSE2;
}
if (IS_ALIGNED(width, 16)) {
YUY2ToUVRow = YUY2ToUVRow_Unaligned_SSE2;
YUY2ToYRow = YUY2ToYRow_Unaligned_SSE2;
if (IS_ALIGNED(src_yuy2, 16) && IS_ALIGNED(src_stride_yuy2, 16)) {
YUY2ToUVRow = YUY2ToUVRow_SSE2;
if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
YUY2ToYRow = YUY2ToYRow_SSE2;
}
}
}
}
#endif
for (int y = 0; y < height - 1; y += 2) {
YUY2ToUVRow(src_yuy2, src_stride_yuy2, dst_u, dst_v, width);
YUY2ToYRow(src_yuy2, dst_y, width);
YUY2ToYRow(src_yuy2 + src_stride_yuy2, dst_y + dst_stride_y, width);
src_yuy2 += src_stride_yuy2 * 2;
dst_y += dst_stride_y * 2;
dst_u += dst_stride_u;
dst_v += dst_stride_v;
}
if (height & 1) {
YUY2ToUVRow_C(src_yuy2, 0, dst_u, dst_v, width);
YUY2ToYRow_C(src_yuy2, dst_y, width);
}
return 0;
}
// Convert UYVY to I420.
int UYVYToI420(const uint8* src_uyvy, int src_stride_uyvy,
uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height) {
// Negative height means invert the image.
if (height < 0) {
height = -height;
src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy;
src_stride_uyvy = -src_stride_uyvy;
}
void (*UYVYToUVRow)(const uint8* src_uyvy, int src_stride_uyvy,
uint8* dst_u, uint8* dst_v, int pix);
void (*UYVYToYRow)(const uint8* src_uyvy,
uint8* dst_y, int pix);
UYVYToYRow = UYVYToYRow_C;
UYVYToUVRow = UYVYToUVRow_C;
#if defined(HAS_UYVYTOYROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
if (TestReadSafe(src_uyvy, src_stride_uyvy, width, height, 2, 32)) {
UYVYToUVRow = UYVYToUVRow_Any_SSE2;
UYVYToYRow = UYVYToYRow_Any_SSE2;
}
if (IS_ALIGNED(width, 16)) {
UYVYToUVRow = UYVYToUVRow_Unaligned_SSE2;
UYVYToYRow = UYVYToYRow_Unaligned_SSE2;
if (IS_ALIGNED(src_uyvy, 16) && IS_ALIGNED(src_stride_uyvy, 16)) {
UYVYToUVRow = UYVYToUVRow_SSE2;
if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
UYVYToYRow = UYVYToYRow_SSE2;
}
}
}
}
#endif
for (int y = 0; y < height - 1; y += 2) {
UYVYToUVRow(src_uyvy, src_stride_uyvy, dst_u, dst_v, width);
UYVYToYRow(src_uyvy, dst_y, width);
UYVYToYRow(src_uyvy + src_stride_uyvy, dst_y + dst_stride_y, width);
src_uyvy += src_stride_uyvy * 2;
dst_y += dst_stride_y * 2;
dst_u += dst_stride_u;
dst_v += dst_stride_v;
}
if (height & 1) {
UYVYToUVRow_C(src_uyvy, 0, dst_u, dst_v, width);
UYVYToYRow_C(src_uyvy, dst_y, width);
}
return 0;
}
int ARGBToI420(const uint8* src_argb, int src_stride_argb,
uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height) {
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
src_stride_argb = -src_stride_argb;
} }
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix); void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix);
void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width); uint8* dst_u, uint8* dst_v, int width);
ARGBToYRow = ARGBToYRow_C;
ARGBToUVRow = ARGBToUVRow_C;
#if defined(HAS_ARGBTOYROW_SSSE3) #if defined(HAS_ARGBTOYROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && if (TestCpuFlag(kCpuHasSSSE3)) {
IS_ALIGNED(width, 16) && if (TestReadSafe(src_argb, src_stride_argb, width, height, 4, 64)) {
IS_ALIGNED(src_frame, 16) && IS_ALIGNED(src_stride_frame, 16) && if (IS_ALIGNED(width, 2)) {
IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
ARGBToYRow = ARGBToYRow_SSSE3; }
} else if (TestCpuFlag(kCpuHasSSSE3) && width <= kMaxStride) {
ARGBToYRow = ARGBToYRow_Any_SSSE3; ARGBToYRow = ARGBToYRow_Any_SSSE3;
}
if (IS_ALIGNED(width, 16)) { if (IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_Unaligned_SSSE3;
ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; ARGBToYRow = ARGBToYRow_Unaligned_SSSE3;
if (IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) {
ARGBToUVRow = ARGBToUVRow_SSSE3;
if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
ARGBToYRow = ARGBToYRow_SSSE3;
} }
} else
#endif
{
ARGBToYRow = ARGBToYRow_C;
} }
#if defined(HAS_ARGBTOUVROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 16) &&
IS_ALIGNED(src_frame, 16) && IS_ALIGNED(src_stride_frame, 16)) {
ARGBToUVRow = ARGBToUVRow_SSSE3;
} else if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 2) && width <= kMaxStride) {
ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
if (IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_Unaligned_SSSE3;
} }
} else
#endif
{
ARGBToUVRow = ARGBToUVRow_C;
} }
#endif
for (int y = 0; y < (height - 1); y += 2) { for (int y = 0; y < height - 1; y += 2) {
ARGBToUVRow(src_frame, src_stride_frame, dst_u, dst_v, width); ARGBToUVRow(src_argb, src_stride_argb, dst_u, dst_v, width);
ARGBToYRow(src_frame, dst_y, width); ARGBToYRow(src_argb, dst_y, width);
ARGBToYRow(src_frame + src_stride_frame, dst_y + dst_stride_y, width); ARGBToYRow(src_argb + src_stride_argb, dst_y + dst_stride_y, width);
src_frame += src_stride_frame * 2; src_argb += src_stride_argb * 2;
dst_y += dst_stride_y * 2; dst_y += dst_stride_y * 2;
dst_u += dst_stride_u; dst_u += dst_stride_u;
dst_v += dst_stride_v; dst_v += dst_stride_v;
} }
if (height & 1) { if (height & 1) {
ARGBToUVRow(src_frame, 0, dst_u, dst_v, width); ARGBToUVRow(src_argb, 0, dst_u, dst_v, width);
ARGBToYRow(src_frame, dst_y, width); ARGBToYRow(src_argb, dst_y, width);
} }
return 0; return 0;
} }
int BGRAToI420(const uint8* src_frame, int src_stride_frame, int BGRAToI420(const uint8* src_bgra, int src_stride_bgra,
uint8* dst_y, int dst_stride_y, uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u, uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v, uint8* dst_v, int dst_stride_v,
int width, int height) { int width, int height) {
if (height < 0) { if (height < 0) {
height = -height; height = -height;
src_frame = src_frame + (height - 1) * src_stride_frame; src_bgra = src_bgra + (height - 1) * src_stride_bgra;
src_stride_frame = -src_stride_frame; src_stride_bgra = -src_stride_bgra;
} }
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix); void (*BGRAToYRow)(const uint8* src_bgra, uint8* dst_y, int pix);
void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, void (*BGRAToUVRow)(const uint8* src_bgra0, int src_stride_bgra,
uint8* dst_u, uint8* dst_v, int width); uint8* dst_u, uint8* dst_v, int width);
BGRAToYRow = BGRAToYRow_C;
BGRAToUVRow = BGRAToUVRow_C;
#if defined(HAS_BGRATOYROW_SSSE3) #if defined(HAS_BGRATOYROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && if (TestCpuFlag(kCpuHasSSSE3)) {
IS_ALIGNED(width, 16) && if (TestReadSafe(src_bgra, src_stride_bgra, width, height, 4, 64)) {
IS_ALIGNED(src_frame, 16) && IS_ALIGNED(src_stride_frame, 16) && if (IS_ALIGNED(width, 2)) {
IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { BGRAToUVRow = BGRAToUVRow_Any_SSSE3;
ARGBToYRow = BGRAToYRow_SSSE3;
} else if (TestCpuFlag(kCpuHasSSSE3) && width <= kMaxStride) {
ARGBToYRow = BGRAToYRow_Any_SSSE3;
if (IS_ALIGNED(width, 16)) {
ARGBToYRow = BGRAToYRow_Unaligned_SSSE3;
} }
} else BGRAToYRow = BGRAToYRow_Any_SSSE3;
#endif
{
ARGBToYRow = BGRAToYRow_C;
} }
#if defined(HAS_BGRATOUVROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 16) &&
IS_ALIGNED(src_frame, 16) && IS_ALIGNED(src_stride_frame, 16)) {
ARGBToUVRow = BGRAToUVRow_SSSE3;
} else if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 2) && width <= kMaxStride) {
ARGBToUVRow = BGRAToUVRow_Any_SSSE3;
if (IS_ALIGNED(width, 16)) { if (IS_ALIGNED(width, 16)) {
ARGBToUVRow = BGRAToUVRow_Unaligned_SSSE3; BGRAToUVRow = BGRAToUVRow_Unaligned_SSSE3;
BGRAToYRow = BGRAToYRow_Unaligned_SSSE3;
if (IS_ALIGNED(src_bgra, 16) && IS_ALIGNED(src_stride_bgra, 16)) {
BGRAToUVRow = BGRAToUVRow_SSSE3;
if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
BGRAToYRow = BGRAToYRow_SSSE3;
}
}
} }
} else
#endif
{
ARGBToUVRow = BGRAToUVRow_C;
} }
#endif
for (int y = 0; y < (height - 1); y += 2) { for (int y = 0; y < height - 1; y += 2) {
ARGBToUVRow(src_frame, src_stride_frame, dst_u, dst_v, width); BGRAToUVRow(src_bgra, src_stride_bgra, dst_u, dst_v, width);
ARGBToYRow(src_frame, dst_y, width); BGRAToYRow(src_bgra, dst_y, width);
ARGBToYRow(src_frame + src_stride_frame, dst_y + dst_stride_y, width); BGRAToYRow(src_bgra + src_stride_bgra, dst_y + dst_stride_y, width);
src_frame += src_stride_frame * 2; src_bgra += src_stride_bgra * 2;
dst_y += dst_stride_y * 2; dst_y += dst_stride_y * 2;
dst_u += dst_stride_u; dst_u += dst_stride_u;
dst_v += dst_stride_v; dst_v += dst_stride_v;
} }
if (height & 1) { if (height & 1) {
ARGBToUVRow(src_frame, 0, dst_u, dst_v, width); BGRAToUVRow_C(src_bgra, 0, dst_u, dst_v, width);
ARGBToYRow(src_frame, dst_y, width); BGRAToYRow_C(src_bgra, dst_y, width);
} }
return 0; return 0;
} }
int ABGRToI420(const uint8* src_frame, int src_stride_frame, int ABGRToI420(const uint8* src_abgr, int src_stride_abgr,
uint8* dst_y, int dst_stride_y, uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u, uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v, uint8* dst_v, int dst_stride_v,
int width, int height) { int width, int height) {
if (height < 0) { if (height < 0) {
height = -height; height = -height;
src_frame = src_frame + (height - 1) * src_stride_frame; src_abgr = src_abgr + (height - 1) * src_stride_abgr;
src_stride_frame = -src_stride_frame; src_stride_abgr = -src_stride_abgr;
} }
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix); void (*ABGRToYRow)(const uint8* src_abgr, uint8* dst_y, int pix);
void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, void (*ABGRToUVRow)(const uint8* src_abgr0, int src_stride_abgr,
uint8* dst_u, uint8* dst_v, int width); uint8* dst_u, uint8* dst_v, int width);
ABGRToYRow = ABGRToYRow_C;
ABGRToUVRow = ABGRToUVRow_C;
#if defined(HAS_ABGRTOYROW_SSSE3) #if defined(HAS_ABGRTOYROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && if (TestCpuFlag(kCpuHasSSSE3)) {
IS_ALIGNED(width, 16) && if (TestReadSafe(src_abgr, src_stride_abgr, width, height, 4, 64)) {
IS_ALIGNED(src_frame, 16) && IS_ALIGNED(src_stride_frame, 16) && if (IS_ALIGNED(width, 2)) {
IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { ABGRToUVRow = ABGRToUVRow_Any_SSSE3;
ARGBToYRow = ABGRToYRow_SSSE3;
} else if (TestCpuFlag(kCpuHasSSSE3) && width <= kMaxStride) {
ARGBToYRow = ABGRToYRow_Any_SSSE3;
if (IS_ALIGNED(width, 16)) {
ARGBToYRow = ABGRToYRow_Unaligned_SSSE3;
} }
} else ABGRToYRow = ABGRToYRow_Any_SSSE3;
#endif
{
ARGBToYRow = ABGRToYRow_C;
} }
#if defined(HAS_ABGRTOUVROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 16) &&
IS_ALIGNED(src_frame, 16) && IS_ALIGNED(src_stride_frame, 16)) {
ARGBToUVRow = ABGRToUVRow_SSSE3;
} else if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 2) && width <= kMaxStride) {
ARGBToUVRow = ABGRToUVRow_Any_SSSE3;
if (IS_ALIGNED(width, 16)) { if (IS_ALIGNED(width, 16)) {
ARGBToUVRow = ABGRToUVRow_Unaligned_SSSE3; ABGRToUVRow = ABGRToUVRow_Unaligned_SSSE3;
ABGRToYRow = ABGRToYRow_Unaligned_SSSE3;
if (IS_ALIGNED(src_abgr, 16) && IS_ALIGNED(src_stride_abgr, 16)) {
ABGRToUVRow = ABGRToUVRow_SSSE3;
if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
ABGRToYRow = ABGRToYRow_SSSE3;
}
} }
} else
#endif
{
ARGBToUVRow = ABGRToUVRow_C;
} }
}
#endif
for (int y = 0; y < (height - 1); y += 2) { for (int y = 0; y < height - 1; y += 2) {
ARGBToUVRow(src_frame, src_stride_frame, dst_u, dst_v, width); ABGRToUVRow(src_abgr, src_stride_abgr, dst_u, dst_v, width);
ARGBToYRow(src_frame, dst_y, width); ABGRToYRow(src_abgr, dst_y, width);
ARGBToYRow(src_frame + src_stride_frame, dst_y + dst_stride_y, width); ABGRToYRow(src_abgr + src_stride_abgr, dst_y + dst_stride_y, width);
src_frame += src_stride_frame * 2; src_abgr += src_stride_abgr * 2;
dst_y += dst_stride_y * 2; dst_y += dst_stride_y * 2;
dst_u += dst_stride_u; dst_u += dst_stride_u;
dst_v += dst_stride_v; dst_v += dst_stride_v;
} }
if (height & 1) { if (height & 1) {
ARGBToUVRow(src_frame, 0, dst_u, dst_v, width); ABGRToUVRow_C(src_abgr, 0, dst_u, dst_v, width);
ARGBToYRow(src_frame, dst_y, width); ABGRToYRow_C(src_abgr, dst_y, width);
} }
return 0; return 0;
} }
int RGB24ToI420(const uint8* src_frame, int src_stride_frame, int RGB24ToI420(const uint8* src_rgb24, int src_stride_rgb24,
uint8* dst_y, int dst_stride_y, uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u, uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v, uint8* dst_v, int dst_stride_v,
int width, int height) { int width, int height) {
if (width * 4 > kMaxStride) { // row buffer is required
return -1;
}
if (height < 0) { if (height < 0) {
height = -height; height = -height;
src_frame = src_frame + (height - 1) * src_stride_frame; src_rgb24 = src_rgb24 + (height - 1) * src_stride_rgb24;
src_stride_frame = -src_stride_frame; src_stride_rgb24 = -src_stride_rgb24;
} }
SIMD_ALIGNED(uint8 row[kMaxStride * 2]); SIMD_ALIGNED(uint8 row[kMaxStride * 2]);
void (*RGB24ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix); void (*RGB24ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix);
RGB24ToARGBRow = RGB24ToARGBRow_C;
#if defined(HAS_RGB24TOARGBROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) &&
TestReadSafe(src_rgb24, src_stride_rgb24, width, height, 3, 48)) {
RGB24ToARGBRow = RGB24ToARGBRow_SSSE3;
}
#endif
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix); void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix);
void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width); uint8* dst_u, uint8* dst_v, int width);
#if defined(HAS_RGB24TOARGBROW_SSSE3)
ARGBToYRow = ARGBToYRow_C;
ARGBToUVRow = ARGBToUVRow_C;
#if defined(HAS_ARGBTOYROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) { if (TestCpuFlag(kCpuHasSSSE3)) {
RGB24ToARGBRow = RGB24ToARGBRow_SSSE3; if (IS_ALIGNED(width, 2)) {
} else ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
#endif
{
RGB24ToARGBRow = RGB24ToARGBRow_C;
} }
#if defined(HAS_ARGBTOYROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 16) &&
IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
ARGBToYRow = ARGBToYRow_SSSE3;
} else if (TestCpuFlag(kCpuHasSSSE3) && width <= kMaxStride) {
ARGBToYRow = ARGBToYRow_Any_SSSE3; ARGBToYRow = ARGBToYRow_Any_SSSE3;
if (IS_ALIGNED(width, 16)) { if (IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_SSSE3;
ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; ARGBToYRow = ARGBToYRow_Unaligned_SSSE3;
if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
ARGBToYRow = ARGBToYRow_SSSE3;
} }
} else
#endif
{
ARGBToYRow = ARGBToYRow_C;
} }
#if defined(HAS_ARGBTOUVROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_SSSE3;
} else if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 2) && width <= kMaxStride) {
ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
} else
#endif
{
ARGBToUVRow = ARGBToUVRow_C;
} }
#endif
for (int y = 0; y < (height - 1); y += 2) { for (int y = 0; y < height - 1; y += 2) {
RGB24ToARGBRow(src_frame, row, width); RGB24ToARGBRow(src_rgb24, row, width);
RGB24ToARGBRow(src_frame + src_stride_frame, row + kMaxStride, width); RGB24ToARGBRow(src_rgb24 + src_stride_rgb24, row + kMaxStride, width);
ARGBToUVRow(row, kMaxStride, dst_u, dst_v, width); ARGBToUVRow(row, kMaxStride, dst_u, dst_v, width);
ARGBToYRow(row, dst_y, width); ARGBToYRow(row, dst_y, width);
ARGBToYRow(row + kMaxStride, dst_y + dst_stride_y, width); ARGBToYRow(row + kMaxStride, dst_y + dst_stride_y, width);
src_frame += src_stride_frame * 2; src_rgb24 += src_stride_rgb24 * 2;
dst_y += dst_stride_y * 2; dst_y += dst_stride_y * 2;
dst_u += dst_stride_u; dst_u += dst_stride_u;
dst_v += dst_stride_v; dst_v += dst_stride_v;
} }
if (height & 1) { if (height & 1) {
RGB24ToARGBRow(src_frame, row, width); RGB24ToARGBRow_C(src_rgb24, row, width);
ARGBToUVRow(row, 0, dst_u, dst_v, width); ARGBToUVRow(row, 0, dst_u, dst_v, width);
ARGBToYRow(row, dst_y, width); ARGBToYRow(row, dst_y, width);
} }
return 0; return 0;
} }
int RAWToI420(const uint8* src_frame, int src_stride_frame, int RAWToI420(const uint8* src_raw, int src_stride_raw,
uint8* dst_y, int dst_stride_y, uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u, uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v, uint8* dst_v, int dst_stride_v,
int width, int height) { int width, int height) {
if (width * 4 > kMaxStride) { // row buffer is required
return -1;
}
if (height < 0) { if (height < 0) {
height = -height; height = -height;
src_frame = src_frame + (height - 1) * src_stride_frame; src_raw = src_raw + (height - 1) * src_stride_raw;
src_stride_frame = -src_stride_frame; src_stride_raw = -src_stride_raw;
} }
SIMD_ALIGNED(uint8 row[kMaxStride * 2]); SIMD_ALIGNED(uint8 row[kMaxStride * 2]);
void (*RAWToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix); void (*RAWToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix);
RAWToARGBRow = RAWToARGBRow_C;
#if defined(HAS_RAWTOARGBROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) &&
TestReadSafe(src_raw, src_stride_raw, width, height, 3, 48)) {
RAWToARGBRow = RAWToARGBRow_SSSE3;
}
#endif
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix); void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix);
void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width); uint8* dst_u, uint8* dst_v, int width);
#if defined(HAS_RAWTOARGBROW_SSSE3)
ARGBToYRow = ARGBToYRow_C;
ARGBToUVRow = ARGBToUVRow_C;
#if defined(HAS_ARGBTOYROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) { if (TestCpuFlag(kCpuHasSSSE3)) {
RAWToARGBRow = RAWToARGBRow_SSSE3; if (IS_ALIGNED(width, 2)) {
} else ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
#endif
{
RAWToARGBRow = RAWToARGBRow_C;
} }
#if defined(HAS_ARGBTOYROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 16) &&
IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
ARGBToYRow = ARGBToYRow_SSSE3;
} else if (TestCpuFlag(kCpuHasSSSE3) && width <= kMaxStride) {
ARGBToYRow = ARGBToYRow_Any_SSSE3; ARGBToYRow = ARGBToYRow_Any_SSSE3;
if (IS_ALIGNED(width, 16)) { if (IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_SSSE3;
ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; ARGBToYRow = ARGBToYRow_Unaligned_SSSE3;
if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
ARGBToYRow = ARGBToYRow_SSSE3;
} }
} else
#endif
{
ARGBToYRow = ARGBToYRow_C;
} }
#if defined(HAS_ARGBTOUVROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_SSSE3;
} else if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 2) && width <= kMaxStride) {
ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
} else
#endif
{
ARGBToUVRow = ARGBToUVRow_C;
} }
#endif
for (int y = 0; y < (height - 1); y += 2) { for (int y = 0; y < height - 1; y += 2) {
RAWToARGBRow(src_frame, row, width); RAWToARGBRow(src_raw, row, width);
RAWToARGBRow(src_frame + src_stride_frame, row + kMaxStride, width); RAWToARGBRow(src_raw + src_stride_raw, row + kMaxStride, width);
ARGBToUVRow(row, kMaxStride, dst_u, dst_v, width); ARGBToUVRow(row, kMaxStride, dst_u, dst_v, width);
ARGBToYRow(row, dst_y, width); ARGBToYRow(row, dst_y, width);
ARGBToYRow(row + kMaxStride, dst_y + dst_stride_y, width); ARGBToYRow(row + kMaxStride, dst_y + dst_stride_y, width);
src_frame += src_stride_frame * 2; src_raw += src_stride_raw * 2;
dst_y += dst_stride_y * 2; dst_y += dst_stride_y * 2;
dst_u += dst_stride_u; dst_u += dst_stride_u;
dst_v += dst_stride_v; dst_v += dst_stride_v;
} }
if (height & 1) { if (height & 1) {
RAWToARGBRow(src_frame, row, width); RAWToARGBRow_C(src_raw, row, width);
ARGBToUVRow(row, 0, dst_u, dst_v, width); ARGBToUVRow(row, 0, dst_u, dst_v, width);
ARGBToYRow(row, dst_y, width); ARGBToYRow(row, dst_y, width);
} }
return 0; return 0;
} }
int RGB565ToI420(const uint8* src_frame, int src_stride_frame, int RGB565ToI420(const uint8* src_rgb565, int src_stride_rgb565,
uint8* dst_y, int dst_stride_y, uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u, uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v, uint8* dst_v, int dst_stride_v,
int width, int height) { int width, int height) {
if (width * 4 > kMaxStride) { // row buffer is required
return -1;
}
if (height < 0) { if (height < 0) {
height = -height; height = -height;
src_frame = src_frame + (height - 1) * src_stride_frame; src_rgb565 = src_rgb565 + (height - 1) * src_stride_rgb565;
src_stride_frame = -src_stride_frame; src_stride_rgb565 = -src_stride_rgb565;
} }
SIMD_ALIGNED(uint8 row[kMaxStride * 2]); SIMD_ALIGNED(uint8 row[kMaxStride * 2]);
void (*RGB565ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix); void (*RGB565ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix);
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix);
void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, RGB565ToARGBRow = RGB565ToARGBRow_C;
uint8* dst_u, uint8* dst_v, int width);
#if defined(HAS_RGB565TOARGBROW_SSE2) #if defined(HAS_RGB565TOARGBROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) { if (TestCpuFlag(kCpuHasSSE2) &&
TestReadSafe(src_rgb565, src_stride_rgb565, width, height, 2, 16)) {
RGB565ToARGBRow = RGB565ToARGBRow_SSE2; RGB565ToARGBRow = RGB565ToARGBRow_SSE2;
} else
#endif
{
RGB565ToARGBRow = RGB565ToARGBRow_C;
} }
#endif
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix);
void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width);
ARGBToYRow = ARGBToYRow_C;
ARGBToUVRow = ARGBToUVRow_C;
#if defined(HAS_ARGBTOYROW_SSSE3) #if defined(HAS_ARGBTOYROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && if (TestCpuFlag(kCpuHasSSSE3)) {
IS_ALIGNED(width, 16) && if (IS_ALIGNED(width, 2)) {
IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
ARGBToYRow = ARGBToYRow_SSSE3; }
} else if (TestCpuFlag(kCpuHasSSSE3) && width <= kMaxStride) {
ARGBToYRow = ARGBToYRow_Any_SSSE3; ARGBToYRow = ARGBToYRow_Any_SSSE3;
if (IS_ALIGNED(width, 16)) { if (IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_SSSE3;
ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; ARGBToYRow = ARGBToYRow_Unaligned_SSSE3;
if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
ARGBToYRow = ARGBToYRow_SSSE3;
} }
} else
#endif
{
ARGBToYRow = ARGBToYRow_C;
} }
#if defined(HAS_ARGBTOUVROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_SSSE3;
} else if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 2) && width <= kMaxStride) {
ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
} else
#endif
{
ARGBToUVRow = ARGBToUVRow_C;
} }
#endif
for (int y = 0; y < (height - 1); y += 2) { for (int y = 0; y < height - 1; y += 2) {
RGB565ToARGBRow(src_frame, row, width); RGB565ToARGBRow(src_rgb565, row, width);
RGB565ToARGBRow(src_frame + src_stride_frame, row + kMaxStride, width); RGB565ToARGBRow(src_rgb565 + src_stride_rgb565, row + kMaxStride, width);
ARGBToUVRow(row, kMaxStride, dst_u, dst_v, width); ARGBToUVRow(row, kMaxStride, dst_u, dst_v, width);
ARGBToYRow(row, dst_y, width); ARGBToYRow(row, dst_y, width);
ARGBToYRow(row + kMaxStride, dst_y + dst_stride_y, width); ARGBToYRow(row + kMaxStride, dst_y + dst_stride_y, width);
src_frame += src_stride_frame * 2; src_rgb565 += src_stride_rgb565 * 2;
dst_y += dst_stride_y * 2; dst_y += dst_stride_y * 2;
dst_u += dst_stride_u; dst_u += dst_stride_u;
dst_v += dst_stride_v; dst_v += dst_stride_v;
} }
if (height & 1) { if (height & 1) {
RGB565ToARGBRow(src_frame, row, width); RGB565ToARGBRow_C(src_rgb565, row, width);
ARGBToUVRow(row, 0, dst_u, dst_v, width); ARGBToUVRow(row, 0, dst_u, dst_v, width);
ARGBToYRow(row, dst_y, width); ARGBToYRow(row, dst_y, width);
} }
return 0; return 0;
} }
int ARGB1555ToI420(const uint8* src_frame, int src_stride_frame, int ARGB1555ToI420(const uint8* src_argb1555, int src_stride_argb1555,
uint8* dst_y, int dst_stride_y, uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u, uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v, uint8* dst_v, int dst_stride_v,
int width, int height) { int width, int height) {
if (width * 4 > kMaxStride) { // row buffer is required
return -1;
}
if (height < 0) { if (height < 0) {
height = -height; height = -height;
src_frame = src_frame + (height - 1) * src_stride_frame; src_argb1555 = src_argb1555 + (height - 1) * src_stride_argb1555;
src_stride_frame = -src_stride_frame; src_stride_argb1555 = -src_stride_argb1555;
} }
SIMD_ALIGNED(uint8 row[kMaxStride * 2]); SIMD_ALIGNED(uint8 row[kMaxStride * 2]);
void (*ARGB1555ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix); void (*ARGB1555ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix);
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix);
void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, ARGB1555ToARGBRow = ARGB1555ToARGBRow_C;
uint8* dst_u, uint8* dst_v, int width);
#if defined(HAS_ARGB1555TOARGBROW_SSE2) #if defined(HAS_ARGB1555TOARGBROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) { if (TestCpuFlag(kCpuHasSSE2) &&
TestReadSafe(src_argb1555, src_stride_argb1555, width, height, 2, 16)) {
ARGB1555ToARGBRow = ARGB1555ToARGBRow_SSE2; ARGB1555ToARGBRow = ARGB1555ToARGBRow_SSE2;
} else
#endif
{
ARGB1555ToARGBRow = ARGB1555ToARGBRow_C;
} }
#endif
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix);
void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width);
ARGBToYRow = ARGBToYRow_C;
ARGBToUVRow = ARGBToUVRow_C;
#if defined(HAS_ARGBTOYROW_SSSE3) #if defined(HAS_ARGBTOYROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && if (TestCpuFlag(kCpuHasSSSE3)) {
IS_ALIGNED(width, 16) && if (IS_ALIGNED(width, 2)) {
IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
ARGBToYRow = ARGBToYRow_SSSE3; }
} else if (TestCpuFlag(kCpuHasSSSE3) && width <= kMaxStride) {
ARGBToYRow = ARGBToYRow_Any_SSSE3; ARGBToYRow = ARGBToYRow_Any_SSSE3;
if (IS_ALIGNED(width, 16)) { if (IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_SSSE3;
ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; ARGBToYRow = ARGBToYRow_Unaligned_SSSE3;
if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
ARGBToYRow = ARGBToYRow_SSSE3;
} }
} else
#endif
{
ARGBToYRow = ARGBToYRow_C;
} }
#if defined(HAS_ARGBTOUVROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_SSSE3;
} else if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 2) && width <= kMaxStride) {
ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
} else
#endif
{
ARGBToUVRow = ARGBToUVRow_C;
} }
#endif
for (int y = 0; y < (height - 1); y += 2) { for (int y = 0; y < height - 1; y += 2) {
ARGB1555ToARGBRow(src_frame, row, width); ARGB1555ToARGBRow(src_argb1555, row, width);
ARGB1555ToARGBRow(src_frame + src_stride_frame, row + kMaxStride, width); ARGB1555ToARGBRow(src_argb1555 + src_stride_argb1555,
row + kMaxStride, width);
ARGBToUVRow(row, kMaxStride, dst_u, dst_v, width); ARGBToUVRow(row, kMaxStride, dst_u, dst_v, width);
ARGBToYRow(row, dst_y, width); ARGBToYRow(row, dst_y, width);
ARGBToYRow(row + kMaxStride, dst_y + dst_stride_y, width); ARGBToYRow(row + kMaxStride, dst_y + dst_stride_y, width);
src_frame += src_stride_frame * 2; src_argb1555 += src_stride_argb1555 * 2;
dst_y += dst_stride_y * 2; dst_y += dst_stride_y * 2;
dst_u += dst_stride_u; dst_u += dst_stride_u;
dst_v += dst_stride_v; dst_v += dst_stride_v;
} }
if (height & 1) { if (height & 1) {
ARGB1555ToARGBRow(src_frame, row, width); ARGB1555ToARGBRow_C(src_argb1555, row, width);
ARGBToUVRow(row, 0, dst_u, dst_v, width); ARGBToUVRow(row, 0, dst_u, dst_v, width);
ARGBToYRow(row, dst_y, width); ARGBToYRow(row, dst_y, width);
} }
return 0; return 0;
} }
int ARGB4444ToI420(const uint8* src_frame, int src_stride_frame, int ARGB4444ToI420(const uint8* src_argb4444, int src_stride_argb4444,
uint8* dst_y, int dst_stride_y, uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u, uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v, uint8* dst_v, int dst_stride_v,
int width, int height) { int width, int height) {
if (width * 4 > kMaxStride) { // row buffer is required
return -1;
}
if (height < 0) { if (height < 0) {
height = -height; height = -height;
src_frame = src_frame + (height - 1) * src_stride_frame; src_argb4444 = src_argb4444 + (height - 1) * src_stride_argb4444;
src_stride_frame = -src_stride_frame; src_stride_argb4444 = -src_stride_argb4444;
} }
SIMD_ALIGNED(uint8 row[kMaxStride * 2]); SIMD_ALIGNED(uint8 row[kMaxStride * 2]);
void (*ARGB4444ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix); void (*ARGB4444ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix);
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix);
void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, ARGB4444ToARGBRow = ARGB4444ToARGBRow_C;
uint8* dst_u, uint8* dst_v, int width);
#if defined(HAS_ARGB4444TOARGBROW_SSE2) #if defined(HAS_ARGB4444TOARGBROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) { if (TestCpuFlag(kCpuHasSSE2) &&
TestReadSafe(src_argb4444, src_stride_argb4444, width, height, 2, 16)) {
ARGB4444ToARGBRow = ARGB4444ToARGBRow_SSE2; ARGB4444ToARGBRow = ARGB4444ToARGBRow_SSE2;
} else
#endif
{
ARGB4444ToARGBRow = ARGB4444ToARGBRow_C;
} }
#endif
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix);
void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width);
ARGBToYRow = ARGBToYRow_C;
ARGBToUVRow = ARGBToUVRow_C;
#if defined(HAS_ARGBTOYROW_SSSE3) #if defined(HAS_ARGBTOYROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && if (TestCpuFlag(kCpuHasSSSE3)) {
IS_ALIGNED(width, 16) && if (IS_ALIGNED(width, 2)) {
IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
ARGBToYRow = ARGBToYRow_SSSE3; }
} else if (TestCpuFlag(kCpuHasSSSE3) && width <= kMaxStride) {
ARGBToYRow = ARGBToYRow_Any_SSSE3; ARGBToYRow = ARGBToYRow_Any_SSSE3;
if (IS_ALIGNED(width, 16)) { if (IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_SSSE3;
ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; ARGBToYRow = ARGBToYRow_Unaligned_SSSE3;
if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
ARGBToYRow = ARGBToYRow_SSSE3;
} }
} else
#endif
{
ARGBToYRow = ARGBToYRow_C;
} }
#if defined(HAS_ARGBTOUVROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_SSSE3;
} else if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 2) && width <= kMaxStride) {
ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
} else
#endif
{
ARGBToUVRow = ARGBToUVRow_C;
} }
#endif
for (int y = 0; y < (height - 1); y += 2) { for (int y = 0; y < height - 1; y += 2) {
ARGB4444ToARGBRow(src_frame, row, width); ARGB4444ToARGBRow(src_argb4444, row, width);
ARGB4444ToARGBRow(src_frame + src_stride_frame, row + kMaxStride, width); ARGB4444ToARGBRow(src_argb4444 + src_stride_argb4444,
row + kMaxStride, width);
ARGBToUVRow(row, kMaxStride, dst_u, dst_v, width); ARGBToUVRow(row, kMaxStride, dst_u, dst_v, width);
ARGBToYRow(row, dst_y, width); ARGBToYRow(row, dst_y, width);
ARGBToYRow(row + kMaxStride, dst_y + dst_stride_y, width); ARGBToYRow(row + kMaxStride, dst_y + dst_stride_y, width);
src_frame += src_stride_frame * 2; src_argb4444 += src_stride_argb4444 * 2;
dst_y += dst_stride_y * 2; dst_y += dst_stride_y * 2;
dst_u += dst_stride_u; dst_u += dst_stride_u;
dst_v += dst_stride_v; dst_v += dst_stride_v;
} }
if (height & 1) { if (height & 1) {
ARGB4444ToARGBRow(src_frame, row, width); ARGB4444ToARGBRow_C(src_argb4444, row, width);
ARGBToUVRow(row, 0, dst_u, dst_v, width); ARGBToUVRow(row, 0, dst_u, dst_v, width);
ARGBToYRow(row, dst_y, width); ARGBToYRow(row, dst_y, width);
} }
......
...@@ -928,110 +928,6 @@ int Q420ToI420(const uint8* src_y, int src_stride_y, ...@@ -928,110 +928,6 @@ int Q420ToI420(const uint8* src_y, int src_stride_y,
return 0; return 0;
} }
// Convert YUY2 to I420.
int YUY2ToI420(const uint8* src_yuy2, int src_stride_yuy2,
uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height) {
// Negative height means invert the image.
if (height < 0) {
height = -height;
src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2;
src_stride_yuy2 = -src_stride_yuy2;
}
void (*YUY2ToUVRow)(const uint8* src_yuy2, int src_stride_yuy2,
uint8* dst_u, uint8* dst_v, int pix);
void (*YUY2ToYRow)(const uint8* src_yuy2,
uint8* dst_y, int pix);
YUY2ToYRow = YUY2ToYRow_C;
YUY2ToUVRow = YUY2ToUVRow_C;
#if defined(HAS_YUY2TOI420ROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
if (width <= kMaxStride) {
YUY2ToUVRow = YUY2ToUVRow_Any_SSE2;
YUY2ToYRow = YUY2ToYRow_Any_SSE2;
}
if (IS_ALIGNED(width, 16)) {
YUY2ToUVRow = YUY2ToUVRow_Unaligned_SSE2;
YUY2ToYRow = YUY2ToYRow_Unaligned_SSE2;
if (IS_ALIGNED(src_yuy2, 16) && IS_ALIGNED(src_stride_yuy2, 16)) {
YUY2ToUVRow = YUY2ToUVRow_SSE2;
if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
YUY2ToYRow = YUY2ToYRow_SSE2;
}
}
}
}
#endif
for (int y = 0; y < height - 1; y += 2) {
YUY2ToUVRow(src_yuy2, src_stride_yuy2, dst_u, dst_v, width);
YUY2ToYRow(src_yuy2, dst_y, width);
YUY2ToYRow(src_yuy2 + src_stride_yuy2, dst_y + dst_stride_y, width);
src_yuy2 += src_stride_yuy2 * 2;
dst_y += dst_stride_y * 2;
dst_u += dst_stride_u;
dst_v += dst_stride_v;
}
if (height & 1) {
YUY2ToUVRow(src_yuy2, 0, dst_u, dst_v, width);
YUY2ToYRow(src_yuy2, dst_y, width);
}
return 0;
}
// Convert UYVY to I420.
int UYVYToI420(const uint8* src_uyvy, int src_stride_uyvy,
uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height) {
// Negative height means invert the image.
if (height < 0) {
height = -height;
src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy;
src_stride_uyvy = -src_stride_uyvy;
}
void (*UYVYToUVRow)(const uint8* src_uyvy, int src_stride_uyvy,
uint8* dst_u, uint8* dst_v, int pix);
void (*UYVYToYRow)(const uint8* src_uyvy,
uint8* dst_y, int pix);
UYVYToYRow = UYVYToYRow_C;
UYVYToUVRow = UYVYToUVRow_C;
#if defined(HAS_UYVYTOI420ROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
if (width <= kMaxStride) {
UYVYToUVRow = UYVYToUVRow_Any_SSE2;
UYVYToYRow = UYVYToYRow_Any_SSE2;
}
if (IS_ALIGNED(width, 16)) {
UYVYToUVRow = UYVYToUVRow_Unaligned_SSE2;
UYVYToYRow = UYVYToYRow_Unaligned_SSE2;
if (IS_ALIGNED(src_uyvy, 16) && IS_ALIGNED(src_stride_uyvy, 16)) {
UYVYToUVRow = UYVYToUVRow_SSE2;
if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
UYVYToYRow = UYVYToYRow_SSE2;
}
}
}
}
#endif
for (int y = 0; y < height - 1; y += 2) {
UYVYToUVRow(src_uyvy, src_stride_uyvy, dst_u, dst_v, width);
UYVYToYRow(src_uyvy, dst_y, width);
UYVYToYRow(src_uyvy + src_stride_uyvy, dst_y + dst_stride_y, width);
src_uyvy += src_stride_uyvy * 2;
dst_y += dst_stride_y * 2;
dst_u += dst_stride_u;
dst_v += dst_stride_v;
}
if (height & 1) {
UYVYToUVRow(src_uyvy, 0, dst_u, dst_v, width);
UYVYToYRow(src_uyvy, dst_y, width);
}
return 0;
}
// Convert I420 to ARGB. // Convert I420 to ARGB.
int I420ToARGB(const uint8* src_y, int src_stride_y, int I420ToARGB(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u, const uint8* src_u, int src_stride_u,
......
...@@ -46,8 +46,10 @@ extern "C" { ...@@ -46,8 +46,10 @@ extern "C" {
#define HAS_I444TOARGBROW_SSSE3 #define HAS_I444TOARGBROW_SSSE3
#define HAS_MIRRORROW_SSSE3 #define HAS_MIRRORROW_SSSE3
#define HAS_MIRRORROW_SSE2 #define HAS_MIRRORROW_SSE2
#define HAS_YUY2TOI420ROW_SSE2 #define HAS_YUY2TOYROW_SSE2
#define HAS_UYVYTOI420ROW_SSE2 #define HAS_UYVYTOYROW_SSE2
#define HAS_YUY2TOUVROW_SSE2
#define HAS_UYVYTOUVROW_SSE2
#endif #endif
// The following are available on Windows platforms // The following are available on Windows platforms
......
...@@ -839,7 +839,7 @@ void MirrorRow_SSE2(const uint8* src, uint8* dst, int width) { ...@@ -839,7 +839,7 @@ void MirrorRow_SSE2(const uint8* src, uint8* dst, int width) {
} }
#endif #endif
#ifdef HAS_YUY2TOI420ROW_SSE2 #ifdef HAS_YUY2TOYROW_SSE2
void YUY2ToYRow_SSE2(const uint8* src_yuy2, uint8* dst_y, int pix) { void YUY2ToYRow_SSE2(const uint8* src_yuy2, uint8* dst_y, int pix) {
asm volatile ( asm volatile (
"pcmpeqb %%xmm5,%%xmm5 \n" "pcmpeqb %%xmm5,%%xmm5 \n"
...@@ -1100,7 +1100,7 @@ void UYVYToUVRow_Unaligned_SSE2(const uint8* src_uyvy, int stride_uyvy, ...@@ -1100,7 +1100,7 @@ void UYVYToUVRow_Unaligned_SSE2(const uint8* src_uyvy, int stride_uyvy,
); );
} }
#endif // HAS_YUY2TOI420ROW_SSE2 #endif // HAS_YUY2TOYROW_SSE2
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
......
...@@ -1530,7 +1530,7 @@ __asm { ...@@ -1530,7 +1530,7 @@ __asm {
} }
#endif #endif
#ifdef HAS_YUY2TOI420ROW_SSE2 #ifdef HAS_YUY2TOYROW_SSE2
__declspec(naked) __declspec(naked)
void YUY2ToYRow_SSE2(const uint8* src_yuy2, void YUY2ToYRow_SSE2(const uint8* src_yuy2,
uint8* dst_y, int pix) { uint8* dst_y, int pix) {
...@@ -1798,7 +1798,7 @@ void UYVYToUVRow_Unaligned_SSE2(const uint8* src_uyvy, int stride_uyvy, ...@@ -1798,7 +1798,7 @@ void UYVYToUVRow_Unaligned_SSE2(const uint8* src_uyvy, int stride_uyvy,
ret ret
} }
} }
#endif // HAS_YUY2TOI420ROW_SSE2 #endif // HAS_YUY2TOYROW_SSE2
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment