summaryrefslogtreecommitdiff
path: root/v4l2-apps/libv4l/libv4lconvert/control
diff options
context:
space:
mode:
Diffstat (limited to 'v4l2-apps/libv4l/libv4lconvert/control')
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol-priv.h7
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c107
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.h7
3 files changed, 53 insertions, 68 deletions
diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol-priv.h b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol-priv.h
index 0157af280..14e4fe838 100644
--- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol-priv.h
+++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol-priv.h
@@ -24,16 +24,12 @@
#define V4LCONTROL_SHM_SIZE 4096
-#define V4LCONTROL_WANTS_WB (1 << V4LCONTROL_WHITEBALANCE)
-#define V4LCONTROL_WANTS_NORM ((1 << V4LCONTROL_NORMALIZE) | \
- (1 << V4LCONTROL_NORM_LOW_BOUND) | \
- (1 << V4LCONTROL_NORM_HIGH_BOUND))
-
struct v4lcontrol_data {
int fd; /* Device fd */
int flags; /* Special flags for this device */
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() */
};
struct v4lcontrol_flags_info {
@@ -46,7 +42,6 @@ struct v4lcontrol_flags_info {
const char *manufacturer;
const char *product; */
int flags;
- int controls;
};
#endif
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,21 +285,11 @@ 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,
@@ -306,26 +297,6 @@ struct v4l2_queryctrl fake_controls[V4LCONTROL_COUNT] = {
.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,
.name = "Horizontal flip",
@@ -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;
diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.h b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.h
index 43ef7c49f..85129ee4c 100644
--- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.h
+++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.h
@@ -26,13 +26,11 @@
#define V4LCONTROL_HFLIPPED 0x01
#define V4LCONTROL_VFLIPPED 0x02
#define V4LCONTROL_ROTATED_90_JPEG 0x04
+#define V4LCONTROL_WANTS_WB 0x08
/* Controls */
enum {
V4LCONTROL_WHITEBALANCE,
- V4LCONTROL_NORMALIZE,
- V4LCONTROL_NORM_LOW_BOUND,
- V4LCONTROL_NORM_HIGH_BOUND,
V4LCONTROL_HFLIP,
V4LCONTROL_VFLIP,
V4LCONTROL_COUNT };
@@ -45,6 +43,9 @@ void v4lcontrol_destroy(struct v4lcontrol_data *data);
/* Functions used by v4lprocessing to get the control state */
int v4lcontrol_get_flags(struct v4lcontrol_data *data);
int v4lcontrol_get_ctrl(struct v4lcontrol_data *data, int ctrl);
+/* Check if the controls have changed since the last time this function
+ was called */
+int v4lcontrol_controls_changed(struct v4lcontrol_data *data);
/* Check if we must go through the conversion path (and thus alloc conversion
buffers, etc. in libv4l2). Note this always return 1 if we *may* need
rotate90 / flipping / processing, as if we actually need this may change