linux-v4l2: Fixup invalid id

Previous fix in #2547 altered id before they were handed off to
callbacks and v4l2 wont strip its own flags from ids resulting in
invalid ids in the ioctl.

Instead add cleanup section and jump all branches there before looping.

(Jim edit: I'm changing this entire function so that it isn't horrible.)
master
Kurt Kartaltepe 2020-03-22 16:42:04 -07:00 committed by jp9000
parent 54c5ac250f
commit b822faf73b
1 changed files with 49 additions and 49 deletions

View File

@ -86,11 +86,58 @@ static int_fast32_t v4l2_update_controls_menu(int_fast32_t dev,
return 0;
}
#define INVALID_CONTROL_FLAGS \
(V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_READ_ONLY | \
V4L2_CTRL_FLAG_VOLATILE)
static inline bool valid_control(struct v4l2_queryctrl *qctrl)
{
return (qctrl->flags & INVALID_CONTROL_FLAGS) == 0;
}
static inline bool add_control_property(obs_properties_t *props,
obs_data_t *settings, int_fast32_t dev,
struct v4l2_queryctrl *qctrl)
{
obs_property_t *prop = NULL;
if (!valid_control(qctrl)) {
return;
}
switch (qctrl->type) {
case V4L2_CTRL_TYPE_INTEGER:
prop = obs_properties_add_int_slider(
props, (char *)qctrl->name, (char *)qctrl->name,
qctrl->minimum, qctrl->maximum, qctrl->step);
obs_data_set_default_int(settings, (char *)qctrl->name,
qctrl->default_value);
obs_property_set_modified_callback2(prop, v4l2_control_changed,
UINT_TO_POINTER(qctrl->id));
break;
case V4L2_CTRL_TYPE_BOOLEAN:
prop = obs_properties_add_bool(props, (char *)qctrl->name,
(char *)qctrl->name);
obs_data_set_default_bool(settings, (char *)qctrl->name,
qctrl->default_value);
obs_property_set_modified_callback2(prop, v4l2_control_changed,
UINT_TO_POINTER(qctrl->id));
break;
case V4L2_CTRL_TYPE_MENU:
case V4L2_CTRL_TYPE_INTEGER_MENU:
v4l2_update_controls_menu(dev, props, qctrl);
obs_data_set_default_int(settings, (char *)qctrl->name,
qctrl->default_value);
blog(LOG_INFO, "setting default for %s to %d",
(char *)qctrl->name, qctrl->default_value);
break;
}
}
int_fast32_t v4l2_update_controls(int_fast32_t dev, obs_properties_t *props,
obs_data_t *settings)
{
struct v4l2_queryctrl qctrl;
obs_property_t *prop = NULL;
if (!dev || !props)
return -1;
@ -98,55 +145,8 @@ int_fast32_t v4l2_update_controls(int_fast32_t dev, obs_properties_t *props,
memset(&qctrl, 0, sizeof(qctrl));
qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
while (0 == v4l2_ioctl(dev, VIDIOC_QUERYCTRL, &qctrl)) {
add_control_property(props, settings, dev, &qctrl);
qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
blog(LOG_INFO, "found control %s but it is disabled",
qctrl.name);
continue;
}
if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
blog(LOG_INFO, "found control %s but it is readonly",
qctrl.name);
continue;
}
if (qctrl.flags & V4L2_CTRL_FLAG_VOLATILE) {
blog(LOG_INFO, "found control %s but it is volatile",
qctrl.name);
continue;
}
switch (qctrl.type) {
case V4L2_CTRL_TYPE_INTEGER:
prop = obs_properties_add_int_slider(
props, (char *)qctrl.name, (char *)qctrl.name,
qctrl.minimum, qctrl.maximum, qctrl.step);
obs_data_set_default_int(settings, (char *)qctrl.name,
qctrl.default_value);
obs_property_set_modified_callback2(
prop, v4l2_control_changed,
UINT_TO_POINTER(qctrl.id));
break;
case V4L2_CTRL_TYPE_BOOLEAN:
prop = obs_properties_add_bool(
props, (char *)qctrl.name, (char *)qctrl.name);
obs_data_set_default_bool(settings, (char *)qctrl.name,
qctrl.default_value);
obs_property_set_modified_callback2(
prop, v4l2_control_changed,
UINT_TO_POINTER(qctrl.id));
break;
case V4L2_CTRL_TYPE_MENU:
case V4L2_CTRL_TYPE_INTEGER_MENU:
v4l2_update_controls_menu(dev, props, &qctrl);
obs_data_set_default_int(settings, (char *)qctrl.name,
qctrl.default_value);
blog(LOG_INFO, "setting default for %s to %d",
(char *)qctrl.name, qctrl.default_value);
break;
}
}
return 0;