瀏覽代碼

V4L/DVB (8637): v4l2: add v4l2_ctrl_query_menu_valid_items support function

v4l2_ctrl_query_menu_valid_items() makes it easy to handle control menus
that have a lot of invalid 'holes'. For example, many MPEG encoders only
support a limited subset of audio bitrates. In that case a driver can
specify an array listing the set of valid bitrates and pass that to
this function.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Hans Verkuil 17 年之前
父節點
當前提交
1e55126666
共有 2 個文件被更改,包括 24 次插入1 次删除
  1. 22 1
      drivers/media/video/v4l2-common.c
  2. 2 0
      include/media/v4l2-common.h

+ 22 - 1
drivers/media/video/v4l2-common.c

@@ -643,6 +643,7 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qc
 {
 {
 	int i;
 	int i;
 
 
+	qmenu->reserved = 0;
 	if (menu_items == NULL ||
 	if (menu_items == NULL ||
 	    (qctrl && (qmenu->index < qctrl->minimum || qmenu->index > qctrl->maximum)))
 	    (qctrl && (qmenu->index < qctrl->minimum || qmenu->index > qctrl->maximum)))
 		return -EINVAL;
 		return -EINVAL;
@@ -650,11 +651,31 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qc
 	if (menu_items[i] == NULL || menu_items[i][0] == '\0')
 	if (menu_items[i] == NULL || menu_items[i][0] == '\0')
 		return -EINVAL;
 		return -EINVAL;
 	snprintf(qmenu->name, sizeof(qmenu->name), menu_items[qmenu->index]);
 	snprintf(qmenu->name, sizeof(qmenu->name), menu_items[qmenu->index]);
-	qmenu->reserved = 0;
 	return 0;
 	return 0;
 }
 }
 EXPORT_SYMBOL(v4l2_ctrl_query_menu);
 EXPORT_SYMBOL(v4l2_ctrl_query_menu);
 
 
+/* Fill in a struct v4l2_querymenu based on the specified array of valid
+   menu items (terminated by V4L2_CTRL_MENU_IDS_END).
+   Use this if there are 'holes' in the list of valid menu items. */
+int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *ids)
+{
+	const char **menu_items = v4l2_ctrl_get_menu(qmenu->id);
+
+	qmenu->reserved = 0;
+	if (menu_items == NULL || ids == NULL)
+		return -EINVAL;
+	while (*ids != V4L2_CTRL_MENU_IDS_END) {
+		if (*ids++ == qmenu->index) {
+			snprintf(qmenu->name, sizeof(qmenu->name),
+				       menu_items[qmenu->index]);
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+EXPORT_SYMBOL(v4l2_ctrl_query_menu_valid_items);
+
 /* ctrl_classes points to an array of u32 pointers, the last element is
 /* ctrl_classes points to an array of u32 pointers, the last element is
    a NULL pointer. Each u32 array is a 0-terminated array of control IDs.
    a NULL pointer. Each u32 array is a 0-terminated array of control IDs.
    Each array must be sorted low to high and belong to the same control
    Each array must be sorted low to high and belong to the same control

+ 2 - 0
include/media/v4l2-common.h

@@ -82,6 +82,8 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
 int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl);
 int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl);
 int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu,
 int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu,
 		struct v4l2_queryctrl *qctrl, const char **menu_items);
 		struct v4l2_queryctrl *qctrl, const char **menu_items);
+#define V4L2_CTRL_MENU_IDS_END (0xffffffff)
+int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *ids);
 u32 v4l2_ctrl_next(const u32 * const *ctrl_classes, u32 id);
 u32 v4l2_ctrl_next(const u32 * const *ctrl_classes, u32 id);
 
 
 /* ------------------------------------------------------------------------- */
 /* ------------------------------------------------------------------------- */