From fa59c01eadd849ed2e5b0cf1406347bf632c80ed Mon Sep 17 00:00:00 2001 From: "hans@rhel5-devel.localdomain" Date: Mon, 13 Apr 2009 20:02:34 +0200 Subject: libv4l: add video processing: whitebalance and normalize From: Hans de Goede As the version number shows this work is the basis for a beta release of the 0.6.x series, the big change here is the addition of video processing to libv4l currently this only does whitebalance and normalizing (which turns out to be useless for most cams) but the basic framework for doing video processing, and being able to control it through fake v4l2 controls using for example v4l2ucp is there. The initial version of this code was written by 3 of my computer science students: Elmar Kleijn, Sjoerd Piepenbrink and Radjnies Bhansingh. This initial hg commit is a cleaned up and somewhat bug fixed version of their code. Priority: normal Signed-off-by: Hans de Goede --- .../libv4l/libv4lconvert/control/libv4lcontrol.c | 210 +++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c new file mode 100644 index 000000000..cb4e34327 --- /dev/null +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -0,0 +1,210 @@ +/* +# (C) 2008-2009 Elmar Kleijn +# (C) 2008-2009 Sjoerd Piepenbrink +# (C) 2008-2009 Radjnies Bhansingh +# (C) 2008-2009 Hans de Goede + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "libv4lcontrol.h" +#include "libv4lcontrol-priv.h" + +/* These headers are not needed by us, but by linux/videodev2.h, + which is broken on some systems and doesn't include them itself :( */ +#include +#include +#include +/* end broken header workaround includes */ +#include + +static void v4lcontrol_init(struct v4lcontrol_data *data, int first_time) +{ + /* FIXME: Temporary spoof future communication with driver by always enabling + the fake controls */ + data->controls = (1 << V4LCONTROL_WHITEBALANCE) | + (1 << V4LCONTROL_NORMALIZE) | (1 << V4LCONTROL_NORM_LOW_BOUND) | + (1 << V4LCONTROL_NORM_HIGH_BOUND); + + if (first_time) { + /* Initialize the new shm object when created */ + memset(data->shm_values, 0, sizeof(V4LCONTROL_SHM_SIZE)); + data->shm_values[V4LCONTROL_WHITEBALANCE] = 1; + data->shm_values[V4LCONTROL_NORM_HIGH_BOUND] = 255; + } +} + +struct v4lcontrol_data *v4lcontrol_create(int fd) +{ + int shm_fd; + int init = 0; + char shm_name[256]; + struct v4l2_capability cap; + + struct v4lcontrol_data *data = calloc(1, sizeof(struct v4lcontrol_data)); + + if (!data) + return NULL; + + syscall(SYS_ioctl, fd, VIDIOC_QUERYCAP, &cap); + snprintf(shm_name, 256, "/%s:%s", cap.bus_info, cap.card); + + /* Open the shared memory object identified by shm_name */ + if ((shm_fd = shm_open(shm_name, (O_CREAT | O_EXCL | O_RDWR), + (S_IREAD | S_IWRITE))) >= 0) + init = 1; + else if ((shm_fd = shm_open(shm_name, O_RDWR, (S_IREAD | S_IWRITE))) < 0) + goto error; + + /* Set the shared memory size */ + ftruncate(shm_fd, V4LCONTROL_SHM_SIZE); + + /* Retreive a pointer to the shm object */ + data->shm_values = mmap(NULL, V4LCONTROL_SHM_SIZE, (PROT_READ | PROT_WRITE), + MAP_SHARED, shm_fd, 0); + close(shm_fd); + + if (data->shm_values == MAP_FAILED) + goto error; + + v4lcontrol_init(data, init); /* Set the driver defined fake controls */ + + data->fd = fd; + + return data; + +error: + free(data); + return NULL; +} + +void v4lcontrol_destroy(struct v4lcontrol_data *data) +{ + munmap(data->shm_values, V4LCONTROL_SHM_SIZE); + free(data); +} + +/* FIXME get better CID's for normalize */ +struct v4l2_queryctrl fake_controls[V4LCONTROL_COUNT] = { +{ + .id = V4L2_CID_AUTO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Whitebalance", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + .flags = 0 +}, +{ + .id = V4L2_CID_DO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Normalize", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + .flags = 0 +}, +{ + .id = V4L2_CID_BLACK_LEVEL, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Normalize: low bound", + .minimum = 0, + .maximum = 127, + .step = 1, + .default_value = 0, + .flags = 0 +}, +{ + .id = V4L2_CID_WHITENESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Normalize: high bound", + .minimum = 128, + .maximum = 255, + .step = 1, + .default_value = 255, + .flags = 0 +}, +}; + +int v4lcontrol_vidioc_queryctrl(struct v4lcontrol_data *data, void *arg) +{ + int i; + struct v4l2_queryctrl *ctrl = arg; + + for (i = 0; i < V4LCONTROL_COUNT; i++) + if ((data->controls & (1 << i)) && + ctrl->id == fake_controls[i].id) { + memcpy(ctrl, &fake_controls[i], sizeof(struct v4l2_queryctrl)); + return 0; + } + + return syscall(SYS_ioctl, data->fd, VIDIOC_QUERYCTRL, arg); +} + +int v4lcontrol_vidioc_g_ctrl(struct v4lcontrol_data *data, void *arg) +{ + int i; + struct v4l2_control *ctrl = arg; + + for (i = 0; i < V4LCONTROL_COUNT; i++) + if ((data->controls & (1 << i)) && + ctrl->id == fake_controls[i].id) { + ctrl->value = data->shm_values[i]; + return 0; + } + + return syscall(SYS_ioctl, data->fd, VIDIOC_G_CTRL, arg); +} + +int v4lcontrol_vidioc_s_ctrl(struct v4lcontrol_data *data, void *arg) +{ + int i; + struct v4l2_control *ctrl = arg; + + for (i = 0; i < V4LCONTROL_COUNT; i++) + if ((data->controls & (1 << i)) && + ctrl->id == fake_controls[i].id) { + if (ctrl->value > fake_controls[i].maximum || + ctrl->value < fake_controls[i].minimum) { + errno = EINVAL; + return -1; + } + + data->shm_values[i] = ctrl->value; + return 0; + } + + return syscall(SYS_ioctl, data->fd, VIDIOC_S_CTRL, arg); +} + +int v4lcontrol_get_ctrl(struct v4lcontrol_data *data, int ctrl) +{ + if (data->controls & (1 << ctrl)) + return data->shm_values[ctrl]; + + return 0; +} -- cgit v1.2.3 From 10a09b9ec6e08fb95c36f26d7f69834b0387386b Mon Sep 17 00:00:00 2001 From: "hans@rhel5-devel.localdomain" Date: Tue, 14 Apr 2009 09:51:35 +0200 Subject: libv4l: Enable whitebalancing algorithm based on USB id's From: Hans de Goede * Determine wether or not to do whitebalance and/or normalize at all based on USB-ID's. * Add rotate90 hack to flags based on usb-id. Priority: normal Signed-off-by: Hans de Goede --- .../libv4l/libv4lconvert/control/libv4lcontrol.c | 159 +++++++++++++++++++-- 1 file changed, 145 insertions(+), 14 deletions(-) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index cb4e34327..de8b608f9 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -40,27 +40,139 @@ /* end broken header workaround includes */ #include -static void v4lcontrol_init(struct v4lcontrol_data *data, int first_time) +#define ARRAY_SIZE(x) ((int)sizeof(x)/(int)sizeof((x)[0])) + +/* Workaround these potentially missing from videodev2.h */ +#ifndef V4L2_IN_ST_HFLIP +#define V4L2_IN_ST_HFLIP 0x00000010 /* Frames are flipped horizontally */ +#endif + +#ifndef V4L2_IN_ST_VFLIP +#define V4L2_IN_ST_VFLIP 0x00000020 /* Frames are flipped vertically */ +#endif + + +/* List of cams which need special flags */ +static const struct v4lcontrol_flags_info v4lcontrol_flags[] = { +/* First: Upside down devices */ + /* Philips SPC200NC */ + { 0x0471, 0x0325, 0, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0 }, + /* Philips SPC300NC */ + { 0x0471, 0x0326, 0, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0 }, + /* Philips SPC210NC */ + { 0x0471, 0x032d, 0, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0 }, + /* Genius E-M 112 */ + { 0x093a, 0x2476, 0, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0 }, +/* Second: devices which can benifit from software video processing */ + /* Pac207 based devices */ + { 0x041e, 0x4028, 0, 0, V4LCONTROL_WANTS_WB }, + { 0x093a, 0x2460, 0x1f, 0, V4LCONTROL_WANTS_WB }, + { 0x145f, 0x013a, 0, 0, V4LCONTROL_WANTS_WB }, + { 0x2001, 0xf115, 0, 0, V4LCONTROL_WANTS_WB }, + /* Pac7302 based devices */ + { 0x093a, 0x2620, 0x0f, V4LCONTROL_ROTATED_90_JPEG, V4LCONTROL_WANTS_WB }, +}; + +static void v4lcontrol_init_flags(struct v4lcontrol_data *data) { - /* FIXME: Temporary spoof future communication with driver by always enabling - the fake controls */ - data->controls = (1 << V4LCONTROL_WHITEBALANCE) | - (1 << V4LCONTROL_NORMALIZE) | (1 << V4LCONTROL_NORM_LOW_BOUND) | - (1 << V4LCONTROL_NORM_HIGH_BOUND); - - if (first_time) { - /* Initialize the new shm object when created */ - memset(data->shm_values, 0, sizeof(V4LCONTROL_SHM_SIZE)); - data->shm_values[V4LCONTROL_WHITEBALANCE] = 1; - data->shm_values[V4LCONTROL_NORM_HIGH_BOUND] = 255; + struct stat st; + FILE *f; + char sysfs_name[512]; + unsigned short vendor_id = 0; + unsigned short product_id = 0; + int i, minor; + char c, *s, buf[32]; + struct v4l2_input input; + + if ((syscall(SYS_ioctl, data->fd, VIDIOC_G_INPUT, &input.index) == 0) && + (syscall(SYS_ioctl, data->fd, VIDIOC_ENUMINPUT, &input) == 0)) { + if (input.status & V4L2_IN_ST_HFLIP) + data->flags |= V4LCONTROL_HFLIPPED; + if (input.status & V4L2_IN_ST_VFLIP) + data->flags |= V4LCONTROL_VFLIPPED; } + + if (fstat(data->fd, &st) || !S_ISCHR(st.st_mode)) { + return; /* Should never happen */ + } + + /* find ourselve in sysfs */ + for (i = 0; i < 256; i++) { + snprintf(sysfs_name, sizeof(sysfs_name), + "/sys/class/video4linux/video%d/dev", i); + f = fopen(sysfs_name, "r"); + if (!f) + continue; + + s = fgets(buf, sizeof(buf), f); + fclose(f); + + if (s && sscanf(buf, "%*d:%d%c", &minor, &c) == 2 && c == '\n' && + minor == minor(st.st_rdev)) + break; + } + if (i == 256) + return; /* Not found, sysfs not mounted? */ + + /* Get vendor and product ID */ + snprintf(sysfs_name, sizeof(sysfs_name), + "/sys/class/video4linux/video%d/device/modalias", i); + f = fopen(sysfs_name, "r"); + if (f) { + s = fgets(buf, sizeof(buf), f); + fclose(f); + + if (!s || + sscanf(s, "usb:v%4hxp%4hx%c", &vendor_id, &product_id, &c) != 3 || + c != 'd') + return; /* Not an USB device */ + } else { + /* Try again assuming the device link points to the usb + device instead of the usb interface (bug in older versions + of gspca) */ + + /* Get product ID */ + snprintf(sysfs_name, sizeof(sysfs_name), + "/sys/class/video4linux/video%d/device/idVendor", i); + f = fopen(sysfs_name, "r"); + if (!f) + return; /* Not an USB device (or no sysfs) */ + + s = fgets(buf, sizeof(buf), f); + fclose(f); + + if (!s || sscanf(s, "%04hx%c", &vendor_id, &c) != 2 || c != '\n') + return; /* Should never happen */ + + /* Get product ID */ + snprintf(sysfs_name, sizeof(sysfs_name), + "/sys/class/video4linux/video%d/device/idProduct", i); + f = fopen(sysfs_name, "r"); + if (!f) + return; /* Should never happen */ + + s = fgets(buf, sizeof(buf), f); + fclose(f); + + if (!s || sscanf(s, "%04hx%c", &product_id, &c) != 2 || c != '\n') + return; /* Should never happen */ + } + + for (i = 0; i < ARRAY_SIZE(v4lcontrol_flags); i++) + if (v4lcontrol_flags[i].vendor_id == vendor_id && + v4lcontrol_flags[i].product_id == + (product_id & ~v4lcontrol_flags[i].product_mask)) { + data->flags |= v4lcontrol_flags[i].flags; + data->controls = v4lcontrol_flags[i].controls; + break; + } } struct v4lcontrol_data *v4lcontrol_create(int fd) { int shm_fd; int init = 0; - char shm_name[256]; + char *s, shm_name[256]; struct v4l2_capability cap; struct v4lcontrol_data *data = calloc(1, sizeof(struct v4lcontrol_data)); @@ -89,10 +201,24 @@ struct v4lcontrol_data *v4lcontrol_create(int fd) if (data->shm_values == MAP_FAILED) goto error; - v4lcontrol_init(data, init); /* Set the driver defined fake controls */ + if (init) { + /* Initialize the new shm object we created */ + memset(data->shm_values, 0, sizeof(V4LCONTROL_SHM_SIZE)); + data->shm_values[V4LCONTROL_WHITEBALANCE] = 1; + data->shm_values[V4LCONTROL_NORM_HIGH_BOUND] = 255; + } data->fd = fd; + v4lcontrol_init_flags(data); + + /* Allow overriding through environment */ + if ((s = getenv("LIBV4LCONTROL_FLAGS"))) + data->flags = strtol(s, NULL, 0); + + if ((s = getenv("LIBV4LCONTROL_CONTROLS"))) + data->controls = strtol(s, NULL, 0); + return data; error: @@ -201,6 +327,11 @@ int v4lcontrol_vidioc_s_ctrl(struct v4lcontrol_data *data, void *arg) return syscall(SYS_ioctl, data->fd, VIDIOC_S_CTRL, arg); } +int v4lcontrol_get_flags(struct v4lcontrol_data *data) +{ + return data->flags; +} + int v4lcontrol_get_ctrl(struct v4lcontrol_data *data, int ctrl) { if (data->controls & (1 << ctrl)) -- cgit v1.2.3 From 58d3334b54c207b8e04e7035969e0c2acfa1ce73 Mon Sep 17 00:00:00 2001 From: "hans@rhel5-devel.localdomain" Date: Tue, 14 Apr 2009 15:03:07 +0200 Subject: libv4l: Only allow supported destination formats when doing processing From: Hans de Goede Only report / allow supported destination formats in enum_fmt / try_fmt / g_fmt / s_fmt when processing, rotating or flipping. Priority: normal Signed-off-by: Hans de Goede --- v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index de8b608f9..b09ffc582 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -339,3 +339,8 @@ int v4lcontrol_get_ctrl(struct v4lcontrol_data *data, int ctrl) return 0; } + +/* See the comment about this in libv4lconvert.h */ +int v4lcontrol_needs_conversion(struct v4lcontrol_data *data) { + return data->flags || data->controls; +} -- cgit v1.2.3 From 279a5b30fa2545d54a582d9a8e4dd3e4beceac40 Mon Sep 17 00:00:00 2001 From: "hans@rhel5-devel.localdomain" Date: Thu, 16 Apr 2009 09:52:50 +0200 Subject: libv4l: genius messenger 112 needs both upside down and whitebalance flags. From: Hans de Goede libv4l: genius messenger 112 needs both upside down and whitebalance flags. Priority: normal Signed-off-by: Hans de Goede --- v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index b09ffc582..ff9b3b5c1 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -61,9 +61,10 @@ static const struct v4lcontrol_flags_info v4lcontrol_flags[] = { { 0x0471, 0x0326, 0, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0 }, /* Philips SPC210NC */ { 0x0471, 0x032d, 0, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0 }, - /* Genius E-M 112 */ - { 0x093a, 0x2476, 0, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0 }, -/* Second: devices which can benifit from software video processing */ + /* Genius E-M 112 (also needs processing) */ + { 0x093a, 0x2476, 0, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, + V4LCONTROL_WANTS_WB }, +/* Second: devices which can benefit from software video processing */ /* Pac207 based devices */ { 0x041e, 0x4028, 0, 0, V4LCONTROL_WANTS_WB }, { 0x093a, 0x2460, 0x1f, 0, V4LCONTROL_WANTS_WB }, -- cgit v1.2.3 From 53edb5d92907f9dd3f0dff06eff83cc864345e00 Mon Sep 17 00:00:00 2001 From: "hans@rhel5-devel.localdomain" Date: Thu, 16 Apr 2009 11:26:54 +0200 Subject: libv4l: if the card name contains a / replace it with a - in the shm name From: Hans de Goede / is not allowed inside shm names, so if the card name contains a / replace it with a - Priority: normal Signed-off-by: Hans de Goede --- v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index ff9b3b5c1..4834c786a 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -172,7 +172,7 @@ static void v4lcontrol_init_flags(struct v4lcontrol_data *data) struct v4lcontrol_data *v4lcontrol_create(int fd) { int shm_fd; - int init = 0; + int i, init = 0; char *s, shm_name[256]; struct v4l2_capability cap; @@ -184,6 +184,11 @@ struct v4lcontrol_data *v4lcontrol_create(int fd) syscall(SYS_ioctl, fd, VIDIOC_QUERYCAP, &cap); snprintf(shm_name, 256, "/%s:%s", cap.bus_info, cap.card); + /* / is not allowed inside shm names */ + for (i = 1; shm_name[i]; i++) + if (shm_name[i] == '/') + shm_name[i] = '-'; + /* Open the shared memory object identified by shm_name */ if ((shm_fd = shm_open(shm_name, (O_CREAT | O_EXCL | O_RDWR), (S_IREAD | S_IWRITE))) >= 0) -- cgit v1.2.3 From b2a1a64aa8c773f2648b5526bf414277d3106854 Mon Sep 17 00:00:00 2001 From: "hans@rhel5-devel.localdomain" Date: Thu, 16 Apr 2009 11:31:21 +0200 Subject: libv4l: Only created shared memory segment when we have fake v4l2 controls From: Hans de Goede libv4l: Only created shared memory segment when we have fake v4l2 controls Priority: normal Signed-off-by: Hans de Goede --- .../libv4l/libv4lconvert/control/libv4lcontrol.c | 28 ++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index 4834c786a..2aa2d8b38 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -181,6 +181,20 @@ struct v4lcontrol_data *v4lcontrol_create(int fd) if (!data) return NULL; + data->fd = fd; + + v4lcontrol_init_flags(data); + + /* Allow overriding through environment */ + if ((s = getenv("LIBV4LCONTROL_FLAGS"))) + data->flags = strtol(s, NULL, 0); + + if ((s = getenv("LIBV4LCONTROL_CONTROLS"))) + data->controls = strtol(s, NULL, 0); + + if (data->controls == 0) + return data; /* No need to create a shared memory segment */ + syscall(SYS_ioctl, fd, VIDIOC_QUERYCAP, &cap); snprintf(shm_name, 256, "/%s:%s", cap.bus_info, cap.card); @@ -214,17 +228,6 @@ struct v4lcontrol_data *v4lcontrol_create(int fd) data->shm_values[V4LCONTROL_NORM_HIGH_BOUND] = 255; } - data->fd = fd; - - v4lcontrol_init_flags(data); - - /* Allow overriding through environment */ - if ((s = getenv("LIBV4LCONTROL_FLAGS"))) - data->flags = strtol(s, NULL, 0); - - if ((s = getenv("LIBV4LCONTROL_CONTROLS"))) - data->controls = strtol(s, NULL, 0); - return data; error: @@ -234,7 +237,8 @@ error: void v4lcontrol_destroy(struct v4lcontrol_data *data) { - munmap(data->shm_values, V4LCONTROL_SHM_SIZE); + if (data->controls) + munmap(data->shm_values, V4LCONTROL_SHM_SIZE); free(data); } -- cgit v1.2.3 From 53d7375e8b366a0639000eb0377a93fc20ee563b Mon Sep 17 00:00:00 2001 From: "hans@rhel5-devel.localdomain" Date: Fri, 17 Apr 2009 11:12:08 +0200 Subject: libv4l: Add sq905 to the list of devices which benefit from whitebalancing From: Hans de Goede libv4l: Add sq905 to the list of devices which benefit from whitebalancing Priority: normal Signed-off-by: Hans de Goede --- v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index 2aa2d8b38..93c08c0c2 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -72,6 +72,8 @@ static const struct v4lcontrol_flags_info v4lcontrol_flags[] = { { 0x2001, 0xf115, 0, 0, V4LCONTROL_WANTS_WB }, /* Pac7302 based devices */ { 0x093a, 0x2620, 0x0f, V4LCONTROL_ROTATED_90_JPEG, V4LCONTROL_WANTS_WB }, + /* sq905 devices */ + { 0x2770, 0x9120, 0, 0, V4LCONTROL_WANTS_WB }, }; static void v4lcontrol_init_flags(struct v4lcontrol_data *data) -- cgit v1.2.3 From 89b93efcabe5cc48d405d26843b53d288286752b Mon Sep 17 00:00:00 2001 From: "hans@localhost.localdomain" Date: Sat, 16 May 2009 12:57:18 +0200 Subject: libv4l: Support V4L2_CTRL_FLAG_NEXT_CTRL for fake controls From: Adam Baker The "fake" controls added by libv4l to provide whitebalance on some cameras do not respect the V4L2_CTRL_FLAG_NEXT_CTRL and hence don't appear on control programs that try to use that flag if there are any driver controls that do support the flag. Add support for V4L2_CTRL_FLAG_NEXT_CTRL Priority: normal Signed-off-by: Adam Baker Signed-off-by: Hans de Goede --- .../libv4l/libv4lconvert/control/libv4lcontrol.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index 93c08c0c2..63de07bf1 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -292,7 +292,10 @@ int v4lcontrol_vidioc_queryctrl(struct v4lcontrol_data *data, void *arg) { int i; struct v4l2_queryctrl *ctrl = arg; + int retval; + __u32 orig_id=ctrl->id; + /* if we have an exact match return it */ for (i = 0; i < V4LCONTROL_COUNT; i++) if ((data->controls & (1 << i)) && ctrl->id == fake_controls[i].id) { @@ -300,7 +303,21 @@ int v4lcontrol_vidioc_queryctrl(struct v4lcontrol_data *data, void *arg) return 0; } - return syscall(SYS_ioctl, data->fd, VIDIOC_QUERYCTRL, arg); + /* find out what the kernel driver would respond. */ + retval = syscall(SYS_ioctl, data->fd, VIDIOC_QUERYCTRL, arg); + + /* if any of our controls have an id > orig_id but less than + ctrl->id then return that control instead. */ + if (orig_id & V4L2_CTRL_FLAG_NEXT_CTRL) + for (i = 0; i < V4LCONTROL_COUNT; i++) + if ((data->controls & (1 << i)) && + (fake_controls[i].id > (orig_id & ~V4L2_CTRL_FLAG_NEXT_CTRL)) && + (fake_controls[i].id <= ctrl->id)) { + memcpy(ctrl, &fake_controls[i], sizeof(struct v4l2_queryctrl)); + retval = 0; + } + + return retval; } int v4lcontrol_vidioc_g_ctrl(struct v4lcontrol_data *data, void *arg) -- cgit v1.2.3 From 719bdce1fa2e052cbd9c4cc21362dd21b662f989 Mon Sep 17 00:00:00 2001 From: "hans@localhost.localdomain" Date: Sat, 16 May 2009 22:04:27 +0200 Subject: libv4l: add ability to determine flags based on DMI info From: Hans de Goede It is possible for the same laptop webcam module (so same usb id) to be mounted upside down in some models and the right way up in other laptop models. This patch adds the ability to only apply flags to a webcam based on the combination of usb id and dmi info to identify the laptop model. It also adds the webcam in the Asus N50Vn as the first upside down cam identified this way. Priority: normal Signed-off-by: Hans de Goede --- .../libv4l/libv4lconvert/control/libv4lcontrol.c | 49 +++++++++++++++++----- 1 file changed, 38 insertions(+), 11 deletions(-) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index 63de07bf1..1ffd05cc4 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -56,24 +56,28 @@ static const struct v4lcontrol_flags_info v4lcontrol_flags[] = { /* First: Upside down devices */ /* Philips SPC200NC */ - { 0x0471, 0x0325, 0, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0 }, + { 0x0471, 0x0325, 0, NULL, NULL, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0 }, /* Philips SPC300NC */ - { 0x0471, 0x0326, 0, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0 }, + { 0x0471, 0x0326, 0, NULL, NULL, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0 }, /* Philips SPC210NC */ - { 0x0471, 0x032d, 0, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0 }, + { 0x0471, 0x032d, 0, NULL, NULL, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0 }, /* Genius E-M 112 (also needs processing) */ - { 0x093a, 0x2476, 0, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, + { 0x093a, 0x2476, 0, NULL, NULL, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, V4LCONTROL_WANTS_WB }, + /* Asus N50Vn laptop */ + { 0x04f2, 0xb106, 0, "ASUSTeK Computer Inc. ", "N50Vn ", + V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0 }, /* Second: devices which can benefit from software video processing */ /* Pac207 based devices */ - { 0x041e, 0x4028, 0, 0, V4LCONTROL_WANTS_WB }, - { 0x093a, 0x2460, 0x1f, 0, V4LCONTROL_WANTS_WB }, - { 0x145f, 0x013a, 0, 0, V4LCONTROL_WANTS_WB }, - { 0x2001, 0xf115, 0, 0, V4LCONTROL_WANTS_WB }, + { 0x041e, 0x4028, 0, NULL, NULL, 0, V4LCONTROL_WANTS_WB }, + { 0x093a, 0x2460, 0x1f, NULL, NULL, 0, V4LCONTROL_WANTS_WB }, + { 0x145f, 0x013a, 0, NULL, NULL, 0, V4LCONTROL_WANTS_WB }, + { 0x2001, 0xf115, 0, NULL, NULL, 0, V4LCONTROL_WANTS_WB }, /* Pac7302 based devices */ - { 0x093a, 0x2620, 0x0f, V4LCONTROL_ROTATED_90_JPEG, V4LCONTROL_WANTS_WB }, + { 0x093a, 0x2620, 0x0f, NULL, NULL, V4LCONTROL_ROTATED_90_JPEG, + V4LCONTROL_WANTS_WB }, /* sq905 devices */ - { 0x2770, 0x9120, 0, 0, V4LCONTROL_WANTS_WB }, + { 0x2770, 0x9120, 0, NULL, NULL, 0, V4LCONTROL_WANTS_WB }, }; static void v4lcontrol_init_flags(struct v4lcontrol_data *data) @@ -83,6 +87,8 @@ static void v4lcontrol_init_flags(struct v4lcontrol_data *data) char sysfs_name[512]; unsigned short vendor_id = 0; unsigned short product_id = 0; + char dmi_board_vendor[512] = ""; + char dmi_board_name[512]= ""; int i, minor; char c, *s, buf[32]; struct v4l2_input input; @@ -161,10 +167,31 @@ static void v4lcontrol_init_flags(struct v4lcontrol_data *data) return; /* Should never happen */ } + /* Get DMI board vendor and name */ + f = fopen("/sys/devices/virtual/dmi/id/board_vendor", "r"); + if (f) { + s = fgets(dmi_board_vendor, sizeof(dmi_board_vendor), f); + if (s) + s[strlen(s) - 1] = 0; + fclose(f); + } + + f = fopen("/sys/devices/virtual/dmi/id/board_name", "r"); + if (f) { + s = fgets(dmi_board_name, sizeof(dmi_board_name), f); + if (s) + s[strlen(s) - 1] = 0; + fclose(f); + } + for (i = 0; i < ARRAY_SIZE(v4lcontrol_flags); i++) if (v4lcontrol_flags[i].vendor_id == vendor_id && v4lcontrol_flags[i].product_id == - (product_id & ~v4lcontrol_flags[i].product_mask)) { + (product_id & ~v4lcontrol_flags[i].product_mask) && + (v4lcontrol_flags[i].dmi_board_vendor == NULL || + !strcmp(v4lcontrol_flags[i].dmi_board_vendor, dmi_board_vendor)) && + (v4lcontrol_flags[i].dmi_board_name == NULL || + !strcmp(v4lcontrol_flags[i].dmi_board_name, dmi_board_name))) { data->flags |= v4lcontrol_flags[i].flags; data->controls = v4lcontrol_flags[i].controls; break; -- cgit v1.2.3 From 34a210b573f9c8ff8f07077f239be95d9d9248c5 Mon Sep 17 00:00:00 2001 From: "hans@rhel5-devel.localdomain" Date: Wed, 20 May 2009 07:23:00 +0200 Subject: libv4l: add fake controls controlling the software h- and v-flipping From: Hans de Goede When we need to go through the fake mmap buffer anyways, we can add fake controls at no cost. So in the case of webcams which only support non standard pixformats, export fake flipping controls, as this can be done at no (performace) cost (until the user activates them). Priority: normal Signed-off-by: Hans de Goede --- .../libv4l/libv4lconvert/control/libv4lcontrol.c | 42 ++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index 1ffd05cc4..b120aa2fc 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -198,12 +198,13 @@ static void v4lcontrol_init_flags(struct v4lcontrol_data *data) } } -struct v4lcontrol_data *v4lcontrol_create(int fd) +struct v4lcontrol_data *v4lcontrol_create(int fd, int always_needs_conversion) { int shm_fd; int i, init = 0; char *s, shm_name[256]; struct v4l2_capability cap; + struct v4l2_queryctrl ctrl; struct v4lcontrol_data *data = calloc(1, sizeof(struct v4lcontrol_data)); @@ -214,6 +215,17 @@ struct v4lcontrol_data *v4lcontrol_create(int fd) v4lcontrol_init_flags(data); + /* If the device always needs conversion, we can add fake controls at no cost + (no cost when not activated by the user that is) */ + if (always_needs_conversion || v4lcontrol_needs_conversion(data)) { + ctrl.id = V4L2_CID_HFLIP; + if (syscall(SYS_ioctl, data->fd, VIDIOC_QUERYCTRL, &ctrl) == -1) + data->controls |= 1 << V4LCONTROL_HFLIP; + ctrl.id = V4L2_CID_VFLIP; + if (syscall(SYS_ioctl, data->fd, VIDIOC_QUERYCTRL, &ctrl) == -1) + data->controls |= 1 << V4LCONTROL_VFLIP; + } + /* Allow overriding through environment */ if ((s = getenv("LIBV4LCONTROL_FLAGS"))) data->flags = strtol(s, NULL, 0); @@ -313,6 +325,26 @@ struct v4l2_queryctrl fake_controls[V4LCONTROL_COUNT] = { .default_value = 255, .flags = 0 }, +{ + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Horizontal flip", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + .flags = 0 +}, +{ + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Vertical flip", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + .flags = 0 +}, }; int v4lcontrol_vidioc_queryctrl(struct v4lcontrol_data *data, void *arg) @@ -390,8 +422,14 @@ int v4lcontrol_get_flags(struct v4lcontrol_data *data) int v4lcontrol_get_ctrl(struct v4lcontrol_data *data, int ctrl) { - if (data->controls & (1 << ctrl)) + if (data->controls & (1 << ctrl)) { + /* Special case for devices with flipped input */ + if ((ctrl == V4LCONTROL_HFLIP && (data->flags & V4LCONTROL_HFLIPPED)) || + (ctrl == V4LCONTROL_VFLIP && (data->flags & V4LCONTROL_VFLIPPED))) + return !data->shm_values[ctrl]; + return data->shm_values[ctrl]; + } return 0; } -- cgit v1.2.3 From 62805a6b176a0bbd17ab8fa421791765186fb77d Mon Sep 17 00:00:00 2001 From: "hans@localhost.localdomain" Date: Thu, 21 May 2009 13:08:29 +0200 Subject: libv4l: rewrite video processing code From: Hans de Goede Rewrite video processing code to make it easier to add more video filters (and with little extra processing cost). As part of this the normalize filter has been removed as it wasn't functioning satisfactory anyways Priority: normal Signed-off-by: Hans de Goede --- .../libv4l/libv4lconvert/control/libv4lcontrol.c | 107 +++++++++------------ 1 file changed, 48 insertions(+), 59 deletions(-) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index b120aa2fc..4d227c366 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -56,30 +56,32 @@ static const struct v4lcontrol_flags_info v4lcontrol_flags[] = { /* First: Upside down devices */ /* Philips SPC200NC */ - { 0x0471, 0x0325, 0, NULL, NULL, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0 }, + { 0x0471, 0x0325, 0, NULL, NULL, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED }, /* Philips SPC300NC */ - { 0x0471, 0x0326, 0, NULL, NULL, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0 }, + { 0x0471, 0x0326, 0, NULL, NULL, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED }, /* Philips SPC210NC */ - { 0x0471, 0x032d, 0, NULL, NULL, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0 }, - /* Genius E-M 112 (also needs processing) */ - { 0x093a, 0x2476, 0, NULL, NULL, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, - V4LCONTROL_WANTS_WB }, + { 0x0471, 0x032d, 0, NULL, NULL, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED }, + /* Genius E-M 112 (also want whitebalance by default) */ + { 0x093a, 0x2476, 0, NULL, NULL, + V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED|V4LCONTROL_WANTS_WB }, /* Asus N50Vn laptop */ { 0x04f2, 0xb106, 0, "ASUSTeK Computer Inc. ", "N50Vn ", - V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0 }, -/* Second: devices which can benefit from software video processing */ + V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED }, +/* Second: devices which should use sw whitebalance by default */ /* Pac207 based devices */ - { 0x041e, 0x4028, 0, NULL, NULL, 0, V4LCONTROL_WANTS_WB }, - { 0x093a, 0x2460, 0x1f, NULL, NULL, 0, V4LCONTROL_WANTS_WB }, - { 0x145f, 0x013a, 0, NULL, NULL, 0, V4LCONTROL_WANTS_WB }, - { 0x2001, 0xf115, 0, NULL, NULL, 0, V4LCONTROL_WANTS_WB }, + { 0x041e, 0x4028, 0, NULL, NULL, V4LCONTROL_WANTS_WB }, + { 0x093a, 0x2460, 0x1f, NULL, NULL, V4LCONTROL_WANTS_WB }, + { 0x145f, 0x013a, 0, NULL, NULL, V4LCONTROL_WANTS_WB }, + { 0x2001, 0xf115, 0, NULL, NULL, V4LCONTROL_WANTS_WB }, /* Pac7302 based devices */ - { 0x093a, 0x2620, 0x0f, NULL, NULL, V4LCONTROL_ROTATED_90_JPEG, - V4LCONTROL_WANTS_WB }, + { 0x093a, 0x2620, 0x0f, NULL, NULL, + V4LCONTROL_ROTATED_90_JPEG|V4LCONTROL_WANTS_WB }, /* sq905 devices */ - { 0x2770, 0x9120, 0, NULL, NULL, 0, V4LCONTROL_WANTS_WB }, + { 0x2770, 0x9120, 0, NULL, NULL, V4LCONTROL_WANTS_WB }, }; +static const struct v4l2_queryctrl fake_controls[]; + static void v4lcontrol_init_flags(struct v4lcontrol_data *data) { struct stat st; @@ -193,7 +195,6 @@ static void v4lcontrol_init_flags(struct v4lcontrol_data *data) (v4lcontrol_flags[i].dmi_board_name == NULL || !strcmp(v4lcontrol_flags[i].dmi_board_name, dmi_board_name))) { data->flags |= v4lcontrol_flags[i].flags; - data->controls = v4lcontrol_flags[i].controls; break; } } @@ -215,21 +216,21 @@ struct v4lcontrol_data *v4lcontrol_create(int fd, int always_needs_conversion) v4lcontrol_init_flags(data); + /* Allow overriding through environment */ + if ((s = getenv("LIBV4LCONTROL_FLAGS"))) + data->flags = strtol(s, NULL, 0); + /* If the device always needs conversion, we can add fake controls at no cost (no cost when not activated by the user that is) */ if (always_needs_conversion || v4lcontrol_needs_conversion(data)) { - ctrl.id = V4L2_CID_HFLIP; - if (syscall(SYS_ioctl, data->fd, VIDIOC_QUERYCTRL, &ctrl) == -1) - data->controls |= 1 << V4LCONTROL_HFLIP; - ctrl.id = V4L2_CID_VFLIP; - if (syscall(SYS_ioctl, data->fd, VIDIOC_QUERYCTRL, &ctrl) == -1) - data->controls |= 1 << V4LCONTROL_VFLIP; + for (i = 0; i < V4LCONTROL_COUNT; i++) { + ctrl.id = fake_controls[i].id; + if (syscall(SYS_ioctl, data->fd, VIDIOC_QUERYCTRL, &ctrl) == -1) + data->controls |= 1 << i; + } } /* Allow overriding through environment */ - if ((s = getenv("LIBV4LCONTROL_FLAGS"))) - data->flags = strtol(s, NULL, 0); - if ((s = getenv("LIBV4LCONTROL_CONTROLS"))) data->controls = strtol(s, NULL, 0); @@ -265,8 +266,8 @@ struct v4lcontrol_data *v4lcontrol_create(int fd, int always_needs_conversion) if (init) { /* Initialize the new shm object we created */ memset(data->shm_values, 0, sizeof(V4LCONTROL_SHM_SIZE)); - data->shm_values[V4LCONTROL_WHITEBALANCE] = 1; - data->shm_values[V4LCONTROL_NORM_HIGH_BOUND] = 255; + if (data->flags & V4LCONTROL_WANTS_WB) + data->shm_values[V4LCONTROL_WHITEBALANCE] = 1; } return data; @@ -284,47 +285,17 @@ void v4lcontrol_destroy(struct v4lcontrol_data *data) } /* FIXME get better CID's for normalize */ -struct v4l2_queryctrl fake_controls[V4LCONTROL_COUNT] = { +static const struct v4l2_queryctrl fake_controls[V4LCONTROL_COUNT] = { { .id = V4L2_CID_AUTO_WHITE_BALANCE, .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Whitebalance", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - .flags = 0 -}, -{ - .id = V4L2_CID_DO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Normalize", + .name = "Whitebalance (software)", .minimum = 0, .maximum = 1, .step = 1, .default_value = 0, .flags = 0 }, -{ - .id = V4L2_CID_BLACK_LEVEL, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Normalize: low bound", - .minimum = 0, - .maximum = 127, - .step = 1, - .default_value = 0, - .flags = 0 -}, -{ - .id = V4L2_CID_WHITENESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Normalize: high bound", - .minimum = 128, - .maximum = 255, - .step = 1, - .default_value = 255, - .flags = 0 -}, { .id = V4L2_CID_HFLIP, .type = V4L2_CTRL_TYPE_BOOLEAN, @@ -359,6 +330,11 @@ int v4lcontrol_vidioc_queryctrl(struct v4lcontrol_data *data, void *arg) if ((data->controls & (1 << i)) && ctrl->id == fake_controls[i].id) { memcpy(ctrl, &fake_controls[i], sizeof(struct v4l2_queryctrl)); + /* Hmm, not pretty */ + if (ctrl->id == V4L2_CID_AUTO_WHITE_BALANCE && + (data->flags & V4LCONTROL_WANTS_WB)) + ctrl->default_value = 1; + return 0; } @@ -434,6 +410,19 @@ int v4lcontrol_get_ctrl(struct v4lcontrol_data *data, int ctrl) return 0; } +int v4lcontrol_controls_changed(struct v4lcontrol_data *data) +{ + int res; + + res = memcmp(data->shm_values, data->old_values, + V4LCONTROL_COUNT * sizeof(unsigned int)); + + memcpy(data->old_values, data->shm_values, + V4LCONTROL_COUNT * sizeof(unsigned int)); + + return res; +} + /* See the comment about this in libv4lconvert.h */ int v4lcontrol_needs_conversion(struct v4lcontrol_data *data) { return data->flags || data->controls; -- cgit v1.2.3 From 51949cfaadebd8e341fed1e85eca683dd40195d2 Mon Sep 17 00:00:00 2001 From: "hans@rhel5-devel.localdomain" Date: Mon, 25 May 2009 15:25:15 +0200 Subject: libv4l: add software autogain / exposure From: Hans de Goede Add software autogain / exposure, for camera's which have gain and exposure controls but do not contain the ability to calculate the average lumination in hardware (which is needed to do this in the kernel). This patch enables this for the spca561 rev12a, but it should be usefull for other cameras too. Priority: normal Signed-off-by: Hans de Goede --- .../libv4l/libv4lconvert/control/libv4lcontrol.c | 36 ++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index 4d227c366..edf86483d 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -67,7 +67,7 @@ static const struct v4lcontrol_flags_info v4lcontrol_flags[] = { /* Asus N50Vn laptop */ { 0x04f2, 0xb106, 0, "ASUSTeK Computer Inc. ", "N50Vn ", V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED }, -/* Second: devices which should use sw whitebalance by default */ +/* Second: devices which should use some software processing by default */ /* Pac207 based devices */ { 0x041e, 0x4028, 0, NULL, NULL, V4LCONTROL_WANTS_WB }, { 0x093a, 0x2460, 0x1f, NULL, NULL, V4LCONTROL_WANTS_WB }, @@ -78,6 +78,9 @@ static const struct v4lcontrol_flags_info v4lcontrol_flags[] = { V4LCONTROL_ROTATED_90_JPEG|V4LCONTROL_WANTS_WB }, /* sq905 devices */ { 0x2770, 0x9120, 0, NULL, NULL, V4LCONTROL_WANTS_WB }, + /* spca561 revison 12a devices */ + { 0x041e, 0x403b, 0, NULL, NULL, V4LCONTROL_WANTS_WB_AUTOGAIN }, + { 0x046d, 0x0928, 7, NULL, NULL, V4LCONTROL_WANTS_WB_AUTOGAIN }, }; static const struct v4l2_queryctrl fake_controls[]; @@ -223,13 +226,17 @@ struct v4lcontrol_data *v4lcontrol_create(int fd, int always_needs_conversion) /* If the device always needs conversion, we can add fake controls at no cost (no cost when not activated by the user that is) */ if (always_needs_conversion || v4lcontrol_needs_conversion(data)) { - for (i = 0; i < V4LCONTROL_COUNT; i++) { + for (i = 0; i < V4LCONTROL_AUTO_ENABLE_COUNT; i++) { ctrl.id = fake_controls[i].id; if (syscall(SYS_ioctl, data->fd, VIDIOC_QUERYCTRL, &ctrl) == -1) data->controls |= 1 << i; } } + if (data->flags & V4LCONTROL_WANTS_AUTOGAIN) + data->controls |= 1 << V4LCONTROL_AUTOGAIN | + 1 << V4LCONTROL_AUTOGAIN_TARGET; + /* Allow overriding through environment */ if ((s = getenv("LIBV4LCONTROL_CONTROLS"))) data->controls = strtol(s, NULL, 0); @@ -266,6 +273,10 @@ struct v4lcontrol_data *v4lcontrol_create(int fd, int always_needs_conversion) if (init) { /* Initialize the new shm object we created */ memset(data->shm_values, 0, sizeof(V4LCONTROL_SHM_SIZE)); + + for (i = 0; i < V4LCONTROL_COUNT; i++) + data->shm_values[i] = fake_controls[i].default_value; + if (data->flags & V4LCONTROL_WANTS_WB) data->shm_values[V4LCONTROL_WHITEBALANCE] = 1; } @@ -316,6 +327,27 @@ static const struct v4l2_queryctrl fake_controls[V4LCONTROL_COUNT] = { .default_value = 0, .flags = 0 }, +{}, /* Dummy place holder for V4LCONTROL_AUTO_ENABLE_COUNT */ +{ + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Auto Gain (software)", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + .flags = 0 +}, +{ + .id = V4L2_CTRL_CLASS_USER + 0x2000, /* FIXME */ + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Auto Gain target", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 100, + .flags = 0 +}, }; int v4lcontrol_vidioc_queryctrl(struct v4lcontrol_data *data, void *arg) -- cgit v1.2.3 From 7b1960c67fb907d4885734c31a41898a9fe6dfa7 Mon Sep 17 00:00:00 2001 From: "hans@rhel5-devel.localdomain" Date: Mon, 25 May 2009 20:59:10 +0200 Subject: libv4l: Fix a few small issues with V4L2_CTRL_FLAG_NEXT_CTRL handling From: Hans de Goede libv4l: Fix a few small issues with V4L2_CTRL_FLAG_NEXT_CTRL handling Priority: normal Signed-off-by: Hans de Goede --- .../libv4l/libv4lconvert/control/libv4lcontrol.c | 39 ++++++++++++++++------ 1 file changed, 29 insertions(+), 10 deletions(-) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index edf86483d..3f57afb72 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -223,6 +223,10 @@ struct v4lcontrol_data *v4lcontrol_create(int fd, int always_needs_conversion) if ((s = getenv("LIBV4LCONTROL_FLAGS"))) data->flags = strtol(s, NULL, 0); + ctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL; + if (syscall(SYS_ioctl, data->fd, VIDIOC_QUERYCTRL, &ctrl) == 0) + data->priv_flags |= V4LCONTROL_SUPPORTS_NEXT_CTRL; + /* If the device always needs conversion, we can add fake controls at no cost (no cost when not activated by the user that is) */ if (always_needs_conversion || v4lcontrol_needs_conversion(data)) { @@ -350,6 +354,17 @@ static const struct v4l2_queryctrl fake_controls[V4LCONTROL_COUNT] = { }, }; +static void v4lcontrol_copy_queryctrl(struct v4lcontrol_data *data, + struct v4l2_queryctrl *ctrl, int i) +{ + memcpy(ctrl, &fake_controls[i], sizeof(struct v4l2_queryctrl)); + + /* Hmm, not pretty */ + if (ctrl->id == V4L2_CID_AUTO_WHITE_BALANCE && + (data->flags & V4LCONTROL_WANTS_WB)) + ctrl->default_value = 1; +} + int v4lcontrol_vidioc_queryctrl(struct v4lcontrol_data *data, void *arg) { int i; @@ -361,28 +376,32 @@ int v4lcontrol_vidioc_queryctrl(struct v4lcontrol_data *data, void *arg) for (i = 0; i < V4LCONTROL_COUNT; i++) if ((data->controls & (1 << i)) && ctrl->id == fake_controls[i].id) { - memcpy(ctrl, &fake_controls[i], sizeof(struct v4l2_queryctrl)); - /* Hmm, not pretty */ - if (ctrl->id == V4L2_CID_AUTO_WHITE_BALANCE && - (data->flags & V4LCONTROL_WANTS_WB)) - ctrl->default_value = 1; - + v4lcontrol_copy_queryctrl(data, ctrl, i); return 0; } /* find out what the kernel driver would respond. */ retval = syscall(SYS_ioctl, data->fd, VIDIOC_QUERYCTRL, arg); - /* if any of our controls have an id > orig_id but less than - ctrl->id then return that control instead. */ - if (orig_id & V4L2_CTRL_FLAG_NEXT_CTRL) + if ((data->priv_flags & V4LCONTROL_SUPPORTS_NEXT_CTRL) && + (orig_id & V4L2_CTRL_FLAG_NEXT_CTRL)) { + /* If the hardware has no more controls check if we still have any + fake controls with a higher id then the hardware's highest */ + if (retval) + ctrl->id = V4L2_CTRL_FLAG_NEXT_CTRL; + + /* If any of our controls have an id > orig_id but less than + ctrl->id then return that control instead. Note we do not + break when we have a match, but keep iterating, so that + we end up with the fake ctrl with the lowest CID > orig_id. */ for (i = 0; i < V4LCONTROL_COUNT; i++) if ((data->controls & (1 << i)) && (fake_controls[i].id > (orig_id & ~V4L2_CTRL_FLAG_NEXT_CTRL)) && (fake_controls[i].id <= ctrl->id)) { - memcpy(ctrl, &fake_controls[i], sizeof(struct v4l2_queryctrl)); + v4lcontrol_copy_queryctrl(data, ctrl, i); retval = 0; } + } return retval; } -- cgit v1.2.3 From 08f4c9bb91fbc3e348322f140e1a0c1f662b7478 Mon Sep 17 00:00:00 2001 From: "hans@rhel5-devel.localdomain" Date: Tue, 26 May 2009 10:07:18 +0200 Subject: libv4l: add gamma correction to video processing From: Hans de Goede add gamma correction to the video processing, and enable it by default (correct for a display gamma of 1.5) for pac207 based cams. Priority: normal Signed-off-by: Hans de Goede --- .../libv4l/libv4lconvert/control/libv4lcontrol.c | 28 ++++++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index 3f57afb72..6bf5b6229 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -63,16 +63,16 @@ static const struct v4lcontrol_flags_info v4lcontrol_flags[] = { { 0x0471, 0x032d, 0, NULL, NULL, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED }, /* Genius E-M 112 (also want whitebalance by default) */ { 0x093a, 0x2476, 0, NULL, NULL, - V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED|V4LCONTROL_WANTS_WB }, + V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED|V4LCONTROL_WANTS_WB, 1500 }, /* Asus N50Vn laptop */ { 0x04f2, 0xb106, 0, "ASUSTeK Computer Inc. ", "N50Vn ", V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED }, /* Second: devices which should use some software processing by default */ /* Pac207 based devices */ - { 0x041e, 0x4028, 0, NULL, NULL, V4LCONTROL_WANTS_WB }, - { 0x093a, 0x2460, 0x1f, NULL, NULL, V4LCONTROL_WANTS_WB }, - { 0x145f, 0x013a, 0, NULL, NULL, V4LCONTROL_WANTS_WB }, - { 0x2001, 0xf115, 0, NULL, NULL, V4LCONTROL_WANTS_WB }, + { 0x041e, 0x4028, 0, NULL, NULL, V4LCONTROL_WANTS_WB, 1500 }, + { 0x093a, 0x2460, 0x1f, NULL, NULL, V4LCONTROL_WANTS_WB, 1500 }, + { 0x145f, 0x013a, 0, NULL, NULL, V4LCONTROL_WANTS_WB, 1500 }, + { 0x2001, 0xf115, 0, NULL, NULL, V4LCONTROL_WANTS_WB, 1500 }, /* Pac7302 based devices */ { 0x093a, 0x2620, 0x0f, NULL, NULL, V4LCONTROL_ROTATED_90_JPEG|V4LCONTROL_WANTS_WB }, @@ -198,6 +198,7 @@ static void v4lcontrol_init_flags(struct v4lcontrol_data *data) (v4lcontrol_flags[i].dmi_board_name == NULL || !strcmp(v4lcontrol_flags[i].dmi_board_name, dmi_board_name))) { data->flags |= v4lcontrol_flags[i].flags; + data->flags_info = &v4lcontrol_flags[i]; break; } } @@ -283,6 +284,9 @@ struct v4lcontrol_data *v4lcontrol_create(int fd, int always_needs_conversion) if (data->flags & V4LCONTROL_WANTS_WB) data->shm_values[V4LCONTROL_WHITEBALANCE] = 1; + + if (data->flags_info && data->flags_info->default_gamma) + data->shm_values[V4LCONTROL_GAMMA] = data->flags_info->default_gamma; } return data; @@ -331,6 +335,16 @@ static const struct v4l2_queryctrl fake_controls[V4LCONTROL_COUNT] = { .default_value = 0, .flags = 0 }, +{ + .id = V4L2_CID_GAMMA, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gamma (software)", + .minimum = 500, /* == 0.5 */ + .maximum = 3000, /* == 3.0 */ + .step = 1, + .default_value = 1000, /* == 1.0 */ + .flags = 0 +}, {}, /* Dummy place holder for V4LCONTROL_AUTO_ENABLE_COUNT */ { .id = V4L2_CID_AUTOGAIN, @@ -363,6 +377,10 @@ static void v4lcontrol_copy_queryctrl(struct v4lcontrol_data *data, if (ctrl->id == V4L2_CID_AUTO_WHITE_BALANCE && (data->flags & V4LCONTROL_WANTS_WB)) ctrl->default_value = 1; + + if (ctrl->id == V4L2_CID_GAMMA && data->flags_info && + data->flags_info->default_gamma) + ctrl->default_value = data->flags_info->default_gamma; } int v4lcontrol_vidioc_queryctrl(struct v4lcontrol_data *data, void *arg) -- cgit v1.2.3 From f0caf21e8eff58357cc92d4b151b05c7447e8438 Mon Sep 17 00:00:00 2001 From: "hans@rhel5-devel.localdomain" Date: Tue, 26 May 2009 10:11:14 +0200 Subject: libv4l: activate software whitebalance by default on some cams From: Hans de Goede libv4l: activate software whitebalance by default on some cams Priority: normal Signed-off-by: Hans de Goede --- v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index 6bf5b6229..ec3750408 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -76,11 +76,15 @@ static const struct v4lcontrol_flags_info v4lcontrol_flags[] = { /* Pac7302 based devices */ { 0x093a, 0x2620, 0x0f, NULL, NULL, V4LCONTROL_ROTATED_90_JPEG|V4LCONTROL_WANTS_WB }, + /* Pac7311 based devices */ + { 0x093a, 0x2600, 0x0f, NULL, NULL, V4LCONTROL_WANTS_WB }, /* sq905 devices */ { 0x2770, 0x9120, 0, NULL, NULL, V4LCONTROL_WANTS_WB }, /* spca561 revison 12a devices */ { 0x041e, 0x403b, 0, NULL, NULL, V4LCONTROL_WANTS_WB_AUTOGAIN }, { 0x046d, 0x0928, 7, NULL, NULL, V4LCONTROL_WANTS_WB_AUTOGAIN }, + /* logitech quickcam express stv06xx + pb0100 */ + { 0x046d, 0x0840, 0, NULL, NULL, V4LCONTROL_WANTS_WB }, }; static const struct v4l2_queryctrl fake_controls[]; -- cgit v1.2.3 From 2e6d2fb93c7435890fd4789e4c01456f4150ff7e Mon Sep 17 00:00:00 2001 From: "hans@rhel5-devel.localdomain" Date: Fri, 29 May 2009 11:42:59 +0200 Subject: libv4l: Fix a crash in v4lcontrol_controls_changed() From: Hans de Goede Don't crash when v4lcontrol_controls_changed() gets called and we have no fake controls (null pointer dereference). Priority: normal Signed-off-by: Hans de Goede --- v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index ec3750408..da2fbcdce 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -487,6 +487,9 @@ int v4lcontrol_controls_changed(struct v4lcontrol_data *data) { int res; + if (!data->controls) + return 0; + res = memcmp(data->shm_values, data->old_values, V4LCONTROL_COUNT * sizeof(unsigned int)); -- cgit v1.2.3 From 5999b7d164dbf3118a3a75ee3f6f0b48cb8845c1 Mon Sep 17 00:00:00 2001 From: "hans@rhel5-devel.localdomain" Date: Tue, 2 Jun 2009 15:34:34 +0200 Subject: libv4l: initial support for compiling on FreeBSD From: Hans Petter Selasky Add a patch by Hans Petter Selasky , which should lead to allowing use of libv4l (and the Linux webcam drivers ported to userspace usb drivers) on FreeBSd, this is a work in progress Priority: normal Signed-off-by: Hans Petter Selasky Signed-off-by: Hans de Goede --- .../libv4l/libv4lconvert/control/libv4lcontrol.c | 25 ++++++++-------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index da2fbcdce..2f459c396 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -28,16 +28,9 @@ #include #include #include -#include #include "libv4lcontrol.h" #include "libv4lcontrol-priv.h" - -/* These headers are not needed by us, but by linux/videodev2.h, - which is broken on some systems and doesn't include them itself :( */ -#include -#include -#include -/* end broken header workaround includes */ +#include "../libv4lsyscall-priv.h" #include #define ARRAY_SIZE(x) ((int)sizeof(x)/(int)sizeof((x)[0])) @@ -102,8 +95,8 @@ static void v4lcontrol_init_flags(struct v4lcontrol_data *data) char c, *s, buf[32]; struct v4l2_input input; - if ((syscall(SYS_ioctl, data->fd, VIDIOC_G_INPUT, &input.index) == 0) && - (syscall(SYS_ioctl, data->fd, VIDIOC_ENUMINPUT, &input) == 0)) { + if ((SYS_IOCTL(data->fd, VIDIOC_G_INPUT, &input.index) == 0) && + (SYS_IOCTL(data->fd, VIDIOC_ENUMINPUT, &input) == 0)) { if (input.status & V4L2_IN_ST_HFLIP) data->flags |= V4LCONTROL_HFLIPPED; if (input.status & V4L2_IN_ST_VFLIP) @@ -229,7 +222,7 @@ struct v4lcontrol_data *v4lcontrol_create(int fd, int always_needs_conversion) data->flags = strtol(s, NULL, 0); ctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL; - if (syscall(SYS_ioctl, data->fd, VIDIOC_QUERYCTRL, &ctrl) == 0) + if (SYS_IOCTL(data->fd, VIDIOC_QUERYCTRL, &ctrl) == 0) data->priv_flags |= V4LCONTROL_SUPPORTS_NEXT_CTRL; /* If the device always needs conversion, we can add fake controls at no cost @@ -237,7 +230,7 @@ struct v4lcontrol_data *v4lcontrol_create(int fd, int always_needs_conversion) if (always_needs_conversion || v4lcontrol_needs_conversion(data)) { for (i = 0; i < V4LCONTROL_AUTO_ENABLE_COUNT; i++) { ctrl.id = fake_controls[i].id; - if (syscall(SYS_ioctl, data->fd, VIDIOC_QUERYCTRL, &ctrl) == -1) + if (SYS_IOCTL(data->fd, VIDIOC_QUERYCTRL, &ctrl) == -1) data->controls |= 1 << i; } } @@ -253,7 +246,7 @@ struct v4lcontrol_data *v4lcontrol_create(int fd, int always_needs_conversion) if (data->controls == 0) return data; /* No need to create a shared memory segment */ - syscall(SYS_ioctl, fd, VIDIOC_QUERYCAP, &cap); + SYS_IOCTL(fd, VIDIOC_QUERYCAP, &cap); snprintf(shm_name, 256, "/%s:%s", cap.bus_info, cap.card); /* / is not allowed inside shm names */ @@ -403,7 +396,7 @@ int v4lcontrol_vidioc_queryctrl(struct v4lcontrol_data *data, void *arg) } /* find out what the kernel driver would respond. */ - retval = syscall(SYS_ioctl, data->fd, VIDIOC_QUERYCTRL, arg); + retval = SYS_IOCTL(data->fd, VIDIOC_QUERYCTRL, arg); if ((data->priv_flags & V4LCONTROL_SUPPORTS_NEXT_CTRL) && (orig_id & V4L2_CTRL_FLAG_NEXT_CTRL)) { @@ -440,7 +433,7 @@ int v4lcontrol_vidioc_g_ctrl(struct v4lcontrol_data *data, void *arg) return 0; } - return syscall(SYS_ioctl, data->fd, VIDIOC_G_CTRL, arg); + return SYS_IOCTL(data->fd, VIDIOC_G_CTRL, arg); } int v4lcontrol_vidioc_s_ctrl(struct v4lcontrol_data *data, void *arg) @@ -461,7 +454,7 @@ int v4lcontrol_vidioc_s_ctrl(struct v4lcontrol_data *data, void *arg) return 0; } - return syscall(SYS_ioctl, data->fd, VIDIOC_S_CTRL, arg); + return SYS_IOCTL(data->fd, VIDIOC_S_CTRL, arg); } int v4lcontrol_get_flags(struct v4lcontrol_data *data) -- cgit v1.2.3 From 5fefedb3c3a7a0ceaa161e4a3c1e180ba22cd364 Mon Sep 17 00:00:00 2001 From: "hans@rhel5-devel.localdomain" Date: Fri, 5 Jun 2009 16:02:40 +0200 Subject: libv4l: recognize when controls are disabled From: Hans de Goede libv4l: recognize when controls are disabled Priority: normal Signed-off-by: Hans de Goede --- v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index 2f459c396..b50b686df 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -203,7 +203,7 @@ static void v4lcontrol_init_flags(struct v4lcontrol_data *data) struct v4lcontrol_data *v4lcontrol_create(int fd, int always_needs_conversion) { int shm_fd; - int i, init = 0; + int i, rc, init = 0; char *s, shm_name[256]; struct v4l2_capability cap; struct v4l2_queryctrl ctrl; @@ -230,7 +230,8 @@ struct v4lcontrol_data *v4lcontrol_create(int fd, int always_needs_conversion) if (always_needs_conversion || v4lcontrol_needs_conversion(data)) { for (i = 0; i < V4LCONTROL_AUTO_ENABLE_COUNT; i++) { ctrl.id = fake_controls[i].id; - if (SYS_IOCTL(data->fd, VIDIOC_QUERYCTRL, &ctrl) == -1) + rc = SYS_IOCTL(data->fd, VIDIOC_QUERYCTRL, &ctrl); + if (rc == -1 || (rc == 0 && (ctrl.flags & V4L2_CTRL_FLAG_DISABLED))) data->controls |= 1 << i; } } -- cgit v1.2.3 From 77e3c46ba9e763ac240f56d9365208c422fc6b20 Mon Sep 17 00:00:00 2001 From: "hans@rhel5-devel.localdomain" Date: Mon, 8 Jun 2009 11:16:43 +0200 Subject: libv4l: move ov518 decompression code to an external helper From: Hans de Goede Change support for decompressing ov518 "JPEG" to piping data through an external helper as I've failed to contact Mark W. McClelland to get permission to relicense the code. If you know a working email address for Mark W. McClelland, please let me know. Priority: normal Signed-off-by: Hans de Goede --- v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index b50b686df..8a77728a6 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -316,7 +316,7 @@ static const struct v4l2_queryctrl fake_controls[V4LCONTROL_COUNT] = { { .id = V4L2_CID_HFLIP, .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Horizontal flip", + .name = "Horizontal flip (sw)", .minimum = 0, .maximum = 1, .step = 1, @@ -326,7 +326,7 @@ static const struct v4l2_queryctrl fake_controls[V4LCONTROL_COUNT] = { { .id = V4L2_CID_VFLIP, .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Vertical flip", + .name = "Vertical flip (sw)", .minimum = 0, .maximum = 1, .step = 1, -- cgit v1.2.3 From 5e90c221e48890f2f2433f153d9584bc4bdd327a Mon Sep 17 00:00:00 2001 From: "hans@rhel5-devel.localdomain" Date: Wed, 17 Jun 2009 23:35:22 +0200 Subject: libv4l: enable automatic gain / exposure control for st6422 devices From: Hans de Goede libv4l: enable automatic gain / exposure control for st6422 devices Priority: normal Signed-off-by: Hans de Goede --- v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c') diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c index 8a77728a6..4e600351b 100644 --- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c +++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c @@ -78,6 +78,11 @@ static const struct v4lcontrol_flags_info v4lcontrol_flags[] = { { 0x046d, 0x0928, 7, NULL, NULL, V4LCONTROL_WANTS_WB_AUTOGAIN }, /* logitech quickcam express stv06xx + pb0100 */ { 0x046d, 0x0840, 0, NULL, NULL, V4LCONTROL_WANTS_WB }, + /* logitech quickcam messenger variants, st6422 */ + { 0x046d, 0x08f0, 0, NULL, NULL, V4LCONTROL_WANTS_AUTOGAIN }, + { 0x046d, 0x08f5, 0, NULL, NULL, V4LCONTROL_WANTS_AUTOGAIN }, + { 0x046d, 0x08f6, 0, NULL, NULL, V4LCONTROL_WANTS_AUTOGAIN }, + { 0x046d, 0x08da, 0, NULL, NULL, V4LCONTROL_WANTS_AUTOGAIN }, }; static const struct v4l2_queryctrl fake_controls[]; -- cgit v1.2.3