Re: [PATCH] media: uvcvideo: fix incorrect minimum value mapping for relative ptz controls

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Linh

Could you share the "lsusb  -v " info of your device, and also what
are the raw values from the device for UVC_GET_MAX, UVC_GET_MIN for
UVC_CT_PANTILT_RELATIVE_CONTROL and UVC_CT_ZOOM_RELATIVE_CONTROL ?

Something like this (not tested :) ):

diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index e59a463c27618..76c7adc3aa579 100644
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -415,7 +415,11 @@ static s32 uvc_ctrl_get_zoom(struct
uvc_control_mapping *mapping,
                return (zoom == 0) ? 0 : (zoom > 0 ? data[2] : -data[2]);

        case UVC_GET_MIN:
+               printk(KERN_ERR "zoom: GET_MIN 0%x 0x%x 0%x\n",
data[0], data[1], data[2]);
+               return data[2];
        case UVC_GET_MAX:
+               printk(KERN_ERR "zoom: GET_MAX 0%x 0x%x 0%x\n",
data[0], data[1], data[2]);
+               fallthrough;
        case UVC_GET_RES:
        case UVC_GET_DEF:
        default:
@@ -441,8 +445,11 @@ static s32 uvc_ctrl_get_rel_speed(struct
uvc_control_mapping *mapping,
                return (rel == 0) ? 0 : (rel > 0 ? data[first+1]
                                                 : -data[first+1]);
        case UVC_GET_MIN:
+               printk(KERN_ERR "speed: GET_MIN 0%x 0x%x 0%x\n",
data[first], data[first+1], data[first+2]);
                return -data[first+1];
        case UVC_GET_MAX:
+               printk(KERN_ERR "speed: GET_MAX 0%x 0x%x 0%x\n",
data[first], data[first+1], data[first+2]);
+               fallthrough;
        case UVC_GET_RES:
        case UVC_GET_DEF:
        default:

Thanks!

On Tue, 19 Mar 2024 at 06:30, Linh Vu <linh.tp.vu@xxxxxxxxx> wrote:
>
> When mapping from UVC_CT_PANTILT_RELATIVE_CONTROL
> to V4L2_CID_PAN_SPEED and V4L2_CID_TILT_SPEED,
> and from UVC_CT_ZOOM_RELATIVE_CONTROL to V4L2_CID_ZOOM_CONTINUOUS,
> the minimum value of the movement should be negated of the maximum value.
>
> For example, if a UVC device (e.g., OBSBOT Tiny 2) declares a pan speed
> range [1, 160], its V4L2_CID_PAN_SPEED mapping has range [-160, 160].
>
> Currently, calling ioctl with VIDIOC_QUERY_EXT_CTRL and V4L2_CID_PAN_SPEED
> returns a minimum value of -1. When calling ioctl with VIDIOC_S_CTRL,
> V4L2_CID_PAN_SPEED and -100, the speed (velocity) of the pan movement gets
> clamped to -1.
>
> To get the minimum value of V4L2_CID_PAN_SPEED,
> uvc_ctrl_get_rel_speed is called with
> uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN) as data,
> which should be uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX).
>
> The same thing should be done for V4L2_CID_TILT_SPEED and
> V4L2_CID_ZOOM_CONTINUOUS.
>
> For V4L2_CID_ZOOM_CONTINUOUS, uvc_ctrl_get_zoom does not add the
> sign to the returned minimum value, so it's impossible to zoom out.
>
> Modify the data that is passed when querying the minimum
> value for V4L2_CID_PAN_SPEED, V4L2_CID_TILT_SPEED and
> V4L2_CID_ZOOM_CONTINUOUS.
> Also add sign to the returned minimum value in uvc_ctrl_get_zoom.
> Thus, the correct minimum value for relative PTZ controls can be returned.
>
> Signed-off-by: Linh Vu <linh.tp.vu@xxxxxxxxx>
> ---
>  drivers/media/usb/uvc/uvc_ctrl.c | 24 +++++++++++++++++++-----
>  1 file changed, 19 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
> index e59a463c27618..00fd7e74e6d6b 100644
> --- a/drivers/media/usb/uvc/uvc_ctrl.c
> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> @@ -415,6 +415,7 @@ static s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping,
>                 return (zoom == 0) ? 0 : (zoom > 0 ? data[2] : -data[2]);
>
>         case UVC_GET_MIN:
> +               return -data[2];
>         case UVC_GET_MAX:
>         case UVC_GET_RES:
>         case UVC_GET_DEF:
> @@ -1322,9 +1323,16 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
>                 break;
>         }
>
> -       if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN)
> -               v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN,
> -                                    uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
> +       if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN) {
> +               if (v4l2_ctrl->id == V4L2_CID_PAN_SPEED
> +               || v4l2_ctrl->id == V4L2_CID_TILT_SPEED
> +               || v4l2_ctrl->id == V4L2_CID_ZOOM_CONTINUOUS)
> +                       v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN,
> +                                               uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
> +               else
> +                       v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN,
> +                                               uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
> +       }
>
>         if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX)
>                 v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX,
> @@ -1909,9 +1917,15 @@ int uvc_ctrl_set(struct uvc_fh *handle,
>                         if (ret < 0)
>                                 return ret;
>                 }
> +               if (mapping->id == V4L2_CID_PAN_SPEED
> +               || mapping->id == V4L2_CID_TILT_SPEED
> +               || mapping->id == V4L2_CID_ZOOM_CONTINUOUS)
> +                       min = mapping->get(mapping, UVC_GET_MIN,
> +                                       uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
> +               else
> +                       min = mapping->get(mapping, UVC_GET_MIN,
> +                                       uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
>
> -               min = mapping->get(mapping, UVC_GET_MIN,
> -                                  uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
>                 max = mapping->get(mapping, UVC_GET_MAX,
>                                    uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
>                 step = mapping->get(mapping, UVC_GET_RES,
>
> base-commit: e0b8eb0f6d652981bfd9ba7c619c9d81ed087ad0
> --
> 2.34.1
>
>


-- 
Ricardo Ribalda




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux