This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 041c83166cfb9a5216b6fa38f2436c4319890d90 Author: niyinghao <[email protected]> AuthorDate: Mon May 11 10:13:26 2026 +0800 video/v4l2_cap: support V4L2_CTRL_FLAG_NEXT_CTRL enumeration Add NEXT_CTRL/NEXT_COMPOUND flag handling in capture_query_ext_ctrl to iterate through known CID ranges and find the next supported control. Also populate ctrl->id in capture_queryctrl so userspace gets the correct control ID back. Signed-off-by: niyinghao <[email protected]> --- drivers/video/v4l2_cap.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ include/sys/video_controls.h | 8 +++++++ 2 files changed, 62 insertions(+) diff --git a/drivers/video/v4l2_cap.c b/drivers/video/v4l2_cap.c index 181a6a6f1ea..db446d85211 100644 --- a/drivers/video/v4l2_cap.c +++ b/drivers/video/v4l2_cap.c @@ -31,6 +31,7 @@ #include <errno.h> #include <poll.h> +#include <sys/param.h> #include <nuttx/kmalloc.h> #include <nuttx/mutex.h> #include <nuttx/poll.h> @@ -3394,6 +3395,7 @@ static int capture_queryctrl(FAR struct file *filep, /* Replace gotten value to VIDIOC_QUERYCTRL */ + ctrl->id = ext_ctrl.id; ctrl->type = ext_ctrl.type; ctrl->minimum = ext_ctrl.minimum; ctrl->maximum = ext_ctrl.maximum; @@ -3414,6 +3416,7 @@ static int capture_query_ext_ctrl(FAR struct file *filep, imgsensor_capability_range_t *range = &value.u.range; imgsensor_capability_discrete_t *disc = &value.u.discrete; imgsensor_capability_elems_t *elem = &value.u.elems; + uint32_t id; int ret; if (cmng == NULL || attr == NULL) @@ -3423,6 +3426,57 @@ static int capture_query_ext_ctrl(FAR struct file *filep, ASSERT(cmng->imgsensor); + id = attr->id; + + /* Handle V4L2_CTRL_FLAG_NEXT_CTRL: find the next supported control + * after the given ID by iterating through known CID ranges. + */ + + if (id & (V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND)) + { + static const uint16_t cid_ranges[][2] = + { + { V4L2_CTRL_CLASS_USER, V4L2_CID_USER_LAST }, + { V4L2_CTRL_CLASS_CAMERA, V4L2_CID_CAMERA_LAST }, + { V4L2_CTRL_CLASS_FLASH, V4L2_CID_FLASH_LAST }, + { V4L2_CTRL_CLASS_JPEG, V4L2_CID_JPEG_LAST }, + }; + + uint32_t start = (id & ~(V4L2_CTRL_FLAG_NEXT_CTRL | + V4L2_CTRL_FLAG_NEXT_COMPOUND)) + 1; + size_t i; + + for (i = 0; i < nitems(cid_ranges); i++) + { + uint32_t cid; + uint32_t range_start = cid_ranges[i][0]; + uint32_t range_end = cid_ranges[i][1]; + + cid = start > range_start ? start : range_start; + for (; cid <= range_end; cid++) + { + if (cid == V4L2_CID_SCENE_MODE) + { + id = cid; + goto found; + } + + ret = IMGSENSOR_GET_SUPPORTED_VALUE(cmng->imgsensor, + cid, &value); + if (ret == OK) + { + id = cid; + goto found; + } + } + } + + return -EINVAL; /* No more controls */ + +found: + attr->id = id; + } + attr->flags = 0; attr->elem_size = 0; attr->elems = 1; diff --git a/include/sys/video_controls.h b/include/sys/video_controls.h index 2a069c5a120..452bc14b16e 100644 --- a/include/sys/video_controls.h +++ b/include/sys/video_controls.h @@ -108,6 +108,8 @@ enum v4l2_colorfx #define V4L2_CID_LENS_SHADING_CORRECTION USER_CID(19) /* Lens shading correction */ +#define V4L2_CID_USER_LAST V4L2_CID_GAIN + /* Camera class control IDs */ #define V4L2_CID_EXPOSURE_AUTO CAMERA_CID(0) /* Auto exposure */ @@ -242,10 +244,14 @@ enum v4l2_scene_mode #define V4L2_CID_EXPOSURE_METERING_SPOT_POSITION CAMERA_CID(22) +#define V4L2_CID_CAMERA_LAST V4L2_CID_EXPOSURE_METERING_SPOT_POSITION + /* Flash and privacy (indicator) light controls */ #define V4L2_CID_FLASH_LED_MODE FLASH_CID(0) +#define V4L2_CID_FLASH_LAST V4L2_CID_FLASH_LED_MODE + /* Enumeration for V4L2_CID_FLASH_LED_MODE */ enum v4l2_flash_led_mode @@ -259,6 +265,8 @@ enum v4l2_flash_led_mode #define V4L2_CID_JPEG_COMPRESSION_QUALITY JPEG_CID(0) /* JPEG quality */ +#define V4L2_CID_JPEG_LAST V4L2_CID_JPEG_COMPRESSION_QUALITY + /* MPEG-class control IDs */ /* The MPEG controls are applicable to all codec controls
