From patchwork Wed Sep 10 09:35:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 24300 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 977B3BDB13 for ; Wed, 10 Sep 2025 09:35:55 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A576C69371; Wed, 10 Sep 2025 11:35:54 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="P7puctDu"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B3FE5613A5 for ; Wed, 10 Sep 2025 11:35:50 +0200 (CEST) Received: from neptunite.hamster-moth.ts.net (unknown [IPv6:2404:7a81:160:2100:e06d:abb0:39cf:8f3a]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id F1FBFE1F; Wed, 10 Sep 2025 11:34:35 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1757496877; bh=m6bI58WwhtOUg1WlCbhv4VbF5TIeUYVhy8tK5tEpm/M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=P7puctDud4FGeTIsLwBB5HTdDFtnRaQHxRo9R9RBo6zxxi4E7er7hrMCLPIT9PgCf kf1rnlmhMKd5V2Fiqd0tzjbagy7MqhKPoC8Eglhmjq30YGpJ13CLgfUeK3Ln5lrXOA VdOq0/rmIJPKEg4hNyaKbGrCK1/sT/cJZSPgOJ60= From: Paul Elder To: libcamera-devel@lists.libcamera.org Cc: Paul Elder Subject: [PATCH 1/2] libcamera: control_serializer: Deserialize array ControlInfos Date: Wed, 10 Sep 2025 18:35:18 +0900 Message-ID: <20250910093539.3216782-2-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250910093539.3216782-1-paul.elder@ideasonboard.com> References: <20250910093539.3216782-1-paul.elder@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" Array controls (eg. ColourCorrectionMatrix, FrameDurationLimits, ColourGains) are serialized properly by the ControlSerializer, but are not deserialized properly. This is because their arrayness and size are not considered during deserialization. Fix this by checking arrayness and size of the ControlInfo's default value during deserialization of ControlInfoMap. Only the default value needs to be checked as that is the only part of the ControlInfo that will be non-scalar; min/max are defined to be scalar values. This was not noticed before as the default value of the ControlInfo of other array controls had been set to scalar values similar to min/max, and ColourCorrectionMatrix was the first control to properly define a non-scalar default value. Other array controls that define a scalar default value need to be fixed to define a properly sized default ControlInfo value. Bug: https://bugs.libcamera.org/show_bug.cgi?id=285 Signed-off-by: Paul Elder --- include/libcamera/internal/control_serializer.h | 3 ++- src/libcamera/control_serializer.cpp | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/libcamera/internal/control_serializer.h b/include/libcamera/internal/control_serializer.h index 8a63ae44a13e..79d6eff2a940 100644 --- a/include/libcamera/internal/control_serializer.h +++ b/include/libcamera/internal/control_serializer.h @@ -49,7 +49,8 @@ private: ControlValue loadControlValue(ByteStreamBuffer &buffer, bool isArray = false, unsigned int count = 1); - ControlInfo loadControlInfo(ByteStreamBuffer &buffer); + ControlInfo loadControlInfo(ByteStreamBuffer &buffer, + bool isArray, unsigned int count); unsigned int serial_; unsigned int serialSeed_; diff --git a/src/libcamera/control_serializer.cpp b/src/libcamera/control_serializer.cpp index 050f8512bd52..db3ddaaa2e78 100644 --- a/src/libcamera/control_serializer.cpp +++ b/src/libcamera/control_serializer.cpp @@ -397,11 +397,14 @@ ControlValue ControlSerializer::loadControlValue(ByteStreamBuffer &buffer, return value; } -ControlInfo ControlSerializer::loadControlInfo(ByteStreamBuffer &b) +ControlInfo ControlSerializer::loadControlInfo(ByteStreamBuffer &b, + bool isArray, + unsigned int count) { + /* min and max are scalars */ ControlValue min = loadControlValue(b); ControlValue max = loadControlValue(b); - ControlValue def = loadControlValue(b); + ControlValue def = loadControlValue(b, isArray, count); return ControlInfo(min, max, def); } @@ -519,7 +522,7 @@ ControlInfoMap ControlSerializer::deserialize(ByteStreamBuffer & } /* Create and store the ControlInfo. */ - ctrls.emplace(controlId, loadControlInfo(values)); + ctrls.emplace(controlId, loadControlInfo(values, controlId->isArray(), controlId->size())); } /* From patchwork Wed Sep 10 09:35:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 24301 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 CC46ABDB13 for ; Wed, 10 Sep 2025 09:35:57 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 38B7F69373; Wed, 10 Sep 2025 11:35:57 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="iW86BMI7"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 107BB6936D for ; Wed, 10 Sep 2025 11:35:53 +0200 (CEST) Received: from neptunite.hamster-moth.ts.net (unknown [IPv6:2404:7a81:160:2100:e06d:abb0:39cf:8f3a]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 5728A13BE; Wed, 10 Sep 2025 11:34:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1757496879; bh=I8w60WaPrlPNbQXQzr32O6HN3oKRmGIoRX/bP5evqqg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iW86BMI7uCs+l4QCiJ5JMy86kDVf85u3SGwSpkWvQs5O7clec/p/rF7b6tffEibQv ENdAJcgNY6UEpiBrwg4Qh6lEfsuoKJZuc2O42MKN/Q/SqYfTEL6/DCRQaetp0u2tn+ ezBaCiOePbvBxYCLIjYe8fD0v0rdeYgRRHe25TgU= From: Paul Elder To: libcamera-devel@lists.libcamera.org Cc: Paul Elder Subject: [PATCH 2/2] ipa: ipu3, mali-c55, rkisp1, rpi: Fix reporting non-scalar controls Date: Wed, 10 Sep 2025 18:35:19 +0900 Message-ID: <20250910093539.3216782-3-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250910093539.3216782-1-paul.elder@ideasonboard.com> References: <20250910093539.3216782-1-paul.elder@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" The ControlInfos of non-scalar controls that are reported in controls() must have scalar min/max and non-scalar default values for controls that have a defined size. Currently this is relevant to the following controls: - ColourGains - ColourCorrectionMatrix - FrameDurationLimits A mismatch of scalarness in these fields causes deserialization errors in ControlSerializer which manifest when IPAs are run in isolation. Fix the scalarness of these controls where relevant. Signed-off-by: Paul Elder --- src/ipa/ipu3/ipu3.cpp | 4 +++- src/ipa/mali-c55/mali-c55.cpp | 5 ++++- src/ipa/rkisp1/algorithms/awb.cpp | 5 ++++- src/ipa/rkisp1/rkisp1.cpp | 4 +++- src/ipa/rpi/common/ipa_base.cpp | 7 ++++++- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 1cae08bf255f..e71639a16522 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -280,10 +281,11 @@ void IPAIPU3::updateControls(const IPACameraSensorInfo &sensorInfo, uint64_t frameSize = lineLength * frameHeights[i]; frameDurations[i] = frameSize / (sensorInfo.pixelRate / 1000000U); } + std::array defFrameDurations = { frameDurations[2], frameDurations[2] }; controls[&controls::FrameDurationLimits] = ControlInfo(frameDurations[0], frameDurations[1], - frameDurations[2]); + Span{ defFrameDurations }); controls.merge(context_.ctrlMap); *ipaControls = ControlInfoMap(std::move(controls), controls::controls); diff --git a/src/ipa/mali-c55/mali-c55.cpp b/src/ipa/mali-c55/mali-c55.cpp index 7d45e7310aec..c63d3b2bb7be 100644 --- a/src/ipa/mali-c55/mali-c55.cpp +++ b/src/ipa/mali-c55/mali-c55.cpp @@ -5,6 +5,7 @@ * Mali-C55 ISP image processing algorithms */ +#include #include #include #include @@ -14,6 +15,7 @@ #include #include +#include #include #include @@ -234,9 +236,10 @@ void IPAMaliC55::updateControls(const IPACameraSensorInfo &sensorInfo, frameDurations[i] = frameSize / (sensorInfo.pixelRate / 1000000U); } + std::array defFrameDurations = { frameDurations[2], frameDurations[2] }; ctrlMap[&controls::FrameDurationLimits] = ControlInfo(frameDurations[0], frameDurations[1], - frameDurations[2]); + Span{ defFrameDurations }); /* * Compute exposure time limits from the V4L2_CID_EXPOSURE control diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp index 399fb51be414..a664011a9f0d 100644 --- a/src/ipa/rkisp1/algorithms/awb.cpp +++ b/src/ipa/rkisp1/algorithms/awb.cpp @@ -91,7 +91,10 @@ int Awb::init(IPAContext &context, const YamlObject &tuningData) kMaxColourTemperature, kDefaultColourTemperature); cmap[&controls::AwbEnable] = ControlInfo(false, true); - cmap[&controls::ColourGains] = ControlInfo(0.0f, 3.996f, 1.0f); + + std::array defColourGains = { 1.0f, 1.0f }; + cmap[&controls::ColourGains] = ControlInfo(0.0f, 3.996f, + Span{ defColourGains }); if (!tuningData.contains("algorithm")) LOG(RkISP1Awb, Info) << "No AWB algorithm specified." diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index cf66d5553dcd..6eb3ae9c6310 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -430,10 +430,12 @@ void IPARkISP1::updateControls(const IPACameraSensorInfo &sensorInfo, uint64_t frameSize = lineLength * frameHeights[i]; frameDurations[i] = frameSize / (sensorInfo.pixelRate / 1000000U); } + std::array defFrameDurations = { frameDurations[2], frameDurations[2] }; /* \todo Move this (and other agc-related controls) to agc */ context_.ctrlMap[&controls::FrameDurationLimits] = - ControlInfo(frameDurations[0], frameDurations[1], frameDurations[2]); + ControlInfo(frameDurations[0], frameDurations[1], + ControlValue(Span{ defFrameDurations })); ctrlMap.insert(context_.ctrlMap.begin(), context_.ctrlMap.end()); *ipaControls = ControlInfoMap(std::move(ctrlMap), controls::controls); diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp index 6448e6abd735..e34e890f0bdc 100644 --- a/src/ipa/rpi/common/ipa_base.cpp +++ b/src/ipa/rpi/common/ipa_base.cpp @@ -7,6 +7,7 @@ #include "ipa_base.h" +#include #include #include @@ -243,10 +244,14 @@ int32_t IpaBase::configure(const IPACameraSensorInfo &sensorInfo, const ConfigPa * based on the current sensor mode. */ ControlInfoMap::Map ctrlMap = ipaControls; + std::array defFrameDurations = { + static_cast(defaultMinFrameDuration.get()), + static_cast(defaultMinFrameDuration.get()) + }; ctrlMap[&controls::FrameDurationLimits] = ControlInfo(static_cast(mode_.minFrameDuration.get()), static_cast(mode_.maxFrameDuration.get()), - static_cast(defaultMinFrameDuration.get())); + Span{ defFrameDurations }); ctrlMap[&controls::AnalogueGain] = ControlInfo(static_cast(mode_.minAnalogueGain),