diff options
Diffstat (limited to 'v4l2-apps/libv4l/libv4lconvert/control')
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 |