libv4l: Prefer compressed pixformats for resolutions > 176x144
authorhans@localhost.localdomain <hans@localhost.localdomain>
Wed, 3 Sep 2008 12:24:30 +0000 (14:24 +0200)
committerhans@localhost.localdomain <hans@localhost.localdomain>
Wed, 3 Sep 2008 12:24:30 +0000 (14:24 +0200)
From: Hans de Goede <j.w.r.degoede@hhs.nl>

libv4l: Prefer compressed pixformats for resolutions > 176x144

Priority: normal

Signed-off-by: Hans de Goede <j.w.r.degoede@hhs.nl>
lib/ChangeLog
lib/libv4l2/libv4l2.c
lib/libv4lconvert/libv4lconvert-priv.h
lib/libv4lconvert/libv4lconvert.c

index 31611e0..8a7131a 100644 (file)
@@ -1,6 +1,7 @@
 libv4l-0.4.3
 ------------
 * Add suport for YUYV and YVYU packed pixel formats (Jean-Francois Moine)
+* Prefer compressed pixformats for resolutions > 176x144
 
 libv4l-0.4.2
 ------------
index 7029f69..937c06c 100644 (file)
@@ -739,6 +739,17 @@ int v4l2_ioctl (int fd, unsigned long int request, ...)
        if (result)
          break;
 
