浏览代码

v4l2: Ignore menu controls with no permissible values

At least one V4L2 device reports a menu control when queried with
QUERYCTRL yet does not report supporting a single value in its legal
range when queried with QUERYMENU. Such devices are arguably
ill-behaved, but the Linux UVC driver takes no special care to ignore
such pathological controls, so we have to do it ourselves.

Without this patch, a menu control with no valid values would cause
v4l2_control_changed to go into an infinite loop, since every S_CTRL
request on such pathological control properties would always fail,
triggering an additional modification event. By ignoring these
properties altogether, we avoid that problem, and the user benefits by
not having the UI cluttered by a confusing and useless menu control.
Alexis King 4 年之前
父节点
当前提交
08d4456339
共有 1 个文件被更改,包括 14 次插入9 次删除
  1. 14 9
      plugins/linux-v4l2/v4l2-controls.c

+ 14 - 9
plugins/linux-v4l2/v4l2-controls.c

@@ -73,9 +73,8 @@ static bool v4l2_control_changed(void *data, obs_properties_t *props,
 	return ret;
 	return ret;
 }
 }
 
 
-static int_fast32_t v4l2_update_controls_menu(int_fast32_t dev,
-					      obs_properties_t *props,
-					      struct v4l2_queryctrl *qctrl)
+static bool v4l2_update_controls_menu(int_fast32_t dev, obs_properties_t *props,
+				      struct v4l2_queryctrl *qctrl)
 {
 {
 	obs_property_t *prop;
 	obs_property_t *prop;
 	struct v4l2_querymenu qmenu;
 	struct v4l2_querymenu qmenu;
@@ -99,7 +98,12 @@ static int_fast32_t v4l2_update_controls_menu(int_fast32_t dev,
 		}
 		}
 	}
 	}
 
 
-	return 0;
+	if (obs_property_list_item_count(prop) == 0) {
+		obs_properties_remove_by_name(props, (char *)qctrl->name);
+		return false;
+	}
+
+	return true;
 }
 }
 
 
 #define INVALID_CONTROL_FLAGS                                 \
 #define INVALID_CONTROL_FLAGS                                 \
@@ -141,11 +145,12 @@ static inline void add_control_property(obs_properties_t *props,
 		break;
 		break;
 	case V4L2_CTRL_TYPE_MENU:
 	case V4L2_CTRL_TYPE_MENU:
 	case V4L2_CTRL_TYPE_INTEGER_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);
+		if (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;
 		break;
 	}
 	}
 }
 }