From patchwork Mon Feb 17 18:53:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22798 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 9F255C3200 for ; Mon, 17 Feb 2025 18:53:42 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4EAF868681; Mon, 17 Feb 2025 19:53:42 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="qBkVCvH2"; dkim-atps=neutral Received: from mail-10631.protonmail.ch (mail-10631.protonmail.ch [79.135.106.31]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AEFCB61865 for ; Mon, 17 Feb 2025 19:53:40 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1739818420; x=1740077620; bh=W3kXEG4CVS9x8wIs8L3t6X8PiWkNwz/iR/pvgT10KVQ=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=qBkVCvH24mj+Z2VpEtCp2h0ulHAg3+8KUZhCnVm8pPEKhWaH1cxd19hhDfaKsiizQ y0gYj35p7j/gzLWcQjQvqe+1tuAZpwDQaQkTA3GskKWw+BfxjObLRsVBYBkzbPs8Ih 0uqUExqgkW6iH1sMtA/ChOdY0wbY6ujYqnmO36M6TESOquu/X7AmgpFv+rHtdS1oLB nPh52fGWKTWoGUjUGByDZ4Zr+PzWnEFCxCcT4q/Y8OdwaL/h5tigixl+g3aIMMgGmP Ae0IvjWTt2ia1oR2zygH3akWdsF3TH2z2W2lb/ydb4VNmxD3GI9Q6rpvQmJUAfeQ1i R0XfXiYFyeVKA== Date: Mon, 17 Feb 2025 18:53:34 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Subject: [PATCH v2 1/2] libcamera: pipeline: uvcvideo: Fix `ExposureTimeMode` control setup Message-ID: <20250217185327.306509-2-pobrn@protonmail.com> In-Reply-To: <20250217185327.306509-1-pobrn@protonmail.com> References: <20250217185327.306509-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 0ca59c9146b2b7a74c5c5e060aaa0739cd6a4529 MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" `ControlInfo(Span{...})` calls the incorrect constructor of `ControlInfo`. The intended constructor to be called is `ControlInfo(Span, ...)` however that is not called because a span of `const int32_t` is passed. Instead, the constructor `ControlInfo(const ControlValue &min, const ControlValue &max, ...)` will be called. Furthermore, since `values.back()` is used, only the last element of the array is actually populated. To fix this, convert the array to contain `ControlValue` objects and use a separate variable to keep track of which element is to be populated next. The available modes are saved for later so that the appropriate mode can be selected when the control is set. Fixes: bad8d591f8acfa ("libcamera: uvcvideo: Register ExposureTimeMode control") Signed-off-by: Barnabás Pőcze Reviewed-by: Kieran Bingham --- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 46 ++++++++++++-------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index dedcac89b..1f604b91e 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -58,6 +59,13 @@ public: Stream stream_; std::map> formats_; + std::bitset< + std::max(V4L2_EXPOSURE_AUTO, + std::max(V4L2_EXPOSURE_MANUAL, + std::max(V4L2_EXPOSURE_APERTURE_PRIORITY, + V4L2_EXPOSURE_SHUTTER_PRIORITY))) + 1 + > availableExposureModes_; + private: bool generateId(); @@ -725,25 +733,25 @@ void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info, * ExposureTimeModeManual = { V4L2_EXPOSURE_MANUAL, * V4L2_EXPOSURE_SHUTTER_PRIORITY } */ - std::array values{}; - - auto it = std::find_if(v4l2Values.begin(), v4l2Values.end(), - [&](const ControlValue &val) { - return (val.get() == V4L2_EXPOSURE_APERTURE_PRIORITY || - val.get() == V4L2_EXPOSURE_AUTO) ? true : false; - }); - if (it != v4l2Values.end()) - values.back() = static_cast(controls::ExposureTimeModeAuto); - - it = std::find_if(v4l2Values.begin(), v4l2Values.end(), - [&](const ControlValue &val) { - return (val.get() == V4L2_EXPOSURE_SHUTTER_PRIORITY || - val.get() == V4L2_EXPOSURE_MANUAL) ? true : false; - }); - if (it != v4l2Values.end()) - values.back() = static_cast(controls::ExposureTimeModeManual); - - info = ControlInfo{Span{values}, values[0]}; + for (const ControlValue &value : v4l2Values) { + auto x = value.get(); + if (0 <= x && static_cast(x) < availableExposureModes_.size()) + availableExposureModes_[x] = true; + } + + std::array values; + std::size_t count = 0; + + if (availableExposureModes_[V4L2_EXPOSURE_AUTO] || availableExposureModes_[V4L2_EXPOSURE_APERTURE_PRIORITY]) + values[count++] = controls::ExposureTimeModeAuto; + + if (availableExposureModes_[V4L2_EXPOSURE_MANUAL] || availableExposureModes_[V4L2_EXPOSURE_SHUTTER_PRIORITY]) + values[count++] = controls::ExposureTimeModeManual; + + if (count == 0) + return; + + info = ControlInfo{ Span{ values.data(), count }, values[0] }; break; } case V4L2_CID_EXPOSURE_ABSOLUTE: From patchwork Mon Feb 17 18:53:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22799 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 09CE3C3200 for ; Mon, 17 Feb 2025 18:53:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B348768688; Mon, 17 Feb 2025 19:53:45 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="QQYezlda"; dkim-atps=neutral Received: from mail-4316.protonmail.ch (mail-4316.protonmail.ch [185.70.43.16]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6FD3361865 for ; Mon, 17 Feb 2025 19:53:43 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1739818422; x=1740077622; bh=zHoIEDaDOGUvDYe/IV0z5ARBxOdRvW4cNCYionKzpz0=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=QQYezldaNwOGw996QkWJ9qBV7DRAUv4Bz4J+k5DS7Rf6WJpA1HqgSm3aiL17u13U6 1jWYqi+agm9Nmx/QQ6r3n1GMZ8hpob8n3hyOls/7rtoh7/51cZw9vs3d1TUO4JoY2P U5Df4zim/R4qhC69OhpIonSLQaRVAmOZ10K3+xf8w5pLWIYWHV7OKhcnKnVPFfd93V PQg1RxCLtoXKuhAhRHEZbY7qlGr39F7t53gOophHo8qxp5NkTRwR//Imdd9vCPXAbr Ml93v9kkAw5ZbVaEDfpUx5QPVtLtjguR3ymqfOqbl4gzY2NI1vlfA5wXgQHesKieGg jQmsnN2p/bKEg== Date: Mon, 17 Feb 2025 18:53:39 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Subject: [PATCH v2 2/2] libcamera: pipeline: uvcvideo: Fix `ExposureTimeMode` control setting Message-ID: <20250217185327.306509-3-pobrn@protonmail.com> In-Reply-To: <20250217185327.306509-1-pobrn@protonmail.com> References: <20250217185327.306509-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: e0315efea8086eee23569feb191d46dd17cf465b MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The mapping in `UVCCameraData::processControl()` is not entirely correct because the control value is retrieved as a `bool` instead of `int32_t`. Additionally, the available modes are not taken into account. To fix this, retrieve the control with the proper type - `int32_t` -, and use the available modes stored in `UVCCameraData` to determine which value to use for the V4L2 control. Fixes: bad8d591f8acfa ("libcamera: uvcvideo: Register ExposureTimeMode control") Signed-off-by: Barnabás Pőcze Reviewed-by: Jacopo Mondi --- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 38 +++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 1f604b91e..adab6aa18 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -103,8 +103,8 @@ public: bool match(DeviceEnumerator *enumerator) override; private: - int processControl(ControlList *controls, unsigned int id, - const ControlValue &value); + int processControl(UVCCameraData *data, ControlList *controls, + unsigned int id, const ControlValue &value); int processControls(UVCCameraData *data, Request *request); bool acquireDevice(Camera *camera) override; @@ -297,8 +297,8 @@ void PipelineHandlerUVC::stopDevice(Camera *camera) data->video_->releaseBuffers(); } -int PipelineHandlerUVC::processControl(ControlList *controls, unsigned int id, - const ControlValue &value) +int PipelineHandlerUVC::processControl(UVCCameraData *data, ControlList *controls, + unsigned int id, const ControlValue &value) { uint32_t cid; @@ -342,10 +342,30 @@ int PipelineHandlerUVC::processControl(ControlList *controls, unsigned int id, } case V4L2_CID_EXPOSURE_AUTO: { - int32_t ivalue = value.get() - ? V4L2_EXPOSURE_APERTURE_PRIORITY - : V4L2_EXPOSURE_MANUAL; - controls->set(V4L2_CID_EXPOSURE_AUTO, ivalue); + v4l2_exposure_auto_type exposureMode = {}; + + switch (value.get()) { + case controls::ExposureTimeModeAuto: + if (data->availableExposureModes_[V4L2_EXPOSURE_AUTO]) + exposureMode = V4L2_EXPOSURE_AUTO; + else if (data->availableExposureModes_[V4L2_EXPOSURE_APERTURE_PRIORITY]) + exposureMode = V4L2_EXPOSURE_APERTURE_PRIORITY; + else + ASSERT(false); + break; + case controls::ExposureTimeModeManual: + if (data->availableExposureModes_[V4L2_EXPOSURE_MANUAL]) + exposureMode = V4L2_EXPOSURE_MANUAL; + else if (data->availableExposureModes_[V4L2_EXPOSURE_SHUTTER_PRIORITY]) + exposureMode = V4L2_EXPOSURE_SHUTTER_PRIORITY; + else + ASSERT(false); + break; + default: + return -EINVAL; + } + + controls->set(V4L2_CID_EXPOSURE_AUTO, exposureMode); break; } @@ -383,7 +403,7 @@ int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request) ControlList controls(data->video_->controls()); for (const auto &[id, value] : request->controls()) - processControl(&controls, id, value); + processControl(data, &controls, id, value); for (const auto &ctrl : controls) LOG(UVC, Debug)