From patchwork Wed Aug 5 16:12:48 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 27629 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 E1E8CC3339 for ; Wed, 5 Aug 2026 16:13:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3F0B16814A; Wed, 5 Aug 2026 18:13:33 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="HHiRpgzA"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9704A68117 for ; Wed, 5 Aug 2026 18:13:28 +0200 (CEST) Received: from [192.168.125.177] (mob-109-113-25-35.net.vodafone.it [109.113.25.35]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B3FE95B3; Wed, 5 Aug 2026 18:12:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1785946338; bh=PZjf6FQi9gCzmouGinDVKkg+erELkT3B1ZUh0u8Sa2k=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=HHiRpgzA7vjuk3uxPHcMC4FWMgpjy9sshtSlaDWeSqH7ZCKgFHXLTGsjl/a+59DxS tWmIsyBUSo9/1eQxijnu0nqVVegW9vjxP3Py4TJkha674YzA8/H8E8dV2japqOaFUj ks2qYKjvVSZCYT4T0gsjMQCF82G0H4xqbjLzk60Q= From: Jacopo Mondi Date: Wed, 05 Aug 2026 18:12:48 +0200 Subject: [PATCH v7 06/32] ipa: simple: Port to use libipa CcmAlgorithm MIME-Version: 1.0 Message-Id: <20260805-libipa-algorithms-v7-6-7425b5b795d4@ideasonboard.com> References: <20260805-libipa-algorithms-v7-0-7425b5b795d4@ideasonboard.com> In-Reply-To: <20260805-libipa-algorithms-v7-0-7425b5b795d4@ideasonboard.com> To: libcamera-devel@lists.libcamera.org, Stefan Klug , Milan Zamazal Cc: Jacopo Mondi , Kieran Bingham , Robert Mader X-Mailer: b4 0.16-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=6404; i=jacopo.mondi@ideasonboard.com; h=from:subject:message-id; bh=f2e+ElLswiS5th0nFoFYfobTzlHF8UV7oPYZ1lTpAwc=; b=owEBbQKS/ZANAwAKAXI0Bo8WoVY8AcsmYgBqc2EaIBwwUDj/01wfuOYEaZURTkjtrWr5h/yHt PHTjCo+1aiJAjMEAAEKAB0WIQS1xD1IgJogio9YOMByNAaPFqFWPAUCanNhGgAKCRByNAaPFqFW PFXcD/0ZVychiS8FrKcYWCUcobUDbYQi5wK6R6LNL4AYsbpxoMW+XcqzELcF3DX9kp/roLcYVTs VX41FA98dIpzFhlHnoSLWsrb6KblMdQ37WOEt6HWI1kjS44AtE7W84wGyqgNlJSDIJB3wxF4rBM koglMCwqHIladAZfcqKOaLGBjQpPLxUSbgys6T9GrJ6fvSKlCo8LqxL5NDswaU7PwK0E+boqUft lzhx7MUMGjsY81f8+7JCyjcoR1/CEJsXQjaxIadJGQPzi+Ai2EyU0+vF14vQ3/Nv8yq4GMtKQVg ZeEZQQzlVBbzDnecmzxKsMqHigzrFNvH1rRCDM+H6UzGIeixlbMjXQJ2Sotikd7oQMgYsdfpn2W zW+uxpppSM1/vXC7r6zYpXToSAgkH5P1yG655Qo1PJODleGXJgXPQYGP5CQ0zEO1Is+pl3f+bd4 0yre0FSD8ZYOvJ9aWC4oLoj+mBb6ouTq3IL3ZQUgPqrE7AahuDFYRTLGfGtQIYTg+YhRsjaeFiL gzGDUjy1f5p58J0QWJ2Yco18CnVOgPjhFZr3XrS8v/FExZ/IcByb5Mr9cfZXIAq1j26YRe4ZDfO keayTm8DOur4HtXyYpAE0QXbVnsINuInv3g44UHS6RArbSZT6DQr3pyRVrrpboKrWt2AqgONGig JjIxulFO712U6NA== X-Developer-Key: i=jacopo.mondi@ideasonboard.com; a=openpgp; fpr=72392EDC88144A65C701EA9BA5826A2587AD026B 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: Kieran Bingham Now that libipa provides a common CCM algorithm implementation, replace the custom handling with the common Ccm. Signed-off-by: Kieran Bingham Signed-off-by: Jacopo Mondi Tested-by: Robert Mader Reviewed-by: Milan Zamazal Tested-by: Milan Zamazal --- v5->v6: - Remove a few [[maybe_unused]] - Add Milan's tag - Reword title to match other patches in the series --- src/ipa/simple/algorithms/ccm.cpp | 74 ++++++++++++++++++++++----------------- src/ipa/simple/algorithms/ccm.h | 22 +++++++----- src/ipa/simple/ipa_context.h | 5 +-- 3 files changed, 58 insertions(+), 43 deletions(-) diff --git a/src/ipa/simple/algorithms/ccm.cpp b/src/ipa/simple/algorithms/ccm.cpp index 1174784edc7e..8b6da543a719 100644 --- a/src/ipa/simple/algorithms/ccm.cpp +++ b/src/ipa/simple/algorithms/ccm.cpp @@ -8,54 +8,64 @@ #include "ccm.h" -#include -#include - -#include - #include "libcamera/internal/matrix.h" -namespace { - -constexpr unsigned int kTemperatureThreshold = 100; - -} - namespace libcamera { namespace ipa::soft::algorithms { LOG_DEFINE_CATEGORY(IPASoftCcm) -int Ccm::init([[maybe_unused]] IPAContext &context, const ValueNode &tuningData) +/** + * \copydoc libcamera::ipa::Algorithm::init + */ +int Ccm::init(IPAContext &context, const ValueNode &tuningData) { - int ret = ccm_.readYaml(tuningData["ccms"], "ct", "ccm"); - if (ret < 0) { - LOG(IPASoftCcm, Error) - << "Failed to parse 'ccm' parameter from tuning file."; - return ret; - } - + /* Informs the 'adjust' component that CCM is available to apply Saturation */ context.ccmEnabled = true; - return 0; + return ccmAlgo_.init(tuningData, context.ctrlMap); } -void Ccm::prepare(IPAContext &context, [[maybe_unused]] const uint32_t frame, - IPAFrameContext &frameContext, [[maybe_unused]] DebayerParams *params) +/** + * \copydoc libcamera::ipa::Algorithm::configure + */ +int Ccm::configure(IPAContext &context, + [[maybe_unused]] const IPAConfigInfo &configInfo) +{ + return ccmAlgo_.configure(context.activeState.ccm, + context.activeState.awb.automatic.colourTemperature); +} + +/** + * \copydoc libcamera::ipa::Algorithm::queueRequest + */ +void Ccm::queueRequest(IPAContext &context, + [[maybe_unused]] const uint32_t frame, + IPAFrameContext &frameContext, + const ControlList &controls) { - const unsigned int ct = frameContext.awb.colourTemperature; + /* Nothing to do here, the ccm will be calculated in prepare() */ + if (frameContext.awb.autoEnabled) + return; - /* Change CCM only on bigger temperature changes. */ - if (!currentCcm_ || - utils::abs_diff(ct, lastCt_) >= kTemperatureThreshold) { - currentCcm_ = ccm_.getInterpolated(ct); - lastCt_ = ct; - } + ccmAlgo_.queueRequest(context.activeState.ccm, frameContext.ccm, controls); +} +void Ccm::prepare(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, [[maybe_unused]] DebayerParams *params) +{ + if (frameContext.awb.autoEnabled) + ccmAlgo_.prepare(context.activeState.ccm, frameContext.ccm, + frame, frameContext.awb.colourTemperature); + + /* + * \todo: Split out combined matrix into individual parameters in + * DebayerParams and perform any pre-multiplication combination in the + * SoftISP component directly. + */ context.activeState.combinedMatrix = - currentCcm_.value() * context.activeState.combinedMatrix; - frameContext.ccm = currentCcm_.value(); + frameContext.ccm.ccm * context.activeState.combinedMatrix; } void Ccm::process([[maybe_unused]] IPAContext &context, @@ -64,7 +74,7 @@ void Ccm::process([[maybe_unused]] IPAContext &context, [[maybe_unused]] const SwIspStats *stats, ControlList &metadata) { - metadata.set(controls::ColourCorrectionMatrix, frameContext.ccm.data()); + ccmAlgo_.process(frameContext.ccm, metadata); } REGISTER_IPA_ALGORITHM(Ccm, "Ccm") diff --git a/src/ipa/simple/algorithms/ccm.h b/src/ipa/simple/algorithms/ccm.h index b20a7da8aa33..27f11bcbd6e9 100644 --- a/src/ipa/simple/algorithms/ccm.h +++ b/src/ipa/simple/algorithms/ccm.h @@ -7,13 +7,15 @@ #pragma once -#include +#include -#include "libcamera/internal/matrix.h" +#include "libcamera/internal/value_node.h" -#include +#include "libipa/ccm.h" +#include "libipa/fixedpoint.h" #include "algorithm.h" +#include "ipa_context.h" namespace libcamera { @@ -22,10 +24,14 @@ namespace ipa::soft::algorithms { class Ccm : public Algorithm { public: - Ccm() = default; - ~Ccm() = default; - int init(IPAContext &context, const ValueNode &tuningData) override; + + int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; + + void queueRequest(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + const ControlList &controls) override; + void prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, @@ -36,9 +42,7 @@ public: ControlList &metadata) override; private: - unsigned int lastCt_; - Interpolator> ccm_; - std::optional> currentCcm_; + CcmAlgorithm> ccmAlgo_; }; } /* namespace ipa::soft::algorithms */ diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h index 29643a655ce1..ff312ae8f4e7 100644 --- a/src/ipa/simple/ipa_context.h +++ b/src/ipa/simple/ipa_context.h @@ -17,6 +17,7 @@ #include "libcamera/internal/vector.h" #include +#include #include #include "core_ipa_interface.h" @@ -38,6 +39,7 @@ struct IPASessionConfiguration { struct IPAActiveState { ipa::awb::ActiveState awb; + ipa::ccm::ActiveState ccm; struct { int32_t exposure; @@ -63,8 +65,7 @@ struct IPAActiveState { struct IPAFrameContext : public FrameContext { ipa::awb::FrameContext awb; - - Matrix ccm; + ipa::ccm::FrameContext ccm; struct { int32_t exposure;