Implement I010ToNV12 conversion
I010, also known as YUV420P10, is 10 bit YUV pixel format with 3 planes.
Both I010 and NV12 are 4:2:0 subsampling. NV12 has a Y plane, and an
interleaved UV plane.
Bug: 357721018
Change-Id: If215529b9eda8e0fb32aed666ca179c90244aaff
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/5764823
Reviewed-by: Frank Barchard <fbarchard@chromium.org>
diff --git a/include/libyuv/convert.h b/include/libyuv/convert.h
index 7802f59..5c7669b 100644
--- a/include/libyuv/convert.h
+++ b/include/libyuv/convert.h
@@ -525,6 +525,21 @@
int width,
int height);
+// Convert 10 bit YUV I010 to NV12
+LIBYUV_API
+int I010ToNV12(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_uv,
+ int dst_stride_uv,
+ int width,
+ int height);
+
// Convert I210 to P210
LIBYUV_API
int I210ToP210(const uint16_t* src_y,
diff --git a/source/convert.cc b/source/convert.cc
index 000d6fe..83f7806 100644
--- a/source/convert.cc
+++ b/source/convert.cc
@@ -646,6 +646,55 @@
}
LIBYUV_API
+int I010ToNV12(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_uv,
+ 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;
+ }
+
+ // 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;
+}
+
+LIBYUV_API
int I210ToP210(const uint16_t* src_y,
int src_stride_y,
const uint16_t* src_u,