The patch number 8983 was added via [EMAIL PROTECTED]
to http://linuxtv.org/hg/v4l-dvb master development tree.

Kernel patches in this development tree may be modified to be backward
compatible with older kernels. Compatibility modifications will be
removed before inclusion into the mainstream Kernel

If anyone has any objections, please let us know by sending a message to:
        [EMAIL PROTECTED]

------

From: Hans de Goede  <[EMAIL PROTECTED]>
libv4l: 0.5.0 release


* Add support for enumerating framesizes and frameintervals of emulated
  formats when the driver supports it for the real format
* Make sure the video device always gets opened RW even if the application
  asks for RO
* Add Genius E-Messenger 112 (093a:2476) to list of cams which have their
  sensor upside down

Priority: normal

Signed-off-by: Hans de Goede <[EMAIL PROTECTED]>


---

 v4l2-apps/lib/libv4l/ChangeLog                          |    9 
 v4l2-apps/lib/libv4l/Makefile                           |    2 
 v4l2-apps/lib/libv4l/include/libv4lconvert.h            |   10 
 v4l2-apps/lib/libv4l/libv4l1/libv4l1.c                  |   15 
 v4l2-apps/lib/libv4l/libv4l1/log.c                      |    6 
 v4l2-apps/lib/libv4l/libv4l2/libv4l2.c                  |   13 
 v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c              |   15 
 v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h |    3 
 v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c      |  153 +++++++++-
 9 files changed, 201 insertions(+), 25 deletions(-)

diff -r 5ad201ef46e8 -r 10a002640754 v4l2-apps/lib/libv4l/ChangeLog
--- a/v4l2-apps/lib/libv4l/ChangeLog    Wed Sep 03 14:24:30 2008 +0200
+++ b/v4l2-apps/lib/libv4l/ChangeLog    Mon Sep 15 13:48:21 2008 +0200
@@ -1,3 +1,12 @@ libv4l-0.4.3
+libv4l-0.5.0
+------------
+* Add support for enumerating framesizes and frameintervals of emulated
+  formats when the driver supports it for the real format
+* Make sure the video device always gets opened RW even if the application
+  asks for RO
+* Add Genius E-Messenger 112 (093a:2476) to list of cams which have their
+  sensor upside down
+
 libv4l-0.4.3
 ------------
 * Add suport for YUYV and YVYU packed pixel formats (Jean-Francois Moine)
diff -r 5ad201ef46e8 -r 10a002640754 v4l2-apps/lib/libv4l/Makefile
--- a/v4l2-apps/lib/libv4l/Makefile     Wed Sep 03 14:24:30 2008 +0200
+++ b/v4l2-apps/lib/libv4l/Makefile     Mon Sep 15 13:48:21 2008 +0200
@@ -1,5 +1,5 @@ LIB_RELEASE=0
 LIB_RELEASE=0
-V4L2_LIB_VERSION=$(LIB_RELEASE).4.3
+V4L2_LIB_VERSION=$(LIB_RELEASE).5.0
 
 all clean install:
        $(MAKE) -C libv4lconvert V4L2_LIB_VERSION=$(V4L2_LIB_VERSION) $@
