From patchwork Tue Oct 28 17:08:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 24857 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 2115CBE080 for ; Tue, 28 Oct 2025 17:09:15 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A2AA360821; Tue, 28 Oct 2025 18:09:13 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="XKqhKvKH"; 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 4722C607F1 for ; Tue, 28 Oct 2025 18:09:11 +0100 (CET) Received: from rui-Precision-7560.local (unknown [209.216.122.90]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 5CB4416CD; Tue, 28 Oct 2025 18:07:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761671242; bh=eeCBzBL8knMj7SOHL8cPG4cTxQ4Q8BekHEC9qDqMWqo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XKqhKvKH+Fs8M023MryMCDmt3/2nre5VGC/xYM2aW+DbBIRVsYbnr711KRkb5GbCM 2ILEoNpCXa5kY5Hm1MFKXR7VIigKxM11bsFK8AlBsi14CIsht38yyg1YXcwQSELbF7 yxqzT6aFyxvogf9qr25Qfw52yhW/YIJmzvJV6YQs= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v1 05/16] ipa: rkisp1: algorithms: dpf: add Dpf parseSingleConfig helper Date: Tue, 28 Oct 2025 13:08:34 -0400 Message-ID: <20251028170847.2673396-5-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251028170847.2673396-1-rui.wang@ideasonboard.com> References: <20251028170847.2673396-1-rui.wang@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" Rework domain filter, NLL, gain, and strength parsing into a parseSingleConfig() helper. This extracts the parsing logic so it can be reused for both the base tuning and per-ISO-level configuration blocks. Signed-off-by: Rui Wang --- src/ipa/rkisp1/algorithms/dpf.cpp | 109 ++++++++++++++++++++++++++++++ src/ipa/rkisp1/algorithms/dpf.h | 7 +- 2 files changed, 115 insertions(+), 1 deletion(-) diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp index cb6095da..9d1e6435 100644 --- a/src/ipa/rkisp1/algorithms/dpf.cpp +++ b/src/ipa/rkisp1/algorithms/dpf.cpp @@ -171,6 +171,115 @@ int Dpf::init([[maybe_unused]] IPAContext &context, return 0; } +bool Dpf::parseSingleConfig(const YamlObject &config, + rkisp1_cif_isp_dpf_config &cfg, + rkisp1_cif_isp_dpf_strength_config &strength) +{ + /* + * The domain kernel is configured with a 9x9 kernel for the green + * pixels, and a 13x9 or 9x9 kernel for red and blue pixels. + * + * For the green component, we have the 9x9 kernel specified + * as 6 coefficients: + * Y + * ^ + * 4 | 6 5 4 5 6 + * 3 | 5 3 3 5 + * 2 | 5 3 2 3 5 + * 1 | 3 1 1 3 + * 0 - 4 2 0 2 4 + * -1 | 3 1 1 3 + * -2 | 5 3 2 3 5 + * -3 | 5 3 3 5 + * -4 | 6 5 4 5 6 + * +---------|--------> X + * -4....-1 0 1 2 3 4 + * + * For the red and blue components, we have the 13x9 kernel specified + * as 6 coefficients: + * + * Y + * ^ + * 4 | 6 5 4 3 4 5 6 + * | + * 2 | 5 4 2 1 2 4 5 + * | + * 0 - 5 3 1 0 1 3 5 + * | + * -2 | 5 4 2 1 2 4 5 + * | + * -4 | 6 5 4 3 4 5 6 + * +----------|-------------|---> X + * -6...........-1 0 1......6 + * + * For a 9x9 kernel, columns -6 and 6 are dropped, so coefficient + * number 6 is not used. + */ + + if (!config.contains("DomainFilter")) { + LOG(RkISP1Dpf, Error) << "DomainFilter section missing"; + return false; + } + const YamlObject &dFObject = config["DomainFilter"]; + + std::vector gCoeffs; + if (!yamlHelper::optList8(dFObject, "g", gCoeffs, RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS)) + return false; + std::copy_n(gCoeffs.begin(), gCoeffs.size(), std::begin(cfg.g_flt.spatial_coeff)); + cfg.g_flt.gr_enable = true; + cfg.g_flt.gb_enable = true; + + uint32_t rbFilterSize; + if (!yamlHelper::optFilterCoeffs(dFObject, "rb", cfg.rb_flt.spatial_coeff, rbFilterSize, RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS)) + return false; + cfg.rb_flt.fltsize = rbFilterSize ? RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9 : RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9; + cfg.rb_flt.r_enable = true; + cfg.rb_flt.b_enable = true; + + if (!config.contains("NoiseLevelFunction")) { + LOG(RkISP1Dpf, Error) << "NoiseLevelFunction section missing"; + return false; + } + const YamlObject &rFObject = config["NoiseLevelFunction"]; + + std::vector nllCoeffs; + if (!yamlHelper::optList16(rFObject, "coeff", nllCoeffs, RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS)) + return false; + std::copy_n(nllCoeffs.begin(), nllCoeffs.size(), std::begin(cfg.nll.coeff)); + + const std::map scaleModeMap = { + { "linear", RKISP1_CIF_ISP_NLL_SCALE_LINEAR }, + { "logarithmic", RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC } + }; + if (!yamlHelper::optEnum(rFObject, "scale-mode", cfg.nll.scale_mode, RKISP1_CIF_ISP_NLL_SCALE_LINEAR, scaleModeMap)) { + LOG(RkISP1Dpf, Error) << "NoiseLevelFunction:scale-mode expected 'linear' or 'logarithmic'"; + return false; + } + + if (!config.contains("Gain")) { + LOG(RkISP1Dpf, Error) << "Gain section missing"; + return false; + } + const YamlObject &gObject = config["Gain"]; + + yamlHelper::opt32(gObject, "gain_mode", cfg.gain.mode, RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS); + yamlHelper::opt16(gObject, "nf_r_gain", cfg.gain.nf_r_gain, 256); + yamlHelper::opt16(gObject, "nf_b_gain", cfg.gain.nf_b_gain, 256); + yamlHelper::opt16(gObject, "nf_gr_gain", cfg.gain.nf_gr_gain, 256); + yamlHelper::opt16(gObject, "nf_gb_gain", cfg.gain.nf_gb_gain, 256); + + if (!config.contains("FilterStrength")) { + LOG(RkISP1Dpf, Error) << "FilterStrength section missing"; + return false; + } + const YamlObject &fSObject = config["FilterStrength"]; + + yamlHelper::opt8(fSObject, "r", strength.r, 64); + yamlHelper::opt8(fSObject, "g", strength.g, 64); + yamlHelper::opt8(fSObject, "b", strength.b, 64); + return true; +} + /** * \copydoc libcamera::ipa::Algorithm::queueRequest */ diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h index 2dd8cd36..cfd6ef44 100644 --- a/src/ipa/rkisp1/algorithms/dpf.h +++ b/src/ipa/rkisp1/algorithms/dpf.h @@ -10,12 +10,14 @@ #include #include "algorithm.h" +#include "denoise.h" +#include "yaml_helper.h" namespace libcamera { namespace ipa::rkisp1::algorithms { -class Dpf : public Algorithm +class Dpf : public DenoiseBaseAlgorithm { public: Dpf(); @@ -32,6 +34,9 @@ public: private: struct rkisp1_cif_isp_dpf_config config_; struct rkisp1_cif_isp_dpf_strength_config strengthConfig_; + bool parseSingleConfig(const YamlObject &config, + rkisp1_cif_isp_dpf_config &cfg, + rkisp1_cif_isp_dpf_strength_config &strength); }; } /* namespace ipa::rkisp1::algorithms */