aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXin Li <delphij@google.com>2019-07-01 20:59:32 +0000
committerXin Li <delphij@google.com>2019-07-01 20:59:32 +0000
commit953aa50f56471dee0e5169f34acda4c82059b5fe (patch)
tree15421faf5c7b9194cc887ca4f063b3bad9d44226
parentd447e578c38b3edda95ac80901c03c7063880fcd (diff)
parent0a5d58014bee5deb2d0665c73f39bae7ea6ba29b (diff)
downloadlibyuv-953aa50f56471dee0e5169f34acda4c82059b5fe.tar.gz
DO NOT MERGE - Merge qt-dev-plus-aosp-without-vendor (5699924) into stage-aosp-mastertemp_140451723
Bug: 134405016 Change-Id: I8f1653c7e8f3f6f74acc3eca1d490e4575ad9e61
-rw-r--r--OWNERS1
-rw-r--r--files/include/libyuv/convert_argb.h54
-rw-r--r--files/source/convert_argb.cc216
-rw-r--r--files/unit_test/convert_test.cc2
4 files changed, 249 insertions, 24 deletions
diff --git a/OWNERS b/OWNERS
index be5f88c7..a607e727 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,3 +1,4 @@
fbarchard@google.com
phoglund@google.com
magjed@google.com
+chz@google.com
diff --git a/files/include/libyuv/convert_argb.h b/files/include/libyuv/convert_argb.h
index f43a5060..6bdfd95c 100644
--- a/files/include/libyuv/convert_argb.h
+++ b/files/include/libyuv/convert_argb.h
@@ -58,8 +58,8 @@ int I420ToABGR(const uint8* src_y,
int src_stride_u,
const uint8* src_v,
int src_stride_v,
- uint8* dst_argb,
- int dst_stride_argb,
+ uint8* dst_abgr,
+ int dst_stride_abgr,
int width,
int height);
@@ -190,6 +190,28 @@ int NV21ToARGB(const uint8* src_y,
int width,
int height);
+// Convert NV12 to ABGR.
+LIBYUV_API
+int NV12ToABGR(const uint8* src_y,
+ int src_stride_y,
+ const uint8* src_uv,
+ int src_stride_uv,
+ uint8* dst_abgr,
+ int dst_stride_abgr,
+ int width,
+ int height);
+
+// Convert NV21 to ABGR.
+LIBYUV_API
+int NV21ToABGR(const uint8* src_y,
+ int src_stride_y,
+ const uint8* src_uv,
+ int src_stride_uv,
+ uint8* dst_abgr,
+ int dst_stride_abgr,
+ int width,
+ int height);
+
// Convert M420 to ARGB.
LIBYUV_API
int M420ToARGB(const uint8* src_m420,
@@ -410,6 +432,34 @@ int MJPGToARGB(const uint8* sample,
int dst_height);
#endif
+// Convert Android420 to ARGB.
+LIBYUV_API
+int Android420ToARGB(const uint8* src_y,
+ int src_stride_y,
+ const uint8* src_u,
+ int src_stride_u,
+ const uint8* src_v,
+ int src_stride_v,
+ int src_pixel_stride_uv,
+ uint8* dst_argb,
+ int dst_stride_argb,
+ int width,
+ int height);
+
+// Convert Android420 to ABGR.
+LIBYUV_API
+int Android420ToABGR(const uint8* src_y,
+ int src_stride_y,
+ const uint8* src_u,
+ int src_stride_u,
+ const uint8* src_v,
+ int src_stride_v,
+ int src_pixel_stride_uv,
+ uint8* dst_abgr,
+ int dst_stride_abgr,
+ int width,
+ int height);
+
// Convert camera sample to ARGB with cropping, rotation and vertical flip.
// "src_size" is needed to parse MJPG.
// "dst_stride_argb" number of bytes in a row of the dst_argb plane.
diff --git a/files/source/convert_argb.cc b/files/source/convert_argb.cc
index 5007bdb9..983be578 100644
--- a/files/source/convert_argb.cc
+++ b/files/source/convert_argb.cc
@@ -1295,16 +1295,16 @@ int ARGB4444ToARGB(const uint8* src_argb4444,
return 0;
}
-// Convert NV12 to ARGB.
-LIBYUV_API
-int NV12ToARGB(const uint8* src_y,
- int src_stride_y,
- const uint8* src_uv,
- int src_stride_uv,
- uint8* dst_argb,
- int dst_stride_argb,
- int width,
- int height) {
+// Convert NV12 to ARGB with matrix
+static int NV12ToARGBMatrix(const uint8* src_y,
+ int src_stride_y,
+ const uint8* src_uv,
+ int src_stride_uv,
+ uint8* dst_argb,
+ int dst_stride_argb,
+ const struct YuvConstants* yuvconstants,
+ int width,
+ int height) {
int y;
void (*NV12ToARGBRow)(const uint8* y_buf, const uint8* uv_buf, uint8* rgb_buf,
const struct YuvConstants* yuvconstants, int width) =
@@ -1360,7 +1360,7 @@ int NV12ToARGB(const uint8* src_y,
#endif
for (y = 0; y < height; ++y) {
- NV12ToARGBRow(src_y, src_uv, dst_argb, &kYuvI601Constants, width);
+ NV12ToARGBRow(src_y, src_uv, dst_argb, yuvconstants, width);
dst_argb += dst_stride_argb;
src_y += src_stride_y;
if (y & 1) {
@@ -1370,16 +1370,16 @@ int NV12ToARGB(const uint8* src_y,
return 0;
}
-// Convert NV21 to ARGB.
-LIBYUV_API
-int NV21ToARGB(const uint8* src_y,
- int src_stride_y,
- const uint8* src_uv,
- int src_stride_uv,
- uint8* dst_argb,
- int dst_stride_argb,
- int width,
- int height) {
+// Convert NV21 to ARGB with matrix
+static int NV21ToARGBMatrix(const uint8* src_y,
+ int src_stride_y,
+ const uint8* src_uv,
+ int src_stride_uv,
+ uint8* dst_argb,
+ int dst_stride_argb,
+ const struct YuvConstants* yuvconstants,
+ int width,
+ int height) {
int y;
void (*NV21ToARGBRow)(const uint8* y_buf, const uint8* uv_buf, uint8* rgb_buf,
const struct YuvConstants* yuvconstants, int width) =
@@ -1427,7 +1427,7 @@ int NV21ToARGB(const uint8* src_y,
#endif
for (y = 0; y < height; ++y) {
- NV21ToARGBRow(src_y, src_uv, dst_argb, &kYuvI601Constants, width);
+ NV21ToARGBRow(src_y, src_uv, dst_argb, yuvconstants, width);
dst_argb += dst_stride_argb;
src_y += src_stride_y;
if (y & 1) {
@@ -1437,6 +1437,64 @@ int NV21ToARGB(const uint8* src_y,
return 0;
}
+// Convert NV12 to ARGB.
+LIBYUV_API
+int NV12ToARGB(const uint8* src_y,
+ int src_stride_y,
+ const uint8* src_uv,
+ int src_stride_uv,
+ uint8* dst_argb,
+ int dst_stride_argb,
+ int width,
+ int height) {
+ return NV12ToARGBMatrix(src_y, src_stride_y, src_uv, src_stride_uv, dst_argb,
+ dst_stride_argb, &kYuvI601Constants, width, height);
+}
+
+// Convert NV21 to ARGB.
+LIBYUV_API
+int NV21ToARGB(const uint8* src_y,
+ int src_stride_y,
+ const uint8* src_uv,
+ int src_stride_uv,
+ uint8* dst_argb,
+ int dst_stride_argb,
+ int width,
+ int height) {
+ return NV21ToARGBMatrix(src_y, src_stride_y, src_uv, src_stride_uv, dst_argb,
+ dst_stride_argb, &kYuvI601Constants, width, height);
+}
+
+// Convert NV12 to ABGR.
+// To output ABGR instead of ARGB swap the UV and use a mirrored yuv matrix.
+// To swap the UV use NV12 instead of NV21.LIBYUV_API
+LIBYUV_API
+int NV12ToABGR(const uint8* src_y,
+ int src_stride_y,
+ const uint8* src_uv,
+ int src_stride_uv,
+ uint8* dst_abgr,
+ int dst_stride_abgr,
+ int width,
+ int height) {
+ return NV21ToARGBMatrix(src_y, src_stride_y, src_uv, src_stride_uv, dst_abgr,
+ dst_stride_abgr, &kYvuI601Constants, width, height);
+}
+
+// Convert NV21 to ABGR.
+LIBYUV_API
+int NV21ToABGR(const uint8* src_y,
+ int src_stride_y,
+ const uint8* src_vu,
+ int src_stride_vu,
+ uint8* dst_abgr,
+ int dst_stride_abgr,
+ int width,
+ int height) {
+ return NV12ToARGBMatrix(src_y, src_stride_y, src_vu, src_stride_vu, dst_abgr,
+ dst_stride_abgr, &kYvuI601Constants, width, height);
+}
+
// Convert M420 to ARGB.
LIBYUV_API
int M420ToARGB(const uint8* src_m420,
@@ -1647,6 +1705,120 @@ int UYVYToARGB(const uint8* src_uyvy,
}
return 0;
}
+static void WeavePixels(const uint8* src_u,
+ const uint8* src_v,
+ int src_pixel_stride_uv,
+ uint8* dst_uv,
+ int width) {
+ int i;
+ for (i = 0; i < width; ++i) {
+ dst_uv[0] = *src_u;
+ dst_uv[1] = *src_v;
+ dst_uv += 2;
+ src_u += src_pixel_stride_uv;
+ src_v += src_pixel_stride_uv;
+ }
+}
+
+// Convert Android420 to ARGB.
+LIBYUV_API
+int Android420ToARGBMatrix(const uint8* src_y,
+ int src_stride_y,
+ const uint8* src_u,
+ int src_stride_u,
+ const uint8* src_v,
+ int src_stride_v,
+ int src_pixel_stride_uv,
+ uint8* dst_argb,
+ int dst_stride_argb,
+ const struct YuvConstants* yuvconstants,
+ int width,
+ int height) {
+ int y;
+ uint8* dst_uv;
+ const ptrdiff_t vu_off = src_v - src_u;
+ int halfwidth = (width + 1) >> 1;
+ int halfheight = (height + 1) >> 1;
+ if (!src_y || !src_u || !src_v || !dst_argb || width <= 0 || height == 0) {
+ return -1;
+ }
+ // Negative height means invert the image.
+ if (height < 0) {
+ height = -height;
+ halfheight = (height + 1) >> 1;
+ dst_argb = dst_argb + (height - 1) * dst_stride_argb;
+ dst_stride_argb = -dst_stride_argb;
+ }
+
+ // I420
+ if (src_pixel_stride_uv == 1) {
+ return I420ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
+ src_stride_v, dst_argb, dst_stride_argb,
+ yuvconstants, width, height);
+ // NV21
+ } else if (src_pixel_stride_uv == 2 && vu_off == -1 &&
+ src_stride_u == src_stride_v) {
+ return NV21ToARGBMatrix(src_y, src_stride_y, src_v, src_stride_v, dst_argb,
+ dst_stride_argb, yuvconstants, width, height);
+ // NV12
+ } else if (src_pixel_stride_uv == 2 && vu_off == 1 &&
+ src_stride_u == src_stride_v) {
+ return NV12ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, dst_argb,
+ dst_stride_argb, yuvconstants, width, height);
+ }
+
+ // General case fallback creates NV12
+ align_buffer_64(plane_uv, halfwidth * 2 * halfheight);
+ dst_uv = plane_uv;
+ for (y = 0; y < halfheight; ++y) {
+ WeavePixels(src_u, src_v, src_pixel_stride_uv, dst_uv, halfwidth);
+ src_u += src_stride_u;
+ src_v += src_stride_v;
+ dst_uv += halfwidth * 2;
+ }
+ NV12ToARGBMatrix(src_y, src_stride_y, plane_uv, halfwidth * 2, dst_argb,
+ dst_stride_argb, yuvconstants, width, height);
+ free_aligned_buffer_64(plane_uv);
+ return 0;
+}
+
+// Convert Android420 to ARGB.
+LIBYUV_API
+int Android420ToARGB(const uint8* src_y,
+ int src_stride_y,
+ const uint8* src_u,
+ int src_stride_u,
+ const uint8* src_v,
+ int src_stride_v,
+ int src_pixel_stride_uv,
+ uint8* dst_argb,
+ int dst_stride_argb,
+ int width,
+ int height) {
+ return Android420ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
+ src_stride_v, src_pixel_stride_uv, dst_argb,
+ dst_stride_argb, &kYuvI601Constants, width,
+ height);
+}
+
+// Convert Android420 to ABGR.
+LIBYUV_API
+int Android420ToABGR(const uint8* src_y,
+ int src_stride_y,
+ const uint8* src_u,
+ int src_stride_u,
+ const uint8* src_v,
+ int src_stride_v,
+ int src_pixel_stride_uv,
+ uint8* dst_abgr,
+ int dst_stride_abgr,
+ int width,
+ int height) {
+ return Android420ToARGBMatrix(src_y, src_stride_y, src_v, src_stride_v, src_u,
+ src_stride_u, src_pixel_stride_uv, dst_abgr,
+ dst_stride_abgr, &kYvuI601Constants, width,
+ height);
+}
#ifdef __cplusplus
} // extern "C"
diff --git a/files/unit_test/convert_test.cc b/files/unit_test/convert_test.cc
index 04d5a404..41564351 100644
--- a/files/unit_test/convert_test.cc
+++ b/files/unit_test/convert_test.cc
@@ -735,6 +735,8 @@ TESTQPLANARTOB(I420Alpha, 2, 2, ABGR, 4, 4, 1, 2)
TESTBIPLANARTOB(NV12, 2, 2, ARGB, 4, 2)
TESTBIPLANARTOB(NV21, 2, 2, ARGB, 4, 2)
+TESTBIPLANARTOB(NV12, 2, 2, ABGR, 4, 2)
+TESTBIPLANARTOB(NV21, 2, 2, ABGR, 4, 2)
TESTBIPLANARTOB(NV12, 2, 2, RGB565, 2, 9)
#ifdef DO_THREE_PLANES