Browse Source

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 years ago
parent
commit
1e55126666
2 changed files with 24 additions and 1 deletions
  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);
 
 
 /* ------------------------------------------------------------------------- */
 /* ------------------------------------------------------------------------- */