summaryrefslogtreecommitdiff
path: root/v4l2-apps/libv4l
diff options
context:
space:
mode:
authorhans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain>2009-03-11 13:23:30 +0100
committerhans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain>2009-03-11 13:23:30 +0100
commitee232e3e24844fa93b83949e34e6a2cc60f8cdfc (patch)
tree3a92e3bd3395e18bb3635c83969a9724270ac5ce /v4l2-apps/libv4l
parent093f82628ef903225b639005aaf13516e5144db1 (diff)
downloadmediapointer-dvb-s2-ee232e3e24844fa93b83949e34e6a2cc60f8cdfc.tar.gz
mediapointer-dvb-s2-ee232e3e24844fa93b83949e34e6a2cc60f8cdfc.tar.bz2
libv4l: us USB-id's instead of USB product string in upside down dev table
From: Hans de Goede <hdegoede@redhat.com> Switch to using USB-id's instead of USB product string, as not all devices set a unique product string. This fixes the upside down issues with genius e-messenger 112 cams Priority: normal Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'v4l2-apps/libv4l')
-rw-r--r--v4l2-apps/libv4l/ChangeLog3
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h6
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c57
3 files changed, 55 insertions, 11 deletions
diff --git a/v4l2-apps/libv4l/ChangeLog b/v4l2-apps/libv4l/ChangeLog
index c4f6ffae5..a23632027 100644
--- a/v4l2-apps/libv4l/ChangeLog
+++ b/v4l2-apps/libv4l/ChangeLog
@@ -5,6 +5,9 @@ libv4l-0.5.8
* Remove v4lconvert_yvyu_to_yuv420 function as its functionality is
duplicate with v4lconvert_yuyv_to_yuv420
* Use Requires.private where appropiate in .pc files (patch by Gregor Jasny)
+* Switch to using USB-id's instead of USB product string, as not all devices
+ set a unique product string. This fixes the upside down issues with
+ genius e-messenger 112 cams
libv4l-0.5.7
------------
diff --git a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h
index c8fa705f0..6bcf2cb26 100644
--- a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h
+++ b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h
@@ -96,7 +96,11 @@ struct v4lconvert_data {
};
struct v4lconvert_flags_info {
- const char *card;
+ unsigned short vendor_id;
+ unsigned short product_id;
+/* We could also use the USB manufacturer and product strings some devices have
+ const char *manufacturer;
+ const char *product; */
int flags;
};
diff --git a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c
index 776bbfe14..8cc63d47a 100644
--- a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c
+++ b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c
@@ -21,6 +21,8 @@
#include <stdlib.h>
#include <syscall.h>
#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include "libv4lconvert.h"
#include "libv4lconvert-priv.h"
@@ -66,11 +68,10 @@ static const struct v4lconvert_pixfmt supported_dst_pixfmts[] = {
/* List of cams which need special flags */
static const struct v4lconvert_flags_info v4lconvert_flags[] = {
- { "SPC 200NC ", V4LCONVERT_ROTATE_180 },
- { "SPC 300NC ", V4LCONVERT_ROTATE_180 }, /* Unconfirmed ! */
- { "SPC210NC ", V4LCONVERT_ROTATE_180 },
- { "USB Camera (0471:0326)", V4LCONVERT_ROTATE_180 }, /* SPC300NC */
- { "USB Camera (093a:2476)", V4LCONVERT_ROTATE_180 }, /* Genius E-M 112 */
+ { 0x0471, 0x0325, V4LCONVERT_ROTATE_180 }, /* Philips SPC200NC */
+ { 0x0471, 0x0326, V4LCONVERT_ROTATE_180 }, /* Philips SPC300NC */
+ { 0x0471, 0x032d, V4LCONVERT_ROTATE_180 }, /* Philips SPC210NC */
+ { 0x093a, 0x2476, V4LCONVERT_ROTATE_180 }, /* Genius E-M 112 */
};
/* List of well known resolutions which we can get by cropping somewhat larger
@@ -86,6 +87,46 @@ static const int v4lconvert_crop_res[][2] = {
{ 176, 144 },
};
+static int v4lconvert_get_flags(int fd)
+{
+ struct stat st;
+ FILE *f;
+ char sysfs_name[512];
+ unsigned short vendor_id = 0;
+ unsigned short product_id = 0;
+ int i;
+
+ if (fstat(fd, &st) || !S_ISCHR(st.st_mode))
+ return 0; /* Should never happen */
+
+ /* Get product ID */
+ snprintf(sysfs_name, sizeof(sysfs_name),
+ "/sys/class/video4linux/video%d/device/idVendor",
+ minor(st.st_rdev));
+ f = fopen(sysfs_name, "r");
+ if (!f)
+ return 0; /* Not an USB device (or no sysfs) */
+ i = fscanf(f, "%hx", &vendor_id);
+ fclose(f);
+
+ /* Get product ID */
+ snprintf(sysfs_name, sizeof(sysfs_name),
+ "/sys/class/video4linux/video%d/device/idProduct",
+ minor(st.st_rdev));
+ f = fopen(sysfs_name, "r");
+ if (!f)
+ return 0; /* Should never happen */
+ i = fscanf(f, "%hx", &product_id);
+ fclose(f);
+
+ for (i = 0; i < ARRAY_SIZE(v4lconvert_flags); i++)
+ if (v4lconvert_flags[i].vendor_id == vendor_id &&
+ v4lconvert_flags[i].product_id == product_id)
+ return v4lconvert_flags[i].flags;
+
+ return 0;
+}
+
struct v4lconvert_data *v4lconvert_create(int fd)
{
int i, j;
@@ -117,12 +158,8 @@ struct v4lconvert_data *v4lconvert_create(int fd)
data->no_formats = i;
/* Check if this cam has any special flags */
+ data->flags = v4lconvert_get_flags(data->fd);
if (syscall(SYS_ioctl, fd, VIDIOC_QUERYCAP, &cap) == 0) {
- for (i = 0; i < ARRAY_SIZE(v4lconvert_flags); i++)
- if (!strcmp((const char *)v4lconvert_flags[i].card, (char *)cap.card)) {
- data->flags = v4lconvert_flags[i].flags;
- break;
- }
if (!strcmp((char *)cap.driver, "uvcvideo"))
data->flags |= V4LCONVERT_IS_UVC;
}