summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain>2009-05-25 20:59:10 +0200
committerhans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain>2009-05-25 20:59:10 +0200
commit7b1960c67fb907d4885734c31a41898a9fe6dfa7 (patch)
tree08a71b25fb926793b7575e70421f58b28ace41aa
parent2ffc360be1c38ab86399d6d574ee7cc0671c03d6 (diff)
downloadmediapointer-dvb-s2-7b1960c67fb907d4885734c31a41898a9fe6dfa7.tar.gz
mediapointer-dvb-s2-7b1960c67fb907d4885734c31a41898a9fe6dfa7.tar.bz2
libv4l: Fix a few small issues with V4L2_CTRL_FLAG_NEXT_CTRL handling
From: Hans de Goede <hdegoede@redhat.com> libv4l: Fix a few small issues with V4L2_CTRL_FLAG_NEXT_CTRL handling Priority: normal Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol-priv.h5
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c39
2 files changed, 33 insertions, 11 deletions
diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol-priv.h b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol-priv.h
index 14e4fe838..14481a9a2 100644
--- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol-priv.h
+++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol-priv.h
@@ -24,9 +24,12 @@
#define V4LCONTROL_SHM_SIZE 4096
+#define V4LCONTROL_SUPPORTS_NEXT_CTRL 0x01
+
struct v4lcontrol_data {
int fd; /* Device fd */
- int flags; /* Special flags for this device */
+ int flags; /* Flags for this device */
+ int priv_flags; /* Internal use only flags */
int controls; /* Which controls to use for this device */
unsigned int *shm_values; /* shared memory control value store */
unsigned int old_values[V4LCONTROL_COUNT]; /* for controls_changed() */
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;
}