From 17d31e6a4a3134d6ffbee9c7ed4a30faac7d0b29 Mon Sep 17 00:00:00 2001 From: Frank Barchard Date: Tue, 23 Aug 2016 19:05:25 -0700 Subject: [PATCH] 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 . --- README.chromium | 2 +- docs/formats.md | 9 +++++++++ include/libyuv/version.h | 2 +- source/convert.cc | 4 ++-- unit_test/convert_test.cc | 36 +++++++++++++++++++++--------------- 5 files changed, 34 insertions(+), 19 deletions(-) diff --git a/README.chromium b/README.chromium index c16c71dfe..f68fdb4e5 100644 --- a/README.chromium +++ b/README.chromium @@ -1,6 +1,6 @@ Name: libyuv URL: http://code.google.com/p/libyuv/ -Version: 1612 +Version: 1613 License: BSD License File: LICENSE diff --git a/docs/formats.md b/docs/formats.md index a7cfed821..f3a35420f 100644 --- a/docs/formats.md +++ b/docs/formats.md @@ -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. 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 There are 4 ARGB layouts - ARGB, BGRA, ABGR and RGBA. ARGB is most common by far, used for screen formats, and windows webcam drivers. diff --git a/include/libyuv/version.h b/include/libyuv/version.h index e2223c720..d4c83e29a 100644 --- a/include/libyuv/version.h +++ b/include/libyuv/version.h @@ -11,6 +11,6 @@ #ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT #define INCLUDE_LIBYUV_VERSION_H_ -#define LIBYUV_VERSION 1612 +#define LIBYUV_VERSION 1613 #endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT diff --git a/source/convert.cc b/source/convert.cc index 08e5e5d67..d0896cfb6 100644 --- a/source/convert.cc +++ b/source/convert.cc @@ -44,6 +44,7 @@ static int I4xxToI420(const uint8* src_y, int src_stride_y, src_uv_width == 0 || src_uv_height == 0) { return -1; } + // TODO(fbarchard): make Y optional. ScalePlane(src_y, src_stride_y, src_y_width, src_y_height, dst_y, dst_stride_y, dst_y_width, dst_y_height, kFilterBilinear); @@ -313,8 +314,7 @@ static int X420ToI420(const uint8* src_y, int width, int height) { int halfwidth = (width + 1) >> 1; int halfheight = (height + 1) >> 1; - if (!src_y || !src_uv || - !dst_y || !dst_u || !dst_v || + if (!src_uv || !dst_u || !dst_v || width <= 0 || height == 0) { return -1; } diff --git a/unit_test/convert_test.cc b/unit_test/convert_test.cc index 6d8f60648..7542ddf44 100644 --- a/unit_test/convert_test.cc +++ b/unit_test/convert_test.cc @@ -427,7 +427,8 @@ TESTPLANARTOBP(I420, 2, 2, NV12, 2, 2) TESTPLANARTOBP(I420, 2, 2, NV21, 2, 2) #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) { \ const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ const int kHeight = benchmark_height_; \ @@ -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_uv + OFF, \ 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ - dst_y_c, kWidth, \ + DOY ? dst_y_c : NULL, kWidth, \ dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X), \ dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X), \ kWidth, NEG kHeight); \ @@ -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_uv + OFF, \ 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ - dst_y_opt, kWidth, \ + DOY ? dst_y_opt : NULL, kWidth, \ dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \ dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \ kWidth, NEG kHeight); \ } \ int max_diff = 0; \ - for (int i = 0; i < kHeight; ++i) { \ - for (int j = 0; j < kWidth; ++j) { \ - int abs_diff = \ - abs(static_cast(dst_y_c[i * kWidth + j]) - \ - static_cast(dst_y_opt[i * kWidth + j])); \ - if (abs_diff > max_diff) { \ - max_diff = abs_diff; \ + if (DOY) { \ + for (int i = 0; i < kHeight; ++i) { \ + for (int j = 0; j < kWidth; ++j) { \ + int abs_diff = \ + abs(static_cast(dst_y_c[i * kWidth + j]) - \ + static_cast(dst_y_opt[i * kWidth + j])); \ + 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 j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \ int abs_diff = \ @@ -537,16 +540,19 @@ TEST_F(LibYUVConvertTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \ FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \ TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_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, \ 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, \ 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, \ 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(NV21, 2, 2, I420, 2, 2)