mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-07 01:06:46 +08:00
yuy2tonv12
R=bcornell@google.com BUG=libyuv:466 Review URL: https://webrtc-codereview.appspot.com/51309004.
This commit is contained in:
parent
faa4b14f85
commit
ce98129951
@ -1,6 +1,6 @@
|
|||||||
Name: libyuv
|
Name: libyuv
|
||||||
URL: http://code.google.com/p/libyuv/
|
URL: http://code.google.com/p/libyuv/
|
||||||
Version: 1447
|
Version: 1448
|
||||||
License: BSD
|
License: BSD
|
||||||
License File: LICENSE
|
License File: LICENSE
|
||||||
|
|
||||||
|
|||||||
@ -85,6 +85,17 @@ int UYVYToI422(const uint8* src_uyvy, int src_stride_uyvy,
|
|||||||
uint8* dst_v, int dst_stride_v,
|
uint8* dst_v, int dst_stride_v,
|
||||||
int width, int height);
|
int width, int height);
|
||||||
|
|
||||||
|
LIBYUV_API
|
||||||
|
int YUY2ToNV12(const uint8* src_yuy2, int src_stride_yuy2,
|
||||||
|
uint8* dst_y, int dst_stride_y,
|
||||||
|
uint8* dst_uv, int dst_stride_uv,
|
||||||
|
int width, int height);
|
||||||
|
|
||||||
|
LIBYUV_API
|
||||||
|
int UYVYToNV12(const uint8* src_uyvy, int src_stride_uyvy,
|
||||||
|
uint8* dst_y, int dst_stride_y,
|
||||||
|
uint8* dst_uv, int dst_stride_uv,
|
||||||
|
int width, int height);
|
||||||
|
|
||||||
// Convert I420 to I400. (calls CopyPlane ignoring u/v).
|
// Convert I420 to I400. (calls CopyPlane ignoring u/v).
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
@ -436,12 +447,6 @@ int ARGBSobelXY(const uint8* src_argb, int src_stride_argb,
|
|||||||
uint8* dst_argb, int dst_stride_argb,
|
uint8* dst_argb, int dst_stride_argb,
|
||||||
int width, int height);
|
int width, int height);
|
||||||
|
|
||||||
LIBYUV_API
|
|
||||||
int UYVYToNV12(const uint8* src_uyvy, int src_stride_uyvy,
|
|
||||||
uint8* dst_y, int dst_stride_y,
|
|
||||||
uint8* dst_uv, int dst_stride_uv,
|
|
||||||
int width, int height);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
} // namespace libyuv
|
} // namespace libyuv
|
||||||
|
|||||||
@ -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 1447
|
#define LIBYUV_VERSION 1448
|
||||||
|
|
||||||
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
|
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
|
||||||
|
|||||||
@ -2341,7 +2341,110 @@ int ARGBCopyYToAlpha(const uint8* src_y, int src_stride_y,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(fbarchard): YUY2ToNV12
|
LIBYUV_API
|
||||||
|
int YUY2ToNV12(const uint8* src_yuy2, int src_stride_yuy2,
|
||||||
|
uint8* dst_y, int dst_stride_y,
|
||||||
|
uint8* dst_uv, int dst_stride_uv,
|
||||||
|
int width, int height) {
|
||||||
|
int y;
|
||||||
|
int halfwidth = (width + 1) >> 1;
|
||||||
|
void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int pix) =
|
||||||
|
SplitUVRow_C;
|
||||||
|
void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr,
|
||||||
|
ptrdiff_t src_stride, int dst_width,
|
||||||
|
int source_y_fraction) = InterpolateRow_C;
|
||||||
|
if (!src_yuy2 ||
|
||||||
|
!dst_y || !dst_uv ||
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
#if defined(HAS_SPLITUVROW_SSE2)
|
||||||
|
if (TestCpuFlag(kCpuHasSSE2)) {
|
||||||
|
SplitUVRow = SplitUVRow_Any_SSE2;
|
||||||
|
if (IS_ALIGNED(width, 16)) {
|
||||||
|
SplitUVRow = SplitUVRow_SSE2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(HAS_SPLITUVROW_AVX2)
|
||||||
|
if (TestCpuFlag(kCpuHasAVX2)) {
|
||||||
|
SplitUVRow = SplitUVRow_Any_AVX2;
|
||||||
|
if (IS_ALIGNED(width, 32)) {
|
||||||
|
SplitUVRow = SplitUVRow_AVX2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(HAS_SPLITUVROW_NEON)
|
||||||
|
if (TestCpuFlag(kCpuHasNEON)) {
|
||||||
|
SplitUVRow = SplitUVRow_Any_NEON;
|
||||||
|
if (IS_ALIGNED(width, 16)) {
|
||||||
|
SplitUVRow = SplitUVRow_NEON;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(HAS_INTERPOLATEROW_SSE2)
|
||||||
|
if (TestCpuFlag(kCpuHasSSE2)) {
|
||||||
|
InterpolateRow = InterpolateRow_Any_SSE2;
|
||||||
|
if (IS_ALIGNED(width, 16)) {
|
||||||
|
InterpolateRow = InterpolateRow_SSE2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(HAS_INTERPOLATEROW_SSSE3)
|
||||||
|
if (TestCpuFlag(kCpuHasSSSE3)) {
|
||||||
|
InterpolateRow = InterpolateRow_Any_SSSE3;
|
||||||
|
if (IS_ALIGNED(width, 16)) {
|
||||||
|
InterpolateRow = InterpolateRow_SSSE3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(HAS_INTERPOLATEROW_AVX2)
|
||||||
|
if (TestCpuFlag(kCpuHasAVX2)) {
|
||||||
|
InterpolateRow = InterpolateRow_Any_AVX2;
|
||||||
|
if (IS_ALIGNED(width, 32)) {
|
||||||
|
InterpolateRow = InterpolateRow_AVX2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(HAS_INTERPOLATEROW_NEON)
|
||||||
|
if (TestCpuFlag(kCpuHasNEON)) {
|
||||||
|
InterpolateRow = InterpolateRow_Any_NEON;
|
||||||
|
if (IS_ALIGNED(width, 16)) {
|
||||||
|
InterpolateRow = InterpolateRow_NEON;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{
|
||||||
|
int awidth = halfwidth * 2;
|
||||||
|
// 2 rows of uv
|
||||||
|
align_buffer_64(rows, awidth * 2);
|
||||||
|
|
||||||
|
for (y = 0; y < height - 1; y += 2) {
|
||||||
|
// Split Y from UV.
|
||||||
|
SplitUVRow(src_yuy2, dst_y, rows, awidth);
|
||||||
|
SplitUVRow(src_yuy2 + src_stride_yuy2, dst_y + dst_stride_y,
|
||||||
|
rows + awidth, awidth);
|
||||||
|
InterpolateRow(dst_uv, rows, awidth, awidth, 128);
|
||||||
|
src_yuy2 += src_stride_yuy2 * 2;
|
||||||
|
dst_y += dst_stride_y * 2;
|
||||||
|
dst_uv += dst_stride_uv;
|
||||||
|
}
|
||||||
|
if (height & 1) {
|
||||||
|
// Split Y from UV.
|
||||||
|
SplitUVRow(src_yuy2, dst_y, dst_uv, width);
|
||||||
|
}
|
||||||
|
free_aligned_buffer_64(rows);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
int UYVYToNV12(const uint8* src_uyvy, int src_stride_uyvy,
|
int UYVYToNV12(const uint8* src_uyvy, int src_stride_uyvy,
|
||||||
uint8* dst_y, int dst_stride_y,
|
uint8* dst_y, int dst_stride_y,
|
||||||
@ -2431,8 +2534,7 @@ int UYVYToNV12(const uint8* src_uyvy, int src_stride_uyvy,
|
|||||||
// Split Y from UV.
|
// Split Y from UV.
|
||||||
SplitUVRow(src_uyvy, rows, dst_y, awidth);
|
SplitUVRow(src_uyvy, rows, dst_y, awidth);
|
||||||
SplitUVRow(src_uyvy + src_stride_uyvy, rows + awidth,
|
SplitUVRow(src_uyvy + src_stride_uyvy, rows + awidth,
|
||||||
dst_y + dst_stride_y,
|
dst_y + dst_stride_y, awidth);
|
||||||
awidth);
|
|
||||||
InterpolateRow(dst_uv, rows, awidth, awidth, 128);
|
InterpolateRow(dst_uv, rows, awidth, awidth, 128);
|
||||||
src_uyvy += src_stride_uyvy * 2;
|
src_uyvy += src_stride_uyvy * 2;
|
||||||
dst_y += dst_stride_y * 2;
|
dst_y += dst_stride_y * 2;
|
||||||
|
|||||||
@ -796,6 +796,7 @@ TEST_F(libyuvTest, FMT_A##To##FMT_PLANAR##N) { \
|
|||||||
|
|
||||||
TESTATOBIPLANAR(ARGB, 4, NV12, 2, 2)
|
TESTATOBIPLANAR(ARGB, 4, NV12, 2, 2)
|
||||||
TESTATOBIPLANAR(ARGB, 4, NV21, 2, 2)
|
TESTATOBIPLANAR(ARGB, 4, NV21, 2, 2)
|
||||||
|
TESTATOBIPLANAR(YUY2, 2, NV12, 2, 2)
|
||||||
TESTATOBIPLANAR(UYVY, 2, NV12, 2, 2)
|
TESTATOBIPLANAR(UYVY, 2, NV12, 2, 2)
|
||||||
|
|
||||||
#define TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \
|
#define TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \
|
||||||
@ -1530,72 +1531,76 @@ TEST_F(libyuvTest, FMT_PLANAR##To##FMT_B##Dither##N) { \
|
|||||||
|
|
||||||
TESTPLANARTOBD(I420, 2, 2, RGB565, 2, 2, 1, 9, ARGB, 4)
|
TESTPLANARTOBD(I420, 2, 2, RGB565, 2, 2, 1, 9, ARGB, 4)
|
||||||
|
|
||||||
TEST_F(libyuvTest, TestUYVYToNV12) {
|
#define TESTPTOB(NAME, UYVYTOI420, UYVYTONV12) \
|
||||||
const int kWidth = benchmark_width_;
|
TEST_F(libyuvTest, NAME) { \
|
||||||
const int kHeight = benchmark_height_;
|
const int kWidth = benchmark_width_; \
|
||||||
|
const int kHeight = benchmark_height_; \
|
||||||
align_buffer_64(orig_uyvy,
|
\
|
||||||
2 * SUBSAMPLE(kWidth, 2) * kHeight);
|
align_buffer_64(orig_uyvy, \
|
||||||
align_buffer_64(orig_y, kWidth * kHeight);
|
2 * SUBSAMPLE(kWidth, 2) * kHeight); \
|
||||||
align_buffer_64(orig_u,
|
align_buffer_64(orig_y, kWidth * kHeight); \
|
||||||
SUBSAMPLE(kWidth, 2) *
|
align_buffer_64(orig_u, \
|
||||||
SUBSAMPLE(kHeight, 2));
|
SUBSAMPLE(kWidth, 2) * \
|
||||||
align_buffer_64(orig_v,
|
SUBSAMPLE(kHeight, 2)); \
|
||||||
SUBSAMPLE(kWidth, 2) *
|
align_buffer_64(orig_v, \
|
||||||
SUBSAMPLE(kHeight, 2));
|
SUBSAMPLE(kWidth, 2) * \
|
||||||
|
SUBSAMPLE(kHeight, 2)); \
|
||||||
align_buffer_64(dst_y_orig, kWidth * kHeight);
|
\
|
||||||
align_buffer_64(dst_uv_orig, 2 *
|
align_buffer_64(dst_y_orig, kWidth * kHeight); \
|
||||||
SUBSAMPLE(kWidth, 2) *
|
align_buffer_64(dst_uv_orig, 2 * \
|
||||||
SUBSAMPLE(kHeight, 2));
|
SUBSAMPLE(kWidth, 2) * \
|
||||||
|
SUBSAMPLE(kHeight, 2)); \
|
||||||
align_buffer_64(dst_y, kWidth * kHeight);
|
\
|
||||||
align_buffer_64(dst_uv, 2 *
|
align_buffer_64(dst_y, kWidth * kHeight); \
|
||||||
SUBSAMPLE(kWidth, 2) *
|
align_buffer_64(dst_uv, 2 * \
|
||||||
SUBSAMPLE(kHeight, 2));
|
SUBSAMPLE(kWidth, 2) * \
|
||||||
|
SUBSAMPLE(kHeight, 2)); \
|
||||||
srandom(time(NULL));
|
\
|
||||||
MemRandomize(orig_uyvy, 2 * SUBSAMPLE(kWidth, 2) * kHeight);
|
srandom(time(NULL)); \
|
||||||
|
MemRandomize(orig_uyvy, 2 * SUBSAMPLE(kWidth, 2) * kHeight); \
|
||||||
/* Convert UYVY to NV12 in 2 steps for reference */
|
\
|
||||||
libyuv::UYVYToI420(orig_uyvy, 2 * SUBSAMPLE(kWidth, 2),
|
/* Convert UYVY to NV12 in 2 steps for reference */ \
|
||||||
orig_y, kWidth,
|
libyuv::UYVYTOI420(orig_uyvy, 2 * SUBSAMPLE(kWidth, 2), \
|
||||||
orig_u, SUBSAMPLE(kWidth, 2),
|
orig_y, kWidth, \
|
||||||
orig_v, SUBSAMPLE(kWidth, 2),
|
orig_u, SUBSAMPLE(kWidth, 2), \
|
||||||
kWidth, kHeight);
|
orig_v, SUBSAMPLE(kWidth, 2), \
|
||||||
libyuv::I420ToNV12(orig_y, kWidth,
|
kWidth, kHeight); \
|
||||||
orig_u, SUBSAMPLE(kWidth, 2),
|
libyuv::I420ToNV12(orig_y, kWidth, \
|
||||||
orig_v, SUBSAMPLE(kWidth, 2),
|
orig_u, SUBSAMPLE(kWidth, 2), \
|
||||||
dst_y_orig, kWidth,
|
orig_v, SUBSAMPLE(kWidth, 2), \
|
||||||
dst_uv_orig, 2 * SUBSAMPLE(kWidth, 2),
|
dst_y_orig, kWidth, \
|
||||||
kWidth, kHeight);
|
dst_uv_orig, 2 * SUBSAMPLE(kWidth, 2), \
|
||||||
|
kWidth, kHeight); \
|
||||||
/* Convert to NV12 */
|
\
|
||||||
for (int i = 0; i < benchmark_iterations_; ++i) {
|
/* Convert to NV12 */ \
|
||||||
libyuv::UYVYToNV12(orig_uyvy, 2 * SUBSAMPLE(kWidth, 2),
|
for (int i = 0; i < benchmark_iterations_; ++i) { \
|
||||||
dst_y, kWidth,
|
libyuv::UYVYTONV12(orig_uyvy, 2 * SUBSAMPLE(kWidth, 2), \
|
||||||
dst_uv, 2 * SUBSAMPLE(kWidth, 2),
|
dst_y, kWidth, \
|
||||||
kWidth, kHeight);
|
dst_uv, 2 * SUBSAMPLE(kWidth, 2), \
|
||||||
}
|
kWidth, kHeight); \
|
||||||
|
} \
|
||||||
for (int i = 0; i < kWidth * kHeight; ++i) {
|
\
|
||||||
EXPECT_EQ(orig_y[i], dst_y[i]);
|
for (int i = 0; i < kWidth * kHeight; ++i) { \
|
||||||
}
|
EXPECT_EQ(orig_y[i], dst_y[i]); \
|
||||||
for (int i = 0; i < kWidth * kHeight; ++i) {
|
} \
|
||||||
EXPECT_EQ(dst_y_orig[i], dst_y[i]);
|
for (int i = 0; i < kWidth * kHeight; ++i) { \
|
||||||
}
|
EXPECT_EQ(dst_y_orig[i], dst_y[i]); \
|
||||||
for (int i = 0; i < 2 * SUBSAMPLE(kWidth, 2) * SUBSAMPLE(kHeight, 2); ++i) {
|
} \
|
||||||
EXPECT_EQ(dst_uv_orig[i], dst_uv[i]);
|
for (int i = 0; i < 2 * SUBSAMPLE(kWidth, 2) * SUBSAMPLE(kHeight, 2); ++i) { \
|
||||||
}
|
EXPECT_EQ(dst_uv_orig[i], dst_uv[i]); \
|
||||||
|
} \
|
||||||
free_aligned_buffer_64(orig_uyvy);
|
\
|
||||||
free_aligned_buffer_64(orig_y);
|
free_aligned_buffer_64(orig_uyvy); \
|
||||||
free_aligned_buffer_64(orig_u);
|
free_aligned_buffer_64(orig_y); \
|
||||||
free_aligned_buffer_64(orig_v);
|
free_aligned_buffer_64(orig_u); \
|
||||||
free_aligned_buffer_64(dst_y_orig);
|
free_aligned_buffer_64(orig_v); \
|
||||||
free_aligned_buffer_64(dst_uv_orig);
|
free_aligned_buffer_64(dst_y_orig); \
|
||||||
free_aligned_buffer_64(dst_y);
|
free_aligned_buffer_64(dst_uv_orig); \
|
||||||
free_aligned_buffer_64(dst_uv);
|
free_aligned_buffer_64(dst_y); \
|
||||||
|
free_aligned_buffer_64(dst_uv); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TESTPTOB(TestYUY2ToNV12, YUY2ToI420, YUY2ToNV12)
|
||||||
|
TESTPTOB(TestUYVYToNV12, UYVYToI420, UYVYToNV12)
|
||||||
|
|
||||||
} // namespace libyuv
|
} // namespace libyuv
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user