From patchwork Thu Dec 18 23:22:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 25607 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 B1F90C326C for ; Thu, 18 Dec 2025 23:22:42 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 30F6C61F61; Fri, 19 Dec 2025 00:22:42 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="lLK4Cv+z"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5B97561F50 for ; Fri, 19 Dec 2025 00:22:40 +0100 (CET) Received: from rui-Precision-7560.local (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id AD278557; Fri, 19 Dec 2025 00:22:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1766100153; bh=WuvnDkrBoyjMA9ku7KaNbMzTIoaNZQhbmzceYq11+qo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lLK4Cv+zNGeiG6uW0B/vNBX3XcrbnxzsaUgo/otJmczqNbrwS8JwlbDCTlXUmHF1Z BMBN0yYM+l9B0smDzepRhGTyT8TPkJZbw0xSZLPWgc6glMljj60XkP7OFYUChlhZzr 8FMl7+hbxUWN2vgM05RcxINA6AA21gaoPbygA7C8= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v6 1/6] ipa: rkisp1: algorithms: dpf: refactor DPF parsing and initialization Date: Thu, 18 Dec 2025 18:22:15 -0500 Message-ID: <20251218232220.761254-2-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251218232220.761254-1-rui.wang@ideasonboard.com> References: <20251218232220.761254-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" Split DPF configuration parsing and initialization into clearer, self-contained helpers and modernized initialization patterns. Introduce parseSingleConfig() as DPF tuning file parser helper make future extensions and maintenance easier. Change strengthconfig.r/g/b parser from uint16 to uint8 to match rkisp1_cif_isp_dpf_strength_config definition. Signed-off-by: Rui Wang --- src/ipa/rkisp1/algorithms/dpf.cpp | 52 ++++++++++++++++++++++--------- src/ipa/rkisp1/algorithms/dpf.h | 5 +++ 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp index 39f3e461..dd3effa1 100644 --- a/src/ipa/rkisp1/algorithms/dpf.cpp +++ b/src/ipa/rkisp1/algorithms/dpf.cpp @@ -46,6 +46,28 @@ Dpf::Dpf() */ int Dpf::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData) +{ + /* Parse tuning block. */ + int ret = parseConfig(tuningData); + if (ret) + return ret; + + return 0; +} + +int Dpf::parseConfig(const YamlObject &tuningData) +{ + /* Parse base config. */ + int ret = parseSingleConfig(tuningData, config_, strengthConfig_); + if (ret) + return ret; + + return 0; +} + +int Dpf::parseSingleConfig(const YamlObject &tuningData, + rkisp1_cif_isp_dpf_config &config, + rkisp1_cif_isp_dpf_strength_config &strengthConfig) { std::vector values; @@ -82,10 +104,10 @@ int Dpf::init([[maybe_unused]] IPAContext &context, } std::copy_n(values.begin(), values.size(), - std::begin(config_.g_flt.spatial_coeff)); + std::begin(config.g_flt.spatial_coeff)); - config_.g_flt.gr_enable = true; - config_.g_flt.gb_enable = true; + config.g_flt.gr_enable = true; + config.g_flt.gb_enable = true; /* * For the red and blue components, we have the 13x9 kernel specified @@ -119,15 +141,15 @@ int Dpf::init([[maybe_unused]] IPAContext &context, return -EINVAL; } - config_.rb_flt.fltsize = values.size() == RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS - ? RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9 - : RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9; + config.rb_flt.fltsize = values.size() == RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS + ? RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9 + : RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9; std::copy_n(values.begin(), values.size(), - std::begin(config_.rb_flt.spatial_coeff)); + std::begin(config.rb_flt.spatial_coeff)); - config_.rb_flt.r_enable = true; - config_.rb_flt.b_enable = true; + config.rb_flt.r_enable = true; + config.rb_flt.b_enable = true; /* * The range kernel is configured with a noise level lookup table (NLL) @@ -147,13 +169,13 @@ int Dpf::init([[maybe_unused]] IPAContext &context, } std::copy_n(nllValues.begin(), nllValues.size(), - std::begin(config_.nll.coeff)); + std::begin(config.nll.coeff)); std::string scaleMode = rFObject["scale-mode"].get(""); if (scaleMode == "linear") { - config_.nll.scale_mode = RKISP1_CIF_ISP_NLL_SCALE_LINEAR; + config.nll.scale_mode = RKISP1_CIF_ISP_NLL_SCALE_LINEAR; } else if (scaleMode == "logarithmic") { - config_.nll.scale_mode = RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC; + config.nll.scale_mode = RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC; } else { LOG(RkISP1Dpf, Error) << "Invalid 'RangeFilter:scale-mode': expected " @@ -164,9 +186,9 @@ int Dpf::init([[maybe_unused]] IPAContext &context, const YamlObject &fSObject = tuningData["FilterStrength"]; - strengthConfig_.r = fSObject["r"].get(64); - strengthConfig_.g = fSObject["g"].get(64); - strengthConfig_.b = fSObject["b"].get(64); + strengthConfig.r = fSObject["r"].get().value_or(64); + strengthConfig.g = fSObject["g"].get().value_or(64); + strengthConfig.b = fSObject["b"].get().value_or(64); return 0; } diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h index 2dd8cd36..39186c55 100644 --- a/src/ipa/rkisp1/algorithms/dpf.h +++ b/src/ipa/rkisp1/algorithms/dpf.h @@ -30,6 +30,11 @@ public: RkISP1Params *params) override; private: + int parseConfig(const YamlObject &tuningData); + int parseSingleConfig(const YamlObject &tuningData, + rkisp1_cif_isp_dpf_config &config, + rkisp1_cif_isp_dpf_strength_config &strengthConfig); + struct rkisp1_cif_isp_dpf_config config_; struct rkisp1_cif_isp_dpf_strength_config strengthConfig_; }; From patchwork Thu Dec 18 23:22:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 25608 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 AAB51C3272 for ; Thu, 18 Dec 2025 23:22:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B6C0861F65; Fri, 19 Dec 2025 00:22:45 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="D6BH3xqt"; 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 B8ABC61F57 for ; Fri, 19 Dec 2025 00:22:44 +0100 (CET) Received: from rui-Precision-7560.local (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 08310596; Fri, 19 Dec 2025 00:22:36 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1766100157; bh=p0MMmt4eNCjUA6jVUvY1G/KltTvNqTEVFZF0BlFx2+A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=D6BH3xqt8VsIvNjheVKXTJZ1MZZhAMMNRxcN9NEPt4zTFvfTQnUbTmhc96Lg3Z9vT 9KM6PU+EvudDfH5GBL0Rv2EQcVGz86w6XC7F6jSUu9gVu+bMU/Pt8ONA/py7bZ5bkb 5YvgfvmJH3WrMFdjQtZF0Jn8SGDgT6rVM5vwlj3U= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v6 2/6] ipa: rkisp1: algorithms: dpf: Implement mode switching Date: Thu, 18 Dec 2025 18:22:16 -0500 Message-ID: <20251218232220.761254-3-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251218232220.761254-1-rui.wang@ideasonboard.com> References: <20251218232220.761254-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" Add support for switching between different noise reduction modes. Introduce `noiseReductionModes_` to store mode-specific configs. LoadReductionConfig() select specific config from configs. Signed-off-by: Rui Wang --- changelog since v5: - Update log verbos from Info to Debug in loadReductionConfig - Update log mode value to string to in loadReductionConfig - improving the return value changed like : if (ret != 0) -> if (ret) Reviewed-by tags from v5 are carried over (no function changes). src/ipa/rkisp1/algorithms/dpf.cpp | 86 +++++++++++++++++++++++++++++-- src/ipa/rkisp1/algorithms/dpf.h | 11 ++++ 2 files changed, 92 insertions(+), 5 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp index dd3effa1..7be30677 100644 --- a/src/ipa/rkisp1/algorithms/dpf.cpp +++ b/src/ipa/rkisp1/algorithms/dpf.cpp @@ -8,6 +8,7 @@ #include "dpf.h" #include +#include #include #include @@ -36,8 +37,20 @@ namespace ipa::rkisp1::algorithms { LOG_DEFINE_CATEGORY(RkISP1Dpf) +namespace { + +const std::map kModesMap = { + { controls::draft::NoiseReductionModeMinimal, "minimal" }, + { controls::draft::NoiseReductionModeFast, "fast" }, + { controls::draft::NoiseReductionModeHighQuality, "highquality" }, + { controls::draft::NoiseReductionModeZSL, "zsl" }, +}; + +} /* namespace */ + Dpf::Dpf() - : config_({}), strengthConfig_({}) + : config_({}), strengthConfig_({}), noiseReductionModes_({}), + runningMode_(controls::draft::NoiseReductionModeOff) { } @@ -62,6 +75,44 @@ int Dpf::parseConfig(const YamlObject &tuningData) if (ret) return ret; + /* Parse modes. */ + return parseModes(tuningData); +} + +int Dpf::parseModes(const YamlObject &tuningData) +{ + /* Parse noise reduction modes. */ + if (!tuningData.contains("modes")) + return -EINVAL; + + noiseReductionModes_.clear(); + for (const auto &entry : tuningData["modes"].asList()) { + std::optional typeOpt = + entry["type"].get(); + if (!typeOpt) { + LOG(RkISP1Dpf, Error) << "Modes entry missing type"; + return -EINVAL; + } + + ModeConfig mode; + auto it = std::find_if(kModesMap.begin(), kModesMap.end(), + [&typeOpt](const auto &pair) { + return pair.second == *typeOpt; + }); + + if (it == kModesMap.end()) { + LOG(RkISP1Dpf, Error) << "Unknown mode type: " << *typeOpt; + return -EINVAL; + } + + mode.modeValue = it->first; + auto ret = parseSingleConfig(entry, mode.dpf, mode.strength); + if (ret) + return ret; + + noiseReductionModes_.push_back(mode); + } + return 0; } @@ -193,6 +244,28 @@ int Dpf::parseSingleConfig(const YamlObject &tuningData, return 0; } +bool Dpf::loadReductionConfig(int32_t mode) +{ + auto it = std::find_if(noiseReductionModes_.begin(), noiseReductionModes_.end(), + [mode](const ModeConfig &m) { + return m.modeValue == mode; + }); + if (it == noiseReductionModes_.end()) { + LOG(RkISP1Dpf, Warning) + << "No DPF config for reduction mode: " << kModesMap.at(mode); + return false; + } + + config_ = it->dpf; + strengthConfig_ = it->strength; + + LOG(RkISP1Dpf, Debug) + << "DPF mode=Reduction (config loaded)" + << " mode=" << kModesMap.at(mode); + + return true; +} + /** * \copydoc libcamera::ipa::Algorithm::queueRequest */ @@ -206,8 +279,6 @@ void Dpf::queueRequest(IPAContext &context, const auto &denoise = controls.get(controls::draft::NoiseReductionMode); if (denoise) { - LOG(RkISP1Dpf, Debug) << "Set denoise to " << *denoise; - switch (*denoise) { case controls::draft::NoiseReductionModeOff: if (dpf.denoise) { @@ -218,9 +289,10 @@ void Dpf::queueRequest(IPAContext &context, case controls::draft::NoiseReductionModeMinimal: case controls::draft::NoiseReductionModeHighQuality: case controls::draft::NoiseReductionModeFast: - if (!dpf.denoise) { - dpf.denoise = true; + case controls::draft::NoiseReductionModeZSL: + if (loadReductionConfig(*denoise)) { update = true; + dpf.denoise = true; } break; default: @@ -229,6 +301,10 @@ void Dpf::queueRequest(IPAContext &context, << *denoise; break; } + if (update) { + runningMode_ = *denoise; + LOG(RkISP1Dpf, Debug) << "Set denoise to " << kModesMap.at(runningMode_); + } } frameContext.dpf.denoise = dpf.denoise; diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h index 39186c55..2a2c7052 100644 --- a/src/ipa/rkisp1/algorithms/dpf.h +++ b/src/ipa/rkisp1/algorithms/dpf.h @@ -30,13 +30,24 @@ public: RkISP1Params *params) override; private: + struct ModeConfig { + int32_t modeValue; + rkisp1_cif_isp_dpf_config dpf; + rkisp1_cif_isp_dpf_strength_config strength; + }; + int parseConfig(const YamlObject &tuningData); + int parseModes(const YamlObject &tuningData); int parseSingleConfig(const YamlObject &tuningData, rkisp1_cif_isp_dpf_config &config, rkisp1_cif_isp_dpf_strength_config &strengthConfig); + bool loadReductionConfig(int32_t mode); + struct rkisp1_cif_isp_dpf_config config_; struct rkisp1_cif_isp_dpf_strength_config strengthConfig_; + std::vector noiseReductionModes_; + int32_t runningMode_; }; } /* namespace ipa::rkisp1::algorithms */ From patchwork Thu Dec 18 23:22:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 25609 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 368F7C3274 for ; Thu, 18 Dec 2025 23:22:51 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5567261F69; Fri, 19 Dec 2025 00:22:51 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="HHs6MDKU"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C0AA561F5A for ; Fri, 19 Dec 2025 00:22:49 +0100 (CET) Received: from rui-Precision-7560.local (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0831B596; Fri, 19 Dec 2025 00:22:41 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1766100162; bh=A3Q1Q6TRRIbZYCCJ33cq9YqfgEixJmLfGCn/DQjxj20=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HHs6MDKUGZrqKnC4TCD2KfVXDgZSKxTAxwhaWVPruCQmrESPf7AKoe5PuJAfVXd7v JtS0c4f7RNKQ9SfSmAn0CZhZYVqg1hyoJzLWKabav9qbTQP6bi4h4TMlIi0n3xERjw O6OagHrEuNii4mXcLA8QLQmvdozx+rRx9aIiN/qI= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v6 3/6] ipa: rkisp1: algorithms: dpf: Refactor prepare() into helpers Date: Thu, 18 Dec 2025 18:22:17 -0500 Message-ID: <20251218232220.761254-4-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251218232220.761254-1-rui.wang@ideasonboard.com> References: <20251218232220.761254-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" Split the prepare() function into prepareDisabledMode() and prepareEnabledMode() to improve readability and maintainability. This separates the logic for disabling and enabling the DPF, making the main prepare() function cleaner and easier to follow. Signed-off-by: Rui Wang --- changelog since v5: Nothing changed Reviewed-by tags from v5 are carried over (no code changes). src/ipa/rkisp1/algorithms/dpf.cpp | 80 ++++++++++++++++++++----------- src/ipa/rkisp1/algorithms/dpf.h | 7 +++ 2 files changed, 58 insertions(+), 29 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp index 7be30677..ee82dfd2 100644 --- a/src/ipa/rkisp1/algorithms/dpf.cpp +++ b/src/ipa/rkisp1/algorithms/dpf.cpp @@ -320,38 +320,60 @@ void Dpf::prepare(IPAContext &context, const uint32_t frame, if (!frameContext.dpf.update && frame > 0) return; + if (!frameContext.dpf.denoise) { + prepareDisabledMode(context, frame, frameContext, params); + return; + } + + prepareEnabledMode(context, frame, frameContext, params); +} + +void Dpf::prepareDisabledMode([[maybe_unused]] IPAContext &context, + [[maybe_unused]] const uint32_t frame, + [[maybe_unused]] IPAFrameContext &frameContext, + RkISP1Params *params) +{ + auto dpfConfig = params->block(); + dpfConfig.setEnabled(false); + auto dpfStrength = params->block(); + dpfStrength.setEnabled(false); +} + +void Dpf::prepareEnabledMode(IPAContext &context, [[maybe_unused]] const uint32_t frame, + [[maybe_unused]] IPAFrameContext &frameContext, + RkISP1Params *params) +{ auto config = params->block(); - config.setEnabled(frameContext.dpf.denoise); + config.setEnabled(true); + *config = config_; + + const auto &awb = context.configuration.awb; + const auto &lsc = context.configuration.lsc; + + auto &mode = config->gain.mode; + + /* + * The DPF needs to take into account the total amount of + * digital gain, which comes from the AWB and LSC modules. The + * DPF hardware can be programmed with a digital gain value + * manually, but can also use the gains supplied by the AWB and + * LSC modules automatically when they are enabled. Use that + * mode of operation as it simplifies control of the DPF. + */ + if (awb.enabled && lsc.enabled) + mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS; + else if (awb.enabled) + mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS; + else if (lsc.enabled) + mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS; + else + mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED; + + config_.gain.mode = mode; auto strengthConfig = params->block(); - strengthConfig.setEnabled(frameContext.dpf.denoise); - - if (frameContext.dpf.denoise) { - *config = config_; - *strengthConfig = strengthConfig_; - - const auto &awb = context.configuration.awb; - const auto &lsc = context.configuration.lsc; - - auto &mode = config->gain.mode; - - /* - * The DPF needs to take into account the total amount of - * digital gain, which comes from the AWB and LSC modules. The - * DPF hardware can be programmed with a digital gain value - * manually, but can also use the gains supplied by the AWB and - * LSC modules automatically when they are enabled. Use that - * mode of operation as it simplifies control of the DPF. - */ - if (awb.enabled && lsc.enabled) - mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS; - else if (awb.enabled) - mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS; - else if (lsc.enabled) - mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS; - else - mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED; - } + strengthConfig.setEnabled(true); + *strengthConfig = strengthConfig_; } REGISTER_IPA_ALGORITHM(Dpf, "Dpf") diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h index 2a2c7052..fcf121cb 100644 --- a/src/ipa/rkisp1/algorithms/dpf.h +++ b/src/ipa/rkisp1/algorithms/dpf.h @@ -44,6 +44,13 @@ private: bool loadReductionConfig(int32_t mode); + void prepareDisabledMode(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + RkISP1Params *params); + void prepareEnabledMode(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + RkISP1Params *params); + struct rkisp1_cif_isp_dpf_config config_; struct rkisp1_cif_isp_dpf_strength_config strengthConfig_; std::vector noiseReductionModes_; From patchwork Thu Dec 18 23:22:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 25610 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 421D4C3257 for ; Thu, 18 Dec 2025 23:22:55 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DD24261F5C; Fri, 19 Dec 2025 00:22:54 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="DOiD8MLK"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4236F61F5C for ; Fri, 19 Dec 2025 00:22:53 +0100 (CET) Received: from rui-Precision-7560.local (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 86A36596; Fri, 19 Dec 2025 00:22:45 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1766100165; bh=3CK6uMw2KOE4Likz+4ZQPxifnHxjNx2m8j+Tz7bjHOI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DOiD8MLKUO6BQSm8+Jma9lDqqI2QUBF2aHs9h4fVo9S1s/4nGmYC9nB3iP/dS/X+k MSKR6dqrdIeINVzXZD3suqOILkEV83NUFCrZnOMZICFQCxIAkCNGkxcYsHw2H76Grd l/fDWJeMAoYxD9tHHgejHyGL6OooZIFFRDWoXmXo= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v6 4/6] ipa: rkisp1: algorithms: dpf: Simplify YAML key names Date: Thu, 18 Dec 2025 18:22:18 -0500 Message-ID: <20251218232220.761254-5-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251218232220.761254-1-rui.wang@ideasonboard.com> References: <20251218232220.761254-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" Rename DPF tuning file keys to shorter, more concise names: - DomainFilter -> filter - NoiseLevelFunction -> nll - FilterStrength -> strength This improves readability and reduces verbosity in tuning files while maintaining the same functionality. Error messages are updated accordingly to reflect the new key names. Signed-off-by: Rui Wang --- changelog since v5: Nothing changed Reviewed-by tags from v5 are carried over (no code changes). src/ipa/rkisp1/algorithms/dpf.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp index ee82dfd2..2c28e38f 100644 --- a/src/ipa/rkisp1/algorithms/dpf.cpp +++ b/src/ipa/rkisp1/algorithms/dpf.cpp @@ -126,7 +126,7 @@ int Dpf::parseSingleConfig(const YamlObject &tuningData, * The domain kernel is configured with a 9x9 kernel for the green * pixels, and a 13x9 or 9x9 kernel for red and blue pixels. */ - const YamlObject &dFObject = tuningData["DomainFilter"]; + const YamlObject &dFObject = tuningData["filter"]; /* * For the green component, we have the 9x9 kernel specified @@ -148,7 +148,7 @@ int Dpf::parseSingleConfig(const YamlObject &tuningData, values = dFObject["g"].getList().value_or(std::vector{}); if (values.size() != RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS) { LOG(RkISP1Dpf, Error) - << "Invalid 'DomainFilter:g': expected " + << "Invalid 'filter:g': expected " << RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS << " elements, got " << values.size(); return -EINVAL; @@ -185,7 +185,7 @@ int Dpf::parseSingleConfig(const YamlObject &tuningData, if (values.size() != RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS && values.size() != RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS - 1) { LOG(RkISP1Dpf, Error) - << "Invalid 'DomainFilter:rb': expected " + << "Invalid 'filter:rb': expected " << RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS - 1 << " or " << RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS << " elements, got " << values.size(); @@ -207,13 +207,13 @@ int Dpf::parseSingleConfig(const YamlObject &tuningData, * which stores a piecewise linear function that characterizes the * sensor noise profile as a noise level function curve (NLF). */ - const YamlObject &rFObject = tuningData["NoiseLevelFunction"]; + const YamlObject &rFObject = tuningData["nll"]; std::vector nllValues; nllValues = rFObject["coeff"].getList().value_or(std::vector{}); if (nllValues.size() != RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS) { LOG(RkISP1Dpf, Error) - << "Invalid 'RangeFilter:coeff': expected " + << "Invalid 'nll:coeff': expected " << RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS << " elements, got " << nllValues.size(); return -EINVAL; @@ -229,13 +229,13 @@ int Dpf::parseSingleConfig(const YamlObject &tuningData, config.nll.scale_mode = RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC; } else { LOG(RkISP1Dpf, Error) - << "Invalid 'RangeFilter:scale-mode': expected " + << "Invalid 'nll:scale-mode': expected " << "'linear' or 'logarithmic' value, got " << scaleMode; return -EINVAL; } - const YamlObject &fSObject = tuningData["FilterStrength"]; + const YamlObject &fSObject = tuningData["strength"]; strengthConfig.r = fSObject["r"].get().value_or(64); strengthConfig.g = fSObject["g"].get().value_or(64); From patchwork Thu Dec 18 23:22:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 25611 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 0AB33C32AF for ; Thu, 18 Dec 2025 23:22:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6463F61F65; Fri, 19 Dec 2025 00:22:58 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="GNJJQUtM"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E1C9E61F60 for ; Fri, 19 Dec 2025 00:22:56 +0100 (CET) Received: from rui-Precision-7560.local (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 312A88CB; Fri, 19 Dec 2025 00:22:49 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1766100169; bh=rIT7AuIqXR+PLkOPACL+ueCsWwvaY6crZYxCvhNVc/8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GNJJQUtMWcXGSLwMPKjcbMydPRR5PdwqxVD5/+UryNQlMNkS3ZL+TaiDokJrgGjVH nFRFgWNV5vQWLAIiIkuIJF6U7WTF7SSDo/A4F1KaxhRlJ7eRvHdczKy2MZ35jcGnND bCSetQVuXxTc4ro852v86Jc88318qFwz+tQ1xqy0= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v6 5/6] ipa: rkisp1: algorithms: dpf: Add detailed config logging Date: Thu, 18 Dec 2025 18:22:19 -0500 Message-ID: <20251218232220.761254-6-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251218232220.761254-1-rui.wang@ideasonboard.com> References: <20251218232220.761254-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" Add logConfig() helper function to log DPF configuration updates when they occur. This provides visibility into the active DPF parameters including: - Control mode and denoise enable state - Filter sizes (9x9 vs 13x9 for rb) - NLL scale mode (linear vs logarithmic) - Gain mode - Strength values (r, g, b) - Spatial filter coefficients (g and rb arrays) - Noise level lookup table coefficients The logging is triggered in prepareEnabledMode() whenever the configuration is updated, helping with debugging and tuning. Signed-off-by: Rui Wang --- changelog since v5: - remove curly bracket in single state if-else Reviewed-by tags from v5 are carried over (no function changes). src/ipa/rkisp1/algorithms/dpf.cpp | 44 +++++++++++++++++++++++++++++++ src/ipa/rkisp1/algorithms/dpf.h | 1 + 2 files changed, 45 insertions(+) diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp index 2c28e38f..8e37b548 100644 --- a/src/ipa/rkisp1/algorithms/dpf.cpp +++ b/src/ipa/rkisp1/algorithms/dpf.cpp @@ -266,6 +266,47 @@ bool Dpf::loadReductionConfig(int32_t mode) return true; } +void Dpf::logConfig(const IPAFrameContext &frameContext) +{ + std::ostringstream ss; + + ss << "DPF config update: "; + ss << " control mode=" << kModesMap.at(runningMode_); + ss << ", denoise=" << (frameContext.dpf.denoise ? "enabled" : "disabled"); + + ss << ", rb_fltsize=" + << (config_.rb_flt.fltsize == RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9 ? "13x9" : "9x9"); + ss << ", nll_scale=" + << (config_.nll.scale_mode == RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC ? "log" : "linear"); + ss << ", gain_mode=" << config_.gain.mode; + ss << ", strength=" << int(strengthConfig_.r) << ',' << int(strengthConfig_.g) << ',' << int(strengthConfig_.b); + + ss << ", g=["; + for (size_t i = 0; i < RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS; ++i) { + if (i) + ss << ','; + ss << int(config_.g_flt.spatial_coeff[i]); + } + ss << "]"; + + ss << ", rb=["; + for (size_t i = 0; i < RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS; ++i) { + if (i) + ss << ','; + ss << int(config_.rb_flt.spatial_coeff[i]); + } + ss << "]"; + + ss << ", nll=["; + for (size_t i = 0; i < RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS; ++i) { + if (i) + ss << ','; + ss << int(config_.nll.coeff[i]); + } + ss << "]"; + LOG(RkISP1Dpf, Debug) << ss.str(); +} + /** * \copydoc libcamera::ipa::Algorithm::queueRequest */ @@ -374,6 +415,9 @@ void Dpf::prepareEnabledMode(IPAContext &context, [[maybe_unused]] const uint32_ auto strengthConfig = params->block(); strengthConfig.setEnabled(true); *strengthConfig = strengthConfig_; + + if (frameContext.dpf.update) + logConfig(frameContext); } REGISTER_IPA_ALGORITHM(Dpf, "Dpf") diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h index fcf121cb..1821da39 100644 --- a/src/ipa/rkisp1/algorithms/dpf.h +++ b/src/ipa/rkisp1/algorithms/dpf.h @@ -43,6 +43,7 @@ private: rkisp1_cif_isp_dpf_strength_config &strengthConfig); bool loadReductionConfig(int32_t mode); + void logConfig(const IPAFrameContext &frameContext); void prepareDisabledMode(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, From patchwork Thu Dec 18 23:22:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 25612 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 454F7C326C for ; Thu, 18 Dec 2025 23:23:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E06BB61F6D; Fri, 19 Dec 2025 00:23:00 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ndVJg/l+"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1930B61F60 for ; Fri, 19 Dec 2025 00:22:59 +0100 (CET) Received: from rui-Precision-7560.local (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 51C6C557; Fri, 19 Dec 2025 00:22:51 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1766100171; bh=BRiVMmSnevNpJdlhYanBCZkP7hZrbGxTkWp5p5GaZA4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ndVJg/l+tjOdGKTbgY7nfxnsL3STjJFfujzVUcQn8jNR9AJ11VmE8yyOz5OsJLZ06 wEGNJ8C2H4a77PSm+Vyx0H4dw6UQZ82UAwQ1YuhWe56p22jQgPrAHSb3KpRnNG9iQ9 rjffBdMkr67PODOte4nFsxN/PGG8Gm6EgT/as8Bs= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v6 6/6] ipa: rkisp1: algorithms: data: enable DPF tuning for imx219/ov5640 Date: Thu, 18 Dec 2025 18:22:20 -0500 Message-ID: <20251218232220.761254-7-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251218232220.761254-1-rui.wang@ideasonboard.com> References: <20251218232220.761254-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" Enable the RkISP1 denoise pre-filter (DPF) for the imx219 sensor by adding the required DPF tuning block to imx219.yaml. Add DPF tuning config for ov5640 to adapt mode selection Signed-off-by: Rui Wang --- changelog since v5: No change Reviewed-by tags from v5 are carried over (no code changes). src/ipa/rkisp1/data/imx219.yaml | 38 ++++++++++++++++++++++++ src/ipa/rkisp1/data/ov5640.yaml | 51 +++++++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 3 deletions(-) diff --git a/src/ipa/rkisp1/data/imx219.yaml b/src/ipa/rkisp1/data/imx219.yaml index 0d99cb52..d6068ada 100644 --- a/src/ipa/rkisp1/data/imx219.yaml +++ b/src/ipa/rkisp1/data/imx219.yaml @@ -111,4 +111,42 @@ algorithms: 1438, 1226, 1059, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1025, 1054, 1185, 1326, 1334, 1334, ] + - Dpf: + filter: + g: [ 18, 13, 9, 5, 3, 1 ] + rb: [ 18, 15, 12, 8, 5, 2 ] + nll: + coeff: [ + 0, 14, 28, 42, 58, 76, 96, 120, + 148, 180, 216, 256, 300, 348, 400, 456, + 520 + ] + scale-mode: "linear" + strength: + r: 80 + g: 80 + b: 80 + modes: + - type: "minimal" + filter: + g: [ 14, 10, 7, 4, 2, 1 ] + rb: [ 14, 11, 8, 4, 2, 1 ] + nll: + coeff: [ 0, 26, 52, 78, 106, 138, 172, 208, 248, 292, 340, 392, 448, 508, 572, 640, 712 ] + scale-mode: "linear" + strength: + r: 60 + g: 60 + b: 60 + - type: "highquality" + filter: + g: [ 22, 18, 13, 8, 5, 2 ] + rb: [ 20, 18, 16, 11, 7, 3 ] + nll: + coeff: [ 0, 26, 52, 78, 106, 138, 172, 208, 248, 292, 340, 392, 448, 508, 572, 640, 712 ] + scale-mode: "linear" + strength: + r: 130 + g: 130 + b: 130 ... diff --git a/src/ipa/rkisp1/data/ov5640.yaml b/src/ipa/rkisp1/data/ov5640.yaml index 4b21d412..f36a45b5 100644 --- a/src/ipa/rkisp1/data/ov5640.yaml +++ b/src/ipa/rkisp1/data/ov5640.yaml @@ -232,19 +232,64 @@ algorithms: green: 2 red-blue: 2 - Dpf: - DomainFilter: + filter: g: [ 16, 16, 16, 16, 16, 16 ] rb: [ 16, 16, 16, 16, 16, 16 ] - NoiseLevelFunction: + nll: coeff: [ 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023 ] scale-mode: "linear" - FilterStrength: + strength: r: 64 g: 64 b: 64 + modes: + - type: "minimal" + filter: + g: [ 14, 10, 7, 4, 2, 1 ] + rb: [ 14, 11, 8, 4, 2, 1 ] + nll: + coeff: [ 0, 26, 52, 78, 106, 138, 172, 208, 248, 292, 340, 392, 448, 508, 572, 640, 712 ] + scale-mode: "linear" + strength: + r: 60 + g: 60 + b: 60 + - type: "highquality" + filter: + g: [ 22, 18, 13, 8, 5, 2 ] + rb: [ 20, 18, 16, 11, 7, 3 ] + nll: + coeff: [ 0, 26, 52, 78, 106, 138, 172, 208, 248, 292, 340, 392, 448, 508, 572, 640, 712 ] + scale-mode: "linear" + strength: + r: 130 + g: 130 + b: 130 + - type: "fast" + filter: + g: [ 16, 12, 9, 5, 3, 1 ] + rb: [ 16, 13, 10, 6, 4, 2 ] + nll: + coeff: [ 0, 16, 32, 48, 66, 86, 108, 132, 160, 192, 228, 268, 312, 360, 412, 468, 528 ] + scale-mode: "linear" + strength: + r: 90 + g: 90 + b: 90 + - type: "zsl" + filter: + g: [ 18, 14, 10, 6, 3, 1 ] + rb: [ 18, 16, 13, 9, 5, 3 ] + nll: + coeff: [ 0, 20, 40, 60, 82, 106, 132, 160, 192, 228, 268, 312, 360, 412, 468, 528, 592 ] + scale-mode: "linear" + strength: + r: 110 + g: 110 + b: 110 - Filter: ...