From patchwork Mon Aug 24 09:06:28 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 28022 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 05124C3339 for ; Mon, 24 Aug 2026 09:07:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AE4F0683B2; Mon, 24 Aug 2026 11:07:34 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="BBg8zWY1"; 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 2415067FEC for ; Mon, 24 Aug 2026 11:07:33 +0200 (CEST) Received: from neptunite.hamster-moth.ts.net (unknown [IPv6:2400:2411:160:2f00:e616:f172:fe90:f1b5]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id CBF55C25; Mon, 24 Aug 2026 11:06:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1787562368; bh=HfBBxlseHzjRbPUNbWq0VbLNDNjxTj3sV1GradrbhiU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BBg8zWY161jNGkzmSDC23bZqP3Uzh1hew76FxGfiKQgAD8DMhauZjr0VTc+8YOMCA m4dVlUag/W/C7nkb5vmwEq9HSE2B2fmqR2P2Wna6X7iBLRpV8pRwBFWTod+vhjUilg Uzf0nEJnutZGnEVmUJQEFXXxLMbi3i/sMUj/vaGU= From: Paul Elder To: laurent.pinchart@ideasonboard.com Cc: Paul Elder , michael.riesch@collabora.com, xuhf@rock-chips.com, stefan.klug@ideasonboard.com, kieran.bingham@ideasonboard.com, dan.scally@ideasonboard.com, jacopo.mondi@ideasonboard.com, nicolas.dufresne@collabora.com, mehdi.djait@linux.intel.com, libcamera-devel@lists.libcamera.org Subject: [PATCH v2 11/20] ipa: rkisp2: algo: ccm: Implement color correction matrix Date: Mon, 24 Aug 2026 18:06:28 +0900 Message-ID: <20260824090641.3705246-12-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20260824090641.3705246-1-paul.elder@ideasonboard.com> References: <20260824090641.3705246-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" Implement a color correction matrix control algorithm for the rkisp2 IPA. This uses the libipa color correction matrix algorithm. Signed-off-by: Paul Elder --- Changes in v2: - rebased on libipa rework --- src/ipa/rkisp2/algorithms/ccm.cpp | 126 ++++++++++++++++++++++++++ src/ipa/rkisp2/algorithms/ccm.h | 57 ++++++++++++ src/ipa/rkisp2/algorithms/meson.build | 1 + 3 files changed, 184 insertions(+) create mode 100644 src/ipa/rkisp2/algorithms/ccm.cpp create mode 100644 src/ipa/rkisp2/algorithms/ccm.h diff --git a/src/ipa/rkisp2/algorithms/ccm.cpp b/src/ipa/rkisp2/algorithms/ccm.cpp new file mode 100644 index 000000000000..803a22264c04 --- /dev/null +++ b/src/ipa/rkisp2/algorithms/ccm.cpp @@ -0,0 +1,126 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2026, Ideas On Board + * + * RkISP2 Color Correction Matrix control algorithm + */ + +#include "ccm.h" + +#include + +#include +#include + +#include + +#include + +#include "libipa/interpolator.h" + +/** + * \file ccm.h + * \brief RkISP2 CCM algorithm implementation + */ + +namespace libcamera { + +namespace ipa::rkisp2::algorithms { + +/** + * \class Ccm + * \brief RkISP2 color correction matrix algorithm + */ + +LOG_DEFINE_CATEGORY(RkISP2Ccm) + +/** + * \copydoc libcamera::ipa::Algorithm::init + */ +int Ccm::init([[maybe_unused]] IPAContext &context, const ValueNode &tuningData) +{ + return ccmAlgo_.init(tuningData, context.ctrlMap); +} + +/** + * \copydoc libcamera::ipa::Algorithm::configure + */ +int Ccm::configure(IPAContext &context, + [[maybe_unused]] const IPACameraSensorInfo &configInfo) +{ + return ccmAlgo_.configure(context.activeState.ccm, + context.activeState.awb.automatic.colourTemperature); +} + +void Ccm::queueRequest(IPAContext &context, + [[maybe_unused]] const uint32_t frame, + IPAFrameContext &frameContext, + const ControlList &controls) +{ + ccmAlgo_.queueRequest(context.activeState.ccm, frameContext.ccm, controls); +} + +void Ccm::setParameters(RkISP2Params *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(); + } + + for (unsigned int i = 0; i < 3; i++) + config->offset[i] = offsets[i][0] & 0xfff; + + config->y_coeff[0] = 0x26; + config->y_coeff[1] = 0x4b; + config->y_coeff[2] = 0x0f; + config->inflection_point = 0xa; + + for (unsigned int i = 0; i < 17; i++) + config->alp[i] = 0x400; + + /* \todo Support alp */ + + LOG(RkISP2Ccm, Debug) << "Setting matrix " << matrix; + LOG(RkISP2Ccm, Debug) << "Setting offsets " << offsets; +} + +/** + * \copydoc libcamera::ipa::Algorithm::prepare + */ +void Ccm::prepare(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, RkISP2Params *params) +{ + if (frameContext.awb.autoEnabled) + ccmAlgo_.prepare(context.activeState.ccm, frameContext.ccm, + frame, frameContext.awb.colourTemperature); + + setParameters(params, frameContext); +} + +/** + * \copydoc libcamera::ipa::Algorithm::process + */ +void Ccm::process([[maybe_unused]] IPAContext &context, + [[maybe_unused]] const uint32_t frame, + IPAFrameContext &frameContext, + [[maybe_unused]] const RkISP2Stats *stats, + ControlList &metadata) +{ + ccmAlgo_.process(frameContext.ccm, metadata); +} + +REGISTER_IPA_ALGORITHM(Ccm, "Ccm") + +} /* namespace ipa::rkisp2::algorithms */ + +} /* namespace libcamera */ diff --git a/src/ipa/rkisp2/algorithms/ccm.h b/src/ipa/rkisp2/algorithms/ccm.h new file mode 100644 index 000000000000..27878f0c187c --- /dev/null +++ b/src/ipa/rkisp2/algorithms/ccm.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2026, Ideas On Board + * + * RkISP2 Color Correction Matrix control algorithm + */ + +#pragma once + +#include + +#include + +#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 { + +namespace ipa::rkisp2::algorithms { + +class Ccm : public Algorithm +{ +public: + Ccm() {} + ~Ccm() = default; + + int init(IPAContext &context, const ValueNode &tuningData) override; + int configure(IPAContext &context, + const IPACameraSensorInfo &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, + RkISP2Params *params) override; + void process(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + const RkISP2Stats *stats, + ControlList &metadata) override; + +private: + void parseYaml(const ValueNode &tuningData); + void setParameters(RkISP2Params *params, IPAFrameContext &context); + + CcmAlgorithm> ccmAlgo_; +}; + +} /* namespace ipa::rkisp2::algorithms */ + +} /* namespace libcamera */ diff --git a/src/ipa/rkisp2/algorithms/meson.build b/src/ipa/rkisp2/algorithms/meson.build index 027e40dd0346..e7ae3d163bfb 100644 --- a/src/ipa/rkisp2/algorithms/meson.build +++ b/src/ipa/rkisp2/algorithms/meson.build @@ -4,5 +4,6 @@ rkisp2_ipa_algorithms = files([ 'agc.cpp', 'awb.cpp', 'bls.cpp', + 'ccm.cpp', ])