From b822faf73bfdcb80b21159f8970ea2d46bd79919 Mon Sep 17 00:00:00 2001 From: Kurt Kartaltepe Date: Sun, 22 Mar 2020 16:42:04 -0700 Subject: [PATCH] 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.) --- plugins/linux-v4l2/v4l2-controls.c | 98 +++++++++++++++--------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/plugins/linux-v4l2/v4l2-controls.c b/plugins/linux-v4l2/v4l2-controls.c index c31a91d06..1ffdab8ad 100644 --- a/plugins/linux-v4l2/v4l2-controls.c +++ b/plugins/linux-v4l2/v4l2-controls.c @@ -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;