diff options
author | hans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain> | 2009-03-11 13:23:30 +0100 |
---|---|---|
committer | hans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain> | 2009-03-11 13:23:30 +0100 |
commit | ee232e3e24844fa93b83949e34e6a2cc60f8cdfc (patch) | |
tree | 3a92e3bd3395e18bb3635c83969a9724270ac5ce /v4l2-apps/libv4l | |
parent | 093f82628ef903225b639005aaf13516e5144db1 (diff) | |
download | mediapointer-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/ChangeLog | 3 | ||||
-rw-r--r-- | v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h | 6 | ||||
-rw-r--r-- | v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c | 57 |
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; } |