Commit edd3a84d authored by Frank Barchard's avatar Frank Barchard

libyuv::YUY2ToY for isolating Y channel of YUY2.

This function is the first step of YUY2 To I420.
Provided primarily for diagnostics.

TBR=wangcheng@google.com
BUG=libyuv:647
TESTED=LibYUVConvertTest.YUY2ToY_Opt

Review URL: https://codereview.chromium.org/2399153004 .
parent a2891ec7
......@@ -111,6 +111,11 @@ int UYVYToNV12(const uint8* src_uyvy, int src_stride_uyvy,
uint8* dst_uv, int dst_stride_uv,
int width, int height);
LIBYUV_API
int YUY2ToY(const uint8* src_yuy2, int src_stride_yuy2,
uint8* dst_y, int dst_stride_y,
int width, int height);
// Convert I420 to I400. (calls CopyPlane ignoring u/v).
LIBYUV_API
int I420ToI400(const uint8* src_y, int src_stride_y,
......
......@@ -588,6 +588,71 @@ int UYVYToI422(const uint8* src_uyvy, int src_stride_uyvy,
return 0;
}
// Convert YUY2 to Y.
LIBYUV_API
int YUY2ToY(const uint8* src_yuy2, int src_stride_yuy2,
uint8* dst_y, int dst_stride_y,
int width, int height) {
int y;
void (*YUY2ToYRow)(const uint8* src_yuy2, uint8* dst_y, int width) =
YUY2ToYRow_C;
if (!src_yuy2 || !dst_y || width <= 0 || height == 0) {
return -1;
}
// 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;
}
// Coalesce rows.
if (src_stride_yuy2 == width * 2 &&
dst_stride_y == width) {
width *= height;
height = 1;
src_stride_yuy2 = dst_stride_y = 0;
}
#if defined(HAS_YUY2TOYROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
YUY2ToYRow = YUY2ToYRow_Any_SSE2;
if (IS_ALIGNED(width, 16)) {
YUY2ToYRow = YUY2ToYRow_SSE2;
}
}
#endif
#if defined(HAS_YUY2TOYROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
YUY2ToYRow = YUY2ToYRow_Any_AVX2;
if (IS_ALIGNED(width, 32)) {
YUY2ToYRow = YUY2ToYRow_AVX2;
}
}
#endif
#if defined(HAS_YUY2TOYROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
YUY2ToYRow = YUY2ToYRow_Any_NEON;
if (IS_ALIGNED(width, 16)) {
YUY2ToYRow = YUY2ToYRow_NEON;
}
}
#endif
#if defined(HAS_YUY2TOYROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
YUY2ToYRow = YUY2ToYRow_Any_MSA;
if (IS_ALIGNED(width, 32)) {
YUY2ToYRow = YUY2ToYRow_MSA;
}
}
#endif
for (y = 0; y < height; ++y) {
YUY2ToYRow(src_yuy2, dst_y, width);
src_yuy2 += src_stride_yuy2;
dst_y += dst_stride_y;
}
return 0;
}
// Mirror I400 with optional flipping
LIBYUV_API
int I400Mirror(const uint8* src_y, int src_stride_y,
......@@ -2699,6 +2764,7 @@ int ARGBCopyYToAlpha(const uint8* src_y, int src_stride_y,
return 0;
}
// TODO(fbarchard): Consider if width is even Y channel can be split
// directly. A SplitUVRow_Odd function could copy the remaining chroma.
......
......@@ -10,6 +10,8 @@
#include "libyuv/row.h"
#include <stdio.h>
#ifdef __cplusplus
namespace libyuv {
extern "C" {
......
......@@ -315,8 +315,6 @@ TEST_F(LibYUVConvertTest, SRC_FMT_PLANAR##To##FMT_PLANAR##_##PN##N) {\
TESTAPLANARTOP(Android420, I420, 1, 0, 0, 2, 2, I420, 2, 2)
TESTAPLANARTOP(Android420, NV12, 2, 0, 1, 2, 2, I420, 2, 2)
TESTAPLANARTOP(Android420, NV21, 2, 1, 0, 2, 2, I420, 2, 2)
// YUV3 causes msan failure. skip for now.
//TESTAPLANARTOP(Android420, YUV3, 3, 0, 1, 2, 2, I420, 2, 2)
#define TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF) \
......@@ -1139,6 +1137,7 @@ TESTATOB(ARGB1555, 2, 2, 1, ARGB, 4, 4, 1, 0)
TESTATOB(ARGB4444, 2, 2, 1, ARGB, 4, 4, 1, 0)
TESTATOB(YUY2, 2, 4, 1, ARGB, 4, 4, 1, 4)
TESTATOB(UYVY, 2, 4, 1, ARGB, 4, 4, 1, 4)
TESTATOB(YUY2, 2, 4, 1, Y, 1, 1, 1, 0)
TESTATOB(I400, 1, 1, 1, ARGB, 4, 4, 1, 0)
TESTATOB(J400, 1, 1, 1, ARGB, 4, 4, 1, 0)
TESTATOB(I400, 1, 1, 1, I400, 1, 1, 1, 0)
......
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