From patchwork Thu Oct 23 10:56:48 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Isaac Scott X-Patchwork-Id: 24722 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 DB9D4C32CE for ; Thu, 23 Oct 2025 10:57:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 64629607D5; Thu, 23 Oct 2025 12:57:06 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="TWS941Ht"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2CB4F607BC for ; Thu, 23 Oct 2025 12:57:04 +0200 (CEST) Received: from isaac-ThinkPad-T16-Gen-2.infra.iob (cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 57177591; Thu, 23 Oct 2025 12:55:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761216919; bh=yn7F384ag+1v3liHRDp6OQRFEvqPutdA8ucEtWoMLZI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TWS941HtrxBIVOwMDmyvr8PVuouTcz5r3LmSjHc3R7NR8tnVHPwNm4THa8gt6Qu0G lDIHh9IsyveEIQqCSVVhGk4LRlCJjTDGVIhRMtL4Ot7bThsX0zLkXpPZj8mUEu5jFJ wDHcA5SqAr4WmHpIyeC2o+unG2s+/vcWX/RwzlJE= From: Isaac Scott To: libcamera-devel@lists.libcamera.org Cc: Isaac Scott Subject: [PATCH 1/4] libcamera: v4l2: Support string control payloads Date: Thu, 23 Oct 2025 11:56:48 +0100 Message-ID: <20251023105651.78395-2-isaac.scott@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251023105651.78395-1-isaac.scott@ideasonboard.com> References: <20251023105651.78395-1-isaac.scott@ideasonboard.com> 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" v4l2 controls can be configured to store a string. This is stored in the v4l2_ctrl_ext when the union within it points to a string as its payload. This can be read similarly to int control payloadsm instead using the maximum length of the string, represented by info.maximum. This pointer can then be reinterpreted as a char *. N.B. It is possible that if the string is less than the maximum length, the data after the string is populated with garbage. This isn't a problem when using the string later, as the std::string will only use up to the null character in the string. Signed-off-by: Isaac Scott --- include/libcamera/controls.h | 3 ++- src/libcamera/controls.cpp | 11 ++++++++--- src/libcamera/v4l2_device.cpp | 28 ++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index c970e4b7b..59b666f16 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -201,7 +201,8 @@ public: T get() const { assert(type_ == details::control_type>::value); - assert(isArray_); + if (type_ != ControlTypeString) + assert(isArray_); using V = typename T::value_type; const V *value = reinterpret_cast(data().data()); diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 1e1b49e6b..f82c4f777 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -276,8 +276,12 @@ std::string ControlValue::toString() const str += value->toString(); break; } + case ControlTypeString: { + const std::string *value = reinterpret_cast(data); + str += *value; + break; + } case ControlTypeNone: - case ControlTypeString: break; } @@ -353,7 +357,8 @@ bool ControlValue::operator==(const ControlValue &other) const void ControlValue::set(ControlType type, bool isArray, const void *data, std::size_t numElements, std::size_t elementSize) { - ASSERT(elementSize == ControlValueSize[type]); + if (type != ControlTypeString) + ASSERT(elementSize == ControlValueSize[type]); reserve(type, isArray, numElements); @@ -375,7 +380,7 @@ void ControlValue::set(ControlType type, bool isArray, const void *data, */ void ControlValue::reserve(ControlType type, bool isArray, std::size_t numElements) { - if (!isArray) + if (!isArray && type != ControlTypeString) numElements = 1; std::size_t oldSize = numElements_ * ControlValueSize[type_]; diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 8c78b8c42..641ea4981 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,8 @@ #include "libcamera/internal/formats.h" #include "libcamera/internal/sysfs.h" +#include "libcamera/controls.h" +#include "linux/videodev2.h" /** * \file v4l2_device.h @@ -230,6 +233,13 @@ ControlList V4L2Device::getControls(Span ids) v4l2Ctrl.p_u32 = reinterpret_cast(data.data()); break; + case V4L2_CTRL_TYPE_STRING: + type = ControlTypeString; + value.reserve(type, false, info.maximum + 1); + data = value.data(); + v4l2Ctrl.string = reinterpret_cast(data.data()); + break; + default: LOG(V4L2, Error) << "Unsupported payload control type " @@ -570,6 +580,8 @@ ControlType V4L2Device::v4l2CtrlType(uint32_t ctrlType) * integer type. */ return ControlTypeInteger32; + case V4L2_CTRL_TYPE_STRING: + return ControlTypeString; default: return ControlTypeNone; @@ -709,6 +721,7 @@ void V4L2Device::listControls() case V4L2_CTRL_TYPE_U8: case V4L2_CTRL_TYPE_U16: case V4L2_CTRL_TYPE_U32: + case V4L2_CTRL_TYPE_STRING: break; /* \todo Support other control types. */ default: @@ -808,6 +821,21 @@ void V4L2Device::updateControls(ControlList *ctrls, value.set(v4l2Ctrl.value64); break; + case ControlTypeString: + /* + * The ControlValue contains storage for the maximum + * length of the string, and its size matches that. After + * the data is retrieved, it must be resized so ControlValue::numElements() + * is correct. + * + * VIDIOC_G_EXT_CTRLS does not return the length of the string, + * so we must reassign and let the std::string_view constructor + * calculate the true length. Because value is a copy, there will be + * no use-after-free issues. + */ + value.set(v4l2Ctrl.string); + break; + default: /* * Note: this catches the ControlTypeInteger32 case. From patchwork Thu Oct 23 10:56:49 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Isaac Scott X-Patchwork-Id: 24723 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 2B788C3331 for ; Thu, 23 Oct 2025 10:57:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0DFDB607DD; Thu, 23 Oct 2025 12:57:09 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="uHcool1f"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2358F607B3 for ; Thu, 23 Oct 2025 12:57:05 +0200 (CEST) Received: from isaac-ThinkPad-T16-Gen-2.infra.iob (cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 32D77591; Thu, 23 Oct 2025 12:55:20 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761216920; bh=ZT1EbruWzhvbayV7rJvu0dBT8JZzRGSCkee99VVXE7c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uHcool1fG/oo10GjCpkZByzum5WgJIhLJ9OY7XkyCT3Lk8i/58hQqOvm2UvpAYnWL Y/uGZp2WEUKQtfn0QQAusTfGTJoQqxdYbiPPtnU39MauPkkud6tbvzTMfvs2rgnEzU zP0xW6d7T8vhMWcUzVyYG8goZSFAzPNfU4PUH9fc= From: Isaac Scott To: libcamera-devel@lists.libcamera.org Cc: Isaac Scott Subject: [PATCH 2/4] libcamera: controls: Add CAMERA_MODULE_IDENTIFIER Date: Thu, 23 Oct 2025 11:56:49 +0100 Message-ID: <20251023105651.78395-3-isaac.scott@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251023105651.78395-1-isaac.scott@ideasonboard.com> References: <20251023105651.78395-1-isaac.scott@ideasonboard.com> 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" Add a string control, and the necessary V4L2_CID to support a read-only string payload. This can be used to store a string identifying a variant of a camera sensor (more accurately, a unique module including that camera sensor). The addition to v4l2-controls.h to add V4L2_CID_CAMERA_MODULE_IDENTIFIER has been posted upstream here: https://lore.kernel.org/linux-media/aPi9c_c9f0dkduLA@kekkonen.localdomain/ Signed-off-by: Isaac Scott --- include/linux/v4l2-controls.h | 2 ++ src/libcamera/property_ids_core.yaml | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/include/linux/v4l2-controls.h b/include/linux/v4l2-controls.h index 4cfae0414..b96142c46 100644 --- a/include/linux/v4l2-controls.h +++ b/include/linux/v4l2-controls.h @@ -1095,6 +1095,8 @@ enum v4l2_auto_focus_range { #define V4L2_CID_HDR_SENSOR_MODE (V4L2_CID_CAMERA_CLASS_BASE+36) +#define V4L2_CID_CAMERA_MODULE_IDENTIFIER (V4L2_CID_CAMERA_CLASS_BASE+37) + /* FM Modulator class control IDs */ #define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900) diff --git a/src/libcamera/property_ids_core.yaml b/src/libcamera/property_ids_core.yaml index 834454a4e..5f47a4ea7 100644 --- a/src/libcamera/property_ids_core.yaml +++ b/src/libcamera/property_ids_core.yaml @@ -701,4 +701,12 @@ controls: Different cameras may report identical devices. + - CameraModuleIdentifier: + type: string + description: | + Specify the camera module identifier. + + The camera module identifier is a string that uniquely identifies the + camera module. It is used to select the appropriate tuning file for + the camera device. ...