summaryrefslogtreecommitdiff
path: root/v4l2-apps/libv4l/libv4lconvert
diff options
context:
space:
mode:
authorhans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain>2009-03-11 13:16:01 +0100
committerhans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain>2009-03-11 13:16:01 +0100
commitd02d1e3c9f20e691d7d3ff62275d57bfc4766e19 (patch)
tree7a64e3e894c9d789abf630c0728050d6dec0ef55 /v4l2-apps/libv4l/libv4lconvert
parentf7cf759077f7b829a1cb451fcef9868b693ec3fe (diff)
downloadmediapointer-dvb-s2-d02d1e3c9f20e691d7d3ff62275d57bfc4766e19.tar.gz
mediapointer-dvb-s2-d02d1e3c9f20e691d7d3ff62275d57bfc4766e19.tar.bz2
libv4l: add UYVY support
From: Julien BLACHE <jb@jblache.org> Attached is a patch to add UYVY support to libv4lconvert. It's obviously a shameless respin of the YVYU conversion routines :P Tested on a USB Apple iSight, which only supports UYVY. Priority: normal Signed-off-by: Julien BLACHE <jb@jblache.org> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'v4l2-apps/libv4l/libv4lconvert')
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h9
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c18
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/rgbyuv.c91
3 files changed, 118 insertions, 0 deletions
diff --git a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h
index 55a5b49be..c268375c8 100644
--- a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h
+++ b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h
@@ -132,6 +132,15 @@ void v4lconvert_yvyu_to_bgr24(const unsigned char *src, unsigned char *dst,
void v4lconvert_yvyu_to_yuv420(const unsigned char *src, unsigned char *dst,
int width, int height, int yvu);
+void v4lconvert_uyvy_to_rgb24(const unsigned char *src, unsigned char *dst,
+ int width, int height);
+
+void v4lconvert_uyvy_to_bgr24(const unsigned char *src, unsigned char *dst,
+ int width, int height);
+
+void v4lconvert_uyvy_to_yuv420(const unsigned char *src, unsigned char *dst,
+ int width, int height, int yvu);
+
void v4lconvert_swap_rgb(const unsigned char *src, unsigned char *dst,
int width, int height);
diff --git a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c
index 889f7463a..c01286b73 100644
--- a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c
+++ b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c
@@ -44,6 +44,7 @@ static const struct v4lconvert_pixfmt supported_src_pixfmts[] = {
SUPPORTED_DST_PIXFMTS,
{ V4L2_PIX_FMT_YUYV, 0 },
{ V4L2_PIX_FMT_YVYU, 0 },
+ { V4L2_PIX_FMT_UYVY, 0 },
{ V4L2_PIX_FMT_SBGGR8, 0 },
{ V4L2_PIX_FMT_SGBRG8, 0 },
{ V4L2_PIX_FMT_SGRBG8, 0 },
@@ -718,6 +719,23 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data,
}
break;
+ case V4L2_PIX_FMT_UYVY:
+ switch (dest_pix_fmt) {
+ case V4L2_PIX_FMT_RGB24:
+ v4lconvert_uyvy_to_rgb24(src, dest, width, height);
+ break;
+ case V4L2_PIX_FMT_BGR24:
+ v4lconvert_uyvy_to_bgr24(src, dest, width, height);
+ break;
+ case V4L2_PIX_FMT_YUV420:
+ v4lconvert_uyvy_to_yuv420(src, dest, width, height, 0);
+ break;
+ case V4L2_PIX_FMT_YVU420:
+ v4lconvert_uyvy_to_yuv420(src, dest, width, height, 1);
+ break;
+ }
+ break;
+
default:
V4LCONVERT_ERR("Unknown src format in conversion\n");
errno = EINVAL;
diff --git a/v4l2-apps/libv4l/libv4lconvert/rgbyuv.c b/v4l2-apps/libv4l/libv4lconvert/rgbyuv.c
index d5feb457e..ec297b1f7 100644
--- a/v4l2-apps/libv4l/libv4lconvert/rgbyuv.c
+++ b/v4l2-apps/libv4l/libv4lconvert/rgbyuv.c
@@ -378,6 +378,97 @@ void v4lconvert_yvyu_to_yuv420(const unsigned char *src, unsigned char *dest,
}
}
+void v4lconvert_uyvy_to_bgr24(const unsigned char *src, unsigned char *dest,
+ int width, int height)
+{
+ int j;
+
+ while (--height >= 0) {
+ for (j = 0; j < width; j += 2) {
+ int u = src[0];
+ int v = src[2];
+ int u1 = (((u - 128) << 7) + (u - 128)) >> 6;
+ int rg = (((u - 128) << 1) + (u - 128) +
+ ((v - 128) << 2) + ((v - 128) << 1)) >> 3;
+ int v1 = (((v - 128) << 1) + (v - 128)) >> 1;
+
+ *dest++ = CLIP(src[1] + u1);
+ *dest++ = CLIP(src[1] - rg);
+ *dest++ = CLIP(src[1] + v1);
+
+ *dest++ = CLIP(src[3] + u1);
+ *dest++ = CLIP(src[3] - rg);
+ *dest++ = CLIP(src[3] + v1);
+ src += 4;
+ }
+ }
+}
+
+void v4lconvert_uyvy_to_rgb24(const unsigned char *src, unsigned char *dest,
+ int width, int height)
+{
+ int j;
+
+ while (--height >= 0) {
+ for (j = 0; j < width; j += 2) {
+ int u = src[0];
+ int v = src[2];
+ int u1 = (((u - 128) << 7) + (u - 128)) >> 6;
+ int rg = (((u - 128) << 1) + (u - 128) +
+ ((v - 128) << 2) + ((v - 128) << 1)) >> 3;
+ int v1 = (((v - 128) << 1) + (v - 128)) >> 1;
+
+ *dest++ = CLIP(src[1] + v1);
+ *dest++ = CLIP(src[1] - rg);
+ *dest++ = CLIP(src[1] + u1);
+
+ *dest++ = CLIP(src[3] + v1);
+ *dest++ = CLIP(src[3] - rg);
+ *dest++ = CLIP(src[3] + u1);
+ src += 4;
+ }
+ }
+}
+
+void v4lconvert_uyvy_to_yuv420(const unsigned char *src, unsigned char *dest,
+ int width, int height, int yvu)
+{
+ int i, j;
+ const unsigned char *src1;
+ unsigned char *udest, *vdest;
+
+ /* copy the Y values */
+ src1 = src;
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j += 2) {
+ *dest++ = src1[1];
+ *dest++ = src1[3];
+ src1 += 4;
+ }
+ }
+
+ /* copy the U and V values */
+ src++; /* point to V */
+ src1 = src + width * 2; /* next line */
+ if (yvu) {
+ vdest = dest;
+ udest = dest + width * height / 4;
+ } else {
+ udest = dest;
+ vdest = dest + width * height / 4;
+ }
+ for (i = 0; i < height; i += 2) {
+ for (j = 0; j < width; j += 2) {
+ *udest++ = ((int) src[0] + src1[0]) / 2; /* U */
+ *vdest++ = ((int) src[2] + src1[2]) / 2; /* V */
+ src += 4;
+ src1 += 4;
+ }
+ src = src1;
+ src1 += width * 2;
+ }
+}
+
void v4lconvert_swap_rgb(const unsigned char *src, unsigned char *dst,
int width, int height)
{