From patchwork Fri Oct 25 15:38:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harvey Yang X-Patchwork-Id: 21756 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 E105BC32A2 for ; Fri, 25 Oct 2024 15:40:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4BF53653A8; Fri, 25 Oct 2024 17:40:02 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="J3CB0Q36"; dkim-atps=neutral Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5080E65397 for ; Fri, 25 Oct 2024 17:39:58 +0200 (CEST) Received: by mail-pj1-x1029.google.com with SMTP id 98e67ed59e1d1-2e2ed59a35eso1729373a91.0 for ; Fri, 25 Oct 2024 08:39:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1729870796; x=1730475596; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Pt92kP2Ie3C+gJduz5FMI/shV0fW2ONlgtJr1apTuUs=; b=J3CB0Q365C+XsMytUBdruiH/jKXG0yudekxNhPEuiLuLqdCs9/tAoNFjy/1MKswNg4 YzXIv245tN5pfaBocFAfGXGCchyg1XzaeGlwBXqYIPOovckU6e7621PNAwoEoZM+jCKk HV9ZEbM+gvKK3eKz5V/jwpLloLjR1LSIDjC4E= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1729870796; x=1730475596; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Pt92kP2Ie3C+gJduz5FMI/shV0fW2ONlgtJr1apTuUs=; b=QqZjhUlW4PV6b+d2Qzi5X56Iaek4Mctwlwm7zyUrxVnknZCaaHfvUE9FyiUBD1h9ul vORr4LkeEDKyI435EGRY4spiOHi1CK3dLSy8+0wczukLgrod45iDW+2HxcQMewHeYNvU hJSmZCNYwd8Jjkvwv6K8PY2Dv7SI/KCDHy4KjDMjjxCpLFU57v8j/D0qWw0KVie+ugle MojmgWt7Hlpsb529oZc4tcx2z9ywycBUxRwK8C/uj9+Oc9kbDwc2YaBi58LUqjhcqwCb sYKU1cViz5zNbgJiK2t6qeRQMtuELpBP3kc6K7Z1WzqRhAv5kH0Msi3wo5PR2SnrGcS/ Kzpg== X-Gm-Message-State: AOJu0Ywz4uSGR34g4+KdZXwTmFQu1gBLDAurS/u0xDRTneG1Tgdao/Oj 4TGoTJ4tqB19ikUDdi0aBK52nzUTpIkbVJMwBT0gp9mQ13GvBa6Xv43VFBVDcQaTPPhq7J2iF14 = X-Google-Smtp-Source: AGHT+IF7guMrG5Bb44d6rCTPm+gannVAph9ZmKujySvzDMgNypCJqds05XNhDRjcDisRKDHF8m5BuA== X-Received: by 2002:a17:90b:17cf:b0:2e2:cc47:f1b0 with SMTP id 98e67ed59e1d1-2e77f321aa7mr7098580a91.3.1729870796473; Fri, 25 Oct 2024 08:39:56 -0700 (PDT) Received: from chenghaoyang-low.c.googlers.com.com (199.211.81.34.bc.googleusercontent.com. [34.81.211.199]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2e8e3555e09sm1612815a91.12.2024.10.25.08.39.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Oct 2024 08:39:56 -0700 (PDT) From: Harvey Yang To: libcamera-devel@lists.libcamera.org Cc: Yudhistira Erlandinata , Harvey Yang Subject: [PATCH v4 2/2] libcamera: Extend u16 control type Date: Fri, 25 Oct 2024 15:38:51 +0000 Message-ID: <20241025153948.1213629-3-chenghaoyang@chromium.org> X-Mailer: git-send-email 2.47.0.163.g1226f6d8fa-goog In-Reply-To: <20241025153948.1213629-1-chenghaoyang@chromium.org> References: <20241025153948.1213629-1-chenghaoyang@chromium.org> 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" From: Yudhistira Erlandinata V4L2 Controls support a wide variety of types not yet supported by the ControlValue type system. Extend the libcamera ControlValue types to support an explicit 16 bit unsigned integer type, and map that to the corresponding V4L2_CTRL_TYPE_U16 type within the v4l2_device support class. It's used on some camera metadata that is of length 16-bits, for example JPEG metadata headers. Signed-off-by: Yudhistira Erlandinata Co-developed-by: Harvey Yang Signed-off-by: Harvey Yang --- include/libcamera/controls.h | 7 ++++++ src/libcamera/controls.cpp | 8 +++++++ src/libcamera/v4l2_device.cpp | 13 +++++++++++ test/controls/control_value.cpp | 40 +++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 6da8ad2c3..162115bb5 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -29,6 +29,7 @@ enum ControlType { ControlTypeNone, ControlTypeBool, ControlTypeByte, + ControlTypeUnsigned16, ControlTypeUnsigned32, ControlTypeInteger32, ControlTypeInteger64, @@ -63,6 +64,12 @@ struct control_type { static constexpr std::size_t size = 0; }; +template<> +struct control_type { + static constexpr ControlType value = ControlTypeUnsigned16; + static constexpr std::size_t size = 0; +}; + template<> struct control_type { static constexpr ControlType value = ControlTypeUnsigned32; diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 8ae295191..3a840bb22 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -54,6 +54,7 @@ static constexpr size_t ControlValueSize[] = { [ControlTypeNone] = 0, [ControlTypeBool] = sizeof(bool), [ControlTypeByte] = sizeof(uint8_t), + [ControlTypeUnsigned16] = sizeof(uint16_t), [ControlTypeUnsigned32] = sizeof(uint32_t), [ControlTypeInteger32] = sizeof(int32_t), [ControlTypeInteger64] = sizeof(int64_t), @@ -75,6 +76,8 @@ static constexpr size_t ControlValueSize[] = { * The control stores a boolean value * \var ControlTypeByte * The control stores a byte value as an unsigned 8-bit integer + * \var ControlTypeUnsigned16 + * The control stores an unsigned 16-bit integer value * \var ControlTypeUnsigned32 * The control stores an unsigned 32-bit integer value * \var ControlTypeInteger32 @@ -233,6 +236,11 @@ std::string ControlValue::toString() const str += std::to_string(*value); break; } + case ControlTypeUnsigned16: { + const uint16_t *value = reinterpret_cast(data); + str += std::to_string(*value); + break; + } case ControlTypeUnsigned32: { const uint32_t *value = reinterpret_cast(data); str += std::to_string(*value); diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index f39ec3760..f6708dadd 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -211,6 +211,10 @@ ControlList V4L2Device::getControls(const std::vector &ids) type = ControlTypeByte; break; + case V4L2_CTRL_TYPE_U16: + type = ControlTypeUnsigned16; + break; + case V4L2_CTRL_TYPE_U32: type = ControlTypeUnsigned32; break; @@ -493,6 +497,9 @@ ControlType V4L2Device::v4l2CtrlType(uint32_t ctrlType) case V4L2_CTRL_TYPE_BOOLEAN: return ControlTypeBool; + case V4L2_CTRL_TYPE_U16: + return ControlTypeUnsigned16; + case V4L2_CTRL_TYPE_U32: return ControlTypeUnsigned32; @@ -544,6 +551,11 @@ std::optional V4L2Device::v4l2ControlInfo(const v4l2_query_ext_ctrl static_cast(ctrl.maximum), static_cast(ctrl.default_value)); + case V4L2_CTRL_TYPE_U16: + return ControlInfo(static_cast(ctrl.minimum), + static_cast(ctrl.maximum), + static_cast(ctrl.default_value)); + case V4L2_CTRL_TYPE_U32: return ControlInfo(static_cast(ctrl.minimum), static_cast(ctrl.maximum), @@ -635,6 +647,7 @@ void V4L2Device::listControls() case V4L2_CTRL_TYPE_BITMASK: case V4L2_CTRL_TYPE_INTEGER_MENU: case V4L2_CTRL_TYPE_U8: + case V4L2_CTRL_TYPE_U16: case V4L2_CTRL_TYPE_U32: break; /* \todo Support other control types. */ diff --git a/test/controls/control_value.cpp b/test/controls/control_value.cpp index 6ca85b739..5084fd0cf 100644 --- a/test/controls/control_value.cpp +++ b/test/controls/control_value.cpp @@ -109,6 +109,46 @@ protected: return TestFail; } + /* + * Unsigned Integer16 type. + */ + value.set(static_cast(42)); + if (value.isNone() || value.isArray() || + value.type() != ControlTypeUnsigned16) { + cerr << "Control type mismatch after setting to uint16_t" << endl; + return TestFail; + } + + if (value.get() != 42) { + cerr << "Control value mismatch after setting to uint16_t" << endl; + return TestFail; + } + + if (value.toString() != "42") { + cerr << "Control string mismatch after setting to uint16_t" << endl; + return TestFail; + } + + std::array uint16s{ 3, 14, 15, 9 }; + value.set(Span(uint16s)); + if (value.isNone() || !value.isArray() || + value.type() != ControlTypeUnsigned16) { + cerr << "Control type mismatch after setting to uint16_t array" << endl; + return TestFail; + } + + Span uint16sResult = value.get>(); + if (uint16s.size() != uint16sResult.size() || + !std::equal(uint16s.begin(), uint16s.end(), uint16sResult.begin())) { + cerr << "Control value mismatch after setting to uint16_t array" << endl; + return TestFail; + } + + if (value.toString() != "[ 3, 14, 15, 9 ]") { + cerr << "Control string mismatch after setting to uint16_t array" << endl; + return TestFail; + } + /* * Unsigned Integer32 type. */