---
The code has ben tested with qv4l2 and vivid.
v4lconvert_nv12_to_yuv420 has not been tested!!, any suggestions for
how to do it?
Thanks!
lib/libv4lconvert/libv4lconvert-priv.h | 6 +++
lib/libv4lconvert/libv4lconvert.c | 19 +++++++++
lib/libv4lconvert/rgbyuv.c | 56 ++++++++++++++++++++++++++
3 files changed, 81 insertions(+)
diff --git a/lib/libv4lconvert/libv4lconvert-priv.h b/lib/libv4lconvert/libv4lconvert-priv.h
index a8046ce2..c45b086e 100644
--- a/lib/libv4lconvert/libv4lconvert-priv.h
+++ b/lib/libv4lconvert/libv4lconvert-priv.h
@@ -285,6 +285,12 @@ void v4lconvert_hm12_to_yuv420(const unsigned char *src,
void v4lconvert_hsv_to_rgb24(const unsigned char *src, unsigned char *dest,
int width, int height, int bgr, int Xin, unsigned char hsv_enc);
+void v4lconvert_nv12_to_rgb24(const unsigned char *src, unsigned char *dest,
+ int width, int height, int bgr);
+
+void v4lconvert_nv12_to_yuv420(const unsigned char *src, unsigned char *dest,
+ int width, int height, int yvu);
+
void v4lconvert_rotate90(unsigned char *src, unsigned char *dest,
struct v4l2_format *fmt);
diff --git a/lib/libv4lconvert/libv4lconvert.c b/lib/libv4lconvert/libv4lconvert.c
index 78fb3432..2111d19f 100644
--- a/lib/libv4lconvert/libv4lconvert.c
+++ b/lib/libv4lconvert/libv4lconvert.c
@@ -116,6 +116,7 @@ static const struct v4lconvert_pixfmt supported_src_pixfmts[] = {
{ V4L2_PIX_FMT_SN9C20X_I420, 12, 6, 3, 1 },
{ V4L2_PIX_FMT_M420, 12, 6, 3, 1 },
{ V4L2_PIX_FMT_HM12, 12, 6, 3, 1 },
+ { V4L2_PIX_FMT_NV12, 12, 6, 3, 1 },
{ V4L2_PIX_FMT_CPIA1, 0, 6, 3, 1 },
/* JPEG and variants */
{ V4L2_PIX_FMT_MJPEG, 0, 7, 7, 0 },
@@ -902,6 +903,24 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data,
}
break;
+ /* NV12 formats */
+ case V4L2_PIX_FMT_NV12:
+ switch (dest_pix_fmt) {
+ case V4L2_PIX_FMT_RGB24:
+ v4lconvert_nv12_to_rgb24(src, dest, width, height, 0);
+ break;
+ case V4L2_PIX_FMT_BGR24:
+ v4lconvert_nv12_to_rgb24(src, dest, width, height, 1);
+ break;
+ case V4L2_PIX_FMT_YUV420:
+ v4lconvert_nv12_to_yuv420(src, dest, width, height, 0);
+ break;
+ case V4L2_PIX_FMT_YVU420:
+ v4lconvert_nv12_to_yuv420(src, dest, width, height, 1);
+ break;
+ }
+ break;
+
/* compressed bayer formats */
case V4L2_PIX_FMT_SPCA561:
case V4L2_PIX_FMT_SN9C10X:
diff --git a/lib/libv4lconvert/rgbyuv.c b/lib/libv4lconvert/rgbyuv.c
index 02c8cb5b..bfe3b15f 100644
--- a/lib/libv4lconvert/rgbyuv.c
+++ b/lib/libv4lconvert/rgbyuv.c
@@ -845,3 +845,59 @@ void v4lconvert_hsv_to_rgb24(const unsigned char *src, unsigned char *dest,
src += bppIN;
}
}
+
+void v4lconvert_nv12_to_rgb24(const unsigned char *src, unsigned char *dest,
+ int width, int height, int bgr)
+{
+ int i, j;
+ const unsigned char *ysrc = src;
+ const unsigned char *uvsrc = src + width * height;
+
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j ++) {
+ if (bgr) {
+ *dest++ = YUV2B(*ysrc, *uvsrc, *(uvsrc + 1));
+ *dest++ = YUV2G(*ysrc, *uvsrc, *(uvsrc + 1));
+ *dest++ = YUV2R(*ysrc, *uvsrc, *(uvsrc + 1));
+ } else {
+ *dest++ = YUV2R(*ysrc, *uvsrc, *(uvsrc + 1));
+ *dest++ = YUV2G(*ysrc, *uvsrc, *(uvsrc + 1));
+ *dest++ = YUV2B(*ysrc, *uvsrc, *(uvsrc + 1));
+ }
+ ysrc++;
+ if (j&1)
+ uvsrc += 2;
+ }
+
+ /* Rewind u and v for next line */
+ if (!(i&1))
+ uvsrc -= width;
+ }
+}
+
+void v4lconvert_nv12_to_yuv420(const unsigned char *src, unsigned char *dest,
+ int width, int height, int yvu)
+{
+ int i, j;
+ const unsigned char *ysrc = src;
+ const unsigned char *uvsrc = src + width * height;
+ unsigned char *ydst = dest;
+ unsigned char *udst, *vdst;
+
+ if (yvu) {
+ vdst = ydst + width * height;
+ udst = vdst + ((width / 2) * (height / 2));
+ } else {
+ udst = ydst + width * height;
+ vdst = udst + ((width / 2) * (height / 2));
+ }
+
+ for (i = 0; i < height; i++)
+ for (j = 0; i < width; j++) {
+ *ydst++ = *ysrc++;
+ if (((i % 2) == 0) && ((j % 2) == 0)) {
+ *udst++ = *uvsrc++;
+ *vdst++ = *uvsrc++;
+ }
+ }
+}