diff -r 5ad201ef46e8 -r 10a002640754 
v4l2-apps/lib/libv4l/include/libv4lconvert.h
--- a/v4l2-apps/lib/libv4l/include/libv4lconvert.h      Wed Sep 03 14:24:30 
2008 +0200
+++ b/v4l2-apps/lib/libv4l/include/libv4lconvert.h      Mon Sep 15 13:48:21 
2008 +0200
@@ -71,6 +71,16 @@ LIBV4L_PUBLIC int v4lconvert_convert(str
 /* get a string describing the last error*/
 LIBV4L_PUBLIC const char *v4lconvert_get_error_message(struct v4lconvert_data 
*data);
 
+/* Just like VIDIOC_ENUM_FRAMESIZE, except that the framesizes of emulated
+   formats can be enumerated as well. */
+LIBV4L_PUBLIC int v4lconvert_enum_framesizes(struct v4lconvert_data *data,
+  struct v4l2_frmsizeenum *frmsize);
+
+/* Just like VIDIOC_ENUM_FRAMEINTERVALS, except that the intervals of emulated
+   formats can be enumerated as well. */
+LIBV4L_PUBLIC int v4lconvert_enum_frameintervals(struct v4lconvert_data *data,
+  struct v4l2_frmivalenum *frmival);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff -r 5ad201ef46e8 -r 10a002640754 v4l2-apps/lib/libv4l/libv4l1/libv4l1.c
--- a/v4l2-apps/lib/libv4l/libv4l1/libv4l1.c    Wed Sep 03 14:24:30 2008 +0200
+++ b/v4l2-apps/lib/libv4l/libv4l1/libv4l1.c    Mon Sep 15 13:48:21 2008 +0200
@@ -259,6 +259,15 @@ int v4l1_open (const char *file, int ofl
   struct v4l2_format fmt2;
   struct v4l2_input input2;
   struct v4l2_standard standard2;
+  int v4l_device = 0;
+
+  /* check if we're opening a video4linux2 device */
+  if (!strncmp(file, "/dev/video", 10) || !strncmp(file, "/dev/v4l/", 9)) {
+    /* Some apps open the device read only, but we need rw rights as the
+       buffers *MUST* be mapped rw */
+    oflag = (oflag & ~O_ACCMODE) | O_RDWR;
+    v4l_device = 1;
+  }
 
   /* original open code */
   if (oflag & O_CREAT)
@@ -276,11 +285,7 @@ int v4l1_open (const char *file, int ofl
     fd = syscall(SYS_open, file, oflag);
   /* end of original open code */
 
-  if (fd == -1)
-    return fd;
-
-  /* check if we're opening a video4linux2 device */
-  if (strncmp(file, "/dev/video", 10) && strncmp(file, "/dev/v4l/", 9))
+  if (fd == -1 || !v4l_device)
     return fd;
 
   /* check that this is an v4l2 device, no need to emulate v4l1 on
diff -r 5ad201ef46e8 -r 10a002640754 v4l2-apps/lib/libv4l/libv4l1/log.c
--- a/v4l2-apps/lib/libv4l/libv4l1/log.c        Wed Sep 03 14:24:30 2008 +0200
+++ b/v4l2-apps/lib/libv4l/libv4l1/log.c        Mon Sep 15 13:48:21 2008 +0200
@@ -66,6 +66,7 @@ void v4l1_log_ioctl(unsigned long int re
 void v4l1_log_ioctl(unsigned long int request, void *arg, int result)
 {
   const char *ioctl_str = "unknown";
+  char buf[40];
 
   if (!v4l1_log_file)
     return;
@@ -77,6 +78,11 @@ void v4l1_log_ioctl(unsigned long int re
 
   if (_IOC_TYPE(request) == 'v' && _IOC_NR(request) < ARRAY_SIZE(v4l1_ioctls))
     ioctl_str = v4l1_ioctls[_IOC_NR(request)];
+  else {
+    snprintf(buf, sizeof(buf), "unknown request: %c %d\n",
+      (int)_IOC_TYPE(request), (int)_IOC_NR(request));
+    ioctl_str = buf;
+  }
 
   fprintf(v4l1_log_file, "request == %s\n", ioctl_str);
 
diff -r 5ad201ef46e8 -r 10a002640754 v4l2-apps/lib/libv4l/libv4l2/libv4l2.c
--- a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c    Wed Sep 03 14:24:30 2008 +0200
+++ b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c    Mon Sep 15 13:48:21 2008 +0200
@@ -649,6 +649,11 @@ int v4l2_ioctl (int fd, unsigned long in
          (devices[index].flags & V4L2_ENABLE_ENUM_FMT_EMULATION))
        is_capture_request = 1;
       break;
+    case VIDIOC_ENUM_FRAMESIZES:
+    case VIDIOC_ENUM_FRAMEINTERVALS:
+      if (devices[index].flags & V4L2_ENABLE_ENUM_FMT_EMULATION)
+       is_capture_request = 1;
+      break;
     case VIDIOC_TRY_FMT:
       if (((struct v4l2_format *)arg)->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
        is_capture_request = 1;
@@ -712,6 +717,14 @@ int v4l2_ioctl (int fd, unsigned long in
 
     case VIDIOC_ENUM_FMT:
       result = v4lconvert_enum_fmt(devices[index].convert, arg);
+      break;
+
+    case VIDIOC_ENUM_FRAMESIZES:
+      result = v4lconvert_enum_framesizes(devices[index].convert, arg);
+      break;
+
+    case VIDIOC_ENUM_FRAMEINTERVALS:
+      result = v4lconvert_enum_frameintervals(devices[index].convert, arg);
       break;
 
     case VIDIOC_TRY_FMT:
diff -r 5ad201ef46e8 -r 10a002640754 v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c
--- a/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c        Wed Sep 03 14:24:30 
2008 +0200
+++ b/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c        Mon Sep 15 13:48:21 
2008 +0200
@@ -53,6 +53,15 @@ LIBV4L_PUBLIC int open (const char *file
 {
   int fd;
   struct v4l2_capability cap;
+  int v4l_device = 0;
+
+  /* check if we're opening a video4linux2 device */
+  if (!strncmp(file, "/dev/video", 10) || !strncmp(file, "/dev/v4l/", 9)) {
+    /* Some apps open the device read only, but we need rw rights as the
+       buffers *MUST* be mapped rw */
+    oflag = (oflag & ~O_ACCMODE) | O_RDWR;
+    v4l_device = 1;
+  }
 
   /* original open code */
   if (oflag & O_CREAT)
@@ -70,11 +79,7 @@ LIBV4L_PUBLIC int open (const char *file
     fd = syscall(SYS_open, file, oflag);
   /* end of original open code */
 
-  if (fd == -1)
-    return fd;
-
-  /* check if we're opening a video4linux2 device */
-  if (strncmp(file, "/dev/video", 10) && strncmp(file, "/dev/v4l/", 9))
+  if (fd == -1 || !v4l_device)
     return fd;
 
   /* check that this is an v4l2 device, libv4l2 only supports v4l2 devices */
diff -r 5ad201ef46e8 -r 10a002640754 
v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h
--- a/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h   Wed Sep 03 
14:24:30 2008 +0200
+++ b/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h   Mon Sep 15 
13:48:21 2008 +0200
@@ -64,6 +64,7 @@
 #endif
 
 #define V4LCONVERT_ERROR_MSG_SIZE 256
+#define V4LCONVERT_MAX_FRAMESIZES 16
 
 #define V4LCONVERT_ERR(...) \
   snprintf(data->error_msg, V4LCONVERT_ERROR_MSG_SIZE, \
@@ -82,6 +83,8 @@ struct v4lconvert_data {
   unsigned int no_formats;
   char error_msg[V4LCONVERT_ERROR_MSG_SIZE];
   struct jdec_private *jdec;
+  struct v4l2_frmsizeenum framesizes[V4LCONVERT_MAX_FRAMESIZES];
+  unsigned int no_framesizes;
 };
 
 struct v4lconvert_flags_info {
diff -r 5ad201ef46e8 -r 10a002640754 
v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c
--- a/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c        Wed Sep 03 
14:24:30 2008 +0200
+++ b/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c        Mon Sep 15 
13:48:21 2008 +0200
@@ -33,6 +33,9 @@
   { V4L2_PIX_FMT_RGB24,  0 }, \
   { V4L2_PIX_FMT_BGR24,  0 }, \
   { V4L2_PIX_FMT_YUV420, 0 }
+
+static void v4lconvert_get_framesizes(struct v4lconvert_data *data,
+  unsigned int pixelformat);
 
 /* Note uncompressed formats must go first so that they are prefered by
    v4lconvert_try_format for low resolutions */
@@ -61,10 +64,11 @@ static const struct v4lconvert_pixfmt su
 
 /* List of cams which need special flags */
 static const struct v4lconvert_flags_info v4lconvert_flags[] = {
+  { "SPC 200NC      ", V4LCONVERT_UPSIDE_DOWN },
+  { "SPC 300NC      ", V4LCONVERT_UPSIDE_DOWN },
   { "USB Camera (0471:0325)", V4LCONVERT_UPSIDE_DOWN }, /* SPC200NC */
   { "USB Camera (0471:0326)", V4LCONVERT_UPSIDE_DOWN }, /* SPC300NC */
-  { "SPC 200NC      ", V4LCONVERT_UPSIDE_DOWN },
-  { "SPC 300NC      ", V4LCONVERT_UPSIDE_DOWN },
+  { "USB Camera (093a:2476)", V4LCONVERT_UPSIDE_DOWN }, /* Genius E-M 112 */
 };
 
 struct v4lconvert_data *v4lconvert_create(int fd)
@@ -93,6 +97,8 @@ struct v4lconvert_data *v4lconvert_creat
        data->supported_src_formats |= 1 << j;
        break;
       }
+
+    v4lconvert_get_framesizes(data, fmt.pixelformat);
   }
 
   data->no_formats = i;
@@ -117,6 +123,17 @@ void v4lconvert_destroy(struct v4lconver
     tinyjpeg_free(data->jdec);
   }
   free(data);
+}
+
+static int v4lconvert_supported_dst_format(unsigned int pixelformat)
+{
+  int i;
+
+  for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++)
+    if (supported_dst_pixfmts[i].fmt == pixelformat)
+      break;
+
+  return i != ARRAY_SIZE(supported_dst_pixfmts);
 }
 
 /* See libv4lconvert.h for description of in / out parameters */
@@ -163,12 +180,8 @@ int v4lconvert_try_format(struct v4lconv
   unsigned int desired_pixfmt = dest_fmt->fmt.pix.pixelformat;
   struct v4l2_format try_fmt, closest_fmt = { .type = 0 };
 
-  for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++)
-    if (supported_dst_pixfmts[i].fmt == desired_pixfmt)
-      break;
-
   /* Can we do conversion to the requested format & type? */
-  if (i == ARRAY_SIZE(supported_dst_pixfmts) ||
+  if (!v4lconvert_supported_dst_format(desired_pixfmt) ||
       dest_fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
     int ret = syscall(SYS_ioctl, data->fd, VIDIOC_TRY_FMT, dest_fmt);
     if (src_fmt)
@@ -243,8 +256,6 @@ int v4lconvert_needs_conversion(struct v
   const struct v4l2_format *src_fmt,  /* in */
   const struct v4l2_format *dest_fmt) /* in */
 {
-  int i;
-
   if(memcmp(src_fmt, dest_fmt, sizeof(*src_fmt)))
     return 1; /* Formats differ */
 
@@ -252,11 +263,7 @@ int v4lconvert_needs_conversion(struct v
     return 0; /* Formats identical and we don't need flip */
 
   /* 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].fmt == dest_fmt->fmt.pix.pixelformat)
-      break;
-
-  if (i == ARRAY_SIZE(supported_dst_pixfmts))
+  if (!v4lconvert_supported_dst_format(dest_fmt->fmt.pix.pixelformat))
     return 0; /* Needs flip but we cannot do it :( */
   else
     return 1; /* Needs flip and thus conversion */
@@ -610,3 +617,121 @@ const char *v4lconvert_get_error_message
 {
   return data->error_msg;
 }
+
+static void v4lconvert_get_framesizes(struct v4lconvert_data *data,
+  unsigned int pixelformat)
+{
+  int i, j, match;
+  struct v4l2_frmsizeenum frmsize = { .pixel_format = pixelformat };
+
+  for (i = 0; ; i++) {
+    frmsize.index = i;
+    if (syscall(SYS_ioctl, data->fd, VIDIOC_ENUM_FRAMESIZES, &frmsize))
+      break;
+
+    /* We got a framesize, check we don't have the same one already */
+    match = 0;
+    for (j = 0; j < data->no_framesizes && !match; j++) {
+      if (frmsize.type != data->framesizes[j].type)
+       continue;
+
+      switch(frmsize.type) {
+       case V4L2_FRMSIZE_TYPE_DISCRETE:
+         if(!memcmp(&frmsize.discrete, &data->framesizes[j].discrete,
+                    sizeof(frmsize.discrete)))
+           match = 1;
+         break;
+       case V4L2_FRMSIZE_TYPE_CONTINUOUS:
+       case V4L2_FRMSIZE_TYPE_STEPWISE:
+         if(!memcmp(&frmsize.stepwise, &data->framesizes[j].stepwise,
+                    sizeof(frmsize.stepwise)))
+           match = 1;
+         break;
+      }
+    }
+    /* Add this framesize if it is not already in our list */
+    if (!match) {
+      if (data->no_framesizes == V4LCONVERT_MAX_FRAMESIZES) {
+       fprintf(stderr,
+         "libv4lconvert: warning more framesizes then I can handle!\n");
+       return;
+      }
+      data->framesizes[data->no_framesizes].type = frmsize.type;
+      switch(frmsize.type) {
+       case V4L2_FRMSIZE_TYPE_DISCRETE:
+         data->framesizes[data->no_framesizes].discrete = frmsize.discrete;
+         break;
+       case V4L2_FRMSIZE_TYPE_CONTINUOUS:
+       case V4L2_FRMSIZE_TYPE_STEPWISE:
+         data->framesizes[data->no_framesizes].stepwise = frmsize.stepwise;
+         break;
+      }
+      data->no_framesizes++;
+    }
+  }
+}
+
+int v4lconvert_enum_framesizes(struct v4lconvert_data *data,
+  struct v4l2_frmsizeenum *frmsize)
+{
+  if (!v4lconvert_supported_dst_format(frmsize->pixel_format))
+    return syscall(SYS_ioctl, data->fd, VIDIOC_ENUM_FRAMESIZES, frmsize);
+
+  if (frmsize->index >= data->no_framesizes) {
+    errno = EINVAL;
+    return -1;
+  }
+
+  frmsize->type = data->framesizes[frmsize->index].type;
+  switch(frmsize->type) {
+    case V4L2_FRMSIZE_TYPE_DISCRETE:
+      frmsize->discrete = data->framesizes[frmsize->index].discrete;
+      break;
+    case V4L2_FRMSIZE_TYPE_CONTINUOUS:
+    case V4L2_FRMSIZE_TYPE_STEPWISE:
+      frmsize->stepwise = data->framesizes[frmsize->index].stepwise;
+      break;
+  }
+
+  return 0;
+}
+
+int v4lconvert_enum_frameintervals(struct v4lconvert_data *data,
+  struct v4l2_frmivalenum *frmival)
+{
+  int res;
+  struct v4l2_format src_fmt, dest_fmt;
+
+  if (!v4lconvert_supported_dst_format(frmival->pixel_format))
+    return syscall(SYS_ioctl, data->fd, VIDIOC_ENUM_FRAMEINTERVALS, frmival);
+
+  /* Check which format we will be using to convert to frmival->pixel_format */
+  memset(&dest_fmt, 0, sizeof(dest_fmt));
+  dest_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  dest_fmt.fmt.pix.pixelformat = frmival->pixel_format;
+  dest_fmt.fmt.pix.width = frmival->width;
+  dest_fmt.fmt.pix.height = frmival->height;
+  if ((res = v4lconvert_try_format(data, &dest_fmt, &src_fmt)))
+    return res;
+
+  /* Check the requested format is supported exactly as requested */
+  if (dest_fmt.fmt.pix.pixelformat != frmival->pixel_format ||
+      dest_fmt.fmt.pix.width  != frmival->width ||
+      dest_fmt.fmt.pix.height != frmival->height) {
+    errno = EINVAL;
+    return -1;
+  }
+
+  /* Enumerate the frameintervals of the source format we will be using */
+  frmival->pixel_format = src_fmt.fmt.pix.pixelformat;
+  frmival->width = src_fmt.fmt.pix.width;
+  frmival->height = src_fmt.fmt.pix.height;
+  res = syscall(SYS_ioctl, data->fd, VIDIOC_ENUM_FRAMEINTERVALS, frmival);
+
+  /* Restore the requested format in the frmival struct */
+  frmival->pixel_format = dest_fmt.fmt.pix.pixelformat;
+  frmival->width = dest_fmt.fmt.pix.width;
+  frmival->height = dest_fmt.fmt.pix.height;
+
+  return res;
+}


---

Patch is available at: 
http://linuxtv.org/hg/v4l-dvb/rev/10a00264075474f8b65b8a4a9e92c13f19f5aa62

_______________________________________________
linuxtv-commits mailing list
linuxtv-commits@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to