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 <wtc@google.com>
This commit is contained in:
Frank Barchard 2024-08-12 11:24:30 -07:00
parent 5045476744
commit a97746349b
4 changed files with 40 additions and 33 deletions

View File

@ -1,6 +1,6 @@
Name: libyuv
URL: https://chromium.googlesource.com/libyuv/libyuv/
Version: 1894
Version: 1895
License: BSD
License File: LICENSE
Shipped: yes

View File

@ -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_

View File

@ -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) {
// 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;
// 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 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.
{
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));
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.
if (I420ToNV12(temp_y, temp_stride_y, temp_u, temp_stride_u, temp_v,
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) == -1) {
free(temp_y);
free(temp_u);
free(temp_v);
return -1;
width, height);
}
// Free temporary buffers.
free(temp_y);
free(temp_u);
free(temp_v);
return 0;
free_aligned_buffer_64(temp_y);
free_aligned_buffer_64(temp_u);
free_aligned_buffer_64(temp_v);
}
return r;
}
LIBYUV_API

View File

@ -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)