+       if (src_fmt.fmt.pix.pixelformat != dest_fmt->fmt.pix.pixelformat &&
+           v4l2_log_file) {
+         int pixfmt = src_fmt.fmt.pix.pixelformat;
+
+         fprintf(v4l2_log_file, "VIDIOC_S_FMT converting from: %c%c%c%c\n",
+           pixfmt & 0xff,
+           (pixfmt >> 8) & 0xff,
+           (pixfmt >> 16) & 0xff,
+           pixfmt >> 24);
+       }
+
        /* Maybe after try format has adjusted width/height etc, to whats
           available nothing has changed (on the cam side) ? */
        if (!memcmp(&devices[index].src_fmt, &src_fmt, sizeof(src_fmt))) {
index efe78bb..a2086e6 100644 (file)
   snprintf(data->error_msg, V4LCONVERT_ERROR_MSG_SIZE, \
   "v4l-convert: error " __VA_ARGS__)
 
+/* Card flags */
 #define V4LCONVERT_UPSIDE_DOWN 0x01
 
+/* Pixformat flags */
+#define V4LCONVERT_COMPRESSED 0x01
+
 struct v4lconvert_data {
   int fd;
   int flags; /* bitfield */
@@ -85,6 +89,11 @@ struct v4lconvert_flags_info {
   int flags;
 };
 
+struct v4lconvert_pixfmt {
+  unsigned int fmt;
+  int flags;
+};
+
 void v4lconvert_yuv420_to_rgb24(const unsigned char *src, unsigned char *dst,
   int width, int height);
 
index 2a9f6ef..cbd4ca5 100644 (file)
 /* Note for proper functioning of v4lconvert_enum_fmt the first entries in
   supported_src_pixfmts must match with the entries in supported_dst_pixfmts */
 #define SUPPORTED_DST_PIXFMTS \
-  V4L2_PIX_FMT_RGB24, \
-  V4L2_PIX_FMT_BGR24, \
-  V4L2_PIX_FMT_YUV420
+  { V4L2_PIX_FMT_RGB24,  0 }, \
+  { V4L2_PIX_FMT_BGR24,  0 }, \
+  { V4L2_PIX_FMT_YUV420, 0 }
 
-static const unsigned int supported_src_pixfmts[] = {
+/* Note uncompressed formats must go first so that they are prefered by
+   v4lconvert_try_format for low resolutions */
+static const struct v4lconvert_pixfmt supported_src_pixfmts[] = {
   SUPPORTED_DST_PIXFMTS,
-  V4L2_PIX_FMT_MJPEG,
-  V4L2_PIX_FMT_JPEG,
-  V4L2_PIX_FMT_YUYV,
-  V4L2_PIX_FMT_YVYU,
-  V4L2_PIX_FMT_SBGGR8,
-  V4L2_PIX_FMT_SGBRG8,
-  V4L2_PIX_FMT_SGRBG8,
-  V4L2_PIX_FMT_SRGGB8,
-  V4L2_PIX_FMT_SPCA501,
-  V4L2_PIX_FMT_SPCA505,
-  V4L2_PIX_FMT_SPCA508,
-  V4L2_PIX_FMT_SPCA561,
-  V4L2_PIX_FMT_SN9C10X,
-  V4L2_PIX_FMT_PAC207,
-  V4L2_PIX_FMT_PJPG,
+  { V4L2_PIX_FMT_YUYV,    0 },
+  { V4L2_PIX_FMT_YVYU,    0 },
+  { V4L2_PIX_FMT_SBGGR8,  0 },
+  { V4L2_PIX_FMT_SGBRG8,  0 },
+  { V4L2_PIX_FMT_SGRBG8,  0 },
+  { V4L2_PIX_FMT_SRGGB8,  0 },
+  { V4L2_PIX_FMT_SPCA501, 0 },
+  { V4L2_PIX_FMT_SPCA505, 0 },
+  { V4L2_PIX_FMT_SPCA508, 0 },
+  { V4L2_PIX_FMT_MJPEG,   V4LCONVERT_COMPRESSED },
+  { V4L2_PIX_FMT_JPEG,    V4LCONVERT_COMPRESSED },
+  { V4L2_PIX_FMT_SPCA561, V4LCONVERT_COMPRESSED },
+  { V4L2_PIX_FMT_SN9C10X, V4LCONVERT_COMPRESSED },
+  { V4L2_PIX_FMT_PAC207,  V4LCONVERT_COMPRESSED },
+  { V4L2_PIX_FMT_PJPG,    V4LCONVERT_COMPRESSED },
 };
 
-static const unsigned int supported_dst_pixfmts[] = {
+static const struct v4lconvert_pixfmt supported_dst_pixfmts[] = {
   SUPPORTED_DST_PIXFMTS
 };
 
@@ -87,7 +89,7 @@ struct v4lconvert_data *v4lconvert_create(int fd)
       break;
 
     for (j = 0; j < ARRAY_SIZE(supported_src_pixfmts); j++)
-      if (fmt.pixelformat == supported_src_pixfmts[j]) {
+      if (fmt.pixelformat == supported_src_pixfmts[j].fmt) {
        data->supported_src_formats |= 1 << j;
        break;
       }
@@ -130,7 +132,7 @@ int v4lconvert_enum_fmt(struct v4lconvert_data *data, struct v4l2_fmtdesc *fmt)
 
   for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++)
     if (!(data->supported_src_formats & (1 << i))) {
-      faked_fmts[no_faked_fmts] = supported_dst_pixfmts[i];
+      faked_fmts[no_faked_fmts] = supported_dst_pixfmts[i].fmt;
       no_faked_fmts++;
     }
 
@@ -162,7 +164,7 @@ int v4lconvert_try_format(struct v4lconvert_data *data,
   struct v4l2_format try_fmt, closest_fmt = { .type = 0 };
 
   for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++)
-    if (supported_dst_pixfmts[i] == desired_pixfmt)
+    if (supported_dst_pixfmts[i].fmt == desired_pixfmt)
       break;
 
   /* Can we do conversion to the requested format & type? */
@@ -180,11 +182,11 @@ int v4lconvert_try_format(struct v4lconvert_data *data,
       continue;
 
     try_fmt = *dest_fmt;
-    try_fmt.fmt.pix.pixelformat = supported_src_pixfmts[i];
+    try_fmt.fmt.pix.pixelformat = supported_src_pixfmts[i].fmt;
 
     if (!syscall(SYS_ioctl, data->fd, VIDIOC_TRY_FMT, &try_fmt))
     {
-      if (try_fmt.fmt.pix.pixelformat == supported_src_pixfmts[i]) {
+      if (try_fmt.fmt.pix.pixelformat == supported_src_pixfmts[i].fmt) {
        int size_x_diff = abs((int)try_fmt.fmt.pix.width -
                              (int)dest_fmt->fmt.pix.width);
        int size_y_diff = abs((int)try_fmt.fmt.pix.height -
@@ -193,7 +195,9 @@ int v4lconvert_try_format(struct v4lconvert_data *data,
                                 size_y_diff * size_y_diff;
        if (size_diff < closest_fmt_size_diff ||
            (size_diff == closest_fmt_size_diff &&
-            try_fmt.fmt.pix.pixelformat == desired_pixfmt)) {
+            (supported_src_pixfmts[i].fmt == desired_pixfmt ||
+             ((try_fmt.fmt.pix.width > 176 || try_fmt.fmt.pix.height > 144) &&
+              (supported_src_pixfmts[i].flags & V4LCONVERT_COMPRESSED))))) {
          closest_fmt_size_diff = size_diff;
          closest_fmt = try_fmt;
        }
@@ -249,7 +253,7 @@ int v4lconvert_needs_conversion(struct v4lconvert_data *data,
 
   /* Formats are identical, but we need flip, do we support the dest_fmt? */
   for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++)
-    if (supported_dst_pixfmts[i] == dest_fmt->fmt.pix.pixelformat)
+    if (supported_dst_pixfmts[i].fmt == dest_fmt->fmt.pix.pixelformat)
       break;
 
   if (i == ARRAY_SIZE(supported_dst_pixfmts))