From patchwork Mon Jun 15 14:05:31 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 26883 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 14441C32D4 for ; Mon, 15 Jun 2026 14:06:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 66A8D623E3; Mon, 15 Jun 2026 16:05:58 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="H3tPig+E"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 88028623E5 for ; Mon, 15 Jun 2026 16:05:48 +0200 (CEST) Received: from [192.168.1.104] (net-93-65-100-155.cust.vodafonedsl.it [93.65.100.155]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id BB1051E2B; Mon, 15 Jun 2026 16:05:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1781532315; bh=iCLTTGrtQhxDI3gU4TkO4My19UTY9C00k1cA68SGo7Y=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=H3tPig+EqMNk4XXt2ayFtnzTw4wljlpDU2hwaBzVFuNzN6nJ+Vcx51PbTsAQoa/tQ plaFGvuW/j9BrQTc9Kmi2NBqI3vsfKEncFDzFyDxosFKMsVLbVgqQp3Bk41HPwpZVT 5xaaRwijhsTCinZxj7UGDsmorOn2Ls8/lljQ6GCU= From: Jacopo Mondi Date: Mon, 15 Jun 2026 16:05:31 +0200 Subject: [PATCH 06/11] ipa: rkisp1: ccm: Port to use CcmAlgorithm MIME-Version: 1.0 Message-Id: <20260615-libipa-algorithms-v1-6-e949c937422e@ideasonboard.com> References: <20260615-libipa-algorithms-v1-0-e949c937422e@ideasonboard.com> In-Reply-To: <20260615-libipa-algorithms-v1-0-e949c937422e@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Jacopo Mondi X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=7981; i=jacopo.mondi@ideasonboard.com; h=from:subject:message-id; bh=iCLTTGrtQhxDI3gU4TkO4My19UTY9C00k1cA68SGo7Y=; b=owEBbQKS/ZANAwAKAXI0Bo8WoVY8AcsmYgBqMAa5X0F9upC4yG9eNASUby0DlOnLC6xyicCwZ mm8Pl9NkDmJAjMEAAEKAB0WIQS1xD1IgJogio9YOMByNAaPFqFWPAUCajAGuQAKCRByNAaPFqFW PLJvD/4oVuFWm5KRWqQ5a7LPfRdhuf6gsaGzPd5MeCEIrma2JF3tWhR23lDC/OpC9E850nCZOw0 6qvOZ8F/lMw02QTIq+gJYidbQGAjQ+q+fAQPVXJDSZp8De1eYSjoBI1m6tKg6alzE7CPb/w0NAq f9fBBhQ0o+X9lPfjRBrm6TONbh+1qVrX9YKme6pHQCCBzpTAVO5t+i9luwSSgwD8gv4rilvVjJi UQSPZzfCtKJQDgi+lgbNa93nC3zcALQhcRO7ugU0RUUQrjD3TfNTlISF5Nsea+Rqr5zYlmoLSjM SEWVTEQsV8fNeHdsT0ViA9325pPzyuyIFnZVYcXJB60Em4JFyOqd4atigUAssZ1vOpgtVtaWxfI rn/BP4YBZrrzPROyvG7H6L/gWmnD11IkD9qxmOWhqm3OtASg4E97tHW+Ym7vQm2o/FaD0fAcWRC H1JXHbuAs6NXCJKBFTylafvpBNu+s2J9S+XBmfY8mKF6CH+vNNnFQs240bG9yfd8SXMlZHjFX0D 9LP3BT9X/px3rbIB6d3WiSUHHLwNZDVF+zf8euatevikC3NSczE9oO6G0J5tlKy/uZzqH7AHOz0 RYNmYRXrPMQMCc8aPQRnx7dsJOGvPUGhIB4BDGdiah74sIyYJhWeHBuMlBIJklCzepOLG/7zgS+ 6cLTh0J4J3zHSDw== 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" Port the Ccm RkISP1 implementation to use the libipa CcmAlgorithm class. Signed-off-by: Jacopo Mondi --- src/ipa/rkisp1/algorithms/ccm.cpp | 97 ++++++++------------------------------- src/ipa/rkisp1/algorithms/ccm.h | 20 ++++---- src/ipa/rkisp1/ipa_context.h | 10 ++-- 3 files changed, 33 insertions(+), 94 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/ccm.cpp b/src/ipa/rkisp1/algorithms/ccm.cpp index 6bb9c7bcfcb3..c1d58fdc43a2 100644 --- a/src/ipa/rkisp1/algorithms/ccm.cpp +++ b/src/ipa/rkisp1/algorithms/ccm.cpp @@ -16,13 +16,11 @@ #include -#include "libcamera/internal/value_node.h" - -#include "libipa/fixedpoint.h" #include "libipa/interpolator.h" /** * \file ccm.h + * \brief RkISP1 CCM algorithm implementation */ namespace libcamera { @@ -31,42 +29,17 @@ namespace ipa::rkisp1::algorithms { /** * \class Ccm - * \brief A color correction matrix algorithm + * \brief RkISP1 color correction matrix algorithm */ LOG_DEFINE_CATEGORY(RkISP1Ccm) -constexpr Matrix kIdentity3x3 = Matrix::identity(); - /** * \copydoc libcamera::ipa::Algorithm::init */ int Ccm::init([[maybe_unused]] IPAContext &context, const ValueNode &tuningData) { - auto &cmap = context.ctrlMap; - cmap[&controls::ColourCorrectionMatrix] = ControlInfo( - ControlValue(-8.0f), - ControlValue(7.993f), - ControlValue(kIdentity3x3.data())); - - int ret = ccm_.readYaml(tuningData["ccms"], "ct", "ccm"); - if (ret < 0) { - LOG(RkISP1Ccm, Warning) - << "Failed to parse 'ccm' " - << "parameter from tuning file; falling back to unit matrix"; - ccm_.setData({ { 0, kIdentity3x3 } }); - } - - ret = offsets_.readYaml(tuningData["ccms"], "ct", "offsets"); - if (ret < 0) { - LOG(RkISP1Ccm, Warning) - << "Failed to parse 'offsets' " - << "parameter from tuning file; falling back to zero offsets"; - - offsets_.setData({ { 0, Matrix({ 0, 0, 0 }) } }); - } - - return 0; + return ccmAlgo_.init(tuningData, context.ctrlMap); } /** @@ -75,10 +48,8 @@ int Ccm::init([[maybe_unused]] IPAContext &context, const ValueNode &tuningData) int Ccm::configure(IPAContext &context, [[maybe_unused]] const IPACameraSensorInfo &configInfo) { - auto &as = context.activeState; - as.ccm.manual = kIdentity3x3; - as.ccm.automatic = ccm_.getInterpolated(as.awb.automatic.temperatureK); - return 0; + return ccmAlgo_.configure(context.activeState.ccm, + context.activeState.awb.automatic.temperatureK); } void Ccm::queueRequest(IPAContext &context, @@ -90,38 +61,28 @@ void Ccm::queueRequest(IPAContext &context, if (frameContext.awb.autoEnabled) return; - auto &ccm = context.activeState.ccm; - - const auto &colourTemperature = controls.get(controls::ColourTemperature); - const auto &ccmMatrix = controls.get(controls::ColourCorrectionMatrix); - if (ccmMatrix) { - ccm.manual = Matrix(*ccmMatrix); - LOG(RkISP1Ccm, Debug) - << "Setting manual CCM from CCM control to " << ccm.manual; - } else if (colourTemperature) { - ccm.manual = ccm_.getInterpolated(*colourTemperature); - LOG(RkISP1Ccm, Debug) - << "Setting manual CCM from CT control to " << ccm.manual; - } - - frameContext.ccm.ccm = ccm.manual; + ccmAlgo_.queueRequest(context.activeState.ccm, frameContext.ccm, controls); } -void Ccm::setParameters(struct rkisp1_cif_isp_ctk_config &config, - const Matrix &matrix, - const Matrix &offsets) +void Ccm::setParameters(RkISP1Params *params, IPAFrameContext &context) { + const Matrix &matrix = context.ccm.ccm; + const Matrix &offsets = context.ccm.offsets; + + auto config = params->block(); + config.setEnabled(true); + /* * 4 bit integer and 7 bit fractional, ranging from -8 (0x400) to * +7.9921875 (0x3ff) */ for (unsigned int i = 0; i < 3; i++) { for (unsigned int j = 0; j < 3; j++) - config.coeff[i][j] = Q<4, 7>(matrix[i][j]).quantized(); + config->coeff[i][j] = Q<4, 7>(matrix[i][j]).quantized(); } for (unsigned int i = 0; i < 3; i++) - config.ct_offset[i] = offsets[i][0] & 0xfff; + config->ct_offset[i] = offsets[i][0] & 0xfff; LOG(RkISP1Ccm, Debug) << "Setting matrix " << matrix; LOG(RkISP1Ccm, Debug) << "Setting offsets " << offsets; @@ -133,29 +94,11 @@ void Ccm::setParameters(struct rkisp1_cif_isp_ctk_config &config, void Ccm::prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, RkISP1Params *params) { - if (!frameContext.awb.autoEnabled) { - auto config = params->block(); - config.setEnabled(true); - setParameters(*config, frameContext.ccm.ccm, Matrix()); - return; - } - - uint32_t ct = frameContext.awb.temperatureK; - if (frame > 0 && ct == ct_) { - frameContext.ccm.ccm = context.activeState.ccm.automatic; - return; - } - - ct_ = ct; - Matrix ccm = ccm_.getInterpolated(ct); - Matrix offsets = offsets_.getInterpolated(ct); - - context.activeState.ccm.automatic = ccm; - frameContext.ccm.ccm = ccm; + if (frameContext.awb.autoEnabled) + ccmAlgo_.prepare(context.activeState.ccm, frameContext.ccm, + frame, frameContext.awb.temperatureK); - auto config = params->block(); - config.setEnabled(true); - setParameters(*config, ccm, offsets); + setParameters(params, frameContext); } /** @@ -167,7 +110,7 @@ void Ccm::process([[maybe_unused]] IPAContext &context, [[maybe_unused]] const rkisp1_stat_buffer *stats, ControlList &metadata) { - metadata.set(controls::ColourCorrectionMatrix, frameContext.ccm.ccm.data()); + ccmAlgo_.process(frameContext.ccm, metadata); } REGISTER_IPA_ALGORITHM(Ccm, "Ccm") diff --git a/src/ipa/rkisp1/algorithms/ccm.h b/src/ipa/rkisp1/algorithms/ccm.h index 9ac537426d16..6689c42092f3 100644 --- a/src/ipa/rkisp1/algorithms/ccm.h +++ b/src/ipa/rkisp1/algorithms/ccm.h @@ -9,11 +9,16 @@ #include -#include "libcamera/internal/matrix.h" +#include -#include "libipa/interpolator.h" +#include "libcamera/internal/value_node.h" + +#include "libipa/ccm.h" +#include "libipa/fixedpoint.h" #include "algorithm.h" +#include "ipa_context.h" +#include "params.h" namespace libcamera { @@ -41,14 +46,9 @@ public: ControlList &metadata) override; private: - void parseYaml(const ValueNode &tuningData); - void setParameters(struct rkisp1_cif_isp_ctk_config &config, - const Matrix &matrix, - const Matrix &offsets); - - unsigned int ct_; - Interpolator> ccm_; - Interpolator> offsets_; + void setParameters(RkISP1Params *params, IPAFrameContext &context); + + CcmAlgorithm> ccmAlgo_; }; } /* namespace ipa::rkisp1::algorithms */ diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index 81b1c7499706..cd97e10bcf2b 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -27,6 +27,7 @@ #include "libipa/agc_mean_luminance.h" #include "libipa/awb.h" #include "libipa/camera_sensor_helper.h" +#include "libipa/ccm.h" #include "libipa/fc_queue.h" #include "libipa/fixedpoint.h" @@ -104,10 +105,7 @@ struct IPAActiveState { ipa::awb::ActiveState awb; - struct { - Matrix manual; - Matrix automatic; - } ccm; + ipa::ccm::ActiveState ccm; struct { BrightnessQ brightness; @@ -203,9 +201,7 @@ struct IPAFrameContext : public FrameContext { double gain; } sensor; - struct { - Matrix ccm; - } ccm; + ipa::ccm::FrameContext ccm; struct { double lux;