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

Reply via email to