From a97746349b244efd54ab1eb0c0a7366717b33f39 Mon Sep 17 00:00:00 2001 From: Frank Barchard Date: Mon, 12 Aug 2024 11:24:30 -0700 Subject: [PATCH] Add test for I010ToNV12 - Add support for negative height to invert - Fix off by 1 on odd width and height - Bump version to 1895 Initial I010 is 2 step planar conversion libyuv_test '--gunit_filter=*010ToNV12_Opt' --gunit_also_run_disabled_tests --libyuv_width=1280 --libyuv_height=720 --libyuv_repeat=1000 --libyuv_flags=-1 --libyuv_cpu_info=-1 Skylake Xeon [ OK ] LibYUVConvertTest.I010ToNV12_Opt (2675 ms) [ OK ] LibYUVConvertTest.P010ToNV12_Opt (1547 ms) Pixel 7 [ OK ] LibYUVConvertTest.I010ToNV12_Opt (464 ms) [ OK ] LibYUVConvertTest.P010ToNV12_Opt (125 ms) Bug: b/357721018, b/357439226 Change-Id: I2ae59783cf328a6592d0ab80c374ae4dc281daf3 Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/5778595 Reviewed-by: Wan-Teh Chang --- README.chromium | 2 +- include/libyuv/version.h | 2 +- source/convert.cc | 68 +++++++++++++++++++++------------------ unit_test/convert_test.cc | 1 + 4 files changed, 40 insertions(+), 33 deletions(-) diff --git a/README.chromium b/README.chromium index 40c02d73f..37db44160 100644 --- a/README.chromium +++ b/README.chromium @@ -1,6 +1,6 @@ Name: libyuv URL: https://chromium.googlesource.com/libyuv/libyuv/ -Version: 1894 +Version: 1895 License: BSD License File: LICENSE Shipped: yes diff --git a/include/libyuv/version.h b/include/libyuv/version.h index 5920422cc..c4b410a8a 100644 --- a/include/libyuv/version.h +++ b/include/libyuv/version.h @@ -11,6 +11,6 @@ #ifndef INCLUDE_LIBYUV_VERSION_H_ #define INCLUDE_LIBYUV_VERSION_H_ -#define LIBYUV_VERSION 1894 +#define LIBYUV_VERSION 1895 #endif // INCLUDE_LIBYUV_VERSION_H_ diff --git a/source/convert.cc b/source/convert.cc index 83f78064f..7c9f364bc 100644 --- a/source/convert.cc +++ b/source/convert.cc @@ -11,6 +11,7 @@ #include "libyuv/convert.h" #include "libyuv/basic_types.h" +#include "libyuv/convert_from.h" // For I420ToNV12() #include "libyuv/cpu_id.h" #include "libyuv/planar_functions.h" #include "libyuv/rotate.h" @@ -658,40 +659,45 @@ int I010ToNV12(const uint16_t* src_y, int dst_stride_uv, int width, int height) { + int r; + if (height < 0) { + height = -height; + int halfheight = (height + 1) >> 1; + src_y = src_y + (height - 1) * src_stride_y; + src_u = src_u + (halfheight - 1) * src_stride_u; + src_v = src_v + (halfheight - 1) * src_stride_v; + src_stride_y = -src_stride_y; + src_stride_u = -src_stride_u; + src_stride_v = -src_stride_v; + } + // Allocate temporary buffers for 3 planes in 8 bit. - uint8_t* temp_y = (uint8_t*)malloc(width * height); - uint8_t* temp_u = (uint8_t*)malloc((width / 2) * (height / 2)); - uint8_t* temp_v = (uint8_t*)malloc((width / 2) * (height / 2)); - int temp_stride_y = width; - int temp_stride_u = width / 2; - int temp_stride_v = width / 2; + { + align_buffer_64(temp_y, width * height); + align_buffer_64(temp_u, ((width + 1) / 2) * ((height + 1) / 2)); + align_buffer_64(temp_v, ((width + 1) / 2) * ((height + 1) / 2)); - // The first step is to convert 10 bit YUV I010 to 8 bit I420 with 3 planes. - if (I010ToI420(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, - temp_y, temp_stride_y, temp_u, temp_stride_u, temp_v, - temp_stride_v, width, height) == -1) { - free(temp_y); - free(temp_u); - free(temp_v); - return -1; + int temp_stride_y = width; + int temp_stride_u = (width + 1) / 2; + int temp_stride_v = (width + 1) / 2; + + // The first step is to convert 10 bit YUV I010 to 8 bit I420 with 3 planes. + r = I010ToI420(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, + temp_y, temp_stride_y, temp_u, temp_stride_u, temp_v, + temp_stride_v, width, height); + if (!r) { + // The second step is to convert 8 bit I420 with 3 planes to 8 bit NV12 with 2 planes. + r = I420ToNV12(temp_y, temp_stride_y, temp_u, temp_stride_u, temp_v, + temp_stride_v, dst_y, dst_stride_y, dst_uv, dst_stride_uv, + width, height); + } + + // Free temporary buffers. + free_aligned_buffer_64(temp_y); + free_aligned_buffer_64(temp_u); + free_aligned_buffer_64(temp_v); } - - // The second step is to convert 8 bit I420 with 3 planes to 8 bit NV12 with 2 planes. - if (I420ToNV12(temp_y, temp_stride_y, temp_u, temp_stride_u, temp_v, - temp_stride_v, dst_y, dst_stride_y, dst_uv, dst_stride_uv, - width, height) == -1) { - free(temp_y); - free(temp_u); - free(temp_v); - return -1; - } - - // Free temporary buffers. - free(temp_y); - free(temp_u); - free(temp_v); - - return 0; + return r; } LIBYUV_API diff --git a/unit_test/convert_test.cc b/unit_test/convert_test.cc index 13a42bc98..84b2e722c 100644 --- a/unit_test/convert_test.cc +++ b/unit_test/convert_test.cc @@ -452,6 +452,7 @@ TESTPLANARTOBP(I422, uint8_t, 1, 2, 1, NV21, uint8_t, 1, 2, 2, 8) TESTPLANARTOBP(I444, uint8_t, 1, 1, 1, NV12, uint8_t, 1, 2, 2, 8) TESTPLANARTOBP(I444, uint8_t, 1, 1, 1, NV21, uint8_t, 1, 2, 2, 8) TESTPLANARTOBP(I400, uint8_t, 1, 2, 2, NV21, uint8_t, 1, 2, 2, 8) +TESTPLANARTOBP(I010, uint16_t, 2, 2, 2, NV12, uint8_t, 1, 2, 2, 8) TESTPLANARTOBP(I010, uint16_t, 2, 2, 2, P010, uint16_t, 2, 2, 2, 10) TESTPLANARTOBP(I210, uint16_t, 2, 2, 1, P210, uint16_t, 2, 2, 1, 10) TESTPLANARTOBP(I012, uint16_t, 2, 2, 2, P012, uint16_t, 2, 2, 2, 12)