From patchwork Thu Sep 18 14:43:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 24405 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 3AE1DC32C2 for ; Thu, 18 Sep 2025 14:44:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9182169385; Thu, 18 Sep 2025 16:44:36 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Iqnj0R8u"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3134669385 for ; Thu, 18 Sep 2025 16:44:33 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:ace3:d2c2:5eff:9cc5]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 7BD2F15EE; Thu, 18 Sep 2025 16:43:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1758206593; bh=gi941HfRJagZuymHyqcptRQwT/eEd3sqBWkoTAKVsC4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Iqnj0R8ui5ogwUlr7F5pJsMjqNH7z0maeNF8INiVJIDvm5OpNwprO1mFddVa8AZz4 v8DgXopo2W1A+SXkkcaSmkXid3VW7XKtbzdXRlahZLqPqD+AgyLg+9jX+wsFvnZJ1s FctwCNyYkFQ2FOYKgNVbtWiNbmvWA9OTf/KGhIOI= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Paul Elder Subject: [PATCH v4 16/19] libipa: agc_mean_luminance: Add support for additional constraints Date: Thu, 18 Sep 2025 16:43:25 +0200 Message-ID: <20250918144333.108695-17-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250918144333.108695-1-stefan.klug@ideasonboard.com> References: <20250918144333.108695-1-stefan.klug@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 support for additional constraints added at runtime. This is for example useful for WDR use cases where you want to add an upper constraint to limit the amount of saturated pixels. Signed-off-by: Stefan Klug Reviewed-by: Paul Elder Reviewed-by: Kieran Bingham --- Changes in v4: - Added missings docs for the constraints parameter - Collected tag Changes in v3: - Added this patch --- src/ipa/ipu3/algorithms/agc.cpp | 2 +- src/ipa/libipa/agc_mean_luminance.cpp | 17 +++++++++++++---- src/ipa/libipa/agc_mean_luminance.h | 3 ++- src/ipa/mali-c55/algorithms/agc.cpp | 3 ++- src/ipa/rkisp1/algorithms/agc.cpp | 4 ++-- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index da045640d569..b0d89541da85 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -117,7 +117,7 @@ int Agc::configure(IPAContext &context, /* \todo Run this again when FrameDurationLimits is passed in */ setLimits(minExposureTime_, maxExposureTime_, minAnalogueGain_, - maxAnalogueGain_); + maxAnalogueGain_, {}); resetFrameCount(); return 0; diff --git a/src/ipa/libipa/agc_mean_luminance.cpp b/src/ipa/libipa/agc_mean_luminance.cpp index 45eba97516f3..64f36bd75dd2 100644 --- a/src/ipa/libipa/agc_mean_luminance.cpp +++ b/src/ipa/libipa/agc_mean_luminance.cpp @@ -7,6 +7,7 @@ #include "agc_mean_luminance.h" +#include #include #include @@ -408,16 +409,20 @@ int AgcMeanLuminance::parseTuningData(const YamlObject &tuningData) * \param[in] maxExposureTime Maximum ewposure time to allow * \param[in] minGain Minimum gain to allow * \param[in] maxGain Maximum gain to allow + * \param[in] constraints Additional constraints to apply * * This function calls \ref ExposureModeHelper::setLimits() for each * ExposureModeHelper that has been created for this class. */ void AgcMeanLuminance::setLimits(utils::Duration minExposureTime, utils::Duration maxExposureTime, - double minGain, double maxGain) + double minGain, double maxGain, + std::vector constraints) { for (auto &[id, helper] : exposureModeHelpers_) helper->setLimits(minExposureTime, maxExposureTime, minGain, maxGain); + + additionalConstraints_ = std::move(constraints); } /** @@ -495,8 +500,7 @@ double AgcMeanLuminance::constraintClampGain(uint32_t constraintModeIndex, const Histogram &hist, double gain) { - std::vector &constraints = constraintModes_[constraintModeIndex]; - for (const AgcConstraint &constraint : constraints) { + auto applyConstraint = [&gain, &hist](const AgcConstraint &constraint) { double newGain = constraint.yTarget * hist.bins() / hist.interQuantileMean(constraint.qLo, constraint.qHi); @@ -515,7 +519,12 @@ double AgcMeanLuminance::constraintClampGain(uint32_t constraintModeIndex, << newGain; gain = newGain; } - } + }; + + std::vector &constraints = constraintModes_[constraintModeIndex]; + std::for_each(constraints.begin(), constraints.end(), applyConstraint); + + std::for_each(additionalConstraints_.begin(), additionalConstraints_.end(), applyConstraint); return gain; } diff --git a/src/ipa/libipa/agc_mean_luminance.h b/src/ipa/libipa/agc_mean_luminance.h index 950b7b893754..d7ec548e3e58 100644 --- a/src/ipa/libipa/agc_mean_luminance.h +++ b/src/ipa/libipa/agc_mean_luminance.h @@ -51,7 +51,7 @@ public: } void setLimits(utils::Duration minExposureTime, utils::Duration maxExposureTime, - double minGain, double maxGain); + double minGain, double maxGain, std::vector constraints); std::map> constraintModes() { @@ -97,6 +97,7 @@ private: utils::Duration filteredExposure_; double relativeLuminanceTarget_; + std::vector additionalConstraints_; std::map> constraintModes_; std::map> exposureModeHelpers_; ControlInfoMap::Map controls_; diff --git a/src/ipa/mali-c55/algorithms/agc.cpp b/src/ipa/mali-c55/algorithms/agc.cpp index 88f8664c9823..f60fddac3f04 100644 --- a/src/ipa/mali-c55/algorithms/agc.cpp +++ b/src/ipa/mali-c55/algorithms/agc.cpp @@ -173,7 +173,8 @@ int Agc::configure(IPAContext &context, setLimits(context.configuration.agc.minShutterSpeed, context.configuration.agc.maxShutterSpeed, context.configuration.agc.minAnalogueGain, - context.configuration.agc.maxAnalogueGain); + context.configuration.agc.maxAnalogueGain, + {}); resetFrameCount(); diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp index d0337fd0027f..d1b6bb7196f4 100644 --- a/src/ipa/rkisp1/algorithms/agc.cpp +++ b/src/ipa/rkisp1/algorithms/agc.cpp @@ -206,7 +206,7 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo) setLimits(context.configuration.sensor.minExposureTime, context.configuration.sensor.maxExposureTime, context.configuration.sensor.minAnalogueGain, - context.configuration.sensor.maxAnalogueGain); + context.configuration.sensor.maxAnalogueGain, {}); resetFrameCount(); @@ -590,7 +590,7 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame, maxAnalogueGain = frameContext.agc.gain; } - setLimits(minExposureTime, maxExposureTime, minAnalogueGain, maxAnalogueGain); + setLimits(minExposureTime, maxExposureTime, minAnalogueGain, maxAnalogueGain, {}); /* * The Agc algorithm needs to know the effective exposure value that was