libv4l: Add support for konica yuv420 format
authorHans de Goede <hdegoede@redhat.com>
Thu, 1 Jul 2010 18:32:15 +0000 (20:32 +0200)
committerHans de Goede <hdegoede@redhat.com>
Thu, 1 Jul 2010 18:32:15 +0000 (20:32 +0200)
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
include/linux/videodev2.h
lib/libv4lconvert/libv4lconvert-priv.h
lib/libv4lconvert/libv4lconvert.c
lib/libv4lconvert/spca501.c

index cb91d23..b73fe20 100644 (file)
@@ -363,6 +363,7 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_STV0680  v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */
 #define V4L2_PIX_FMT_TM6000   v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */
 #define V4L2_PIX_FMT_CIT_YYVYUY v4l2_fourcc('C', 'I', 'T', 'V') /* one line of Y then 1 line of VYUY */
+#define V4L2_PIX_FMT_KONICA420  v4l2_fourcc('K', 'O', 'N', 'I') /* YUV420 planar in blocks of 256 pixels */
 
 /*
  *     F O R M A T   E N U M E R A T I O N
index b3e4c4e..61a8c39 100644 (file)
@@ -149,6 +149,10 @@ void v4lconvert_cit_yyvyuy_to_yuv420(const unsigned char *src,
                unsigned char *ydest,
                int width, int height, int yvu);
 
+void v4lconvert_konica_yuv420_to_yuv420(const unsigned char *src,
+               unsigned char *ydest,
+               int width, int height, int yvu);
+
 int v4lconvert_cpia1_to_yuv420(struct v4lconvert_data *data,
                const unsigned char *src, int src_size,
                unsigned char *dst, int width, int height, int yvu);
index 6d91d7c..f08996a 100644 (file)
@@ -57,6 +57,7 @@ static const struct v4lconvert_pixfmt supported_src_pixfmts[] = {
        { V4L2_PIX_FMT_SPCA505,      V4LCONVERT_NEEDS_CONVERSION },
        { V4L2_PIX_FMT_SPCA508,      V4LCONVERT_NEEDS_CONVERSION },
        { V4L2_PIX_FMT_CIT_YYVYUY,   V4LCONVERT_NEEDS_CONVERSION },
+       { V4L2_PIX_FMT_KONICA420,    V4LCONVERT_NEEDS_CONVERSION },
        { V4L2_PIX_FMT_CPIA1,        V4LCONVERT_NEEDS_CONVERSION },
        { V4L2_PIX_FMT_HM12,         V4LCONVERT_NEEDS_CONVERSION },
        { V4L2_PIX_FMT_MJPEG,        V4LCONVERT_COMPRESSED },
@@ -644,6 +645,7 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data,
        case V4L2_PIX_FMT_SPCA505:
        case V4L2_PIX_FMT_SPCA508:
        case V4L2_PIX_FMT_CIT_YYVYUY:
+       case V4L2_PIX_FMT_KONICA420:
        case V4L2_PIX_FMT_SN9C20X_I420:
        case V4L2_PIX_FMT_CPIA1:
        case V4L2_PIX_FMT_OV511:
@@ -680,6 +682,9 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data,
                case V4L2_PIX_FMT_CIT_YYVYUY:
                        v4lconvert_cit_yyvyuy_to_yuv420(src, d, width, height, yvu);
                        break;
+               case V4L2_PIX_FMT_KONICA420:
+                       v4lconvert_konica_yuv420_to_yuv420(src, d, width, height, yvu);
+                       break;
                case V4L2_PIX_FMT_SN9C20X_I420:
                        v4lconvert_sn9c20x_to_yuv420(src, d, width, height, yvu);
                        break;
index 438c1c3..bf0e08a 100644 (file)
@@ -179,3 +179,42 @@ void v4lconvert_cit_yyvyuy_to_yuv420(const unsigned char *src,
                }
        }
 }
+
+/* Note this is not a spca specific format, but it fits in this file in that
+   it is another funny yuv format */
+/* The konica gspca subdriver using cams send data in blocks of 256 pixels
+   in YUV420 format. */
+void v4lconvert_konica_yuv420_to_yuv420(const unsigned char *src,
+               unsigned char *ydest,
+               int width, int height, int yvu)
+{
+       int i, no_blocks;
+       unsigned char *udest, *vdest;
+
+       if (yvu) {
+               vdest = ydest + width * height;
+               udest = vdest + (width * height) / 4;
+       } else {
+               udest = ydest + width * height;
+               vdest = udest + (width * height) / 4;
+       }
+
+       no_blocks = width * height * 3 / 2;
+       no_blocks /= 256;
+       for (i = 0; i < no_blocks; i++) {
+               /* copy 256 Y pixels */
+               memcpy(ydest, src, 256);
+               src += 256;
+               ydest += 256;
+
+               /* copy 64 U pixels */
+               memcpy(udest, src, 64);
+               src += 64;
+               udest += 64;
+
+               /* copy 64 V pixels */
+               memcpy(udest, src, 64);
+               src += 64;
+               udest += 64;
+       }
+}