From patchwork Mon May 16 09:22:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yunke Cao X-Patchwork-Id: 83302 Received: from vger.kernel.org ([23.128.96.18]) by www.linuxtv.org with esmtp (Exim 4.92) (envelope-from ) id 1nqWw7-00Dvwy-VP; Mon, 16 May 2022 09:22:44 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234079AbiEPJWl (ORCPT + 1 other); Mon, 16 May 2022 05:22:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35134 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238767AbiEPJWk (ORCPT ); Mon, 16 May 2022 05:22:40 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 23351271B for ; Mon, 16 May 2022 02:22:39 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id c205-20020a254ed6000000b0064d5bd93479so5007871ybb.17 for ; Mon, 16 May 2022 02:22:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=reO5JKnmBHODbsdPQlqJVNfolGyx7EchN1hZlFee5aU=; b=SGXmxlJ8cELahAKzCB3W75gxnZ8Q+6SEcI633SRbsUEIDp/enWDLAs2SnP1vf3UT6z BDfrcBRfJLhabI7LwGwUwoJDuz+Yqy2AqnOzpXH3Q28+86sEz83FyM8w6wz1rEGmbrtc Q1kQLb6CRcczAXGOSOm6lMojJUXuWD3rAj3jYpMwVZ9XseR5SJnmjzbaYxpKzF0M+usD AmFhfxb6Tt0jwBnarcmCk7Gr4/CAngOmKLf0riIlTScvwoODO11tsf+2JPz/+eiBeaGr EWz35seDwry12NTeozRVV4venTxbHHtfXZlHkiESRb0Z7uYOvU1scWdj5zie8mTjDHAd 9MoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=reO5JKnmBHODbsdPQlqJVNfolGyx7EchN1hZlFee5aU=; b=lAUnWsr8fBZSvQkwaJZkixrr/x/9ATY2DxcCWAnJ3sqB/q930wFOnRR5aYCDDOIsm6 J+LcElqVOpXTeiYrwQNR2kmO8MeUyvDUJ8h1FEDb9Ub0N6JAp3GY99gy+avzSK/xzO/h cfCwP2ZTZXrxVuebOU6s8xM31EofdreC8mmmRaOQcEhrJJqTQbPQUTXROYGV0QVKeB8v RbIuOjNb8hvEodiAd0nY3vHmpbUwQOWSB85zHWA2mM+7N/lbL3tXh3KlxCTLE3Hipc3o wuLyVY9Faan4VWWCAUNWuTFML2a5/UPq58q+HE71c7V7msW2vaPD25IPG1+rmW4BBaov X/lw== X-Gm-Message-State: AOAM533Ko5gWhj48MK6OUr1NLA9ejCZKjVp0iUFxTevBBGbYsWmG6omw RyvxMgMP8EZrQ6ERyWDzxB19EqW2DuM= X-Google-Smtp-Source: ABdhPJzKYZxOQxwXU2j7+sz9xrAhHZOM0XMrs6b7AJlO5BWtKon5sb6mDn4AMdOgInhKA7e5dN2VPDFjIYY= X-Received: from yunkec1.tok.corp.google.com ([2401:fa00:8f:203:2bd1:4151:d530:8b73]) (user=yunkec job=sendgmr) by 2002:a81:7e0a:0:b0:2ec:e0ab:d19c with SMTP id o10-20020a817e0a000000b002ece0abd19cmr18699697ywn.465.1652692958322; Mon, 16 May 2022 02:22:38 -0700 (PDT) Date: Mon, 16 May 2022 18:22:04 +0900 In-Reply-To: <20220516092209.1801656-1-yunkec@google.com> Message-Id: <20220516092209.1801656-2-yunkec@google.com> Mime-Version: 1.0 References: <20220516092209.1801656-1-yunkec@google.com> X-Mailer: git-send-email 2.36.0.550.gb090851708-goog Subject: [PATCH v1 1/6] media: v4l2_ctrl: Add region of interest rectangle control From: Yunke Cao To: Hans Verkuil , Laurent Pinchart Cc: Tomasz Figa , Sergey Senozhatsky , Ricardo Ribalda , linux-media@vger.kernel.org, Yunke Cao X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-LSpam-Score: -10.0 (----------) X-LSpam-Report: No, score=-10.0 required=5.0 tests=BAYES_00=-1.9,DKIMWL_WL_MED=0.001,DKIM_SIGNED=0.1,DKIM_VALID=-0.1,DKIM_VALID_AU=-0.1,HEADER_FROM_DIFFERENT_DOMAINS=0.5,MAILING_LIST_MULTI=-1,USER_IN_DEF_DKIM_WL=-7.5 autolearn=ham autolearn_force=no Including: 1. Add a control ID. 2. Add p_rect to struct v4l2_ext_control with basic support in v4l2-ctrls. Signed-off-by: Yunke Cao --- .../media/v4l/ext-ctrls-camera.rst | 4 ++++ .../media/v4l/vidioc-g-ext-ctrls.rst | 4 ++++ .../media/videodev2.h.rst.exceptions | 1 + drivers/media/v4l2-core/v4l2-ctrls-core.c | 20 +++++++++++++++++++ drivers/media/v4l2-core/v4l2-ctrls-defs.c | 4 ++++ include/media/v4l2-ctrls.h | 2 ++ include/uapi/linux/v4l2-controls.h | 2 ++ include/uapi/linux/videodev2.h | 2 ++ 8 files changed, 39 insertions(+) diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-camera.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-camera.rst index 4c5061aa9cd4..86a1f09a8a1c 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-camera.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-camera.rst @@ -661,3 +661,7 @@ enum v4l2_scene_mode - .. [#f1] This control may be changed to a menu control in the future, if more options are required. + +``V4L2_CID_REGION_OF_INTEREST_RECT (struct)`` + This control determines the region of interest. Region of interest is an + rectangular area represented by a struct v4l2_rect. diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst index 29971a45a2d4..f4e205ead0a2 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst @@ -189,6 +189,10 @@ still cause this situation. - ``p_area`` - A pointer to a struct :c:type:`v4l2_area`. Valid if this control is of type ``V4L2_CTRL_TYPE_AREA``. + * - struct :c:type:`v4l2_rect` * + - ``p_area`` + - A pointer to a struct :c:type:`v4l2_rect`. Valid if this control is + of type ``V4L2_CTRL_TYPE_RECT``. * - struct :c:type:`v4l2_ctrl_h264_sps` * - ``p_h264_sps`` - A pointer to a struct :c:type:`v4l2_ctrl_h264_sps`. Valid if this control is diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions index 9cbb7a0c354a..7b423475281d 100644 --- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions +++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions @@ -147,6 +147,7 @@ replace symbol V4L2_CTRL_TYPE_HEVC_SPS :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_HEVC_PPS :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_AREA :c:type:`v4l2_ctrl_type` +replace symbol V4L2_CTRL_TYPE_RECT :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_FWHT_PARAMS :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_VP8_FRAME :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR :c:type:`v4l2_ctrl_type` diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c index 8968cec8454e..dcde405c2713 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c @@ -84,6 +84,11 @@ static bool std_equal(const struct v4l2_ctrl *ctrl, u32 idx, return ptr1.p_u16[idx] == ptr2.p_u16[idx]; case V4L2_CTRL_TYPE_U32: return ptr1.p_u32[idx] == ptr2.p_u32[idx]; + case V4L2_CTRL_TYPE_RECT: + return ptr1.p_rect->top == ptr2.p_rect->top && + ptr1.p_rect->left == ptr2.p_rect->left && + ptr1.p_rect->height == ptr2.p_rect->height && + ptr1.p_rect->width == ptr2.p_rect->width; default: if (ctrl->is_int) return ptr1.p_s32[idx] == ptr2.p_s32[idx]; @@ -307,6 +312,11 @@ static void std_log(const struct v4l2_ctrl *ctrl) case V4L2_CTRL_TYPE_VP9_FRAME: pr_cont("VP9_FRAME"); break; + case V4L2_CTRL_TYPE_RECT: + pr_cont("l: %d, t: %d, w: %u, h: %u", + ptr.p_rect->left, ptr.p_rect->top, + ptr.p_rect->width, ptr.p_rect->height); + break; default: pr_cont("unknown type %d", ctrl->type); break; @@ -525,6 +535,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering; struct v4l2_ctrl_hevc_decode_params *p_hevc_decode_params; struct v4l2_area *area; + struct v4l2_rect *rect; void *p = ptr.p + idx * ctrl->elem_size; unsigned int i; @@ -888,6 +899,12 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, return -EINVAL; break; + case V4L2_CTRL_TYPE_RECT: + rect = p; + if (!rect->width || !rect->height) + return -EINVAL; + break; + default: return -EINVAL; } @@ -1456,6 +1473,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, case V4L2_CTRL_TYPE_AREA: elem_size = sizeof(struct v4l2_area); break; + case V4L2_CTRL_TYPE_RECT: + elem_size = sizeof(struct v4l2_rect); + break; default: if (type < V4L2_CTRL_COMPOUND_TYPES) elem_size = sizeof(s32); diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c index 54ca4e6b820b..95f39a2d2ad2 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c @@ -1042,6 +1042,7 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_UNIT_CELL_SIZE: return "Unit Cell Size"; case V4L2_CID_CAMERA_ORIENTATION: return "Camera Orientation"; case V4L2_CID_CAMERA_SENSOR_ROTATION: return "Camera Sensor Rotation"; + case V4L2_CID_REGION_OF_INTEREST_RECT: return "Region Of Interest Rectangle"; /* FM Radio Modulator controls */ /* Keep the order of the 'case's the same as in v4l2-controls.h! */ @@ -1524,6 +1525,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY: *type = V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY; break; + case V4L2_CID_REGION_OF_INTEREST_RECT: + *type = V4L2_CTRL_TYPE_RECT; + break; default: *type = V4L2_CTRL_TYPE_INTEGER; break; diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index b3ce438f1329..919e104de50b 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -58,6 +58,7 @@ struct video_device; * @p_hdr10_cll: Pointer to an HDR10 Content Light Level structure. * @p_hdr10_mastering: Pointer to an HDR10 Mastering Display structure. * @p_area: Pointer to an area. + * @p_rect: Pointer to a rectangle. * @p: Pointer to a compound value. * @p_const: Pointer to a constant compound value. */ @@ -87,6 +88,7 @@ union v4l2_ctrl_ptr { struct v4l2_ctrl_hdr10_cll_info *p_hdr10_cll; struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering; struct v4l2_area *p_area; + struct v4l2_rect *p_rect; void *p; const void *p_const; }; diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index bb40129446d4..499fcddb6254 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -1008,6 +1008,8 @@ enum v4l2_auto_focus_range { #define V4L2_CID_CAMERA_SENSOR_ROTATION (V4L2_CID_CAMERA_CLASS_BASE+35) +#define V4L2_CID_REGION_OF_INTEREST_RECT (V4L2_CID_CAMERA_CLASS_BASE+36) + /* FM Modulator class control IDs */ #define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900) diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 3768a0a80830..b712412cf763 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1751,6 +1751,7 @@ struct v4l2_ext_control { __u16 __user *p_u16; __u32 __user *p_u32; struct v4l2_area __user *p_area; + struct v4l2_rect __user *p_rect; struct v4l2_ctrl_h264_sps __user *p_h264_sps; struct v4l2_ctrl_h264_pps *p_h264_pps; struct v4l2_ctrl_h264_scaling_matrix __user *p_h264_scaling_matrix; @@ -1810,6 +1811,7 @@ enum v4l2_ctrl_type { V4L2_CTRL_TYPE_U16 = 0x0101, V4L2_CTRL_TYPE_U32 = 0x0102, V4L2_CTRL_TYPE_AREA = 0x0106, + V4L2_CTRL_TYPE_RECT = 0x0107, V4L2_CTRL_TYPE_HDR10_CLL_INFO = 0x0110, V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY = 0x0111, From patchwork Mon May 16 09:22:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yunke Cao X-Patchwork-Id: 83303 Received: from vger.kernel.org ([23.128.96.18]) by www.linuxtv.org with esmtp (Exim 4.92) (envelope-from ) id 1nqWwb-00Dvxj-OF; Mon, 16 May 2022 09:23:14 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237665AbiEPJXI (ORCPT + 1 other); Mon, 16 May 2022 05:23:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36338 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237389AbiEPJXF (ORCPT ); Mon, 16 May 2022 05:23:05 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 67CD925EBB for ; Mon, 16 May 2022 02:23:02 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-2fecc57ec14so42197327b3.11 for ; Mon, 16 May 2022 02:23:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=TzhRNhSvZip0U+P9bw1a3ilxnx9VjzybHPf6lKSqclk=; b=mD1uCoSDknaa/Js2AKLj0H7s00Z8HuEwr637YT9atp4sNreo0OdOERQMiMtUD86CFc R3AGtpuxXPwSWWW0Vg2/8aSQdSwmDVE18Eo+/dKSX5ZXMEDGq0vZCDX4i7gnn0CWz/8d L98z8tz2dFT8YEyWOgVtI2Bh4EjO9yr6zHM1E0rAe3qvro98qJ3u0oDVO3iyH8uKod3x KUz84aSnq9lKPGbXDd4bA2hh9KGsRt6yH1n/c/WRFzITxZd+eTsPiRp6RskPOG5zyq9Y 6SDDikI15hdtp0s9fzAjfZbu7qsjkMJAiTqbuE/fD6XT9aJzdGvjUasrc+oE9e+IU2/Y iJxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=TzhRNhSvZip0U+P9bw1a3ilxnx9VjzybHPf6lKSqclk=; b=PYZLXux85GCDKuxXj34ir7pRlVdwuKKQY190TbKUm8JCLVa23M5V3/aC+6mxzR7wKp xsFBbBVdrhwURna8SzSdOlkLN0mWdGGtA/1zOq1IT13fkGpwEW22R4MI6Yiepb5KDQZd 0EoDNC0d6/E9b4hZV5VQXCvsqt2JoIx0eKNtHYEJ82fb38jHH6xNpIf0KJyqLq/CG02t 49LgnpPi3FV9eF6aPaTZTIupofFZ1ABN0sdUiXyNpM2eTv4/1S34+R6vn/XA56gaT0oM 8J2Uc6HT/1DMkqWdYtrJe7cweBshjC/ldGm8iUvKa+zTj+IBGJA3wSBBZgzKqdsthXsE HuPg== X-Gm-Message-State: AOAM533RniPsh13o2M6dwX4OLpiTAQ61rWi6j5DPcYSsCQ5MHF++c7Rn OmxwswYefSJkmWInyp1s/8Q2tGrpyDM= X-Google-Smtp-Source: ABdhPJwXttQIcGW8swzBdEUk/EM8jwX4wkLhMdNdoVsceCM61vVDjDqAK3G2fSxcA0xCO8/B0zgQveOuPjs= X-Received: from yunkec1.tok.corp.google.com ([2401:fa00:8f:203:2bd1:4151:d530:8b73]) (user=yunkec job=sendgmr) by 2002:a5b:38a:0:b0:64a:d339:bdef with SMTP id k10-20020a5b038a000000b0064ad339bdefmr16563120ybp.248.1652692981276; Mon, 16 May 2022 02:23:01 -0700 (PDT) Date: Mon, 16 May 2022 18:22:05 +0900 In-Reply-To: <20220516092209.1801656-1-yunkec@google.com> Message-Id: <20220516092209.1801656-3-yunkec@google.com> Mime-Version: 1.0 References: <20220516092209.1801656-1-yunkec@google.com> X-Mailer: git-send-email 2.36.0.550.gb090851708-goog Subject: [PATCH v1 2/6] media: v4l2_ctrl: Add region of interest auto control From: Yunke Cao To: Hans Verkuil , Laurent Pinchart Cc: Tomasz Figa , Sergey Senozhatsky , Ricardo Ribalda , linux-media@vger.kernel.org, Yunke Cao X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-LSpam-Score: -10.0 (----------) X-LSpam-Report: No, score=-10.0 required=5.0 tests=BAYES_00=-1.9,DKIMWL_WL_MED=0.001,DKIM_SIGNED=0.1,DKIM_VALID=-0.1,DKIM_VALID_AU=-0.1,HEADER_FROM_DIFFERENT_DOMAINS=0.5,MAILING_LIST_MULTI=-1,USER_IN_DEF_DKIM_WL=-7.5 autolearn=ham autolearn_force=no Signed-off-by: Yunke Cao --- .../media/v4l/ext-ctrls-camera.rst | 25 +++++++++++++++++++ drivers/media/v4l2-core/v4l2-ctrls-defs.c | 2 ++ include/uapi/linux/v4l2-controls.h | 9 +++++++ 3 files changed, 36 insertions(+) diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-camera.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-camera.rst index 86a1f09a8a1c..3da66e1e1fc7 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-camera.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-camera.rst @@ -665,3 +665,28 @@ enum v4l2_scene_mode - ``V4L2_CID_REGION_OF_INTEREST_RECT (struct)`` This control determines the region of interest. Region of interest is an rectangular area represented by a struct v4l2_rect. + +``V4L2_CID_REGION_OF_INTEREST_AUTO (bitmask)`` + This determines which, if any, on board features should track to the + Region of Interest. + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + * - ``V4L2_CID_REGION_OF_INTEREST_AUTO_EXPOSURE`` + - Auto Exposure. + * - ``V4L2_CID_REGION_OF_INTEREST_AUTO_IRIS`` + - Auto Iris. + * - ``V4L2_CID_REGION_OF_INTEREST_AUTO_WHITE_BALANCE`` + - Auto White Balance. + * - ``V4L2_CID_REGION_OF_INTEREST_AUTO_FOCUS`` + - Auto Focus. + * - ``V4L2_CID_REGION_OF_INTEREST_AUTO_FACE_DETECT`` + - Auto Face Detect. + * - ``V4L2_CID_REGION_OF_INTEREST_AUTO_DETECT_AND_TRACK`` + - Auto Detect and Track. + * - ``V4L2_CID_REGION_OF_INTEREST_AUTO_IMAGE_STABILIZATION`` + - Image Stabilization. + * - ``V4L2_CID_REGION_OF_INTEREST_AUTO_HIGHER_QUALITY`` + - Higher Quality. diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c index 95f39a2d2ad2..f28763bf95e9 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c @@ -1043,6 +1043,7 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_CAMERA_ORIENTATION: return "Camera Orientation"; case V4L2_CID_CAMERA_SENSOR_ROTATION: return "Camera Sensor Rotation"; case V4L2_CID_REGION_OF_INTEREST_RECT: return "Region Of Interest Rectangle"; + case V4L2_CID_REGION_OF_INTEREST_AUTO: return "Region Of Interest Auto Controls"; /* FM Radio Modulator controls */ /* Keep the order of the 'case's the same as in v4l2-controls.h! */ @@ -1415,6 +1416,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, case V4L2_CID_JPEG_ACTIVE_MARKER: case V4L2_CID_3A_LOCK: case V4L2_CID_AUTO_FOCUS_STATUS: + case V4L2_CID_REGION_OF_INTEREST_AUTO: case V4L2_CID_DV_TX_HOTPLUG: case V4L2_CID_DV_TX_RXSENSE: case V4L2_CID_DV_TX_EDID_PRESENT: diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index 499fcddb6254..f6938e4de129 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -1009,6 +1009,15 @@ enum v4l2_auto_focus_range { #define V4L2_CID_CAMERA_SENSOR_ROTATION (V4L2_CID_CAMERA_CLASS_BASE+35) #define V4L2_CID_REGION_OF_INTEREST_RECT (V4L2_CID_CAMERA_CLASS_BASE+36) +#define V4L2_CID_REGION_OF_INTEREST_AUTO (V4L2_CID_CAMERA_CLASS_BASE+37) +#define V4L2_CID_REGION_OF_INTEREST_AUTO_EXPOSURE (1 << 0) +#define V4L2_CID_REGION_OF_INTEREST_AUTO_IRIS (1 << 1) +#define V4L2_CID_REGION_OF_INTEREST_AUTO_WHITE_BALANCE (1 << 2) +#define V4L2_CID_REGION_OF_INTEREST_AUTO_FOCUS (1 << 3) +#define V4L2_CID_REGION_OF_INTEREST_AUTO_FACE_DETECT (1 << 4) +#define V4L2_CID_REGION_OF_INTEREST_AUTO_DETECT_AND_TRACK (1 << 5) +#define V4L2_CID_REGION_OF_INTEREST_AUTO_IMAGE_STABILIZATION (1 << 6) +#define V4L2_CID_REGION_OF_INTEREST_AUTO_HIGHER_QUALITY (1 << 7) /* FM Modulator class control IDs */ From patchwork Mon May 16 09:22:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yunke Cao X-Patchwork-Id: 83304 Received: from vger.kernel.org ([23.128.96.18]) by www.linuxtv.org with esmtp (Exim 4.92) (envelope-from ) id 1nqWwf-00Dvy5-PB; Mon, 16 May 2022 09:23:18 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238767AbiEPJXP (ORCPT + 1 other); Mon, 16 May 2022 05:23:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36448 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237389AbiEPJXJ (ORCPT ); Mon, 16 May 2022 05:23:09 -0400 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AB3DBBF78 for ; Mon, 16 May 2022 02:23:07 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-2fed3f68a64so37105137b3.14 for ; Mon, 16 May 2022 02:23:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=hQTBi2JjNTY5dBm0eG1Mes5aRu5t5J1VThkesWJ0LLs=; b=Jm1ko2Iug0XYheOmRH2Zo2oZLsHGIHkwq8W0UlOZD97TzLNGQcOvZVboOHnQBpAx+Y ZknBl4owmNUeJ9GOt/8RVymP+tmyUSIRteT0xZ+iQ3SgJQIBD5W9PWZ11OrdWJvmPJ1e LUj3+ZNOJP3daxuP19WoUDiyIfEoxVjL4XNiDAq/qCy5LZqVtuMr1wlrx0rlSKdMHlTk eo3s10myTZOn61/21i3CY0YXTL5rk6WmV8rm3fbuQyfrrWATA1Q9XKiFrkE0ueQl/G8t IftnMMNg6ZlPj+a8ZHvbOll5nDhw13ws4kx5vmua2SXGCIFg7n4fTyH1ucLKeUSfs62m 6uZw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=hQTBi2JjNTY5dBm0eG1Mes5aRu5t5J1VThkesWJ0LLs=; b=zHgVbpSsKh+P9S6T3W7rMPRBQme1UXu9jHtv5QR/2sXI2EG8TitJP+UwnerqQWNTxs mO3mu/oSsNszqmrY3f2u8Powu7xSqeGVarM66rBfPLQcGF4YS7m/azhN1c7uY5RpJ2Na DjjacyZ05cf2wylh/rVfLvwM4Iy7bGTQIA1l2XRbWhyzLLFxY+H7i9B+bmk83sWvVI3Y wZDwbi6g2uu1PEt7fu2II//OJPrQRWG9rssYlUBi6FiMn/VsutYIrPKYlJQrQ6N4hd7w tOAds1a+R02iPIdr3qygsWDRQ3vstZnuPozqZWXUfZ3AOU+gXIuBpyOgQGMPCr+Q8Aqi /bQw== X-Gm-Message-State: AOAM532XroDpmKjqEJHMbP7wpa8sRBcx7pmjyHTv0qGk9c0MpriMUdDN lWVPXXJlewT9nNF03sZxqNzYkE03exI= X-Google-Smtp-Source: ABdhPJzNoFBhYgojaF9JRG52FzmWkggrwwWU85hJ+htZtHvgog5YD1/IVCglOScd8mIMe+t3Do97zBYFqZ8= X-Received: from yunkec1.tok.corp.google.com ([2401:fa00:8f:203:2bd1:4151:d530:8b73]) (user=yunkec job=sendgmr) by 2002:a25:8d12:0:b0:64b:5980:e7cb with SMTP id n18-20020a258d12000000b0064b5980e7cbmr16059858ybl.14.1652692986921; Mon, 16 May 2022 02:23:06 -0700 (PDT) Date: Mon, 16 May 2022 18:22:06 +0900 In-Reply-To: <20220516092209.1801656-1-yunkec@google.com> Message-Id: <20220516092209.1801656-4-yunkec@google.com> Mime-Version: 1.0 References: <20220516092209.1801656-1-yunkec@google.com> X-Mailer: git-send-email 2.36.0.550.gb090851708-goog Subject: [PATCH v1 3/6] media: v4l2_ctrl: Add V4L2_CTRL_WHICH_MIN/MAX_VAL From: Yunke Cao To: Hans Verkuil , Laurent Pinchart Cc: Tomasz Figa , Sergey Senozhatsky , Ricardo Ribalda , linux-media@vger.kernel.org, Yunke Cao X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-LSpam-Score: -10.0 (----------) X-LSpam-Report: No, score=-10.0 required=5.0 tests=BAYES_00=-1.9,DKIMWL_WL_MED=0.001,DKIM_SIGNED=0.1,DKIM_VALID=-0.1,DKIM_VALID_AU=-0.1,HEADER_FROM_DIFFERENT_DOMAINS=0.5,MAILING_LIST_MULTI=-1,USER_IN_DEF_DKIM_WL=-7.5 autolearn=ham autolearn_force=no Added V4L2_CTRL_WHICH_MIN/MAX_VAL and basic support in v4l2-core. Mostly reusing a previous attempt: https://lore.kernel.org/all/20191220134843.25977-1-m.tretter@pengutronix.de/T/#m5c83970af8b774a4b1ea5f2dca4c0a534da4ccbe Signed-off-by: Yunke Cao --- .../media/v4l/vidioc-g-ext-ctrls.rst | 10 +- .../media/videodev2.h.rst.exceptions | 2 + drivers/media/i2c/imx214.c | 4 +- drivers/media/v4l2-core/v4l2-ctrls-api.c | 51 +++++-- drivers/media/v4l2-core/v4l2-ctrls-core.c | 135 ++++++++++++++++-- drivers/media/v4l2-core/v4l2-ioctl.c | 4 +- include/media/v4l2-ctrls.h | 30 +++- include/uapi/linux/videodev2.h | 2 + 8 files changed, 210 insertions(+), 28 deletions(-) diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst index f4e205ead0a2..11336f5d69ed 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst @@ -284,14 +284,18 @@ still cause this situation. - Which value of the control to get/set/try. * - :cspan:`2` ``V4L2_CTRL_WHICH_CUR_VAL`` will return the current value of the control, ``V4L2_CTRL_WHICH_DEF_VAL`` will return the default - value of the control and ``V4L2_CTRL_WHICH_REQUEST_VAL`` indicates that + value of the control, ``V4L2_CTRL_WHICH_MIN_VAL`` will return the minimum + value of the control, ``V4L2_CTRL_WHICH_MAX_VAL`` will return the maximum + value of the control and ``V4L2_CTRL_WHICH_REQUEST_VAL`` indicates that these controls have to be retrieved from a request or tried/set for a request. In the latter case the ``request_fd`` field contains the file descriptor of the request that should be used. If the device does not support requests, then ``EACCES`` will be returned. - When using ``V4L2_CTRL_WHICH_DEF_VAL`` be aware that you can only - get the default value of the control, you cannot set or try it. + When using ``V4L2_CTRL_WHICH_DEF_VAL``, ``V4L2_CTRL_WHICH_MIN_VAL`` + or ``V4L2_CTRL_WHICH_MAX_VAL`` be aware that you can only + get the default/minimum/maximum value of the control, you cannot set + or try it. For backwards compatibility you can also use a control class here (see :ref:`ctrl-class`). In that case all controls have to diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions index 7b423475281d..e2dde31d76df 100644 --- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions +++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions @@ -553,6 +553,8 @@ ignore define V4L2_CTRL_DRIVER_PRIV ignore define V4L2_CTRL_MAX_DIMS ignore define V4L2_CTRL_WHICH_CUR_VAL ignore define V4L2_CTRL_WHICH_DEF_VAL +ignore define V4L2_CTRL_WHICH_MIN_VAL +ignore define V4L2_CTRL_WHICH_MAX_VAL ignore define V4L2_CTRL_WHICH_REQUEST_VAL ignore define V4L2_OUT_CAP_CUSTOM_TIMINGS ignore define V4L2_CID_MAX_CTRLS diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c index 83c1737abeec..1541a81dcd46 100644 --- a/drivers/media/i2c/imx214.c +++ b/drivers/media/i2c/imx214.c @@ -1037,7 +1037,9 @@ static int imx214_probe(struct i2c_client *client) imx214->unit_size = v4l2_ctrl_new_std_compound(&imx214->ctrls, NULL, V4L2_CID_UNIT_CELL_SIZE, - v4l2_ctrl_ptr_create((void *)&unit_size)); + v4l2_ctrl_ptr_create((void *)&unit_size), + v4l2_ctrl_ptr_create(NULL), + v4l2_ctrl_ptr_create(NULL)); ret = imx214->ctrls.error; if (ret) { dev_err(&client->dev, "%s control init failed (%d)\n", diff --git a/drivers/media/v4l2-core/v4l2-ctrls-api.c b/drivers/media/v4l2-core/v4l2-ctrls-api.c index db9baa0bd05f..8a9c816b0dab 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-api.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c @@ -97,6 +97,28 @@ static int def_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl) return ptr_to_user(c, ctrl, ctrl->p_new); } +/* Helper function: copy the minimum control value back to the caller */ +static int min_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl) +{ + int idx; + + for (idx = 0; idx < ctrl->elems; idx++) + ctrl->type_ops->minimum(ctrl, idx, ctrl->p_new); + + return ptr_to_user(c, ctrl, ctrl->p_new); +} + +/* Helper function: copy the maximum control value back to the caller */ +static int max_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl) +{ + int idx; + + for (idx = 0; idx < ctrl->elems; idx++) + ctrl->type_ops->maximum(ctrl, idx, ctrl->p_new); + + return ptr_to_user(c, ctrl, ctrl->p_new); +} + /* Helper function: copy the caller-provider value to the given control value */ static int user_to_ptr(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl, @@ -220,8 +242,8 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl, cs->error_idx = i; if (cs->which && - cs->which != V4L2_CTRL_WHICH_DEF_VAL && - cs->which != V4L2_CTRL_WHICH_REQUEST_VAL && + (cs->which < V4L2_CTRL_WHICH_DEF_VAL || + cs->which > V4L2_CTRL_WHICH_MAX_VAL) && V4L2_CTRL_ID2WHICH(id) != cs->which) { dprintk(vdev, "invalid which 0x%x or control id 0x%x\n", @@ -335,8 +357,8 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl, */ static int class_check(struct v4l2_ctrl_handler *hdl, u32 which) { - if (which == 0 || which == V4L2_CTRL_WHICH_DEF_VAL || - which == V4L2_CTRL_WHICH_REQUEST_VAL) + if (which == 0 || (which >= V4L2_CTRL_WHICH_DEF_VAL && + which <= V4L2_CTRL_WHICH_MAX_VAL)) return 0; return find_ref_lock(hdl, which | 1) ? 0 : -EINVAL; } @@ -356,10 +378,12 @@ int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl, struct v4l2_ctrl_helper *helpers = helper; int ret; int i, j; - bool is_default, is_request; + bool is_default, is_request, is_min, is_max; is_default = (cs->which == V4L2_CTRL_WHICH_DEF_VAL); is_request = (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL); + is_min = (cs->which == V4L2_CTRL_WHICH_MIN_VAL); + is_max = (cs->which == V4L2_CTRL_WHICH_MAX_VAL); cs->error_idx = cs->count; cs->which = V4L2_CTRL_ID2WHICH(cs->which); @@ -399,13 +423,14 @@ int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl, /* * g_volatile_ctrl will update the new control values. - * This makes no sense for V4L2_CTRL_WHICH_DEF_VAL and + * This makes no sense for V4L2_CTRL_WHICH_DEF_VAL, + * V4L2_CTRL_WHICH_MIN_VAL, V4L2_CTRL_WHICH_MAX_VAL and * V4L2_CTRL_WHICH_REQUEST_VAL. In the case of requests * it is v4l2_ctrl_request_complete() that copies the * volatile controls at the time of request completion * to the request, so you don't want to do that again. */ - if (!is_default && !is_request && + if (!is_default && !is_request && !is_min && !is_max && ((master->flags & V4L2_CTRL_FLAG_VOLATILE) || (master->has_volatiles && !is_cur_manual(master)))) { for (j = 0; j < master->ncontrols; j++) @@ -432,6 +457,10 @@ int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl, ret = def_to_user(cs->controls + idx, ref->ctrl); else if (is_request && ref->valid_p_req) ret = req_to_user(cs->controls + idx, ref); + else if (is_min) + ret = min_to_user(cs->controls + idx, ref->ctrl); + else if (is_max) + ret = max_to_user(cs->controls + idx, ref->ctrl); else if (is_volatile) ret = new_to_user(cs->controls + idx, ref->ctrl); else @@ -523,9 +552,11 @@ int try_set_ext_ctrls_common(struct v4l2_fh *fh, cs->error_idx = cs->count; - /* Default value cannot be changed */ - if (cs->which == V4L2_CTRL_WHICH_DEF_VAL) { - dprintk(vdev, "%s: cannot change default value\n", + /* Default/minimum/maximum values cannot be changed */ + if (cs->which == V4L2_CTRL_WHICH_DEF_VAL || + cs->which == V4L2_CTRL_WHICH_MIN_VAL || + cs->which == V4L2_CTRL_WHICH_MAX_VAL) { + dprintk(vdev, "%s: cannot change default/min/max value\n", video_device_node_name(vdev)); return -EINVAL; } diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c index dcde405c2713..d056bd6a1561 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c @@ -186,6 +186,28 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx, } } +static void std_min_compound(const struct v4l2_ctrl *ctrl, u32 idx, + union v4l2_ctrl_ptr ptr) +{ + void *p = ptr.p + idx * ctrl->elem_size; + + if (ctrl->p_min.p_const) + memcpy(p, ctrl->p_min.p_const, ctrl->elem_size); + else + memset(p, 0, ctrl->elem_size); +} + +static void std_max_compound(const struct v4l2_ctrl *ctrl, u32 idx, + union v4l2_ctrl_ptr ptr) +{ + void *p = ptr.p + idx * ctrl->elem_size; + + if (ctrl->p_max.p_const) + memcpy(p, ctrl->p_max.p_const, ctrl->elem_size); + else + memset(p, 0, ctrl->elem_size); +} + static void std_init(const struct v4l2_ctrl *ctrl, u32 idx, union v4l2_ctrl_ptr ptr) { @@ -224,6 +246,82 @@ static void std_init(const struct v4l2_ctrl *ctrl, u32 idx, } } +static void std_minimum(const struct v4l2_ctrl *ctrl, u32 idx, + union v4l2_ctrl_ptr ptr) +{ + switch (ctrl->type) { + case V4L2_CTRL_TYPE_STRING: + idx *= ctrl->elem_size; + memset(ptr.p_char + idx, ' ', ctrl->minimum); + ptr.p_char[idx + ctrl->minimum] = '\0'; + break; + case V4L2_CTRL_TYPE_INTEGER64: + ptr.p_s64[idx] = ctrl->minimum; + break; + case V4L2_CTRL_TYPE_INTEGER: + case V4L2_CTRL_TYPE_INTEGER_MENU: + case V4L2_CTRL_TYPE_MENU: + case V4L2_CTRL_TYPE_BITMASK: + case V4L2_CTRL_TYPE_BOOLEAN: + ptr.p_s32[idx] = ctrl->minimum; + break; + case V4L2_CTRL_TYPE_BUTTON: + case V4L2_CTRL_TYPE_CTRL_CLASS: + ptr.p_s32[idx] = 0; + break; + case V4L2_CTRL_TYPE_U8: + ptr.p_u8[idx] = ctrl->minimum; + break; + case V4L2_CTRL_TYPE_U16: + ptr.p_u16[idx] = ctrl->minimum; + break; + case V4L2_CTRL_TYPE_U32: + ptr.p_u32[idx] = ctrl->minimum; + break; + default: + std_min_compound(ctrl, idx, ptr); + break; + } +} + +static void std_maximum(const struct v4l2_ctrl *ctrl, u32 idx, + union v4l2_ctrl_ptr ptr) +{ + switch (ctrl->type) { + case V4L2_CTRL_TYPE_STRING: + idx *= ctrl->elem_size; + memset(ptr.p_char + idx, ' ', ctrl->maximum); + ptr.p_char[idx + ctrl->maximum] = '\0'; + break; + case V4L2_CTRL_TYPE_INTEGER64: + ptr.p_s64[idx] = ctrl->maximum; + break; + case V4L2_CTRL_TYPE_INTEGER: + case V4L2_CTRL_TYPE_INTEGER_MENU: + case V4L2_CTRL_TYPE_MENU: + case V4L2_CTRL_TYPE_BITMASK: + case V4L2_CTRL_TYPE_BOOLEAN: + ptr.p_s32[idx] = ctrl->maximum; + break; + case V4L2_CTRL_TYPE_BUTTON: + case V4L2_CTRL_TYPE_CTRL_CLASS: + ptr.p_s32[idx] = 0; + break; + case V4L2_CTRL_TYPE_U8: + ptr.p_u8[idx] = ctrl->maximum; + break; + case V4L2_CTRL_TYPE_U16: + ptr.p_u16[idx] = ctrl->maximum; + break; + case V4L2_CTRL_TYPE_U32: + ptr.p_u32[idx] = ctrl->maximum; + break; + default: + std_max_compound(ctrl, idx, ptr); + break; + } +} + static void std_log(const struct v4l2_ctrl *ctrl) { union v4l2_ctrl_ptr ptr = ctrl->p_cur; @@ -986,6 +1084,8 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx, static const struct v4l2_ctrl_type_ops std_type_ops = { .equal = std_equal, .init = std_init, + .minimum = std_minimum, + .maximum = std_maximum, .log = std_log, .validate = std_validate, }; @@ -1369,7 +1469,10 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, s64 min, s64 max, u64 step, s64 def, const u32 dims[V4L2_CTRL_MAX_DIMS], u32 elem_size, u32 flags, const char * const *qmenu, - const s64 *qmenu_int, const union v4l2_ctrl_ptr p_def, + const s64 *qmenu_int, + const union v4l2_ctrl_ptr p_def, + const union v4l2_ctrl_ptr p_min, + const union v4l2_ctrl_ptr p_max, void *priv) { struct v4l2_ctrl *ctrl; @@ -1516,7 +1619,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, sz_extra += 2 * tot_ctrl_size; if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p_const) - sz_extra += elem_size; + sz_extra += elem_size * 3; ctrl = kvzalloc(sizeof(*ctrl) + sz_extra, GFP_KERNEL); if (ctrl == NULL) { @@ -1566,6 +1669,13 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, ctrl->p_def.p = ctrl->p_cur.p + tot_ctrl_size; memcpy(ctrl->p_def.p, p_def.p_const, elem_size); } + if (type >= V4L2_CTRL_COMPOUND_TYPES && + p_min.p_const && p_max.p_const) { + ctrl->p_min.p = ctrl->p_cur.p + 2 * tot_ctrl_size; + memcpy(ctrl->p_min.p, p_min.p_const, elem_size); + ctrl->p_max.p = ctrl->p_cur.p + 3 * tot_ctrl_size; + memcpy(ctrl->p_max.p, p_max.p_const, elem_size); + } for (idx = 0; idx < elems; idx++) { ctrl->type_ops->init(ctrl, idx, ctrl->p_cur); @@ -1618,7 +1728,8 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl, type, min, max, is_menu ? cfg->menu_skip_mask : step, def, cfg->dims, cfg->elem_size, - flags, qmenu, qmenu_int, cfg->p_def, priv); + flags, qmenu, qmenu_int, cfg->p_def, cfg->p_min, + cfg->p_max, priv); if (ctrl) ctrl->is_private = cfg->is_private; return ctrl; @@ -1643,7 +1754,8 @@ struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl, } return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, min, max, step, def, NULL, 0, - flags, NULL, NULL, ptr_null, NULL); + flags, NULL, NULL, ptr_null, ptr_null, + ptr_null, NULL); } EXPORT_SYMBOL(v4l2_ctrl_new_std); @@ -1676,7 +1788,8 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl, } return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, 0, max, mask, def, NULL, 0, - flags, qmenu, qmenu_int, ptr_null, NULL); + flags, qmenu, qmenu_int, ptr_null, ptr_null, + ptr_null, NULL); } EXPORT_SYMBOL(v4l2_ctrl_new_std_menu); @@ -1708,7 +1821,8 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl, } return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, 0, max, mask, def, NULL, 0, - flags, qmenu, NULL, ptr_null, NULL); + flags, qmenu, NULL, ptr_null, ptr_null, + ptr_null, NULL); } EXPORT_SYMBOL(v4l2_ctrl_new_std_menu_items); @@ -1716,7 +1830,9 @@ EXPORT_SYMBOL(v4l2_ctrl_new_std_menu_items); /* Helper function for standard compound controls */ struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl, const struct v4l2_ctrl_ops *ops, u32 id, - const union v4l2_ctrl_ptr p_def) + const union v4l2_ctrl_ptr p_def, + const union v4l2_ctrl_ptr p_min, + const union v4l2_ctrl_ptr p_max) { const char *name; enum v4l2_ctrl_type type; @@ -1730,7 +1846,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl, } return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, min, max, step, def, NULL, 0, - flags, NULL, NULL, p_def, NULL); + flags, NULL, NULL, p_def, p_min, p_max, NULL); } EXPORT_SYMBOL(v4l2_ctrl_new_std_compound); @@ -1754,7 +1870,8 @@ struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl, } return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, 0, max, 0, def, NULL, 0, - flags, NULL, qmenu_int, ptr_null, NULL); + flags, NULL, qmenu_int, ptr_null, ptr_null, + ptr_null, NULL); } EXPORT_SYMBOL(v4l2_ctrl_new_int_menu); diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 96e307fe3aab..6ed6ef87c7ff 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -892,7 +892,9 @@ static bool check_ext_ctrls(struct v4l2_ext_controls *c, unsigned long ioctl) return false; break; case V4L2_CTRL_WHICH_DEF_VAL: - /* Default value cannot be changed */ + case V4L2_CTRL_WHICH_MIN_VAL: + case V4L2_CTRL_WHICH_MAX_VAL: + /* Default, minimum or maximum value cannot be changed */ if (ioctl == VIDIOC_S_EXT_CTRLS || ioctl == VIDIOC_TRY_EXT_CTRLS) { c->error_idx = c->count; diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index 919e104de50b..bd3bab55b766 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -131,6 +131,8 @@ struct v4l2_ctrl_ops { * * @equal: return true if both values are equal. * @init: initialize the value. + * @minimum: set the value to the minimum value of the control. + * @maximum: set the value to the maximum value of the control. * @log: log the value. * @validate: validate the value. Return 0 on success and a negative value * otherwise. @@ -141,6 +143,10 @@ struct v4l2_ctrl_type_ops { union v4l2_ctrl_ptr ptr2); void (*init)(const struct v4l2_ctrl *ctrl, u32 idx, union v4l2_ctrl_ptr ptr); + void (*minimum)(const struct v4l2_ctrl *ctrl, u32 idx, + union v4l2_ctrl_ptr ptr); + void (*maximum)(const struct v4l2_ctrl *ctrl, u32 idx, + union v4l2_ctrl_ptr ptr); void (*log)(const struct v4l2_ctrl *ctrl); int (*validate)(const struct v4l2_ctrl *ctrl, u32 idx, union v4l2_ctrl_ptr ptr); @@ -237,6 +243,12 @@ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv); * @p_def: The control's default value represented via a union which * provides a standard way of accessing control types * through a pointer (for compound controls only). + * @p_min: The control's minimum value represented via a union which + * provides a standard way of accessing control types + * through a pointer (for compound controls only). + * @p_max: The control's maximum value represented via a union which + * provides a standard way of accessing control types + * through a pointer (for compound controls only). * @p_cur: The control's current value represented via a union which * provides a standard way of accessing control types * through a pointer. @@ -292,6 +304,8 @@ struct v4l2_ctrl { } cur; union v4l2_ctrl_ptr p_def; + union v4l2_ctrl_ptr p_min; + union v4l2_ctrl_ptr p_max; union v4l2_ctrl_ptr p_new; union v4l2_ctrl_ptr p_cur; }; @@ -398,6 +412,8 @@ struct v4l2_ctrl_handler { * @step: The control's step value for non-menu controls. * @def: The control's default value. * @p_def: The control's default value for compound controls. + * @p_min: The control's minimum value for compound controls. + * @p_max: The control's maximum value for compound controls. * @dims: The size of each dimension. * @elem_size: The size in bytes of the control. * @flags: The control's flags. @@ -427,6 +443,8 @@ struct v4l2_ctrl_config { u64 step; s64 def; union v4l2_ctrl_ptr p_def; + union v4l2_ctrl_ptr p_min; + union v4l2_ctrl_ptr p_max; u32 dims[V4L2_CTRL_MAX_DIMS]; u32 elem_size; u32 flags; @@ -696,17 +714,21 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl, * @ops: The control ops. * @id: The control ID. * @p_def: The control's default value. + * @p_min: The control's default value. + * @p_ma: The control's default value. * * Sames as v4l2_ctrl_new_std(), but with support to compound controls, thanks - * to the @p_def field. Use v4l2_ctrl_ptr_create() to create @p_def from a - * pointer. Use v4l2_ctrl_ptr_create(NULL) if the default value of the - * compound control should be all zeroes. + * to the @p_def/min/max field. Use v4l2_ctrl_ptr_create() to create + * @p_def/min/max from a pointer. Use v4l2_ctrl_ptr_create(NULL) if the default + * value of the compound control should be all zeroes. * */ struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl, const struct v4l2_ctrl_ops *ops, u32 id, - const union v4l2_ctrl_ptr p_def); + const union v4l2_ctrl_ptr p_def, + const union v4l2_ctrl_ptr p_min, + const union v4l2_ctrl_ptr p_max); /** * v4l2_ctrl_new_int_menu() - Create a new standard V4L2 integer menu control. diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index b712412cf763..d22ebb0102d4 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1793,6 +1793,8 @@ struct v4l2_ext_controls { #define V4L2_CTRL_WHICH_CUR_VAL 0 #define V4L2_CTRL_WHICH_DEF_VAL 0x0f000000 #define V4L2_CTRL_WHICH_REQUEST_VAL 0x0f010000 +#define V4L2_CTRL_WHICH_MIN_VAL 0x0f020000 +#define V4L2_CTRL_WHICH_MAX_VAL 0x0f030000 enum v4l2_ctrl_type { V4L2_CTRL_TYPE_INTEGER = 1, From patchwork Mon May 16 09:22:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yunke Cao X-Patchwork-Id: 83305 Received: from vger.kernel.org ([23.128.96.18]) by www.linuxtv.org with esmtp (Exim 4.92) (envelope-from ) id 1nqWwh-00Dvy5-96; Mon, 16 May 2022 09:23:19 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234139AbiEPJXQ (ORCPT + 1 other); Mon, 16 May 2022 05:23:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36632 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238242AbiEPJXP (ORCPT ); Mon, 16 May 2022 05:23:15 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E81A925EB8 for ; Mon, 16 May 2022 02:23:12 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-2fb7cb07885so124814047b3.23 for ; Mon, 16 May 2022 02:23:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=dggB1sTSjPpcxUIiJu72svtYy7RvemyC223O/9ug7mo=; b=e3+b+N4vexk6YtfeuOf/RueBjLnMIfLpMS8ibeMEA8926v2i5t/GCsE+O6O3tgf0Ya NdsutPZSR4plZp9cxLNfg0tRDWs1zDHAre9ecn4uoAe+8r+9xZQFdbg9PVDGIeGvRNC1 IiymdD3aiF9/D33oe9cv9qS87fSXt4tYMXEvEiUNGiEhz75fn83VXb14viaC/INQ48CW 41pHQ8qMCaoDIzenm247vA0h11JciHwq6q/pC2SINdTHxW0QqjbhMxkpHGj+lP26+BbB gYV49CcBxlcFymTUufM54zT1rS2O/nVocJOsjtMnRU3qWXcKa4fXiP+kO20/abpt2D8P Tzyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=dggB1sTSjPpcxUIiJu72svtYy7RvemyC223O/9ug7mo=; b=tAECZWrS8kv2cqnJysKCDoCRAyLcxhD8nlA2IgY81UCwj+QNghiZ7ODC74psn8tme+ ecqm+rpUCnvTXk0GDJBV+/4/nG7Xr7UTfPOJsKHujvvANtFRGFo2WQ4QVbrhah/bKD2C mKTqRIAahxsSIOTdbgl7N08I7sKmtHi0SyIoj9bw2QLkHsDsGE1pJxfcu6p4Eq7PlvDI zFaTiEH5y8JBwURLROEbHzpB7ahBrdc9W6Vzo8vxoXkC6HsRGyVgSQ62xZu243C6D6IV 4dCi7aONOEQnW12f2VndJSUq3BMolwju/qe5FvdpBn+ZcmMD39r2+tG3mGhWzCL7hzh7 azvA== X-Gm-Message-State: AOAM533wux6bqqJUpryCfKxq//JQIQDf2TO2tKxq5xN+4kaPiNNam1Tv qVUUJb552h9X/U6J+Y7V9va/5RIxF44= X-Google-Smtp-Source: ABdhPJyVy6KVc7JqhnEis/VVINelwpstbMgXhPfu90sgkLJYB8B7V9SOLFGsQfOB+Z92bBeMRaXKOIZXcM8= X-Received: from yunkec1.tok.corp.google.com ([2401:fa00:8f:203:2bd1:4151:d530:8b73]) (user=yunkec job=sendgmr) by 2002:a25:21c3:0:b0:64a:b29a:9b0d with SMTP id h186-20020a2521c3000000b0064ab29a9b0dmr16539550ybh.59.1652692992187; Mon, 16 May 2022 02:23:12 -0700 (PDT) Date: Mon, 16 May 2022 18:22:07 +0900 In-Reply-To: <20220516092209.1801656-1-yunkec@google.com> Message-Id: <20220516092209.1801656-5-yunkec@google.com> Mime-Version: 1.0 References: <20220516092209.1801656-1-yunkec@google.com> X-Mailer: git-send-email 2.36.0.550.gb090851708-goog Subject: [PATCH v1 4/6] media: uvcvideo: implement UVC v1.5 ROI From: Yunke Cao To: Hans Verkuil , Laurent Pinchart Cc: Tomasz Figa , Sergey Senozhatsky , Ricardo Ribalda , linux-media@vger.kernel.org, Yunke Cao X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-LSpam-Score: -10.0 (----------) X-LSpam-Report: No, score=-10.0 required=5.0 tests=BAYES_00=-1.9,DKIMWL_WL_MED=0.001,DKIM_SIGNED=0.1,DKIM_VALID=-0.1,DKIM_VALID_AU=-0.1,HEADER_FROM_DIFFERENT_DOMAINS=0.5,MAILING_LIST_MULTI=-1,USER_IN_DEF_DKIM_WL=-7.5 autolearn=ham autolearn_force=no Supports GET_CUR, GET_DEF, GET_MIN and GET_MAX requests for UVC v1.5 using V4L2 control API. References a rejected attempt that uses v4l2 selection API: https://lore.kernel.org/lkml/20210501082001.100533-2-senozhatsky@chromium.org Signed-off-by: Yunke Cao --- .../userspace-api/media/drivers/uvcvideo.rst | 1 + drivers/media/usb/uvc/uvc_ctrl.c | 173 ++++++++++++++++-- drivers/media/usb/uvc/uvc_v4l2.c | 12 +- drivers/media/usb/uvc/uvcvideo.h | 10 +- include/uapi/linux/usb/video.h | 1 + include/uapi/linux/uvcvideo.h | 1 + 6 files changed, 173 insertions(+), 25 deletions(-) diff --git a/Documentation/userspace-api/media/drivers/uvcvideo.rst b/Documentation/userspace-api/media/drivers/uvcvideo.rst index e5fd8fad333c..43b8431b0d9f 100644 --- a/Documentation/userspace-api/media/drivers/uvcvideo.rst +++ b/Documentation/userspace-api/media/drivers/uvcvideo.rst @@ -181,6 +181,7 @@ Argument: struct uvc_xu_control_mapping UVC_CTRL_DATA_TYPE_BOOLEAN Boolean UVC_CTRL_DATA_TYPE_ENUM Enumeration UVC_CTRL_DATA_TYPE_BITMASK Bitmask + UVC_CTRL_DATA_TYPE_RECT Rectangular area UVCIOC_CTRL_QUERY - Query a UVC XU control diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index b4f6edf968bc..c3d816985f13 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -355,6 +355,15 @@ static const struct uvc_control_info uvc_ctrls[] = { .flags = UVC_CTRL_FLAG_GET_CUR | UVC_CTRL_FLAG_AUTO_UPDATE, }, + { + .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 + }, }; static const u32 uvc_control_classes[] = { @@ -728,6 +737,24 @@ static const struct uvc_control_mapping uvc_ctrl_mappings[] = { .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN, }, + { + .id = V4L2_CID_REGION_OF_INTEREST_RECT, + .entity = UVC_GUID_UVC_CAMERA, + .selector = UVC_CT_REGION_OF_INTEREST_CONTROL, + .size = 64, + .offset = 0, + .v4l2_type = V4L2_CTRL_TYPE_RECT, + .data_type = UVC_CTRL_DATA_TYPE_RECT, + }, + { + .id = V4L2_CID_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, + }, }; /* ------------------------------------------------------------------------ @@ -749,6 +776,33 @@ static inline void uvc_clear_bit(u8 *data, int bit) data[bit >> 3] &= ~(1 << (bit & 7)); } +static void uvc_to_v4l2_rect(struct v4l2_rect *v4l2_rect, + const struct uvc_rect *uvc_rect) +{ + 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; +} + +static int v4l2_to_uvc_rect(struct uvc_rect *uvc_rect, + const struct v4l2_rect *v4l2_rect) +{ + // Safely converts s32 and u32 to u16. + if (v4l2_rect->top > U16_MAX || v4l2_rect->top < 0 || + v4l2_rect->left > U16_MAX || v4l2_rect->left < 0 || + v4l2_rect->height > U16_MAX || v4l2_rect->width > U16_MAX || + v4l2_rect->height + v4l2_rect->top - 1 > U16_MAX || + v4l2_rect->width + v4l2_rect->left - 1 > U16_MAX) + return -ERANGE; + + uvc_rect->top = v4l2_rect->top; + uvc_rect->left = v4l2_rect->left; + uvc_rect->bottom = v4l2_rect->height + v4l2_rect->top - 1; + uvc_rect->right = v4l2_rect->width + v4l2_rect->left - 1; + return 0; +} + /* Extract the bit string specified by mapping->offset and mapping->size * from the little-endian data stored at 'data' and return the result as * a signed 32bit integer. Sign extension will be performed if the mapping @@ -963,11 +1017,23 @@ static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping, return value; } +static void __uvc_ctrl_get_v4l2_rect(struct uvc_control *ctrl, + struct uvc_control_mapping *mapping, + u32 id, + struct v4l2_rect *rect) +{ + struct uvc_rect *uvc_rect = + (struct uvc_rect *)(uvc_ctrl_data(ctrl, id) + + mapping->offset / 8); + uvc_to_v4l2_rect(rect, uvc_rect); +} + static int __uvc_ctrl_get(struct uvc_video_chain *chain, struct uvc_control *ctrl, struct uvc_control_mapping *mapping, - s32 *value) + struct v4l2_ext_control *xctrl) { int ret; + struct v4l2_rect v4l2_rect; if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) return -EACCES; @@ -993,8 +1059,17 @@ static int __uvc_ctrl_get(struct uvc_video_chain *chain, ctrl->loaded = 1; } - *value = __uvc_ctrl_get_value(mapping, + switch (mapping->v4l2_type) { + case V4L2_CTRL_TYPE_RECT: + __uvc_ctrl_get_v4l2_rect(ctrl, mapping, UVC_CTRL_DATA_CURRENT, + &v4l2_rect); + return copy_to_user(xctrl->p_rect, &v4l2_rect, + sizeof(v4l2_rect)); + + default: + xctrl->value = __uvc_ctrl_get_value(mapping, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); + } return 0; } @@ -1104,13 +1179,14 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, __uvc_find_control(ctrl->entity, mapping->master_id, &master_map, &master_ctrl, 0); if (master_ctrl && (master_ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) { - s32 val; - int ret = __uvc_ctrl_get(chain, master_ctrl, master_map, &val); + struct v4l2_ext_control xctrl; + int ret = + __uvc_ctrl_get(chain, master_ctrl, master_map, &xctrl); if (ret < 0) return ret; - if (val != mapping->master_manual) - v4l2_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; + if (xctrl.value != mapping->master_manual) + v4l2_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; } if (!ctrl->cached) { @@ -1344,16 +1420,16 @@ static void uvc_ctrl_send_slave_event(struct uvc_video_chain *chain, struct uvc_control_mapping *mapping = NULL; struct uvc_control *ctrl = NULL; u32 changes = V4L2_EVENT_CTRL_CH_FLAGS; - s32 val = 0; + struct v4l2_ext_control xctrl; __uvc_find_control(master->entity, slave_id, &mapping, &ctrl, 0); if (ctrl == NULL) return; - if (__uvc_ctrl_get(chain, ctrl, mapping, &val) == 0) + if (__uvc_ctrl_get(chain, ctrl, mapping, &xctrl) == 0) changes |= V4L2_EVENT_CTRL_CH_VALUE; - uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes); + uvc_ctrl_send_event(chain, handle, ctrl, mapping, xctrl.value, changes); } void uvc_ctrl_status_event(struct uvc_video_chain *chain, @@ -1515,13 +1591,13 @@ static int uvc_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems) if (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL) { struct v4l2_event ev; u32 changes = V4L2_EVENT_CTRL_CH_FLAGS; - s32 val = 0; + struct v4l2_ext_control xctrl; - if (__uvc_ctrl_get(handle->chain, ctrl, mapping, &val) == 0) + if (__uvc_ctrl_get(handle->chain, ctrl, mapping, &xctrl) == 0) changes |= V4L2_EVENT_CTRL_CH_VALUE; - uvc_ctrl_fill_event(handle->chain, &ev, ctrl, mapping, val, - changes); + uvc_ctrl_fill_event(handle->chain, &ev, ctrl, mapping, + xctrl.value, changes); /* Mark the queue as active, allowing this initial event to be accepted. */ sev->elems = elems; @@ -1682,10 +1758,14 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, } int uvc_ctrl_get(struct uvc_video_chain *chain, - struct v4l2_ext_control *xctrl) + struct v4l2_ext_control *xctrl, u32 v4l2_which) { struct uvc_control *ctrl; struct uvc_control_mapping *mapping; + int ret; + u32 flag; + u32 id; + u8 query; if (__uvc_query_v4l2_class(chain, xctrl->id, 0) >= 0) return -EACCES; @@ -1694,7 +1774,46 @@ int uvc_ctrl_get(struct uvc_video_chain *chain, if (ctrl == NULL) return -EINVAL; - return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value); + switch (v4l2_which) { + case V4L2_CTRL_WHICH_DEF_VAL: + flag = UVC_CTRL_FLAG_GET_DEF; + id = UVC_CTRL_DATA_DEF; + query = UVC_GET_DEF; + break; + case V4L2_CTRL_WHICH_MIN_VAL: + flag = UVC_CTRL_FLAG_GET_MIN; + id = UVC_CTRL_DATA_MIN; + query = UVC_GET_MIN; + break; + case V4L2_CTRL_WHICH_MAX_VAL: + flag = UVC_CTRL_FLAG_GET_MAX; + id = UVC_CTRL_DATA_MAX; + query = UVC_GET_MAX; + break; + case V4L2_CTRL_WHICH_CUR_VAL: + default: + return __uvc_ctrl_get(chain, ctrl, mapping, xctrl); + } + + if (!ctrl->cached) { + ret = uvc_ctrl_populate_cache(chain, ctrl); + if (ret < 0) + return ret; + } + + if (!(ctrl->info.flags & flag)) + return -EACCES; + + if (mapping->v4l2_type == V4L2_CTRL_TYPE_RECT) { + struct v4l2_rect rect; + + __uvc_ctrl_get_v4l2_rect(ctrl, mapping, id, &rect); + return copy_to_user(xctrl->p_rect, &rect, sizeof(rect)); + } + + xctrl->value = mapping->get(mapping, query, uvc_ctrl_data(ctrl, id)); + + return 0; } int uvc_ctrl_set(struct uvc_fh *handle, @@ -1703,6 +1822,8 @@ int uvc_ctrl_set(struct uvc_fh *handle, struct uvc_video_chain *chain = handle->chain; struct uvc_control *ctrl; struct uvc_control_mapping *mapping; + struct v4l2_rect v4l2_rect; + struct uvc_rect uvc_rect; s32 value; u32 step; s32 min; @@ -1774,6 +1895,16 @@ int uvc_ctrl_set(struct uvc_fh *handle, break; + case V4L2_CTRL_TYPE_RECT: + ret = copy_from_user(&v4l2_rect, xctrl->p_rect, + sizeof(v4l2_rect)); + if (ret < 0) + return ret; + ret = v4l2_to_uvc_rect(&uvc_rect, &v4l2_rect); + if (ret < 0) + return ret; + break; + default: value = xctrl->value; break; @@ -1807,8 +1938,16 @@ int uvc_ctrl_set(struct uvc_fh *handle, ctrl->info.size); } - mapping->set(mapping, value, - uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); + switch (mapping->data_type) { + case UVC_CTRL_DATA_TYPE_RECT: + memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT) + + mapping->offset / 8, + &uvc_rect, sizeof(uvc_rect)); + break; + default: + mapping->set(mapping, value, + uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); + } if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) ctrl->handle = handle; diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 711556d13d03..a88d3fe6de93 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -1038,17 +1038,15 @@ static int uvc_ioctl_g_ext_ctrls(struct file *file, void *fh, if (ret < 0) return ret; - if (ctrls->which == V4L2_CTRL_WHICH_DEF_VAL) { + if (ctrls->which == V4L2_CTRL_WHICH_DEF_VAL || + ctrls->which == V4L2_CTRL_WHICH_MIN_VAL || + ctrls->which == V4L2_CTRL_WHICH_MAX_VAL) { for (i = 0; i < ctrls->count; ++ctrl, ++i) { - struct v4l2_queryctrl qc = { .id = ctrl->id }; - - ret = uvc_query_v4l2_ctrl(chain, &qc); + ret = uvc_ctrl_get(chain, ctrl, ctrls->which); if (ret < 0) { ctrls->error_idx = i; return ret; } - - ctrl->value = qc.default_value; } return 0; @@ -1059,7 +1057,7 @@ static int uvc_ioctl_g_ext_ctrls(struct file *file, void *fh, return ret; for (i = 0; i < ctrls->count; ++ctrl, ++i) { - ret = uvc_ctrl_get(chain, ctrl); + ret = uvc_ctrl_get(chain, ctrl, ctrls->which); if (ret < 0) { uvc_ctrl_rollback(handle); ctrls->error_idx = i; diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 143230b3275b..f414ad7d57b2 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -424,6 +424,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, @@ -897,7 +904,8 @@ static inline int uvc_ctrl_rollback(struct uvc_fh *handle) return __uvc_ctrl_commit(handle, 1, NULL); } -int uvc_ctrl_get(struct uvc_video_chain *chain, struct v4l2_ext_control *xctrl); +int uvc_ctrl_get(struct uvc_video_chain *chain, struct v4l2_ext_control *xctrl, + u32 v4l2_which); int uvc_ctrl_set(struct uvc_fh *handle, struct v4l2_ext_control *xctrl); int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id, bool read); diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h index bfdae12cdacf..9076a444758a 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 8288137387c0..d7d77602a5e7 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) From patchwork Mon May 16 09:22:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yunke Cao X-Patchwork-Id: 83306 X-Patchwork-Delegate: laurent.pinchart@ideasonboard.com Received: from vger.kernel.org ([23.128.96.18]) by www.linuxtv.org with esmtp (Exim 4.92) (envelope-from ) id 1nqWwo-00Dvyg-4u; Mon, 16 May 2022 09:23:26 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240904AbiEPJXW (ORCPT + 1 other); Mon, 16 May 2022 05:23:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36844 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238242AbiEPJXT (ORCPT ); Mon, 16 May 2022 05:23:19 -0400 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CB2EF26105 for ; Mon, 16 May 2022 02:23:18 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-2fef1441caaso19977567b3.6 for ; Mon, 16 May 2022 02:23:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=XYcszPVY+/p86mgF6I7vbvgFO/hmQYAS3gPe49Smi58=; b=OAriJZPnh9cWu5KKCXWbOBK6rUmmppd8ZnsaqyNBkGcysh+/FTeOBQTUSUo318nRui VL3IgBEuEh74XklUrPX6OTC5K0tsIm/rGBqRH5gEnlEUvYWtM1QC947pMuU1VzLIg3IL Oaf7aTmvSEk54vImBOBuD7SRyPuGzGhMgf6si4pNsBXF44NuyV2JNHyIUGnzA1AKKVpx ca7wDJXkzYRUsGXizVO2tAp5vUTp+l3h1eR1fHZo2n9IXBcg+qi7InP/ieGg5Rmk95uh TjPJ3239Nlak5OPhTiCbTXIbMCwUXPeo2ZKcodgirkX09jWDI/Zgd4/Y9/WYngkHwelF 5q1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=XYcszPVY+/p86mgF6I7vbvgFO/hmQYAS3gPe49Smi58=; b=H3vv5SOf+etazmil3GBzncqMrVQpIJW64B9/th5HhOVqh9RyoETfk0PgsFl+0IC7E5 B8VmL84vHJUUCJJwFf9C7HNM+h/x1sWApxDjQxH+Fc5ykcFunTEM6wyJQxOLzCXmF2Qf 2yEKCHL0lKTS4AX6S1RCJIiwDgMsSetsDnYKnjxW0ynJiPvPxWbDrhFi9a9OpxQyiZpx GTVRNmrC6kptC44erx7giifRcbR/NZLVfE1KBsZP2mhWYt6NzjT0EP0bEqwVE2dUPI29 c7aywNhhRlfZJNpfcT3yMj4zdNJtF3GHYjJbe8qDcOTHj4to/YFUcWmY9aI20AZjQsXh QHsw== X-Gm-Message-State: AOAM530y/BQmAsFSufGoTaXVfmDGiXWvNEOaXOhwj4pgvGb2NdNXUqHj 99HSXj6MZ9/QjdDHL4WgdDwlXtV1ICI= X-Google-Smtp-Source: ABdhPJwz2wnNurX8uH0kRfuBWLKzkAKTi32jWJY3hKi31FUTKbNB1kWGP16Fy/DgrQ/reYoueQhJZswEWyA= X-Received: from yunkec1.tok.corp.google.com ([2401:fa00:8f:203:2bd1:4151:d530:8b73]) (user=yunkec job=sendgmr) by 2002:a0d:e704:0:b0:2ff:1177:d942 with SMTP id q4-20020a0de704000000b002ff1177d942mr1005759ywe.277.1652692997675; Mon, 16 May 2022 02:23:17 -0700 (PDT) Date: Mon, 16 May 2022 18:22:08 +0900 In-Reply-To: <20220516092209.1801656-1-yunkec@google.com> Message-Id: <20220516092209.1801656-6-yunkec@google.com> Mime-Version: 1.0 References: <20220516092209.1801656-1-yunkec@google.com> X-Mailer: git-send-email 2.36.0.550.gb090851708-goog Subject: [PATCH v1 5/6] media: uvcvideo: Initialize roi to default value From: Yunke Cao To: Hans Verkuil , Laurent Pinchart Cc: Tomasz Figa , Sergey Senozhatsky , Ricardo Ribalda , linux-media@vger.kernel.org, Yunke Cao X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-LSpam-Score: -10.0 (----------) X-LSpam-Report: No, score=-10.0 required=5.0 tests=BAYES_00=-1.9,DKIMWL_WL_MED=0.001,DKIM_SIGNED=0.1,DKIM_VALID=-0.1,DKIM_VALID_AU=-0.1,HEADER_FROM_DIFFERENT_DOMAINS=0.5,MAILING_LIST_MULTI=-1,USER_IN_DEF_DKIM_WL=-7.5 autolearn=ham autolearn_force=no For the devices we tested with, firmwares have wrong initial ROI configuration. Initialize roi by setting to default value. Signed-off-by: Yunke Cao Reported-by: kernel test robot --- drivers/media/usb/uvc/uvc_ctrl.c | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index c3d816985f13..f90b425a0a20 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -2505,6 +2505,40 @@ static void uvc_ctrl_prune_entity(struct uvc_device *dev, } } +static int uvc_ctrl_init_roi(struct uvc_device *dev, struct uvc_control *ctrl) +{ + int ret; + + ret = uvc_query_ctrl(dev, UVC_GET_DEF, ctrl->entity->id, dev->intfnum, + UVC_CT_REGION_OF_INTEREST_CONTROL, + uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF), + ctrl->info.size); + if (ret) + goto out; + + /* + * Some firmwares have wrong GET_CURRENT configuration. E.g. it's + * below GET_MIN, or have rectangle coordinates mixed up. This + * causes problems sometimes, because we are unable to set + * auto-controls value without first setting ROI rectangle to + * valid configuration. + * + * We expect that default configuration is always correct and + * is within the GET_MIN / GET_MAX boundaries. + * + * Set current ROI configuration to GET_DEF, so that we will + * always have properly configured ROI. + */ + ret = uvc_query_ctrl(dev, UVC_SET_CUR, 1, dev->intfnum, + UVC_CT_REGION_OF_INTEREST_CONTROL, + uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF), + ctrl->info.size); +out: + if (ret) + dev_err(&dev->udev->dev, "Failed to fixup ROI (%d).\n", ret); + return ret; +} + /* * Add control information and hardcoded stock control mappings to the given * device. @@ -2537,6 +2571,11 @@ static void uvc_ctrl_init_ctrl(struct uvc_video_chain *chain, * GET_INFO on standard controls. */ uvc_ctrl_get_flags(chain->dev, ctrl, &ctrl->info); + + if (ctrl->info.selector == + UVC_CT_REGION_OF_INTEREST_CONTROL && + uvc_entity_match_guid(ctrl->entity, camera_entity)) + uvc_ctrl_init_roi(chain->dev, ctrl); break; } } From patchwork Mon May 16 09:22:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yunke Cao X-Patchwork-Id: 83307 Received: from vger.kernel.org ([23.128.96.18]) by www.linuxtv.org with esmtp (Exim 4.92) (envelope-from ) id 1nqWwy-00Dvyg-OQ; Mon, 16 May 2022 09:23:36 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242160AbiEPJXe (ORCPT + 1 other); Mon, 16 May 2022 05:23:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37224 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242145AbiEPJXb (ORCPT ); Mon, 16 May 2022 05:23:31 -0400 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A9D8A25EBD for ; Mon, 16 May 2022 02:23:24 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-2fed8245a03so34652647b3.1 for ; Mon, 16 May 2022 02:23:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=IL247PX6DIraKPCB4Qq4FB+o6HNS1RKeiQ6Tz/uvjRQ=; b=KFgP8HYf/u1YqkzNXS8ek75t+U3whxqOaiUbWvQT7rv/TKcZkgXX+KhU98h0mOVw48 mQrzFdDfyO6Yzc9QhMTT5LPNGIWsaQHtcoY8dle/Ji/lX1bJcsqiPyCfiTSOFtYXd2bD CB6TRgK/nXBeyC9kqqlW6T0X/653qAMsT/3LAVag1O011udcUSWyL1ISWQgNlUUaylSo +7Gh+JJMMRMG9Nel5XgfBcr15mm4UdaNOE3NzthppIMc2XMG4j8WH+qwMU+DTVnGKaAs tPIJjx6Twjg84Wjb+cYkufgk7dbiXMvK3+UK0dydlmL4LH6CiYNkKLXiTBVVcCAOGsVY YeFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=IL247PX6DIraKPCB4Qq4FB+o6HNS1RKeiQ6Tz/uvjRQ=; b=T3m66sLIPK2XN3SDyRF+HcHoDg2AeqfmH3eQ2dpnOJEafDfVrSzLvw9btwlL5DItA7 6dHMxBnPaZJleqjRvtNcLMfsCnybML+SbF43ZvayGvpZtomkS50QByRfIorZ2LQ7yszx sfWMoJK/mQ5vFVqy6G94lb31TEI87Op37QAeu7UJHnhG7BYSo6CwTnMt91jOzQMJc+A8 5SKx9FB9SbgAsrupW7Z0WzmpibCkMpuPY2d3qcT4yCxzeyuGXUI4HB8QlPdu7mx+32xx P/Qc+FCjRtlKNTJWLnZFBWOef0RxCaO+IyKVo5P4uZM1lIZFhnxmqsc1Wqt35V7TUIQm plzg== X-Gm-Message-State: AOAM533UNGXh6TwQSGX+k9+EblcOPtWv8hrzudYOydT/tK0WWQVYECvP 3SzGr350ERv0/XD6C/qMp7/6RjqAgeM= X-Google-Smtp-Source: ABdhPJwrI8ICCctSFTq1tdm5cLeSw7m1Id2aR3dWDRNjVo8Bxi19CN/FB37fV3W3h1u9qf8oda/AfwDT3uY= X-Received: from yunkec1.tok.corp.google.com ([2401:fa00:8f:203:2bd1:4151:d530:8b73]) (user=yunkec job=sendgmr) by 2002:a25:258:0:b0:64d:6b57:bf25 with SMTP id 85-20020a250258000000b0064d6b57bf25mr8665650ybc.193.1652693003674; Mon, 16 May 2022 02:23:23 -0700 (PDT) Date: Mon, 16 May 2022 18:22:09 +0900 In-Reply-To: <20220516092209.1801656-1-yunkec@google.com> Message-Id: <20220516092209.1801656-7-yunkec@google.com> Mime-Version: 1.0 References: <20220516092209.1801656-1-yunkec@google.com> X-Mailer: git-send-email 2.36.0.550.gb090851708-goog Subject: [PATCH v1 6/6] media: vivid: Add a roi rectangle control From: Yunke Cao To: Hans Verkuil , Laurent Pinchart Cc: Tomasz Figa , Sergey Senozhatsky , Ricardo Ribalda , linux-media@vger.kernel.org, Yunke Cao X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-LSpam-Score: -10.0 (----------) X-LSpam-Report: No, score=-10.0 required=5.0 tests=BAYES_00=-1.9,DKIMWL_WL_MED=0.001,DKIM_SIGNED=0.1,DKIM_VALID=-0.1,DKIM_VALID_AU=-0.1,HEADER_FROM_DIFFERENT_DOMAINS=0.5,MAILING_LIST_MULTI=-1,USER_IN_DEF_DKIM_WL=-7.5 autolearn=ham autolearn_force=no The control supports current, default, minimum and maximum. Tested by calling ioctls from the user space. Signed-off-by: Yunke Cao --- .../media/test-drivers/vivid/vivid-ctrls.c | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/media/test-drivers/vivid/vivid-ctrls.c b/drivers/media/test-drivers/vivid/vivid-ctrls.c index e7516dc1227b..79093882d386 100644 --- a/drivers/media/test-drivers/vivid/vivid-ctrls.c +++ b/drivers/media/test-drivers/vivid/vivid-ctrls.c @@ -34,6 +34,7 @@ #define VIVID_CID_U8_4D_ARRAY (VIVID_CID_CUSTOM_BASE + 10) #define VIVID_CID_AREA (VIVID_CID_CUSTOM_BASE + 11) #define VIVID_CID_RO_INTEGER (VIVID_CID_CUSTOM_BASE + 12) +#define VIVID_CID_RECT (VIVID_CID_CUSTOM_BASE + 13) #define VIVID_CID_VIVID_BASE (0x00f00000 | 0xf000) #define VIVID_CID_VIVID_CLASS (0x00f00000 | 1) @@ -292,6 +293,38 @@ static const struct v4l2_ctrl_config vivid_ctrl_area = { .p_def.p_const = &area, }; +static const struct v4l2_rect def_rect = { + .left = 0, + .top = 0, + .width = 1000, + .height = 2000, +}; + +static const struct v4l2_rect min_rect = { + .left = 0, + .top = 0, + .width = 1, + .height = 2, +}; + +static const struct v4l2_rect max_rect = { + .left = 0, + .top = 0, + .width = 2000, + .height = 4000, +}; + +static const struct v4l2_ctrl_config vivid_ctrl_rect = { + .ops = &vivid_user_gen_ctrl_ops, + .id = VIVID_CID_RECT, + .name = "Region of Interest Rectangle", + .type = V4L2_CTRL_TYPE_RECT, + .p_def.p_const = &def_rect, + .p_min.p_const = &min_rect, + .p_max.p_const = &max_rect, +}; + + static const struct v4l2_ctrl_config vivid_ctrl_ro_int32 = { .ops = &vivid_user_gen_ctrl_ops, .id = VIVID_CID_RO_INTEGER, @@ -1611,6 +1644,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, dev->int_menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int_menu, NULL); dev->ro_int32 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_ro_int32, NULL); v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_area, NULL); + v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_rect, NULL); v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u32_array, NULL); v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u16_matrix, NULL); v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u8_4d_array, NULL);