From: Yunke Cao <yunkec@google.com>
Implement support for ROI as described in UVC 1.5:
4.2.2.1.20 Digital Region of Interest (ROI) Control
ROI control is implemented using V4L2 control API as
two UVC-specific controls:
V4L2_CID_UVC_REGION_OF_INTEREST_RECT and
V4L2_CID_UVC_REGION_OF_INTEREST_AUTO.
Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
Signed-off-by: Yunke Cao <yunkec@google.com>
---
drivers/media/usb/uvc/uvc_ctrl.c | 81 ++++++++++++++++++++++++++++++++++++++
drivers/media/usb/uvc/uvcvideo.h | 7 ++++
include/uapi/linux/usb/video.h | 1 +
include/uapi/linux/uvcvideo.h | 13 ++++++
include/uapi/linux/v4l2-controls.h | 9 +++++
5 files changed, 111 insertions(+)
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index f262e05ad3a8..5b619ef40dd3 100644
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -358,6 +358,24 @@ static const struct uvc_control_info uvc_ctrls[] = {
.flags = UVC_CTRL_FLAG_GET_CUR
| UVC_CTRL_FLAG_AUTO_UPDATE,
},
+ /*
+ * UVC_CTRL_FLAG_AUTO_UPDATE is needed because the RoI may get updated
+ * by sensors.
+ * "This RoI should be the same as specified in most recent SET_CUR
+ * except in the case where the ‘Auto Detect and Track’ and/or
+ * ‘Image Stabilization’ bit have been set."
+ * 4.2.2.1.20 Digital Region of Interest (ROI) Control
+ */
+ {
+ .entity = UVC_GUID_UVC_CAMERA,
+ .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
+ .index = 21,
+ .size = 10,
+ .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
+ | UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
+ | UVC_CTRL_FLAG_GET_DEF
+ | UVC_CTRL_FLAG_AUTO_UPDATE,
+ },
};
static const u32 uvc_control_classes[] = {
@@ -603,6 +621,44 @@ static const struct uvc_control_mapping *uvc_ctrl_filter_plf_mapping(
return out_mapping;
}
+static int uvc_get_rect(struct uvc_control_mapping *mapping, u8 query,
+ const void *uvc_in, size_t v4l2_size, void *v4l2_out)
+{
+ const struct uvc_rect *uvc_rect = uvc_in;
+ struct v4l2_rect *v4l2_rect = v4l2_out;
+
+ if (WARN_ON(v4l2_size != sizeof(struct v4l2_rect)))
+ return -EINVAL;
+
+ if (uvc_rect->left > uvc_rect->right ||
+ uvc_rect->top > uvc_rect->bottom)
+ return -EIO;
+
+ v4l2_rect->top = uvc_rect->top;
+ v4l2_rect->left = uvc_rect->left;
+ v4l2_rect->height = uvc_rect->bottom - uvc_rect->top + 1;
+ v4l2_rect->width = uvc_rect->right - uvc_rect->left + 1;
+
+ return 0;
+}
+
+static int uvc_set_rect(struct uvc_control_mapping *mapping, size_t v4l2_size,
+ const void *v4l2_in, void *uvc_out)
+{
+ struct uvc_rect *uvc_rect = uvc_out;
+ const struct v4l2_rect *v4l2_rect = v4l2_in;
+
+ if (WARN_ON(v4l2_size != sizeof(struct v4l2_rect)))
+ return -EINVAL;
+
+ uvc_rect->top = max(0xffff, v4l2_rect->top);
+ uvc_rect->left = max(0xffff, v4l2_rect->left);
+ uvc_rect->bottom = max(0xffff, v4l2_rect->height + v4l2_rect->top - 1);
+ uvc_rect->right = max(0xffff, v4l2_rect->width + v4l2_rect->left - 1);
+
+ return 0;
+}
+
static const struct uvc_control_mapping uvc_ctrl_mappings[] = {
{
.id = V4L2_CID_BRIGHTNESS,
@@ -897,6 +953,28 @@ static const struct uvc_control_mapping uvc_ctrl_mappings[] = {
.selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
.filter_mapping = uvc_ctrl_filter_plf_mapping,
},
+ {
+ .id = V4L2_CID_UVC_REGION_OF_INTEREST_RECT,
+ .entity = UVC_GUID_UVC_CAMERA,
+ .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
+ .size = sizeof(struct uvc_rect) * 8,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_RECT,
+ .data_type = UVC_CTRL_DATA_TYPE_RECT,
+ .get = uvc_get_rect,
+ .set = uvc_set_rect,
+ .name = "Region Of Interest Rectangle",
+ },
+ {
+ .id = V4L2_CID_UVC_REGION_OF_INTEREST_AUTO,
+ .entity = UVC_GUID_UVC_CAMERA,
+ .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
+ .size = 16,
+ .offset = 64,
+ .v4l2_type = V4L2_CTRL_TYPE_BITMASK,
+ .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
+ .name = "Region Of Interest Auto Controls",
+ },
};
/* ------------------------------------------------------------------------
@@ -1465,6 +1543,9 @@ static int __uvc_queryctrl_boundaries(struct uvc_video_chain *chain,
static size_t uvc_mapping_v4l2_size(struct uvc_control_mapping *mapping)
{
+ if (mapping->v4l2_type == V4L2_CTRL_TYPE_RECT)
+ return sizeof(struct v4l2_rect);
+
if (uvc_ctrl_mapping_is_compound(mapping))
return DIV_ROUND_UP(mapping->size, 8);
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 8aca1a2fe587..d910a5e5b514 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -294,6 +294,13 @@ struct uvc_streaming_header {
u8 bTriggerUsage;
};
+struct uvc_rect {
+ u16 top;
+ u16 left;
+ u16 bottom;
+ u16 right;
+} __packed;
+
enum uvc_buffer_state {
UVC_BUF_STATE_IDLE = 0,
UVC_BUF_STATE_QUEUED = 1,
diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h
index 2ff0e8a3a683..2afb4420e6c4 100644
--- a/include/uapi/linux/usb/video.h
+++ b/include/uapi/linux/usb/video.h
@@ -104,6 +104,7 @@
#define UVC_CT_ROLL_ABSOLUTE_CONTROL 0x0f
#define UVC_CT_ROLL_RELATIVE_CONTROL 0x10
#define UVC_CT_PRIVACY_CONTROL 0x11
+#define UVC_CT_REGION_OF_INTEREST_CONTROL 0x14
/* A.9.5. Processing Unit Control Selectors */
#define UVC_PU_CONTROL_UNDEFINED 0x00
diff --git a/include/uapi/linux/uvcvideo.h b/include/uapi/linux/uvcvideo.h
index f86185456dc5..cbe15bca9569 100644
--- a/include/uapi/linux/uvcvideo.h
+++ b/include/uapi/linux/uvcvideo.h
@@ -16,6 +16,7 @@
#define UVC_CTRL_DATA_TYPE_BOOLEAN 3
#define UVC_CTRL_DATA_TYPE_ENUM 4
#define UVC_CTRL_DATA_TYPE_BITMASK 5
+#define UVC_CTRL_DATA_TYPE_RECT 6
/* Control flags */
#define UVC_CTRL_FLAG_SET_CUR (1 << 0)
@@ -38,6 +39,18 @@
#define UVC_MENU_NAME_LEN 32
+/* V4L2 driver-specific controls */
+#define V4L2_CID_UVC_REGION_OF_INTEREST_RECT (V4L2_CID_USER_UVC_BASE + 1)
+#define V4L2_CID_UVC_REGION_OF_INTEREST_AUTO (V4L2_CID_USER_UVC_BASE + 2)
+#define V4L2_UVC_REGION_OF_INTEREST_AUTO_EXPOSURE (1 << 0)
+#define V4L2_UVC_REGION_OF_INTEREST_AUTO_IRIS (1 << 1)
+#define V4L2_UVC_REGION_OF_INTEREST_AUTO_WHITE_BALANCE (1 << 2)
+#define V4L2_UVC_REGION_OF_INTEREST_AUTO_FOCUS (1 << 3)
+#define V4L2_UVC_REGION_OF_INTEREST_AUTO_FACE_DETECT (1 << 4)
+#define V4L2_UVC_REGION_OF_INTEREST_AUTO_DETECT_AND_TRACK (1 << 5)
+#define V4L2_UVC_REGION_OF_INTEREST_AUTO_IMAGE_STABILIZATION (1 << 6)
+#define V4L2_UVC_REGION_OF_INTEREST_AUTO_HIGHER_QUALITY (1 << 7)
+
struct uvc_menu_info {
__u32 value;
__u8 name[UVC_MENU_NAME_LEN];
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 974fd254e573..6c91d6fa4708 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -215,6 +215,13 @@ enum v4l2_colorfx {
*/
#define V4L2_CID_USER_THP7312_BASE (V4L2_CID_USER_BASE + 0x11c0)
+/*
+ * The base for the uvc driver controls.
+ * See linux/uvcvideo.h for the list of controls.
+ * We reserve 64 controls for this driver.
+ */
+#define V4L2_CID_USER_UVC_BASE (V4L2_CID_USER_BASE + 0x11e0)
+
/* MPEG-class control IDs */
/* The MPEG controls are applicable to all codec controls
* and the 'MPEG' part of the define is historical */
@@ -1089,6 +1096,8 @@ enum v4l2_auto_focus_range {
#define V4L2_CID_HDR_SENSOR_MODE (V4L2_CID_CAMERA_CLASS_BASE+36)
+/* CAMERA-class private control IDs */
+
/* FM Modulator class control IDs */
#define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900)
--
2.47.0.338.g60cca15819-goog
Hi,
On 14-Nov-24 8:10 PM, Ricardo Ribalda wrote:
> From: Yunke Cao <yunkec@google.com>
>
> Implement support for ROI as described in UVC 1.5:
> 4.2.2.1.20 Digital Region of Interest (ROI) Control
>
> ROI control is implemented using V4L2 control API as
> two UVC-specific controls:
> V4L2_CID_UVC_REGION_OF_INTEREST_RECT and
> V4L2_CID_UVC_REGION_OF_INTEREST_AUTO.
>
> Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
> Signed-off-by: Yunke Cao <yunkec@google.com>
> ---
> drivers/media/usb/uvc/uvc_ctrl.c | 81 ++++++++++++++++++++++++++++++++++++++
> drivers/media/usb/uvc/uvcvideo.h | 7 ++++
> include/uapi/linux/usb/video.h | 1 +
> include/uapi/linux/uvcvideo.h | 13 ++++++
> include/uapi/linux/v4l2-controls.h | 9 +++++
> 5 files changed, 111 insertions(+)
>
> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
> index f262e05ad3a8..5b619ef40dd3 100644
> --- a/drivers/media/usb/uvc/uvc_ctrl.c
> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> @@ -358,6 +358,24 @@ static const struct uvc_control_info uvc_ctrls[] = {
> .flags = UVC_CTRL_FLAG_GET_CUR
> | UVC_CTRL_FLAG_AUTO_UPDATE,
> },
> + /*
> + * UVC_CTRL_FLAG_AUTO_UPDATE is needed because the RoI may get updated
> + * by sensors.
> + * "This RoI should be the same as specified in most recent SET_CUR
> + * except in the case where the ‘Auto Detect and Track’ and/or
> + * ‘Image Stabilization’ bit have been set."
> + * 4.2.2.1.20 Digital Region of Interest (ROI) Control
> + */
> + {
> + .entity = UVC_GUID_UVC_CAMERA,
> + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> + .index = 21,
> + .size = 10,
> + .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
> + | UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
> + | UVC_CTRL_FLAG_GET_DEF
> + | UVC_CTRL_FLAG_AUTO_UPDATE,
> + },
> };
>
> static const u32 uvc_control_classes[] = {
> @@ -603,6 +621,44 @@ static const struct uvc_control_mapping *uvc_ctrl_filter_plf_mapping(
> return out_mapping;
> }
>
> +static int uvc_get_rect(struct uvc_control_mapping *mapping, u8 query,
> + const void *uvc_in, size_t v4l2_size, void *v4l2_out)
> +{
> + const struct uvc_rect *uvc_rect = uvc_in;
> + struct v4l2_rect *v4l2_rect = v4l2_out;
> +
> + if (WARN_ON(v4l2_size != sizeof(struct v4l2_rect)))
> + return -EINVAL;
> +
> + if (uvc_rect->left > uvc_rect->right ||
> + uvc_rect->top > uvc_rect->bottom)
> + return -EIO;
> +
> + v4l2_rect->top = uvc_rect->top;
> + v4l2_rect->left = uvc_rect->left;
> + v4l2_rect->height = uvc_rect->bottom - uvc_rect->top + 1;
> + v4l2_rect->width = uvc_rect->right - uvc_rect->left + 1;
> +
> + return 0;
> +}
> +
> +static int uvc_set_rect(struct uvc_control_mapping *mapping, size_t v4l2_size,
> + const void *v4l2_in, void *uvc_out)
> +{
> + struct uvc_rect *uvc_rect = uvc_out;
> + const struct v4l2_rect *v4l2_rect = v4l2_in;
> +
> + if (WARN_ON(v4l2_size != sizeof(struct v4l2_rect)))
> + return -EINVAL;
> +
> + uvc_rect->top = max(0xffff, v4l2_rect->top);
> + uvc_rect->left = max(0xffff, v4l2_rect->left);
> + uvc_rect->bottom = max(0xffff, v4l2_rect->height + v4l2_rect->top - 1);
> + uvc_rect->right = max(0xffff, v4l2_rect->width + v4l2_rect->left - 1);
As already remarked all 4 lines should be min() not max()
Also this might just be me, but I have a preference for writing top + height
for the bottom rather then writing height + top, since the window starts with
skippig top pixels and then has height pixels filled in. And same for
calculating rect->width. IOW I have a preference for writing this as:
uvc_rect->bottom = min(0xffff, v4l2_rect->top + v4l2_rect->height - 1);
uvc_rect->right = min(0xffff, v4l2_rect->left + v4l2_rect->width - 1);
As I said this might just be me, but to me the above reads more naturally.
> +
> + return 0;
> +}
> +
> static const struct uvc_control_mapping uvc_ctrl_mappings[] = {
> {
> .id = V4L2_CID_BRIGHTNESS,
> @@ -897,6 +953,28 @@ static const struct uvc_control_mapping uvc_ctrl_mappings[] = {
> .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
> .filter_mapping = uvc_ctrl_filter_plf_mapping,
> },
> + {
> + .id = V4L2_CID_UVC_REGION_OF_INTEREST_RECT,
> + .entity = UVC_GUID_UVC_CAMERA,
> + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> + .size = sizeof(struct uvc_rect) * 8,
> + .offset = 0,
> + .v4l2_type = V4L2_CTRL_TYPE_RECT,
> + .data_type = UVC_CTRL_DATA_TYPE_RECT,
> + .get = uvc_get_rect,
> + .set = uvc_set_rect,
> + .name = "Region Of Interest Rectangle",
> + },
> + {
> + .id = V4L2_CID_UVC_REGION_OF_INTEREST_AUTO,
> + .entity = UVC_GUID_UVC_CAMERA,
> + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> + .size = 16,
> + .offset = 64,
> + .v4l2_type = V4L2_CTRL_TYPE_BITMASK,
> + .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
> + .name = "Region Of Interest Auto Controls",
> + },
> };
>
> /* ------------------------------------------------------------------------
> @@ -1465,6 +1543,9 @@ static int __uvc_queryctrl_boundaries(struct uvc_video_chain *chain,
>
> static size_t uvc_mapping_v4l2_size(struct uvc_control_mapping *mapping)
> {
> + if (mapping->v4l2_type == V4L2_CTRL_TYPE_RECT)
> + return sizeof(struct v4l2_rect);
> +
> if (uvc_ctrl_mapping_is_compound(mapping))
> return DIV_ROUND_UP(mapping->size, 8);
>
> diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> index 8aca1a2fe587..d910a5e5b514 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -294,6 +294,13 @@ struct uvc_streaming_header {
> u8 bTriggerUsage;
> };
>
> +struct uvc_rect {
> + u16 top;
> + u16 left;
> + u16 bottom;
> + u16 right;
> +} __packed;
> +
This should probably be grouped togather with uvc_status_* structs which are
also marked __packed because they represent hw API rather then just host
in memory structures.
> enum uvc_buffer_state {
> UVC_BUF_STATE_IDLE = 0,
> UVC_BUF_STATE_QUEUED = 1,
> diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h
> index 2ff0e8a3a683..2afb4420e6c4 100644
> --- a/include/uapi/linux/usb/video.h
> +++ b/include/uapi/linux/usb/video.h
> @@ -104,6 +104,7 @@
> #define UVC_CT_ROLL_ABSOLUTE_CONTROL 0x0f
> #define UVC_CT_ROLL_RELATIVE_CONTROL 0x10
> #define UVC_CT_PRIVACY_CONTROL 0x11
> +#define UVC_CT_REGION_OF_INTEREST_CONTROL 0x14
>
> /* A.9.5. Processing Unit Control Selectors */
> #define UVC_PU_CONTROL_UNDEFINED 0x00
> diff --git a/include/uapi/linux/uvcvideo.h b/include/uapi/linux/uvcvideo.h
> index f86185456dc5..cbe15bca9569 100644
> --- a/include/uapi/linux/uvcvideo.h
> +++ b/include/uapi/linux/uvcvideo.h
> @@ -16,6 +16,7 @@
> #define UVC_CTRL_DATA_TYPE_BOOLEAN 3
> #define UVC_CTRL_DATA_TYPE_ENUM 4
> #define UVC_CTRL_DATA_TYPE_BITMASK 5
> +#define UVC_CTRL_DATA_TYPE_RECT 6
>
> /* Control flags */
> #define UVC_CTRL_FLAG_SET_CUR (1 << 0)
> @@ -38,6 +39,18 @@
>
> #define UVC_MENU_NAME_LEN 32
>
> +/* V4L2 driver-specific controls */
> +#define V4L2_CID_UVC_REGION_OF_INTEREST_RECT (V4L2_CID_USER_UVC_BASE + 1)
> +#define V4L2_CID_UVC_REGION_OF_INTEREST_AUTO (V4L2_CID_USER_UVC_BASE + 2)
> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_EXPOSURE (1 << 0)
> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_IRIS (1 << 1)
> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_WHITE_BALANCE (1 << 2)
> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_FOCUS (1 << 3)
> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_FACE_DETECT (1 << 4)
> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_DETECT_AND_TRACK (1 << 5)
> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_IMAGE_STABILIZATION (1 << 6)
> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_HIGHER_QUALITY (1 << 7)
> +
Hmm, shoudn't these be standardized. At least the ROI rect control seems like
something which could be standardized ?
Was using driver specific CIDs for this discussed with Hans Verkuil ?
> struct uvc_menu_info {
> __u32 value;
> __u8 name[UVC_MENU_NAME_LEN];
> diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
> index 974fd254e573..6c91d6fa4708 100644
> --- a/include/uapi/linux/v4l2-controls.h
> +++ b/include/uapi/linux/v4l2-controls.h
> @@ -215,6 +215,13 @@ enum v4l2_colorfx {
> */
> #define V4L2_CID_USER_THP7312_BASE (V4L2_CID_USER_BASE + 0x11c0)
>
> +/*
> + * The base for the uvc driver controls.
> + * See linux/uvcvideo.h for the list of controls.
> + * We reserve 64 controls for this driver.
> + */
> +#define V4L2_CID_USER_UVC_BASE (V4L2_CID_USER_BASE + 0x11e0)
> +
> /* MPEG-class control IDs */
> /* The MPEG controls are applicable to all codec controls
> * and the 'MPEG' part of the define is historical */
> @@ -1089,6 +1096,8 @@ enum v4l2_auto_focus_range {
>
> #define V4L2_CID_HDR_SENSOR_MODE (V4L2_CID_CAMERA_CLASS_BASE+36)
>
> +/* CAMERA-class private control IDs */
> +
> /* FM Modulator class control IDs */
>
> #define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900)
>
Regards,
Hans
Hi Hans
On Mon, 9 Dec 2024 at 15:22, Hans de Goede <hdegoede@redhat.com> wrote:
>
> Hi,
>
> On 14-Nov-24 8:10 PM, Ricardo Ribalda wrote:
> > From: Yunke Cao <yunkec@google.com>
> >
> > Implement support for ROI as described in UVC 1.5:
> > 4.2.2.1.20 Digital Region of Interest (ROI) Control
> >
> > ROI control is implemented using V4L2 control API as
> > two UVC-specific controls:
> > V4L2_CID_UVC_REGION_OF_INTEREST_RECT and
> > V4L2_CID_UVC_REGION_OF_INTEREST_AUTO.
> >
> > Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
> > Signed-off-by: Yunke Cao <yunkec@google.com>
> > ---
> > drivers/media/usb/uvc/uvc_ctrl.c | 81 ++++++++++++++++++++++++++++++++++++++
> > drivers/media/usb/uvc/uvcvideo.h | 7 ++++
> > include/uapi/linux/usb/video.h | 1 +
> > include/uapi/linux/uvcvideo.h | 13 ++++++
> > include/uapi/linux/v4l2-controls.h | 9 +++++
> > 5 files changed, 111 insertions(+)
> >
> > diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
> > index f262e05ad3a8..5b619ef40dd3 100644
> > --- a/drivers/media/usb/uvc/uvc_ctrl.c
> > +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> > @@ -358,6 +358,24 @@ static const struct uvc_control_info uvc_ctrls[] = {
> > .flags = UVC_CTRL_FLAG_GET_CUR
> > | UVC_CTRL_FLAG_AUTO_UPDATE,
> > },
> > + /*
> > + * UVC_CTRL_FLAG_AUTO_UPDATE is needed because the RoI may get updated
> > + * by sensors.
> > + * "This RoI should be the same as specified in most recent SET_CUR
> > + * except in the case where the ‘Auto Detect and Track’ and/or
> > + * ‘Image Stabilization’ bit have been set."
> > + * 4.2.2.1.20 Digital Region of Interest (ROI) Control
> > + */
> > + {
> > + .entity = UVC_GUID_UVC_CAMERA,
> > + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> > + .index = 21,
> > + .size = 10,
> > + .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
> > + | UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
> > + | UVC_CTRL_FLAG_GET_DEF
> > + | UVC_CTRL_FLAG_AUTO_UPDATE,
> > + },
> > };
> >
> > static const u32 uvc_control_classes[] = {
> > @@ -603,6 +621,44 @@ static const struct uvc_control_mapping *uvc_ctrl_filter_plf_mapping(
> > return out_mapping;
> > }
> >
> > +static int uvc_get_rect(struct uvc_control_mapping *mapping, u8 query,
> > + const void *uvc_in, size_t v4l2_size, void *v4l2_out)
> > +{
> > + const struct uvc_rect *uvc_rect = uvc_in;
> > + struct v4l2_rect *v4l2_rect = v4l2_out;
> > +
> > + if (WARN_ON(v4l2_size != sizeof(struct v4l2_rect)))
> > + return -EINVAL;
> > +
> > + if (uvc_rect->left > uvc_rect->right ||
> > + uvc_rect->top > uvc_rect->bottom)
> > + return -EIO;
> > +
> > + v4l2_rect->top = uvc_rect->top;
> > + v4l2_rect->left = uvc_rect->left;
> > + v4l2_rect->height = uvc_rect->bottom - uvc_rect->top + 1;
> > + v4l2_rect->width = uvc_rect->right - uvc_rect->left + 1;
> > +
> > + return 0;
> > +}
> > +
> > +static int uvc_set_rect(struct uvc_control_mapping *mapping, size_t v4l2_size,
> > + const void *v4l2_in, void *uvc_out)
> > +{
> > + struct uvc_rect *uvc_rect = uvc_out;
> > + const struct v4l2_rect *v4l2_rect = v4l2_in;
> > +
> > + if (WARN_ON(v4l2_size != sizeof(struct v4l2_rect)))
> > + return -EINVAL;
> > +
> > + uvc_rect->top = max(0xffff, v4l2_rect->top);
> > + uvc_rect->left = max(0xffff, v4l2_rect->left);
> > + uvc_rect->bottom = max(0xffff, v4l2_rect->height + v4l2_rect->top - 1);
> > + uvc_rect->right = max(0xffff, v4l2_rect->width + v4l2_rect->left - 1);
>
> As already remarked all 4 lines should be min() not max()
>
> Also this might just be me, but I have a preference for writing top + height
> for the bottom rather then writing height + top, since the window starts with
> skippig top pixels and then has height pixels filled in. And same for
> calculating rect->width. IOW I have a preference for writing this as:
>
> uvc_rect->bottom = min(0xffff, v4l2_rect->top + v4l2_rect->height - 1);
> uvc_rect->right = min(0xffff, v4l2_rect->left + v4l2_rect->width - 1);
>
> As I said this might just be me, but to me the above reads more naturally.
>
>
>
>
> > +
> > + return 0;
> > +}
> > +
> > static const struct uvc_control_mapping uvc_ctrl_mappings[] = {
> > {
> > .id = V4L2_CID_BRIGHTNESS,
> > @@ -897,6 +953,28 @@ static const struct uvc_control_mapping uvc_ctrl_mappings[] = {
> > .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
> > .filter_mapping = uvc_ctrl_filter_plf_mapping,
> > },
> > + {
> > + .id = V4L2_CID_UVC_REGION_OF_INTEREST_RECT,
> > + .entity = UVC_GUID_UVC_CAMERA,
> > + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> > + .size = sizeof(struct uvc_rect) * 8,
> > + .offset = 0,
> > + .v4l2_type = V4L2_CTRL_TYPE_RECT,
> > + .data_type = UVC_CTRL_DATA_TYPE_RECT,
> > + .get = uvc_get_rect,
> > + .set = uvc_set_rect,
> > + .name = "Region Of Interest Rectangle",
> > + },
> > + {
> > + .id = V4L2_CID_UVC_REGION_OF_INTEREST_AUTO,
> > + .entity = UVC_GUID_UVC_CAMERA,
> > + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> > + .size = 16,
> > + .offset = 64,
> > + .v4l2_type = V4L2_CTRL_TYPE_BITMASK,
> > + .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
> > + .name = "Region Of Interest Auto Controls",
> > + },
> > };
> >
> > /* ------------------------------------------------------------------------
> > @@ -1465,6 +1543,9 @@ static int __uvc_queryctrl_boundaries(struct uvc_video_chain *chain,
> >
> > static size_t uvc_mapping_v4l2_size(struct uvc_control_mapping *mapping)
> > {
> > + if (mapping->v4l2_type == V4L2_CTRL_TYPE_RECT)
> > + return sizeof(struct v4l2_rect);
> > +
> > if (uvc_ctrl_mapping_is_compound(mapping))
> > return DIV_ROUND_UP(mapping->size, 8);
> >
> > diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> > index 8aca1a2fe587..d910a5e5b514 100644
> > --- a/drivers/media/usb/uvc/uvcvideo.h
> > +++ b/drivers/media/usb/uvc/uvcvideo.h
> > @@ -294,6 +294,13 @@ struct uvc_streaming_header {
> > u8 bTriggerUsage;
> > };
> >
> > +struct uvc_rect {
> > + u16 top;
> > + u16 left;
> > + u16 bottom;
> > + u16 right;
> > +} __packed;
> > +
>
> This should probably be grouped togather with uvc_status_* structs which are
> also marked __packed because they represent hw API rather then just host
> in memory structures.
>
> > enum uvc_buffer_state {
> > UVC_BUF_STATE_IDLE = 0,
> > UVC_BUF_STATE_QUEUED = 1,
> > diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h
> > index 2ff0e8a3a683..2afb4420e6c4 100644
> > --- a/include/uapi/linux/usb/video.h
> > +++ b/include/uapi/linux/usb/video.h
> > @@ -104,6 +104,7 @@
> > #define UVC_CT_ROLL_ABSOLUTE_CONTROL 0x0f
> > #define UVC_CT_ROLL_RELATIVE_CONTROL 0x10
> > #define UVC_CT_PRIVACY_CONTROL 0x11
> > +#define UVC_CT_REGION_OF_INTEREST_CONTROL 0x14
> >
> > /* A.9.5. Processing Unit Control Selectors */
> > #define UVC_PU_CONTROL_UNDEFINED 0x00
> > diff --git a/include/uapi/linux/uvcvideo.h b/include/uapi/linux/uvcvideo.h
> > index f86185456dc5..cbe15bca9569 100644
> > --- a/include/uapi/linux/uvcvideo.h
> > +++ b/include/uapi/linux/uvcvideo.h
> > @@ -16,6 +16,7 @@
> > #define UVC_CTRL_DATA_TYPE_BOOLEAN 3
> > #define UVC_CTRL_DATA_TYPE_ENUM 4
> > #define UVC_CTRL_DATA_TYPE_BITMASK 5
> > +#define UVC_CTRL_DATA_TYPE_RECT 6
> >
> > /* Control flags */
> > #define UVC_CTRL_FLAG_SET_CUR (1 << 0)
> > @@ -38,6 +39,18 @@
> >
> > #define UVC_MENU_NAME_LEN 32
> >
> > +/* V4L2 driver-specific controls */
> > +#define V4L2_CID_UVC_REGION_OF_INTEREST_RECT (V4L2_CID_USER_UVC_BASE + 1)
> > +#define V4L2_CID_UVC_REGION_OF_INTEREST_AUTO (V4L2_CID_USER_UVC_BASE + 2)
> > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_EXPOSURE (1 << 0)
> > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_IRIS (1 << 1)
> > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_WHITE_BALANCE (1 << 2)
> > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_FOCUS (1 << 3)
> > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_FACE_DETECT (1 << 4)
> > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_DETECT_AND_TRACK (1 << 5)
> > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_IMAGE_STABILIZATION (1 << 6)
> > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_HIGHER_QUALITY (1 << 7)
> > +
>
> Hmm, shoudn't these be standardized. At least the ROI rect control seems like
> something which could be standardized ?
I believe that back in 2022 we deciced to go with custom controls:
https://lore.kernel.org/linux-media/a0fe2b49-12b7-8eaf-c3ef-7af1a247e595@xs4all.nl/
>
> Was using driver specific CIDs for this discussed with Hans Verkuil ?
>
> > struct uvc_menu_info {
> > __u32 value;
> > __u8 name[UVC_MENU_NAME_LEN];
> > diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
> > index 974fd254e573..6c91d6fa4708 100644
> > --- a/include/uapi/linux/v4l2-controls.h
> > +++ b/include/uapi/linux/v4l2-controls.h
> > @@ -215,6 +215,13 @@ enum v4l2_colorfx {
> > */
> > #define V4L2_CID_USER_THP7312_BASE (V4L2_CID_USER_BASE + 0x11c0)
> >
> > +/*
> > + * The base for the uvc driver controls.
> > + * See linux/uvcvideo.h for the list of controls.
> > + * We reserve 64 controls for this driver.
> > + */
> > +#define V4L2_CID_USER_UVC_BASE (V4L2_CID_USER_BASE + 0x11e0)
> > +
> > /* MPEG-class control IDs */
> > /* The MPEG controls are applicable to all codec controls
> > * and the 'MPEG' part of the define is historical */
> > @@ -1089,6 +1096,8 @@ enum v4l2_auto_focus_range {
> >
> > #define V4L2_CID_HDR_SENSOR_MODE (V4L2_CID_CAMERA_CLASS_BASE+36)
> >
> > +/* CAMERA-class private control IDs */
> > +
> > /* FM Modulator class control IDs */
> >
> > #define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900)
> >
>
>
> Regards,
>
> Hans
>
>
--
Ricardo Ribalda
Hi Ricardo, On 9-Dec-24 4:23 PM, Ricardo Ribalda wrote: > Hi Hans > > On Mon, 9 Dec 2024 at 15:22, Hans de Goede <hdegoede@redhat.com> wrote: <snip> >>> diff --git a/include/uapi/linux/uvcvideo.h b/include/uapi/linux/uvcvideo.h >>> index f86185456dc5..cbe15bca9569 100644 >>> --- a/include/uapi/linux/uvcvideo.h >>> +++ b/include/uapi/linux/uvcvideo.h >>> @@ -16,6 +16,7 @@ >>> #define UVC_CTRL_DATA_TYPE_BOOLEAN 3 >>> #define UVC_CTRL_DATA_TYPE_ENUM 4 >>> #define UVC_CTRL_DATA_TYPE_BITMASK 5 >>> +#define UVC_CTRL_DATA_TYPE_RECT 6 >>> >>> /* Control flags */ >>> #define UVC_CTRL_FLAG_SET_CUR (1 << 0) >>> @@ -38,6 +39,18 @@ >>> >>> #define UVC_MENU_NAME_LEN 32 >>> >>> +/* V4L2 driver-specific controls */ >>> +#define V4L2_CID_UVC_REGION_OF_INTEREST_RECT (V4L2_CID_USER_UVC_BASE + 1) >>> +#define V4L2_CID_UVC_REGION_OF_INTEREST_AUTO (V4L2_CID_USER_UVC_BASE + 2) >>> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_EXPOSURE (1 << 0) >>> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_IRIS (1 << 1) >>> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_WHITE_BALANCE (1 << 2) >>> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_FOCUS (1 << 3) >>> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_FACE_DETECT (1 << 4) >>> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_DETECT_AND_TRACK (1 << 5) >>> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_IMAGE_STABILIZATION (1 << 6) >>> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_HIGHER_QUALITY (1 << 7) >>> + >> >> Hmm, shoudn't these be standardized. At least the ROI rect control seems like >> something which could be standardized ? > > I believe that back in 2022 we deciced to go with custom controls: > https://lore.kernel.org/linux-media/a0fe2b49-12b7-8eaf-c3ef-7af1a247e595@xs4all.nl/ Ok that is good enough for me. I just wanted to make sure this was already looked at as a possible generic ctrl. Regards, Hans
Hi Ricardo,
Thanks for the new version!!
On Fri, Nov 15, 2024 at 4:11 AM Ricardo Ribalda <ribalda@chromium.org> wrote:
>
> From: Yunke Cao <yunkec@google.com>
>
> Implement support for ROI as described in UVC 1.5:
> 4.2.2.1.20 Digital Region of Interest (ROI) Control
>
> ROI control is implemented using V4L2 control API as
> two UVC-specific controls:
> V4L2_CID_UVC_REGION_OF_INTEREST_RECT and
> V4L2_CID_UVC_REGION_OF_INTEREST_AUTO.
>
> Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
> Signed-off-by: Yunke Cao <yunkec@google.com>
> ---
> drivers/media/usb/uvc/uvc_ctrl.c | 81 ++++++++++++++++++++++++++++++++++++++
> drivers/media/usb/uvc/uvcvideo.h | 7 ++++
> include/uapi/linux/usb/video.h | 1 +
> include/uapi/linux/uvcvideo.h | 13 ++++++
> include/uapi/linux/v4l2-controls.h | 9 +++++
> 5 files changed, 111 insertions(+)
>
> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
> index f262e05ad3a8..5b619ef40dd3 100644
> --- a/drivers/media/usb/uvc/uvc_ctrl.c
> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> @@ -358,6 +358,24 @@ static const struct uvc_control_info uvc_ctrls[] = {
> .flags = UVC_CTRL_FLAG_GET_CUR
> | UVC_CTRL_FLAG_AUTO_UPDATE,
> },
> + /*
> + * UVC_CTRL_FLAG_AUTO_UPDATE is needed because the RoI may get updated
> + * by sensors.
> + * "This RoI should be the same as specified in most recent SET_CUR
> + * except in the case where the ‘Auto Detect and Track’ and/or
> + * ‘Image Stabilization’ bit have been set."
> + * 4.2.2.1.20 Digital Region of Interest (ROI) Control
> + */
> + {
> + .entity = UVC_GUID_UVC_CAMERA,
> + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> + .index = 21,
> + .size = 10,
> + .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
> + | UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
> + | UVC_CTRL_FLAG_GET_DEF
> + | UVC_CTRL_FLAG_AUTO_UPDATE,
> + },
> };
>
> static const u32 uvc_control_classes[] = {
> @@ -603,6 +621,44 @@ static const struct uvc_control_mapping *uvc_ctrl_filter_plf_mapping(
> return out_mapping;
> }
>
> +static int uvc_get_rect(struct uvc_control_mapping *mapping, u8 query,
> + const void *uvc_in, size_t v4l2_size, void *v4l2_out)
> +{
> + const struct uvc_rect *uvc_rect = uvc_in;
> + struct v4l2_rect *v4l2_rect = v4l2_out;
> +
> + if (WARN_ON(v4l2_size != sizeof(struct v4l2_rect)))
> + return -EINVAL;
> +
> + if (uvc_rect->left > uvc_rect->right ||
> + uvc_rect->top > uvc_rect->bottom)
> + return -EIO;
> +
> + v4l2_rect->top = uvc_rect->top;
> + v4l2_rect->left = uvc_rect->left;
> + v4l2_rect->height = uvc_rect->bottom - uvc_rect->top + 1;
> + v4l2_rect->width = uvc_rect->right - uvc_rect->left + 1;
> +
> + return 0;
> +}
> +
> +static int uvc_set_rect(struct uvc_control_mapping *mapping, size_t v4l2_size,
> + const void *v4l2_in, void *uvc_out)
> +{
> + struct uvc_rect *uvc_rect = uvc_out;
> + const struct v4l2_rect *v4l2_rect = v4l2_in;
> +
> + if (WARN_ON(v4l2_size != sizeof(struct v4l2_rect)))
> + return -EINVAL;
> +
> + uvc_rect->top = max(0xffff, v4l2_rect->top);
> + uvc_rect->left = max(0xffff, v4l2_rect->left);
> + uvc_rect->bottom = max(0xffff, v4l2_rect->height + v4l2_rect->top - 1);
> + uvc_rect->right = max(0xffff, v4l2_rect->width + v4l2_rect->left - 1);
Should these be min()?
>
> +
> + return 0;
> +}
> +
> static const struct uvc_control_mapping uvc_ctrl_mappings[] = {
> {
> .id = V4L2_CID_BRIGHTNESS,
> @@ -897,6 +953,28 @@ static const struct uvc_control_mapping uvc_ctrl_mappings[] = {
> .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
> .filter_mapping = uvc_ctrl_filter_plf_mapping,
> },
> + {
> + .id = V4L2_CID_UVC_REGION_OF_INTEREST_RECT,
> + .entity = UVC_GUID_UVC_CAMERA,
> + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> + .size = sizeof(struct uvc_rect) * 8,
> + .offset = 0,
> + .v4l2_type = V4L2_CTRL_TYPE_RECT,
> + .data_type = UVC_CTRL_DATA_TYPE_RECT,
> + .get = uvc_get_rect,
> + .set = uvc_set_rect,
> + .name = "Region Of Interest Rectangle",
> + },
> + {
> + .id = V4L2_CID_UVC_REGION_OF_INTEREST_AUTO,
> + .entity = UVC_GUID_UVC_CAMERA,
> + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> + .size = 16,
> + .offset = 64,
> + .v4l2_type = V4L2_CTRL_TYPE_BITMASK,
> + .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
> + .name = "Region Of Interest Auto Controls",
> + },
> };
>
> /* ------------------------------------------------------------------------
> @@ -1465,6 +1543,9 @@ static int __uvc_queryctrl_boundaries(struct uvc_video_chain *chain,
>
> static size_t uvc_mapping_v4l2_size(struct uvc_control_mapping *mapping)
> {
> + if (mapping->v4l2_type == V4L2_CTRL_TYPE_RECT)
> + return sizeof(struct v4l2_rect);
> +
> if (uvc_ctrl_mapping_is_compound(mapping))
> return DIV_ROUND_UP(mapping->size, 8);
>
> diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> index 8aca1a2fe587..d910a5e5b514 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -294,6 +294,13 @@ struct uvc_streaming_header {
> u8 bTriggerUsage;
> };
>
> +struct uvc_rect {
> + u16 top;
> + u16 left;
> + u16 bottom;
> + u16 right;
> +} __packed;
> +
> enum uvc_buffer_state {
> UVC_BUF_STATE_IDLE = 0,
> UVC_BUF_STATE_QUEUED = 1,
> diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h
> index 2ff0e8a3a683..2afb4420e6c4 100644
> --- a/include/uapi/linux/usb/video.h
> +++ b/include/uapi/linux/usb/video.h
> @@ -104,6 +104,7 @@
> #define UVC_CT_ROLL_ABSOLUTE_CONTROL 0x0f
> #define UVC_CT_ROLL_RELATIVE_CONTROL 0x10
> #define UVC_CT_PRIVACY_CONTROL 0x11
> +#define UVC_CT_REGION_OF_INTEREST_CONTROL 0x14
>
> /* A.9.5. Processing Unit Control Selectors */
> #define UVC_PU_CONTROL_UNDEFINED 0x00
> diff --git a/include/uapi/linux/uvcvideo.h b/include/uapi/linux/uvcvideo.h
> index f86185456dc5..cbe15bca9569 100644
> --- a/include/uapi/linux/uvcvideo.h
> +++ b/include/uapi/linux/uvcvideo.h
> @@ -16,6 +16,7 @@
> #define UVC_CTRL_DATA_TYPE_BOOLEAN 3
> #define UVC_CTRL_DATA_TYPE_ENUM 4
> #define UVC_CTRL_DATA_TYPE_BITMASK 5
> +#define UVC_CTRL_DATA_TYPE_RECT 6
>
> /* Control flags */
> #define UVC_CTRL_FLAG_SET_CUR (1 << 0)
> @@ -38,6 +39,18 @@
>
> #define UVC_MENU_NAME_LEN 32
>
> +/* V4L2 driver-specific controls */
> +#define V4L2_CID_UVC_REGION_OF_INTEREST_RECT (V4L2_CID_USER_UVC_BASE + 1)
> +#define V4L2_CID_UVC_REGION_OF_INTEREST_AUTO (V4L2_CID_USER_UVC_BASE + 2)
> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_EXPOSURE (1 << 0)
> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_IRIS (1 << 1)
> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_WHITE_BALANCE (1 << 2)
> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_FOCUS (1 << 3)
> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_FACE_DETECT (1 << 4)
> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_DETECT_AND_TRACK (1 << 5)
> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_IMAGE_STABILIZATION (1 << 6)
> +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_HIGHER_QUALITY (1 << 7)
> +
> struct uvc_menu_info {
> __u32 value;
> __u8 name[UVC_MENU_NAME_LEN];
> diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
> index 974fd254e573..6c91d6fa4708 100644
> --- a/include/uapi/linux/v4l2-controls.h
> +++ b/include/uapi/linux/v4l2-controls.h
> @@ -215,6 +215,13 @@ enum v4l2_colorfx {
> */
> #define V4L2_CID_USER_THP7312_BASE (V4L2_CID_USER_BASE + 0x11c0)
>
> +/*
> + * The base for the uvc driver controls.
> + * See linux/uvcvideo.h for the list of controls.
> + * We reserve 64 controls for this driver.
> + */
> +#define V4L2_CID_USER_UVC_BASE (V4L2_CID_USER_BASE + 0x11e0)
> +
> /* MPEG-class control IDs */
> /* The MPEG controls are applicable to all codec controls
> * and the 'MPEG' part of the define is historical */
> @@ -1089,6 +1096,8 @@ enum v4l2_auto_focus_range {
>
> #define V4L2_CID_HDR_SENSOR_MODE (V4L2_CID_CAMERA_CLASS_BASE+36)
>
> +/* CAMERA-class private control IDs */
> +
Do we still need this comment?
Best,
Yunke
> /* FM Modulator class control IDs */
>
> #define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900)
>
> --
> 2.47.0.338.g60cca15819-goog
>
On Mon, 2 Dec 2024 at 09:02, Yunke Cao <yunkec@google.com> wrote:
>
> Hi Ricardo,
>
> Thanks for the new version!!
>
> On Fri, Nov 15, 2024 at 4:11 AM Ricardo Ribalda <ribalda@chromium.org> wrote:
> >
> > From: Yunke Cao <yunkec@google.com>
> >
> > Implement support for ROI as described in UVC 1.5:
> > 4.2.2.1.20 Digital Region of Interest (ROI) Control
> >
> > ROI control is implemented using V4L2 control API as
> > two UVC-specific controls:
> > V4L2_CID_UVC_REGION_OF_INTEREST_RECT and
> > V4L2_CID_UVC_REGION_OF_INTEREST_AUTO.
> >
> > Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
> > Signed-off-by: Yunke Cao <yunkec@google.com>
> > ---
> > drivers/media/usb/uvc/uvc_ctrl.c | 81 ++++++++++++++++++++++++++++++++++++++
> > drivers/media/usb/uvc/uvcvideo.h | 7 ++++
> > include/uapi/linux/usb/video.h | 1 +
> > include/uapi/linux/uvcvideo.h | 13 ++++++
> > include/uapi/linux/v4l2-controls.h | 9 +++++
> > 5 files changed, 111 insertions(+)
> >
> > diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
> > index f262e05ad3a8..5b619ef40dd3 100644
> > --- a/drivers/media/usb/uvc/uvc_ctrl.c
> > +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> > @@ -358,6 +358,24 @@ static const struct uvc_control_info uvc_ctrls[] = {
> > .flags = UVC_CTRL_FLAG_GET_CUR
> > | UVC_CTRL_FLAG_AUTO_UPDATE,
> > },
> > + /*
> > + * UVC_CTRL_FLAG_AUTO_UPDATE is needed because the RoI may get updated
> > + * by sensors.
> > + * "This RoI should be the same as specified in most recent SET_CUR
> > + * except in the case where the ‘Auto Detect and Track’ and/or
> > + * ‘Image Stabilization’ bit have been set."
> > + * 4.2.2.1.20 Digital Region of Interest (ROI) Control
> > + */
> > + {
> > + .entity = UVC_GUID_UVC_CAMERA,
> > + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> > + .index = 21,
> > + .size = 10,
> > + .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
> > + | UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
> > + | UVC_CTRL_FLAG_GET_DEF
> > + | UVC_CTRL_FLAG_AUTO_UPDATE,
> > + },
> > };
> >
> > static const u32 uvc_control_classes[] = {
> > @@ -603,6 +621,44 @@ static const struct uvc_control_mapping *uvc_ctrl_filter_plf_mapping(
> > return out_mapping;
> > }
> >
> > +static int uvc_get_rect(struct uvc_control_mapping *mapping, u8 query,
> > + const void *uvc_in, size_t v4l2_size, void *v4l2_out)
> > +{
> > + const struct uvc_rect *uvc_rect = uvc_in;
> > + struct v4l2_rect *v4l2_rect = v4l2_out;
> > +
> > + if (WARN_ON(v4l2_size != sizeof(struct v4l2_rect)))
> > + return -EINVAL;
> > +
> > + if (uvc_rect->left > uvc_rect->right ||
> > + uvc_rect->top > uvc_rect->bottom)
> > + return -EIO;
> > +
> > + v4l2_rect->top = uvc_rect->top;
> > + v4l2_rect->left = uvc_rect->left;
> > + v4l2_rect->height = uvc_rect->bottom - uvc_rect->top + 1;
> > + v4l2_rect->width = uvc_rect->right - uvc_rect->left + 1;
> > +
> > + return 0;
> > +}
> > +
> > +static int uvc_set_rect(struct uvc_control_mapping *mapping, size_t v4l2_size,
> > + const void *v4l2_in, void *uvc_out)
> > +{
> > + struct uvc_rect *uvc_rect = uvc_out;
> > + const struct v4l2_rect *v4l2_rect = v4l2_in;
> > +
> > + if (WARN_ON(v4l2_size != sizeof(struct v4l2_rect)))
> > + return -EINVAL;
> > +
> > + uvc_rect->top = max(0xffff, v4l2_rect->top);
> > + uvc_rect->left = max(0xffff, v4l2_rect->left);
> > + uvc_rect->bottom = max(0xffff, v4l2_rect->height + v4l2_rect->top - 1);
> > + uvc_rect->right = max(0xffff, v4l2_rect->width + v4l2_rect->left - 1);
>
> Should these be min()?
Ups :).
Fixed in the next version.
Thanks!
>
> >
> > +
> > + return 0;
> > +}
> > +
> > static const struct uvc_control_mapping uvc_ctrl_mappings[] = {
> > {
> > .id = V4L2_CID_BRIGHTNESS,
> > @@ -897,6 +953,28 @@ static const struct uvc_control_mapping uvc_ctrl_mappings[] = {
> > .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
> > .filter_mapping = uvc_ctrl_filter_plf_mapping,
> > },
> > + {
> > + .id = V4L2_CID_UVC_REGION_OF_INTEREST_RECT,
> > + .entity = UVC_GUID_UVC_CAMERA,
> > + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> > + .size = sizeof(struct uvc_rect) * 8,
> > + .offset = 0,
> > + .v4l2_type = V4L2_CTRL_TYPE_RECT,
> > + .data_type = UVC_CTRL_DATA_TYPE_RECT,
> > + .get = uvc_get_rect,
> > + .set = uvc_set_rect,
> > + .name = "Region Of Interest Rectangle",
> > + },
> > + {
> > + .id = V4L2_CID_UVC_REGION_OF_INTEREST_AUTO,
> > + .entity = UVC_GUID_UVC_CAMERA,
> > + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> > + .size = 16,
> > + .offset = 64,
> > + .v4l2_type = V4L2_CTRL_TYPE_BITMASK,
> > + .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
> > + .name = "Region Of Interest Auto Controls",
> > + },
> > };
> >
> > /* ------------------------------------------------------------------------
> > @@ -1465,6 +1543,9 @@ static int __uvc_queryctrl_boundaries(struct uvc_video_chain *chain,
> >
> > static size_t uvc_mapping_v4l2_size(struct uvc_control_mapping *mapping)
> > {
> > + if (mapping->v4l2_type == V4L2_CTRL_TYPE_RECT)
> > + return sizeof(struct v4l2_rect);
> > +
> > if (uvc_ctrl_mapping_is_compound(mapping))
> > return DIV_ROUND_UP(mapping->size, 8);
> >
> > diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> > index 8aca1a2fe587..d910a5e5b514 100644
> > --- a/drivers/media/usb/uvc/uvcvideo.h
> > +++ b/drivers/media/usb/uvc/uvcvideo.h
> > @@ -294,6 +294,13 @@ struct uvc_streaming_header {
> > u8 bTriggerUsage;
> > };
> >
> > +struct uvc_rect {
> > + u16 top;
> > + u16 left;
> > + u16 bottom;
> > + u16 right;
> > +} __packed;
> > +
> > enum uvc_buffer_state {
> > UVC_BUF_STATE_IDLE = 0,
> > UVC_BUF_STATE_QUEUED = 1,
> > diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h
> > index 2ff0e8a3a683..2afb4420e6c4 100644
> > --- a/include/uapi/linux/usb/video.h
> > +++ b/include/uapi/linux/usb/video.h
> > @@ -104,6 +104,7 @@
> > #define UVC_CT_ROLL_ABSOLUTE_CONTROL 0x0f
> > #define UVC_CT_ROLL_RELATIVE_CONTROL 0x10
> > #define UVC_CT_PRIVACY_CONTROL 0x11
> > +#define UVC_CT_REGION_OF_INTEREST_CONTROL 0x14
> >
> > /* A.9.5. Processing Unit Control Selectors */
> > #define UVC_PU_CONTROL_UNDEFINED 0x00
> > diff --git a/include/uapi/linux/uvcvideo.h b/include/uapi/linux/uvcvideo.h
> > index f86185456dc5..cbe15bca9569 100644
> > --- a/include/uapi/linux/uvcvideo.h
> > +++ b/include/uapi/linux/uvcvideo.h
> > @@ -16,6 +16,7 @@
> > #define UVC_CTRL_DATA_TYPE_BOOLEAN 3
> > #define UVC_CTRL_DATA_TYPE_ENUM 4
> > #define UVC_CTRL_DATA_TYPE_BITMASK 5
> > +#define UVC_CTRL_DATA_TYPE_RECT 6
> >
> > /* Control flags */
> > #define UVC_CTRL_FLAG_SET_CUR (1 << 0)
> > @@ -38,6 +39,18 @@
> >
> > #define UVC_MENU_NAME_LEN 32
> >
> > +/* V4L2 driver-specific controls */
> > +#define V4L2_CID_UVC_REGION_OF_INTEREST_RECT (V4L2_CID_USER_UVC_BASE + 1)
> > +#define V4L2_CID_UVC_REGION_OF_INTEREST_AUTO (V4L2_CID_USER_UVC_BASE + 2)
> > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_EXPOSURE (1 << 0)
> > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_IRIS (1 << 1)
> > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_WHITE_BALANCE (1 << 2)
> > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_FOCUS (1 << 3)
> > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_FACE_DETECT (1 << 4)
> > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_DETECT_AND_TRACK (1 << 5)
> > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_IMAGE_STABILIZATION (1 << 6)
> > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_HIGHER_QUALITY (1 << 7)
> > +
> > struct uvc_menu_info {
> > __u32 value;
> > __u8 name[UVC_MENU_NAME_LEN];
> > diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
> > index 974fd254e573..6c91d6fa4708 100644
> > --- a/include/uapi/linux/v4l2-controls.h
> > +++ b/include/uapi/linux/v4l2-controls.h
> > @@ -215,6 +215,13 @@ enum v4l2_colorfx {
> > */
> > #define V4L2_CID_USER_THP7312_BASE (V4L2_CID_USER_BASE + 0x11c0)
> >
> > +/*
> > + * The base for the uvc driver controls.
> > + * See linux/uvcvideo.h for the list of controls.
> > + * We reserve 64 controls for this driver.
> > + */
> > +#define V4L2_CID_USER_UVC_BASE (V4L2_CID_USER_BASE + 0x11e0)
> > +
> > /* MPEG-class control IDs */
> > /* The MPEG controls are applicable to all codec controls
> > * and the 'MPEG' part of the define is historical */
> > @@ -1089,6 +1096,8 @@ enum v4l2_auto_focus_range {
> >
> > #define V4L2_CID_HDR_SENSOR_MODE (V4L2_CID_CAMERA_CLASS_BASE+36)
> >
> > +/* CAMERA-class private control IDs */
> > +
>
> Do we still need this comment?
>
> Best,
> Yunke
>
> > /* FM Modulator class control IDs */
> >
> > #define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900)
> >
> > --
> > 2.47.0.338.g60cca15819-goog
> >
--
Ricardo Ribalda
On Mon, Dec 2, 2024 at 6:26 PM Ricardo Ribalda <ribalda@chromium.org> wrote:
>
> On Mon, 2 Dec 2024 at 09:02, Yunke Cao <yunkec@google.com> wrote:
> >
> > Hi Ricardo,
> >
> > Thanks for the new version!!
> >
> > On Fri, Nov 15, 2024 at 4:11 AM Ricardo Ribalda <ribalda@chromium.org> wrote:
> > >
> > > From: Yunke Cao <yunkec@google.com>
> > >
> > > Implement support for ROI as described in UVC 1.5:
> > > 4.2.2.1.20 Digital Region of Interest (ROI) Control
> > >
> > > ROI control is implemented using V4L2 control API as
> > > two UVC-specific controls:
> > > V4L2_CID_UVC_REGION_OF_INTEREST_RECT and
> > > V4L2_CID_UVC_REGION_OF_INTEREST_AUTO.
> > >
> > > Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
> > > Signed-off-by: Yunke Cao <yunkec@google.com>
> > > ---
> > > drivers/media/usb/uvc/uvc_ctrl.c | 81 ++++++++++++++++++++++++++++++++++++++
> > > drivers/media/usb/uvc/uvcvideo.h | 7 ++++
> > > include/uapi/linux/usb/video.h | 1 +
> > > include/uapi/linux/uvcvideo.h | 13 ++++++
> > > include/uapi/linux/v4l2-controls.h | 9 +++++
> > > 5 files changed, 111 insertions(+)
> > >
> > > diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
> > > index f262e05ad3a8..5b619ef40dd3 100644
> > > --- a/drivers/media/usb/uvc/uvc_ctrl.c
> > > +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> > > @@ -358,6 +358,24 @@ static const struct uvc_control_info uvc_ctrls[] = {
> > > .flags = UVC_CTRL_FLAG_GET_CUR
> > > | UVC_CTRL_FLAG_AUTO_UPDATE,
> > > },
> > > + /*
> > > + * UVC_CTRL_FLAG_AUTO_UPDATE is needed because the RoI may get updated
> > > + * by sensors.
> > > + * "This RoI should be the same as specified in most recent SET_CUR
> > > + * except in the case where the ‘Auto Detect and Track’ and/or
> > > + * ‘Image Stabilization’ bit have been set."
> > > + * 4.2.2.1.20 Digital Region of Interest (ROI) Control
> > > + */
> > > + {
> > > + .entity = UVC_GUID_UVC_CAMERA,
> > > + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> > > + .index = 21,
> > > + .size = 10,
> > > + .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
> > > + | UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
> > > + | UVC_CTRL_FLAG_GET_DEF
> > > + | UVC_CTRL_FLAG_AUTO_UPDATE,
> > > + },
> > > };
> > >
> > > static const u32 uvc_control_classes[] = {
> > > @@ -603,6 +621,44 @@ static const struct uvc_control_mapping *uvc_ctrl_filter_plf_mapping(
> > > return out_mapping;
> > > }
> > >
> > > +static int uvc_get_rect(struct uvc_control_mapping *mapping, u8 query,
> > > + const void *uvc_in, size_t v4l2_size, void *v4l2_out)
> > > +{
> > > + const struct uvc_rect *uvc_rect = uvc_in;
> > > + struct v4l2_rect *v4l2_rect = v4l2_out;
> > > +
> > > + if (WARN_ON(v4l2_size != sizeof(struct v4l2_rect)))
> > > + return -EINVAL;
> > > +
> > > + if (uvc_rect->left > uvc_rect->right ||
> > > + uvc_rect->top > uvc_rect->bottom)
> > > + return -EIO;
> > > +
> > > + v4l2_rect->top = uvc_rect->top;
> > > + v4l2_rect->left = uvc_rect->left;
> > > + v4l2_rect->height = uvc_rect->bottom - uvc_rect->top + 1;
> > > + v4l2_rect->width = uvc_rect->right - uvc_rect->left + 1;
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static int uvc_set_rect(struct uvc_control_mapping *mapping, size_t v4l2_size,
> > > + const void *v4l2_in, void *uvc_out)
> > > +{
> > > + struct uvc_rect *uvc_rect = uvc_out;
> > > + const struct v4l2_rect *v4l2_rect = v4l2_in;
> > > +
> > > + if (WARN_ON(v4l2_size != sizeof(struct v4l2_rect)))
> > > + return -EINVAL;
> > > +
> > > + uvc_rect->top = max(0xffff, v4l2_rect->top);
> > > + uvc_rect->left = max(0xffff, v4l2_rect->left);
> > > + uvc_rect->bottom = max(0xffff, v4l2_rect->height + v4l2_rect->top - 1);
> > > + uvc_rect->right = max(0xffff, v4l2_rect->width + v4l2_rect->left - 1);
> >
> > Should these be min()?
>
> Ups :).
>
> Fixed in the next version.
>
> Thanks!
I've tested the patchset with this fix on Chrome OS and verified ROI
works as expected.
Reviewed-by: Yunke Cao <yunkec@google.com>
Tested-by: Yunke Cao <yunkec@google.com>
>
> >
> > >
> > > +
> > > + return 0;
> > > +}
> > > +
> > > static const struct uvc_control_mapping uvc_ctrl_mappings[] = {
> > > {
> > > .id = V4L2_CID_BRIGHTNESS,
> > > @@ -897,6 +953,28 @@ static const struct uvc_control_mapping uvc_ctrl_mappings[] = {
> > > .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
> > > .filter_mapping = uvc_ctrl_filter_plf_mapping,
> > > },
> > > + {
> > > + .id = V4L2_CID_UVC_REGION_OF_INTEREST_RECT,
> > > + .entity = UVC_GUID_UVC_CAMERA,
> > > + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> > > + .size = sizeof(struct uvc_rect) * 8,
> > > + .offset = 0,
> > > + .v4l2_type = V4L2_CTRL_TYPE_RECT,
> > > + .data_type = UVC_CTRL_DATA_TYPE_RECT,
> > > + .get = uvc_get_rect,
> > > + .set = uvc_set_rect,
> > > + .name = "Region Of Interest Rectangle",
> > > + },
> > > + {
> > > + .id = V4L2_CID_UVC_REGION_OF_INTEREST_AUTO,
> > > + .entity = UVC_GUID_UVC_CAMERA,
> > > + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> > > + .size = 16,
> > > + .offset = 64,
> > > + .v4l2_type = V4L2_CTRL_TYPE_BITMASK,
> > > + .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
> > > + .name = "Region Of Interest Auto Controls",
> > > + },
> > > };
> > >
> > > /* ------------------------------------------------------------------------
> > > @@ -1465,6 +1543,9 @@ static int __uvc_queryctrl_boundaries(struct uvc_video_chain *chain,
> > >
> > > static size_t uvc_mapping_v4l2_size(struct uvc_control_mapping *mapping)
> > > {
> > > + if (mapping->v4l2_type == V4L2_CTRL_TYPE_RECT)
> > > + return sizeof(struct v4l2_rect);
> > > +
> > > if (uvc_ctrl_mapping_is_compound(mapping))
> > > return DIV_ROUND_UP(mapping->size, 8);
> > >
> > > diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> > > index 8aca1a2fe587..d910a5e5b514 100644
> > > --- a/drivers/media/usb/uvc/uvcvideo.h
> > > +++ b/drivers/media/usb/uvc/uvcvideo.h
> > > @@ -294,6 +294,13 @@ struct uvc_streaming_header {
> > > u8 bTriggerUsage;
> > > };
> > >
> > > +struct uvc_rect {
> > > + u16 top;
> > > + u16 left;
> > > + u16 bottom;
> > > + u16 right;
> > > +} __packed;
> > > +
> > > enum uvc_buffer_state {
> > > UVC_BUF_STATE_IDLE = 0,
> > > UVC_BUF_STATE_QUEUED = 1,
> > > diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h
> > > index 2ff0e8a3a683..2afb4420e6c4 100644
> > > --- a/include/uapi/linux/usb/video.h
> > > +++ b/include/uapi/linux/usb/video.h
> > > @@ -104,6 +104,7 @@
> > > #define UVC_CT_ROLL_ABSOLUTE_CONTROL 0x0f
> > > #define UVC_CT_ROLL_RELATIVE_CONTROL 0x10
> > > #define UVC_CT_PRIVACY_CONTROL 0x11
> > > +#define UVC_CT_REGION_OF_INTEREST_CONTROL 0x14
> > >
> > > /* A.9.5. Processing Unit Control Selectors */
> > > #define UVC_PU_CONTROL_UNDEFINED 0x00
> > > diff --git a/include/uapi/linux/uvcvideo.h b/include/uapi/linux/uvcvideo.h
> > > index f86185456dc5..cbe15bca9569 100644
> > > --- a/include/uapi/linux/uvcvideo.h
> > > +++ b/include/uapi/linux/uvcvideo.h
> > > @@ -16,6 +16,7 @@
> > > #define UVC_CTRL_DATA_TYPE_BOOLEAN 3
> > > #define UVC_CTRL_DATA_TYPE_ENUM 4
> > > #define UVC_CTRL_DATA_TYPE_BITMASK 5
> > > +#define UVC_CTRL_DATA_TYPE_RECT 6
> > >
> > > /* Control flags */
> > > #define UVC_CTRL_FLAG_SET_CUR (1 << 0)
> > > @@ -38,6 +39,18 @@
> > >
> > > #define UVC_MENU_NAME_LEN 32
> > >
> > > +/* V4L2 driver-specific controls */
> > > +#define V4L2_CID_UVC_REGION_OF_INTEREST_RECT (V4L2_CID_USER_UVC_BASE + 1)
> > > +#define V4L2_CID_UVC_REGION_OF_INTEREST_AUTO (V4L2_CID_USER_UVC_BASE + 2)
> > > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_EXPOSURE (1 << 0)
> > > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_IRIS (1 << 1)
> > > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_WHITE_BALANCE (1 << 2)
> > > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_FOCUS (1 << 3)
> > > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_FACE_DETECT (1 << 4)
> > > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_DETECT_AND_TRACK (1 << 5)
> > > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_IMAGE_STABILIZATION (1 << 6)
> > > +#define V4L2_UVC_REGION_OF_INTEREST_AUTO_HIGHER_QUALITY (1 << 7)
> > > +
> > > struct uvc_menu_info {
> > > __u32 value;
> > > __u8 name[UVC_MENU_NAME_LEN];
> > > diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
> > > index 974fd254e573..6c91d6fa4708 100644
> > > --- a/include/uapi/linux/v4l2-controls.h
> > > +++ b/include/uapi/linux/v4l2-controls.h
> > > @@ -215,6 +215,13 @@ enum v4l2_colorfx {
> > > */
> > > #define V4L2_CID_USER_THP7312_BASE (V4L2_CID_USER_BASE + 0x11c0)
> > >
> > > +/*
> > > + * The base for the uvc driver controls.
> > > + * See linux/uvcvideo.h for the list of controls.
> > > + * We reserve 64 controls for this driver.
> > > + */
> > > +#define V4L2_CID_USER_UVC_BASE (V4L2_CID_USER_BASE + 0x11e0)
> > > +
> > > /* MPEG-class control IDs */
> > > /* The MPEG controls are applicable to all codec controls
> > > * and the 'MPEG' part of the define is historical */
> > > @@ -1089,6 +1096,8 @@ enum v4l2_auto_focus_range {
> > >
> > > #define V4L2_CID_HDR_SENSOR_MODE (V4L2_CID_CAMERA_CLASS_BASE+36)
> > >
> > > +/* CAMERA-class private control IDs */
> > > +
> >
> > Do we still need this comment?
> >
> > Best,
> > Yunke
> >
> > > /* FM Modulator class control IDs */
> > >
> > > #define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900)
> > >
> > > --
> > > 2.47.0.338.g60cca15819-goog
> > >
>
>
>
> --
> Ricardo Ribalda
Hi Ricardo,
On Thu, 2024-11-14 at 19:10 +0000, Ricardo Ribalda wrote:
>
> + },
> + {
> + .id = V4L2_CID_UVC_REGION_OF_INTEREST_AUTO,
> + .entity = UVC_GUID_UVC_CAMERA,
> + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> + .size = 16,
> + .offset = 64,
> + .v4l2_type = V4L2_CTRL_TYPE_BITMASK,
> + .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
> + .name = "Region Of Interest Auto Controls",
> + },
> };
>
Wouldn't be better to use 8 V4L2_CTRL_TYPE_BOOLEAN controls for this?
Thanks,
Gergo
Hi Gergo
Sorry, I forgot to reply to your comment in v14.
On Thu, 14 Nov 2024 at 20:53, Gergo Koteles <soyer@irl.hu> wrote:
>
> Hi Ricardo,
>
> On Thu, 2024-11-14 at 19:10 +0000, Ricardo Ribalda wrote:
> >
> > + },
> > + {
> > + .id = V4L2_CID_UVC_REGION_OF_INTEREST_AUTO,
> > + .entity = UVC_GUID_UVC_CAMERA,
> > + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> > + .size = 16,
> > + .offset = 64,
> > + .v4l2_type = V4L2_CTRL_TYPE_BITMASK,
> > + .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
> > + .name = "Region Of Interest Auto Controls",
> > + },
> > };
> >
>
> Wouldn't be better to use 8 V4L2_CTRL_TYPE_BOOLEAN controls for this?
If I create 8 Booleans, they will always be shown in the device. And
the user will not have a way to know which values are available and
which are not.
We will also fail the v4l2-compliance test, because there will be up
to 7 boolean controls that will not be able to be set to 1, eventhough
they are writable.
Thanks for the prompt review.
>
> Thanks,
> Gergo
>
--
Ricardo Ribalda
Hi Ricardo,
On 14-Nov-24 9:03 PM, Ricardo Ribalda wrote:
> Hi Gergo
>
> Sorry, I forgot to reply to your comment in v14.
>
> On Thu, 14 Nov 2024 at 20:53, Gergo Koteles <soyer@irl.hu> wrote:
>>
>> Hi Ricardo,
>>
>> On Thu, 2024-11-14 at 19:10 +0000, Ricardo Ribalda wrote:
>>>
>>> + },
>>> + {
>>> + .id = V4L2_CID_UVC_REGION_OF_INTEREST_AUTO,
>>> + .entity = UVC_GUID_UVC_CAMERA,
>>> + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
>>> + .size = 16,
>>> + .offset = 64,
>>> + .v4l2_type = V4L2_CTRL_TYPE_BITMASK,
>>> + .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
>>> + .name = "Region Of Interest Auto Controls",
>>> + },
>>> };
>>>
>>
>> Wouldn't be better to use 8 V4L2_CTRL_TYPE_BOOLEAN controls for this?
>
> If I create 8 Booleans, they will always be shown in the device. And
> the user will not have a way to know which values are available and
> which are not.
>
> We will also fail the v4l2-compliance test, because there will be up
> to 7 boolean controls that will not be able to be set to 1, eventhough
> they are writable.
So why can't these other controls be set to 1? Because only one
of the options in the bitmask can be selected at a time ?
If only 1 bit in the UVC_CTRL_DATA_TYPE_BITMASK for this can be one
at the time, then this should be mapped to a V4L2_CTRL_TYPE_MENU
just like how that is done for V4L2_CID_EXPOSURE_AUTO already.
Actually looking at existing comments about UVC_CTRL_DATA_TYPE_BITMASK
in the driver there is this comment on top of uvc_mapping_get_menu_value()
* For controls of type UVC_CTRL_DATA_TYPE_BITMASK, the UVC control value is
* expressed as a bitmask and is thus guaranteed to have a single bit set.
Assuming this "guaranteed to have a single bit set" comment is valid for
the V4L2_CID_UVC_REGION_OF_INTEREST_AUTO part of UVC_CT_REGION_OF_INTEREST_CONTROL
too then I think we should simply map this to a menu similar to how
this is done for V4L2_CID_EXPOSURE_AUTO.
Note V4L2_CID_EXPOSURE_AUTO is the only existing user of UVC_CTRL_DATA_TYPE_BITMASK
at the moment.
Mapping this to a menu should nicely address Gergo's concerns here.
Regards,
Hans
Hi
On Mon, Nov 18, 2024 at 4:59 PM Hans de Goede <hdegoede@redhat.com> wrote:
>
> Hi Ricardo,
>
> On 14-Nov-24 9:03 PM, Ricardo Ribalda wrote:
> > Hi Gergo
> >
> > Sorry, I forgot to reply to your comment in v14.
> >
> > On Thu, 14 Nov 2024 at 20:53, Gergo Koteles <soyer@irl.hu> wrote:
> >>
> >> Hi Ricardo,
> >>
> >> On Thu, 2024-11-14 at 19:10 +0000, Ricardo Ribalda wrote:
> >>>
> >>> + },
> >>> + {
> >>> + .id = V4L2_CID_UVC_REGION_OF_INTEREST_AUTO,
> >>> + .entity = UVC_GUID_UVC_CAMERA,
> >>> + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> >>> + .size = 16,
> >>> + .offset = 64,
> >>> + .v4l2_type = V4L2_CTRL_TYPE_BITMASK,
> >>> + .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
> >>> + .name = "Region Of Interest Auto Controls",
> >>> + },
> >>> };
> >>>
> >>
> >> Wouldn't be better to use 8 V4L2_CTRL_TYPE_BOOLEAN controls for this?
> >
> > If I create 8 Booleans, they will always be shown in the device. And
> > the user will not have a way to know which values are available and
> > which are not.
> >
> > We will also fail the v4l2-compliance test, because there will be up
> > to 7 boolean controls that will not be able to be set to 1, eventhough
> > they are writable.
>
> So why can't these other controls be set to 1? Because only one
> of the options in the bitmask can be selected at a time ?
>
> If only 1 bit in the UVC_CTRL_DATA_TYPE_BITMASK for this can be one
> at the time, then this should be mapped to a V4L2_CTRL_TYPE_MENU
> just like how that is done for V4L2_CID_EXPOSURE_AUTO already.
>
> Actually looking at existing comments about UVC_CTRL_DATA_TYPE_BITMASK
> in the driver there is this comment on top of uvc_mapping_get_menu_value()
>
> * For controls of type UVC_CTRL_DATA_TYPE_BITMASK, the UVC control value is
> * expressed as a bitmask and is thus guaranteed to have a single bit set.
>
> Assuming this "guaranteed to have a single bit set" comment is valid for
> the V4L2_CID_UVC_REGION_OF_INTEREST_AUTO part of UVC_CT_REGION_OF_INTEREST_CONTROL
> too then I think we should simply map this to a menu similar to how
> this is done for V4L2_CID_EXPOSURE_AUTO.
>
> Note V4L2_CID_EXPOSURE_AUTO is the only existing user of UVC_CTRL_DATA_TYPE_BITMASK
> at the moment.
>
> Mapping this to a menu should nicely address Gergo's concerns here.
The UVC standard is not very clear re bmAutoControls. It says:
"""
The bmAutoControls bitmask determines which, if any, on board features
should track to the region of interest. To detect if a device supports
a particular Auto Control, use GET_MAX which returns a mask indicating
all supported Auto Controls.
GET_CUR returns the current Region of Interest (RoI) being employed by
the device. This RoI should be the same as specified in most recent
SET_CUR except in the case where the ‘Auto Detect and Track’ and/or
‘Image Stabilization’ bit have been set.
"""
Which makes me believe that you can set another Auto value + one of
these ones. So I do not think that we can assume "guaranteed to have a
single bit set".
The behaviour will vary module to module. So I'd rather take a
conservative approach here and let the hardware clamp the value and
not us.
>
> Regards,
>
> Hans
>
Hi Ricardo,
On 18-Nov-24 5:16 PM, Ricardo Ribalda Delgado wrote:
> Hi
>
> On Mon, Nov 18, 2024 at 4:59 PM Hans de Goede <hdegoede@redhat.com> wrote:
>>
>> Hi Ricardo,
>>
>> On 14-Nov-24 9:03 PM, Ricardo Ribalda wrote:
>>> Hi Gergo
>>>
>>> Sorry, I forgot to reply to your comment in v14.
>>>
>>> On Thu, 14 Nov 2024 at 20:53, Gergo Koteles <soyer@irl.hu> wrote:
>>>>
>>>> Hi Ricardo,
>>>>
>>>> On Thu, 2024-11-14 at 19:10 +0000, Ricardo Ribalda wrote:
>>>>>
>>>>> + },
>>>>> + {
>>>>> + .id = V4L2_CID_UVC_REGION_OF_INTEREST_AUTO,
>>>>> + .entity = UVC_GUID_UVC_CAMERA,
>>>>> + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
>>>>> + .size = 16,
>>>>> + .offset = 64,
>>>>> + .v4l2_type = V4L2_CTRL_TYPE_BITMASK,
>>>>> + .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
>>>>> + .name = "Region Of Interest Auto Controls",
>>>>> + },
>>>>> };
>>>>>
>>>>
>>>> Wouldn't be better to use 8 V4L2_CTRL_TYPE_BOOLEAN controls for this?
>>>
>>> If I create 8 Booleans, they will always be shown in the device. And
>>> the user will not have a way to know which values are available and
>>> which are not.
>>>
>>> We will also fail the v4l2-compliance test, because there will be up
>>> to 7 boolean controls that will not be able to be set to 1, eventhough
>>> they are writable.
>>
>> So why can't these other controls be set to 1? Because only one
>> of the options in the bitmask can be selected at a time ?
>>
>> If only 1 bit in the UVC_CTRL_DATA_TYPE_BITMASK for this can be one
>> at the time, then this should be mapped to a V4L2_CTRL_TYPE_MENU
>> just like how that is done for V4L2_CID_EXPOSURE_AUTO already.
>>
>> Actually looking at existing comments about UVC_CTRL_DATA_TYPE_BITMASK
>> in the driver there is this comment on top of uvc_mapping_get_menu_value()
>>
>> * For controls of type UVC_CTRL_DATA_TYPE_BITMASK, the UVC control value is
>> * expressed as a bitmask and is thus guaranteed to have a single bit set.
>>
>> Assuming this "guaranteed to have a single bit set" comment is valid for
>> the V4L2_CID_UVC_REGION_OF_INTEREST_AUTO part of UVC_CT_REGION_OF_INTEREST_CONTROL
>> too then I think we should simply map this to a menu similar to how
>> this is done for V4L2_CID_EXPOSURE_AUTO.
>>
>> Note V4L2_CID_EXPOSURE_AUTO is the only existing user of UVC_CTRL_DATA_TYPE_BITMASK
>> at the moment.
>>
>> Mapping this to a menu should nicely address Gergo's concerns here.
>
> The UVC standard is not very clear re bmAutoControls. It says:
> """
> The bmAutoControls bitmask determines which, if any, on board features
> should track to the region of interest. To detect if a device supports
> a particular Auto Control, use GET_MAX which returns a mask indicating
> all supported Auto Controls.
> GET_CUR returns the current Region of Interest (RoI) being employed by
> the device. This RoI should be the same as specified in most recent
> SET_CUR except in the case where the ‘Auto Detect and Track’ and/or
> ‘Image Stabilization’ bit have been set.
> """
>
> Which makes me believe that you can set another Auto value + one of
> these ones. So I do not think that we can assume "guaranteed to have a
> single bit set".
I see I already was afraid it would be something like this but
it would have been nice if we could have turned this into a menu control.
> The behaviour will vary module to module. So I'd rather take a
> conservative approach here and let the hardware clamp the value and
> not us.
Agreed.
Regards,
Hans
Hi Ricardo,
On Thu, 2024-11-14 at 21:03 +0100, Ricardo Ribalda wrote:
> Hi Gergo
>
> Sorry, I forgot to reply to your comment in v14.
>
> On Thu, 14 Nov 2024 at 20:53, Gergo Koteles <soyer@irl.hu> wrote:
> >
> > Hi Ricardo,
> >
> > On Thu, 2024-11-14 at 19:10 +0000, Ricardo Ribalda wrote:
> > >
> > > + },
> > > + {
> > > + .id = V4L2_CID_UVC_REGION_OF_INTEREST_AUTO,
> > > + .entity = UVC_GUID_UVC_CAMERA,
> > > + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> > > + .size = 16,
> > > + .offset = 64,
> > > + .v4l2_type = V4L2_CTRL_TYPE_BITMASK,
> > > + .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
> > > + .name = "Region Of Interest Auto Controls",
> > > + },
> > > };
> > >
> >
> > Wouldn't be better to use 8 V4L2_CTRL_TYPE_BOOLEAN controls for this?
>
> If I create 8 Booleans, they will always be shown in the device. And
> the user will not have a way to know which values are available and
> which are not.
>
> We will also fail the v4l2-compliance test, because there will be up
> to 7 boolean controls that will not be able to be set to 1, eventhough
> they are writable.
>
And can't it be that only those returned by GET_MAX be added?
```
The bmAutoControls bitmask determines which, if any, on board features
should track to the region of interest. To detect if a device supports
a particular Auto Control, use GET_MAX which returns a mask indicating
all supported Auto Controls.
```
Sorry for the misunderstanding, I just don't quite understand.
Thanks,
Gergo
Hi
On Thu, 14 Nov 2024 at 21:16, Gergo Koteles <soyer@irl.hu> wrote:
>
> Hi Ricardo,
>
> On Thu, 2024-11-14 at 21:03 +0100, Ricardo Ribalda wrote:
> > Hi Gergo
> >
> > Sorry, I forgot to reply to your comment in v14.
> >
> > On Thu, 14 Nov 2024 at 20:53, Gergo Koteles <soyer@irl.hu> wrote:
> > >
> > > Hi Ricardo,
> > >
> > > On Thu, 2024-11-14 at 19:10 +0000, Ricardo Ribalda wrote:
> > > >
> > > > + },
> > > > + {
> > > > + .id = V4L2_CID_UVC_REGION_OF_INTEREST_AUTO,
> > > > + .entity = UVC_GUID_UVC_CAMERA,
> > > > + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> > > > + .size = 16,
> > > > + .offset = 64,
> > > > + .v4l2_type = V4L2_CTRL_TYPE_BITMASK,
> > > > + .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
> > > > + .name = "Region Of Interest Auto Controls",
> > > > + },
> > > > };
> > > >
> > >
> > > Wouldn't be better to use 8 V4L2_CTRL_TYPE_BOOLEAN controls for this?
> >
> > If I create 8 Booleans, they will always be shown in the device. And
> > the user will not have a way to know which values are available and
> > which are not.
> >
> > We will also fail the v4l2-compliance test, because there will be up
> > to 7 boolean controls that will not be able to be set to 1, eventhough
> > they are writable.
> >
>
> And can't it be that only those returned by GET_MAX be added?
>
> ```
> The bmAutoControls bitmask determines which, if any, on board features
> should track to the region of interest. To detect if a device supports
> a particular Auto Control, use GET_MAX which returns a mask indicating
> all supported Auto Controls.
> ```
>
> Sorry for the misunderstanding, I just don't quite understand.
I guess we could, but we would have to make a big change in the way
the controls are probed today. uvc does not use the control framework.
What will be the benefit of using 8 controls?
- Applications still have to know what those controls do, they should
not rely on the control name.
- Changing from lets say AUTO_EXPOSURE to AUTO_FOCUS, will require to
send at least 2 controls via v4l2_s_ext_control... I think it is more
practical and less prone to errrors to send just one control
If the number of autos were unknown, then having multiple controls
could be a good idea, but they are part of the uvc standard and
unlikely to be changed.
Thanks!
>
> Thanks,
>
> Gergo
--
Ricardo Ribalda
Hi Ricardo,
On Thu, 2024-11-14 at 21:28 +0100, Ricardo Ribalda wrote:
> Hi
>
> On Thu, 14 Nov 2024 at 21:16, Gergo Koteles <soyer@irl.hu> wrote:
> >
> > Hi Ricardo,
> >
> > On Thu, 2024-11-14 at 21:03 +0100, Ricardo Ribalda wrote:
> > > Hi Gergo
> > >
> > > Sorry, I forgot to reply to your comment in v14.
> > >
> > > On Thu, 14 Nov 2024 at 20:53, Gergo Koteles <soyer@irl.hu> wrote:
> > > >
> > > > Hi Ricardo,
> > > >
> > > > On Thu, 2024-11-14 at 19:10 +0000, Ricardo Ribalda wrote:
> > > > >
> > > > > + },
> > > > > + {
> > > > > + .id = V4L2_CID_UVC_REGION_OF_INTEREST_AUTO,
> > > > > + .entity = UVC_GUID_UVC_CAMERA,
> > > > > + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> > > > > + .size = 16,
> > > > > + .offset = 64,
> > > > > + .v4l2_type = V4L2_CTRL_TYPE_BITMASK,
> > > > > + .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
> > > > > + .name = "Region Of Interest Auto Controls",
> > > > > + },
> > > > > };
> > > > >
> > > >
> > > > Wouldn't be better to use 8 V4L2_CTRL_TYPE_BOOLEAN controls for this?
> > >
> > > If I create 8 Booleans, they will always be shown in the device. And
> > > the user will not have a way to know which values are available and
> > > which are not.
> > >
> > > We will also fail the v4l2-compliance test, because there will be up
> > > to 7 boolean controls that will not be able to be set to 1, eventhough
> > > they are writable.
> > >
> >
> > And can't it be that only those returned by GET_MAX be added?
> >
> > ```
> > The bmAutoControls bitmask determines which, if any, on board features
> > should track to the region of interest. To detect if a device supports
> > a particular Auto Control, use GET_MAX which returns a mask indicating
> > all supported Auto Controls.
> > ```
> >
> > Sorry for the misunderstanding, I just don't quite understand.
>
> I guess we could, but we would have to make a big change in the way
> the controls are probed today. uvc does not use the control framework.
>
> What will be the benefit of using 8 controls?
> - Applications still have to know what those controls do, they should
> not rely on the control name.
Applications like v4l2-ctl are not aware of every controls, work by
control type, and let the user decide what to do, based on the name.
To avoid having to know each bitmask type control, they need to be able
to query which bit means what and what to display to the user.
Could VIDIOC_QUERYMENU be supplemented with this?
> - Changing from lets say AUTO_EXPOSURE to AUTO_FOCUS, will require to
> send at least 2 controls via v4l2_s_ext_control... I think it is more
> practical and less prone to errrors to send just one control
>
Yes, that could be a good reason.
Thanks,
Gergo
On Fri, 15 Nov 2024 at 01:04, Gergo Koteles <soyer@irl.hu> wrote:
>
> Hi Ricardo,
>
> On Thu, 2024-11-14 at 21:28 +0100, Ricardo Ribalda wrote:
> > Hi
> >
> > On Thu, 14 Nov 2024 at 21:16, Gergo Koteles <soyer@irl.hu> wrote:
> > >
> > > Hi Ricardo,
> > >
> > > On Thu, 2024-11-14 at 21:03 +0100, Ricardo Ribalda wrote:
> > > > Hi Gergo
> > > >
> > > > Sorry, I forgot to reply to your comment in v14.
> > > >
> > > > On Thu, 14 Nov 2024 at 20:53, Gergo Koteles <soyer@irl.hu> wrote:
> > > > >
> > > > > Hi Ricardo,
> > > > >
> > > > > On Thu, 2024-11-14 at 19:10 +0000, Ricardo Ribalda wrote:
> > > > > >
> > > > > > + },
> > > > > > + {
> > > > > > + .id = V4L2_CID_UVC_REGION_OF_INTEREST_AUTO,
> > > > > > + .entity = UVC_GUID_UVC_CAMERA,
> > > > > > + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
> > > > > > + .size = 16,
> > > > > > + .offset = 64,
> > > > > > + .v4l2_type = V4L2_CTRL_TYPE_BITMASK,
> > > > > > + .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
> > > > > > + .name = "Region Of Interest Auto Controls",
> > > > > > + },
> > > > > > };
> > > > > >
> > > > >
> > > > > Wouldn't be better to use 8 V4L2_CTRL_TYPE_BOOLEAN controls for this?
> > > >
> > > > If I create 8 Booleans, they will always be shown in the device. And
> > > > the user will not have a way to know which values are available and
> > > > which are not.
> > > >
> > > > We will also fail the v4l2-compliance test, because there will be up
> > > > to 7 boolean controls that will not be able to be set to 1, eventhough
> > > > they are writable.
> > > >
> > >
> > > And can't it be that only those returned by GET_MAX be added?
> > >
> > > ```
> > > The bmAutoControls bitmask determines which, if any, on board features
> > > should track to the region of interest. To detect if a device supports
> > > a particular Auto Control, use GET_MAX which returns a mask indicating
> > > all supported Auto Controls.
> > > ```
> > >
> > > Sorry for the misunderstanding, I just don't quite understand.
> >
> > I guess we could, but we would have to make a big change in the way
> > the controls are probed today. uvc does not use the control framework.
> >
> > What will be the benefit of using 8 controls?
> > - Applications still have to know what those controls do, they should
> > not rely on the control name.
>
> Applications like v4l2-ctl are not aware of every controls, work by
> control type, and let the user decide what to do, based on the name.
>
> To avoid having to know each bitmask type control, they need to be able
> to query which bit means what and what to display to the user.
>
> Could VIDIOC_QUERYMENU be supplemented with this?
I believe that violates compliance. VIDIOC_QUERYMENU should only be
used on menus.
https://git.linuxtv.org/v4l-utils.git/tree/utils/v4l2-compliance/v4l2-test-controls.cpp?h=v4l-utils-1.28.1#n143
>
>
> > - Changing from lets say AUTO_EXPOSURE to AUTO_FOCUS, will require to
> > send at least 2 controls via v4l2_s_ext_control... I think it is more
> > practical and less prone to errrors to send just one control
> >
>
> Yes, that could be a good reason.
>
> Thanks,
> Gergo
>
>
--
Ricardo Ribalda
© 2016 - 2026 Red Hat, Inc.