Add I412/I212 to I420 functions

They re-use the same method as I410/I210 to I420 with a depth
value of 12 instead of 10.

Bug: b/268505204
Change-Id: I299862b4556461d8c95f0fc1dcd5260e1c1f25cd
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/4581867
Commit-Queue: Vignesh Venkatasubramanian <vigneshv@google.com>
Reviewed-by: Frank Barchard <fbarchard@chromium.org>
This commit is contained in:
Vignesh Venkatasubramanian 2023-06-01 12:32:18 -07:00 committed by libyuv LUCI CQ
parent 1cd65f7865
commit c0f64c14ca
5 changed files with 178 additions and 63 deletions

View File

@ -1,6 +1,6 @@
Name: libyuv Name: libyuv
URL: http://code.google.com/p/libyuv/ URL: http://code.google.com/p/libyuv/
Version: 1869 Version: 1870
License: BSD License: BSD
License File: LICENSE License File: LICENSE

View File

@ -367,6 +367,23 @@ int I212ToI422(const uint16_t* src_y,
int width, int width,
int height); int height);
#define H212ToH420 I212ToI420
LIBYUV_API
int I212ToI420(const uint16_t* src_y,
int src_stride_y,
const uint16_t* src_u,
int src_stride_u,
const uint16_t* src_v,
int src_stride_v,
uint8_t* dst_y,
int dst_stride_y,
uint8_t* dst_u,
int dst_stride_u,
uint8_t* dst_v,
int dst_stride_v,
int width,
int height);
#define H412ToH444 I412ToI444 #define H412ToH444 I412ToI444
LIBYUV_API LIBYUV_API
int I412ToI444(const uint16_t* src_y, int I412ToI444(const uint16_t* src_y,
@ -384,6 +401,24 @@ int I412ToI444(const uint16_t* src_y,
int width, int width,
int height); int height);
#define H412ToH420 I412ToI420
LIBYUV_API
int I412ToI420(const uint16_t* src_y,
int src_stride_y,
const uint16_t* src_u,
int src_stride_u,
const uint16_t* src_v,
int src_stride_v,
uint8_t* dst_y,
int dst_stride_y,
uint8_t* dst_u,
int dst_stride_u,
uint8_t* dst_v,
int dst_stride_v,
int width,
int height);
#define I412ToI012 I410ToI010 #define I412ToI012 I410ToI010
#define H410ToH010 I410ToI010 #define H410ToH010 I410ToI010
#define H412ToH012 I410ToI010 #define H412ToH012 I410ToI010

View File

@ -11,6 +11,6 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_ #ifndef INCLUDE_LIBYUV_VERSION_H_
#define INCLUDE_LIBYUV_VERSION_H_ #define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 1869 #define LIBYUV_VERSION 1870
#endif // INCLUDE_LIBYUV_VERSION_H_ #endif // INCLUDE_LIBYUV_VERSION_H_

View File

@ -203,6 +203,99 @@ static int Planar16bitTo8bit(const uint16_t* src_y,
return 0; return 0;
} }
static int I41xToI420(const uint16_t* src_y,
int src_stride_y,
const uint16_t* src_u,
int src_stride_u,
const uint16_t* src_v,
int src_stride_v,
uint8_t* dst_y,
int dst_stride_y,
uint8_t* dst_u,
int dst_stride_u,
uint8_t* dst_v,
int dst_stride_v,
int width,
int height,
int depth) {
const int scale = 1 << (24 - depth);
if (width <= 0 || height == 0) {
return -1;
}
// Negative height means invert the image.
if (height < 0) {
height = -height;
src_y = src_y + (height - 1) * src_stride_y;
src_u = src_u + (height - 1) * src_stride_u;
src_v = src_v + (height - 1) * src_stride_v;
src_stride_y = -src_stride_y;
src_stride_u = -src_stride_u;
src_stride_v = -src_stride_v;
}
{
const int uv_width = SUBSAMPLE(width, 1, 1);
const int uv_height = SUBSAMPLE(height, 1, 1);
Convert16To8Plane(src_y, src_stride_y, dst_y, dst_stride_y, scale, width,
height);
ScalePlaneDown2_16To8(width, height, uv_width, uv_height, src_stride_u,
dst_stride_u, src_u, dst_u, scale, kFilterBilinear);
ScalePlaneDown2_16To8(width, height, uv_width, uv_height, src_stride_v,
dst_stride_v, src_v, dst_v, scale, kFilterBilinear);
}
return 0;
}
static int I21xToI420(const uint16_t* src_y,
int src_stride_y,
const uint16_t* src_u,
int src_stride_u,
const uint16_t* src_v,
int src_stride_v,
uint8_t* dst_y,
int dst_stride_y,
uint8_t* dst_u,
int dst_stride_u,
uint8_t* dst_v,
int dst_stride_v,
int width,
int height,
int depth) {
const int scale = 1 << (24 - depth);
if (width <= 0 || height == 0) {
return -1;
}
// Negative height means invert the image.
if (height < 0) {
height = -height;
src_y = src_y + (height - 1) * src_stride_y;
src_u = src_u + (height - 1) * src_stride_u;
src_v = src_v + (height - 1) * src_stride_v;
src_stride_y = -src_stride_y;
src_stride_u = -src_stride_u;
src_stride_v = -src_stride_v;
}
{
const int uv_width = SUBSAMPLE(width, 1, 1);
const int uv_height = SUBSAMPLE(height, 1, 1);
const int dy = FixedDiv(height, uv_height);
Convert16To8Plane(src_y, src_stride_y, dst_y, dst_stride_y, scale, width,
height);
ScalePlaneVertical_16To8(height, uv_width, uv_height, src_stride_u,
dst_stride_u, src_u, dst_u, 0, 32768, dy,
/*bpp=*/1, scale, kFilterBilinear);
ScalePlaneVertical_16To8(height, uv_width, uv_height, src_stride_v,
dst_stride_v, src_v, dst_v, 0, 32768, dy,
/*bpp=*/1, scale, kFilterBilinear);
}
return 0;
}
// Convert 10 bit YUV to 8 bit. // Convert 10 bit YUV to 8 bit.
LIBYUV_API LIBYUV_API
int I010ToI420(const uint16_t* src_y, int I010ToI420(const uint16_t* src_y,
@ -240,38 +333,9 @@ int I210ToI420(const uint16_t* src_y,
int dst_stride_v, int dst_stride_v,
int width, int width,
int height) { int height) {
const int depth = 10; return I21xToI420(src_y, src_stride_y, src_u, src_stride_u, src_v,
const int scale = 1 << (24 - depth); src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u,
dst_v, dst_stride_v, width, height, 10);
if (width <= 0 || height == 0) {
return -1;
}
// Negative height means invert the image.
if (height < 0) {
height = -height;
src_y = src_y + (height - 1) * src_stride_y;
src_u = src_u + (height - 1) * src_stride_u;
src_v = src_v + (height - 1) * src_stride_v;
src_stride_y = -src_stride_y;
src_stride_u = -src_stride_u;
src_stride_v = -src_stride_v;
}
{
const int uv_width = SUBSAMPLE(width, 1, 1);
const int uv_height = SUBSAMPLE(height, 1, 1);
const int dy = FixedDiv(height, uv_height);
Convert16To8Plane(src_y, src_stride_y, dst_y, dst_stride_y, scale, width,
height);
ScalePlaneVertical_16To8(height, uv_width, uv_height, src_stride_u,
dst_stride_u, src_u, dst_u, 0, 32768, dy,
/*bpp=*/1, scale, kFilterBilinear);
ScalePlaneVertical_16To8(height, uv_width, uv_height, src_stride_v,
dst_stride_v, src_v, dst_v, 0, 32768, dy,
/*bpp=*/1, scale, kFilterBilinear);
}
return 0;
} }
LIBYUV_API LIBYUV_API
@ -310,35 +374,9 @@ int I410ToI420(const uint16_t* src_y,
int dst_stride_v, int dst_stride_v,
int width, int width,
int height) { int height) {
const int depth = 10; return I41xToI420(src_y, src_stride_y, src_u, src_stride_u, src_v,
const int scale = 1 << (24 - depth); src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u,
dst_v, dst_stride_v, width, height, 10);
if (width <= 0 || height == 0) {
return -1;
}
// Negative height means invert the image.
if (height < 0) {
height = -height;
src_y = src_y + (height - 1) * src_stride_y;
src_u = src_u + (height - 1) * src_stride_u;
src_v = src_v + (height - 1) * src_stride_v;
src_stride_y = -src_stride_y;
src_stride_u = -src_stride_u;
src_stride_v = -src_stride_v;
}
{
const int uv_width = SUBSAMPLE(width, 1, 1);
const int uv_height = SUBSAMPLE(height, 1, 1);
Convert16To8Plane(src_y, src_stride_y, dst_y, dst_stride_y, scale, width,
height);
ScalePlaneDown2_16To8(width, height, uv_width, uv_height, src_stride_u,
dst_stride_u, src_u, dst_u, scale, kFilterBilinear);
ScalePlaneDown2_16To8(width, height, uv_width, uv_height, src_stride_v,
dst_stride_v, src_v, dst_v, scale, kFilterBilinear);
}
return 0;
} }
LIBYUV_API LIBYUV_API
@ -404,6 +442,26 @@ int I212ToI422(const uint16_t* src_y,
0, 12); 0, 12);
} }
LIBYUV_API
int I212ToI420(const uint16_t* src_y,
int src_stride_y,
const uint16_t* src_u,
int src_stride_u,
const uint16_t* src_v,
int src_stride_v,
uint8_t* dst_y,
int dst_stride_y,
uint8_t* dst_u,
int dst_stride_u,
uint8_t* dst_v,
int dst_stride_v,
int width,
int height) {
return I21xToI420(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u,
dst_v, dst_stride_v, width, height, 12);
}
LIBYUV_API LIBYUV_API
int I412ToI444(const uint16_t* src_y, int I412ToI444(const uint16_t* src_y,
int src_stride_y, int src_stride_y,
@ -425,6 +483,26 @@ int I412ToI444(const uint16_t* src_y,
0, 12); 0, 12);
} }
LIBYUV_API
int I412ToI420(const uint16_t* src_y,
int src_stride_y,
const uint16_t* src_u,
int src_stride_u,
const uint16_t* src_v,
int src_stride_v,
uint8_t* dst_y,
int dst_stride_y,
uint8_t* dst_u,
int dst_stride_u,
uint8_t* dst_v,
int dst_stride_v,
int width,
int height) {
return I41xToI420(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u,
dst_v, dst_stride_v, width, height, 12);
}
// Any Ix10 To I010 format with mirroring. // Any Ix10 To I010 format with mirroring.
static int Ix10ToI010(const uint16_t* src_y, static int Ix10ToI010(const uint16_t* src_y,
int src_stride_y, int src_stride_y,

View File

@ -184,7 +184,9 @@ TESTPLANARTOP(I210, uint16_t, 2, 2, 1, I422, uint8_t, 1, 2, 1, 10)
TESTPLANARTOP(I410, uint16_t, 2, 1, 1, I420, uint8_t, 1, 2, 2, 10) TESTPLANARTOP(I410, uint16_t, 2, 1, 1, I420, uint8_t, 1, 2, 2, 10)
TESTPLANARTOP(I410, uint16_t, 2, 1, 1, I444, uint8_t, 1, 1, 1, 10) TESTPLANARTOP(I410, uint16_t, 2, 1, 1, I444, uint8_t, 1, 1, 1, 10)
TESTPLANARTOP(I012, uint16_t, 2, 2, 2, I420, uint8_t, 1, 2, 2, 12) TESTPLANARTOP(I012, uint16_t, 2, 2, 2, I420, uint8_t, 1, 2, 2, 12)
TESTPLANARTOP(I212, uint16_t, 2, 2, 1, I420, uint8_t, 1, 2, 2, 12)
TESTPLANARTOP(I212, uint16_t, 2, 2, 1, I422, uint8_t, 1, 2, 1, 12) TESTPLANARTOP(I212, uint16_t, 2, 2, 1, I422, uint8_t, 1, 2, 1, 12)
TESTPLANARTOP(I412, uint16_t, 2, 1, 1, I420, uint8_t, 1, 2, 2, 12)
TESTPLANARTOP(I412, uint16_t, 2, 1, 1, I444, uint8_t, 1, 1, 1, 12) TESTPLANARTOP(I412, uint16_t, 2, 1, 1, I444, uint8_t, 1, 1, 1, 12)
// Test Android 420 to I420 // Test Android 420 to I420