Commit 17d31e6a authored by Frank Barchard's avatar Frank Barchard

NV12 allow NULL for Y

The conversion from NV12 and other Bi or Tri planar formats, differs only in the UV handling.  The helper function supports passing a NULL for the dst_y channel indicating you only want to do the UV conversion.

TBR=harryjin@google.com
TEST=LibYUVConvertTest.NV12ToI420_NullY (601 ms)
BUG=libyuv:626

Review URL: https://codereview.chromium.org/2276703002 .
parent d58297a2
Name: libyuv Name: libyuv
URL: http://code.google.com/p/libyuv/ URL: http://code.google.com/p/libyuv/
Version: 1612 Version: 1613
License: BSD License: BSD
License File: LICENSE License File: LICENSE
......
...@@ -102,6 +102,15 @@ The following is extracted from video_common.h as a complete list of formats sup ...@@ -102,6 +102,15 @@ The following is extracted from video_common.h as a complete list of formats sup
// 1 Auxiliary compressed YUV format set aside for capturer. // 1 Auxiliary compressed YUV format set aside for capturer.
FOURCC_H264 = FOURCC('H', '2', '6', '4'), FOURCC_H264 = FOURCC('H', '2', '6', '4'),
# Planar YUV
The following formats contains a full size Y plane followed by 1 or 2
planes for UV: I420, I422, I444, I411, I400, NV21, NV12, I400
The size (subsampling) of the UV varies.
I420, NV12 and NV21 are half width, half height
I422, NV16 and NV61 are half width, full height
I444, NV24 and NV42 are full width, full height
I400 and J400 have no chroma channel.
# The ARGB FOURCC # The ARGB FOURCC
There are 4 ARGB layouts - ARGB, BGRA, ABGR and RGBA. ARGB is most common by far, used for screen formats, and windows webcam drivers. There are 4 ARGB layouts - ARGB, BGRA, ABGR and RGBA. ARGB is most common by far, used for screen formats, and windows webcam drivers.
......
...@@ -11,6 +11,6 @@ ...@@ -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 1612 #define LIBYUV_VERSION 1613
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT #endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
...@@ -44,6 +44,7 @@ static int I4xxToI420(const uint8* src_y, int src_stride_y, ...@@ -44,6 +44,7 @@ static int I4xxToI420(const uint8* src_y, int src_stride_y,
src_uv_width == 0 || src_uv_height == 0) { src_uv_width == 0 || src_uv_height == 0) {
return -1; return -1;
} }
// TODO(fbarchard): make Y optional.
ScalePlane(src_y, src_stride_y, src_y_width, src_y_height, ScalePlane(src_y, src_stride_y, src_y_width, src_y_height,
dst_y, dst_stride_y, dst_y_width, dst_y_height, dst_y, dst_stride_y, dst_y_width, dst_y_height,
kFilterBilinear); kFilterBilinear);
...@@ -313,8 +314,7 @@ static int X420ToI420(const uint8* src_y, ...@@ -313,8 +314,7 @@ static int X420ToI420(const uint8* src_y,
int width, int height) { int width, int height) {
int halfwidth = (width + 1) >> 1; int halfwidth = (width + 1) >> 1;
int halfheight = (height + 1) >> 1; int halfheight = (height + 1) >> 1;
if (!src_y || !src_uv || if (!src_uv || !dst_u || !dst_v ||
!dst_y || !dst_u || !dst_v ||
width <= 0 || height == 0) { width <= 0 || height == 0) {
return -1; return -1;
} }
......
...@@ -427,7 +427,8 @@ TESTPLANARTOBP(I420, 2, 2, NV12, 2, 2) ...@@ -427,7 +427,8 @@ TESTPLANARTOBP(I420, 2, 2, NV12, 2, 2)
TESTPLANARTOBP(I420, 2, 2, NV21, 2, 2) TESTPLANARTOBP(I420, 2, 2, NV21, 2, 2)
#define TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ #define TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF) \ FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF, \
DOY) \
TEST_F(LibYUVConvertTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \ TEST_F(LibYUVConvertTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \
const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ const int kWidth = ((W1280) > 0) ? (W1280) : 1; \
const int kHeight = benchmark_height_; \ const int kHeight = benchmark_height_; \
...@@ -471,7 +472,7 @@ TEST_F(LibYUVConvertTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \ ...@@ -471,7 +472,7 @@ TEST_F(LibYUVConvertTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \
SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \ SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \
src_uv + OFF, \ src_uv + OFF, \
2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \
dst_y_c, kWidth, \ DOY ? dst_y_c : NULL, kWidth, \
dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X), \ dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X), \
dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X), \ dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X), \
kWidth, NEG kHeight); \ kWidth, NEG kHeight); \
...@@ -480,23 +481,25 @@ TEST_F(LibYUVConvertTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \ ...@@ -480,23 +481,25 @@ TEST_F(LibYUVConvertTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \
SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \ SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \
src_uv + OFF, \ src_uv + OFF, \
2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \
dst_y_opt, kWidth, \ DOY ? dst_y_opt : NULL, kWidth, \
dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \ dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \
dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \ dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \
kWidth, NEG kHeight); \ kWidth, NEG kHeight); \
} \ } \
int max_diff = 0; \ int max_diff = 0; \
for (int i = 0; i < kHeight; ++i) { \ if (DOY) { \
for (int j = 0; j < kWidth; ++j) { \ for (int i = 0; i < kHeight; ++i) { \
int abs_diff = \ for (int j = 0; j < kWidth; ++j) { \
abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \ int abs_diff = \
static_cast<int>(dst_y_opt[i * kWidth + j])); \ abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \
if (abs_diff > max_diff) { \ static_cast<int>(dst_y_opt[i * kWidth + j])); \
max_diff = abs_diff; \ if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \ } \
} \ } \
EXPECT_LE(max_diff, 1); \
} \ } \
EXPECT_LE(max_diff, 1); \
for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \ for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \
int abs_diff = \ int abs_diff = \
...@@ -537,16 +540,19 @@ TEST_F(LibYUVConvertTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \ ...@@ -537,16 +540,19 @@ TEST_F(LibYUVConvertTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \ FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
benchmark_width_ - 4, _Any, +, 0) \ benchmark_width_ - 4, _Any, +, 0, 1) \
TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
benchmark_width_, _Unaligned, +, 1) \ benchmark_width_, _Unaligned, +, 1, 1) \
TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
benchmark_width_, _Invert, -, 0) \ benchmark_width_, _Invert, -, 0, 1) \
TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
benchmark_width_, _Opt, +, 0) benchmark_width_, _Opt, +, 0, 1) \
TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
benchmark_width_, _NullY, +, 0, 0)
TESTBIPLANARTOP(NV12, 2, 2, I420, 2, 2) TESTBIPLANARTOP(NV12, 2, 2, I420, 2, 2)
TESTBIPLANARTOP(NV21, 2, 2, I420, 2, 2) TESTBIPLANARTOP(NV21, 2, 2, I420, 2, 2)
......
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