From patchwork Mon Dec 8 00:48:02 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 25379 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 AFCD7C3257 for ; Mon, 8 Dec 2025 00:48:38 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4D66A613F2; Mon, 8 Dec 2025 01:48:38 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="s2gWIXWf"; 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 8709B6069A for ; Mon, 8 Dec 2025 01:48:36 +0100 (CET) Received: from localhost.localdomain (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 490A21AE2; Mon, 8 Dec 2025 01:46:18 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1765154778; bh=g09nfQfTn00qYQBsIHnV8bB/7fyBUPxzBvnFg955EKA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=s2gWIXWfo8u+WiZgBudzUCqP5GrAaHQbETFzY98xNTaeInvvkX6eujwUjo1fhwFP3 YYCkbMSkknRuBty182am+juxwejGHzKwCFLporXL8/HIpCWS76Trt1FPz85xyJEzmk nDpo7nOtZfHzfM/I5nS6KxrmWIHTdiBV8tZdtHkE= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v4 1/7] ipa: rkisp1: algorithms: dpf: refactor DPF parsing and initialization Date: Sun, 7 Dec 2025 19:48:02 -0500 Message-ID: <20251208004808.1274417-2-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251208004808.1274417-1-rui.wang@ideasonboard.com> References: <20251208004808.1274417-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 defination Signed-off-by: Rui Wang --- Changelog in v4: -Split V3 one patch into 6 patches -The first patch only focus on code reorgnization, no new logic added -Delete Makefile from V3 patch src/ipa/rkisp1/algorithms/dpf.cpp | 61 +++++++++++++++++++++---------- src/ipa/rkisp1/algorithms/dpf.h | 5 +++ 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp index 39f3e461..cd0a7d9d 100644 --- a/src/ipa/rkisp1/algorithms/dpf.cpp +++ b/src/ipa/rkisp1/algorithms/dpf.cpp @@ -46,6 +46,27 @@ Dpf::Dpf() */ int Dpf::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData) +{ + /* Parse tuning block. */ + if (!parseConfig(tuningData)) { + return -EINVAL; + } + + return 0; +} + +bool Dpf::parseConfig(const YamlObject &tuningData) +{ + /* Parse base config. */ + if (!parseSingleConfig(tuningData, config_, strengthConfig_)) { + return false; + } + return true; +} + +bool Dpf::parseSingleConfig(const YamlObject &tuningData, + rkisp1_cif_isp_dpf_config &config, + rkisp1_cif_isp_dpf_strength_config &strengthConfig) { std::vector values; @@ -78,14 +99,14 @@ int Dpf::init([[maybe_unused]] IPAContext &context, << "Invalid 'DomainFilter:g': expected " << RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS << " elements, got " << values.size(); - return -EINVAL; + return false; } 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 @@ -116,18 +137,18 @@ int Dpf::init([[maybe_unused]] IPAContext &context, << RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS - 1 << " or " << RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS << " elements, got " << values.size(); - return -EINVAL; + return false; } - 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) @@ -143,32 +164,32 @@ int Dpf::init([[maybe_unused]] IPAContext &context, << "Invalid 'RangeFilter:coeff': expected " << RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS << " elements, got " << nllValues.size(); - return -EINVAL; + return false; } 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 " << "'linear' or 'logarithmic' value, got " << scaleMode; - return -EINVAL; + return false; } 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; + return true; } /** diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h index 2dd8cd36..bee6fc9b 100644 --- a/src/ipa/rkisp1/algorithms/dpf.h +++ b/src/ipa/rkisp1/algorithms/dpf.h @@ -30,6 +30,11 @@ public: RkISP1Params *params) override; private: + bool parseConfig(const YamlObject &tuningData); + bool 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 Mon Dec 8 00:48:03 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 25380 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 7ABB1C3257 for ; Mon, 8 Dec 2025 00:48:42 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 33CD9613EB; Mon, 8 Dec 2025 01:48:42 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="s3YZmAl7"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 73B43611BA for ; Mon, 8 Dec 2025 01:48:40 +0100 (CET) Received: from localhost.localdomain (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id EAFD11E29; Mon, 8 Dec 2025 01:46:21 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1765154782; bh=XAh7xLbe/PVjNDq6z2lc7ofo54bT7w+cSFt8kaCSfy8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=s3YZmAl7+cfWTy1F4fQpxK1DbzNsmZKz3dKxKLEBH1iVzT5tTZ/7GufqOt73KBOXn cnSe7nSmuFn0dyNBDCsQsTCnBGr2v8IhmZ++MYBbhoxtihr1IS8nxhCK0Kw05Vsyda /LU/6DeAZhfXJRACIcNkyMIwp+OSUwi3QbEtJesI= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v4 2/7] ipa: rkisp1: algorithms: dpf: Implement noise reduction mode switching Date: Sun, 7 Dec 2025 19:48:03 -0500 Message-ID: <20251208004808.1274417-3-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251208004808.1274417-1-rui.wang@ideasonboard.com> References: <20251208004808.1274417-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 Introduce `noiseReductionModes_` to store current configs. Signed-off-by: Rui Wang --- changelog: - Add blank line - Move V3 first patch's loadReductionConfig and reduction mode helper into this patch src/ipa/rkisp1/algorithms/dpf.cpp | 81 ++++++++++++++++++++++++++++++- src/ipa/rkisp1/algorithms/dpf.h | 11 +++++ 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp index cd0a7d9d..18f2a158 100644 --- a/src/ipa/rkisp1/algorithms/dpf.cpp +++ b/src/ipa/rkisp1/algorithms/dpf.cpp @@ -37,7 +37,9 @@ namespace ipa::rkisp1::algorithms { LOG_DEFINE_CATEGORY(RkISP1Dpf) Dpf::Dpf() - : config_({}), strengthConfig_({}) + : config_({}), strengthConfig_({}), + noiseReductionModes_({}), + runningMode_(controls::draft::NoiseReductionModeOff) { } @@ -61,6 +63,53 @@ bool Dpf::parseConfig(const YamlObject &tuningData) if (!parseSingleConfig(tuningData, config_, strengthConfig_)) { return false; } + + /* Parse modes. */ + if (!parseModes(tuningData)) { + return false; + } + + return true; +} + +bool Dpf::parseModes(const YamlObject &tuningData) +{ + /* Parse noise reduction modes. */ + if (!tuningData.contains("modes")) { + return true; + } + + 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 false; + } + + int32_t modeValue = controls::draft::NoiseReductionModeOff; + if (*typeOpt == "minimal") { + modeValue = controls::draft::NoiseReductionModeMinimal; + } else if (*typeOpt == "fast") { + modeValue = controls::draft::NoiseReductionModeFast; + } else if (*typeOpt == "highquality") { + modeValue = controls::draft::NoiseReductionModeHighQuality; + } else if (*typeOpt == "zsl") { + modeValue = controls::draft::NoiseReductionModeZSL; + } else { + LOG(RkISP1Dpf, Error) << "Unknown mode type: " << *typeOpt; + return false; + } + + ModeConfig mode{}; + mode.modeValue = modeValue; + if (!parseSingleConfig(entry, mode.dpf, mode.strength)) { + return false; + } + noiseReductionModes_.push_back(mode); + } + return true; } @@ -192,6 +241,29 @@ bool Dpf::parseSingleConfig(const YamlObject &tuningData, return true; } +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 " + << static_cast(mode); + return false; + } + + config_ = it->dpf; + strengthConfig_ = it->strength; + + LOG(RkISP1Dpf, Info) + << "DPF mode=Reduction (config loaded)" + << " mode=" << static_cast(mode); + + return true; +} + /** * \copydoc libcamera::ipa::Algorithm::queueRequest */ @@ -207,6 +279,7 @@ void Dpf::queueRequest(IPAContext &context, if (denoise) { LOG(RkISP1Dpf, Debug) << "Set denoise to " << *denoise; + runningMode_ = *denoise; switch (*denoise) { case controls::draft::NoiseReductionModeOff: if (dpf.denoise) { @@ -217,8 +290,12 @@ void Dpf::queueRequest(IPAContext &context, case controls::draft::NoiseReductionModeMinimal: case controls::draft::NoiseReductionModeHighQuality: case controls::draft::NoiseReductionModeFast: - if (!dpf.denoise) { + case controls::draft::NoiseReductionModeZSL: + if (loadReductionConfig(runningMode_)) { + update = true; dpf.denoise = true; + } else { + dpf.denoise = false; update = true; } break; diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h index bee6fc9b..30cbaa57 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; + }; + bool parseConfig(const YamlObject &tuningData); + bool parseModes(const YamlObject &tuningData); bool 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 Mon Dec 8 00:48:04 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 25381 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 27F4DC3257 for ; Mon, 8 Dec 2025 00:48:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D2B0A613F2; Mon, 8 Dec 2025 01:48:45 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="XOl2Iwys"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 989BD611BA for ; Mon, 8 Dec 2025 01:48:43 +0100 (CET) Received: from localhost.localdomain (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 049A01E2B; Mon, 8 Dec 2025 01:46:24 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1765154785; bh=C1cCdb/jlSi9MVxLX2CrJ1kTpj4ehzCLxKGO8bpF0Fo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XOl2Iwyswl95hMPeMua8HO7Vjw8B4u2DStizWcnD425N87KwmjSMz1VfwMf5gjM6X LNV7IogVt4jQtgRRwLKrjBXBtBKzrOoLzkS2WSXoE8L4k5dZdfBlt9GfUESItkJc+c EEab9oxzlY4eoPJUXJ8V/lKCb5F3Y6Umy0DoYyrE= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v4 3/7] ipa: rkisp1: algorithms: dpf: Refactor prepare() into helpers Date: Sun, 7 Dec 2025 19:48:04 -0500 Message-ID: <20251208004808.1274417-4-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251208004808.1274417-1-rui.wang@ideasonboard.com> References: <20251208004808.1274417-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: - Move V3 prepareEnabledMode/prepareDisabledMode into this patch src/ipa/rkisp1/algorithms/dpf.cpp | 82 ++++++++++++++++++++----------- src/ipa/rkisp1/algorithms/dpf.h | 9 ++++ 2 files changed, 62 insertions(+), 29 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp index 18f2a158..edb4c2bf 100644 --- a/src/ipa/rkisp1/algorithms/dpf.cpp +++ b/src/ipa/rkisp1/algorithms/dpf.cpp @@ -320,38 +320,62 @@ 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) +{ + frameContext.dpf.denoise = false; + 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 30cbaa57..99cdbdd3 100644 --- a/src/ipa/rkisp1/algorithms/dpf.h +++ b/src/ipa/rkisp1/algorithms/dpf.h @@ -44,6 +44,15 @@ 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 Mon Dec 8 00:48:05 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 25382 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 23FEBC3257 for ; Mon, 8 Dec 2025 00:48:49 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DB0E3613EB; Mon, 8 Dec 2025 01:48:48 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="XfT+zQ8K"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 053C9613F6 for ; Mon, 8 Dec 2025 01:48:46 +0100 (CET) Received: from localhost.localdomain (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id BA6EE1E29; Mon, 8 Dec 2025 01:46:27 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1765154788; bh=6a2CTYcYxffrUGgL2egvtIROzXsSsMuDi55nPXccj0Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XfT+zQ8KAbvAsI8Y4MOkc/5SezGrUZrbFl8iwoy0wZCjh86HomHCc+73Pa1Tw70gZ LkJaPwZ3MxB65cnTlu+g2lSkbWzsWnt2dv9ObdRMCuh4a9CsWw2nfmzpZ1ni7wU2JN qwAdLvuAy+769mZKUmc6n4xZmEQRKyueqejWTLxE= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v4 4/7] ipa: rkisp1: algorithms: dpf: Simplify YAML key names Date: Sun, 7 Dec 2025 19:48:05 -0500 Message-ID: <20251208004808.1274417-5-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251208004808.1274417-1-rui.wang@ideasonboard.com> References: <20251208004808.1274417-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: - Move V3's Yaml rename Implementation into one sperate patch for highlight 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 edb4c2bf..dea04cc3 100644 --- a/src/ipa/rkisp1/algorithms/dpf.cpp +++ b/src/ipa/rkisp1/algorithms/dpf.cpp @@ -123,7 +123,7 @@ bool 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 @@ -145,7 +145,7 @@ bool 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 false; @@ -182,7 +182,7 @@ bool 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(); @@ -204,13 +204,13 @@ bool 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 false; @@ -226,13 +226,13 @@ bool 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 false; } - 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 Mon Dec 8 00:48:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 25383 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 C818EC3257 for ; Mon, 8 Dec 2025 00:48:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7B9BD613FA; Mon, 8 Dec 2025 01:48:50 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="t6JSnqqr"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 877C9613F2 for ; Mon, 8 Dec 2025 01:48:48 +0100 (CET) Received: from localhost.localdomain (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 25DD51E29; Mon, 8 Dec 2025 01:46:30 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1765154790; bh=TIx7IiB0QruV3c19NCJutrJAVQRu3rhDUppRcubS3eE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=t6JSnqqrMQzdGydF4rrpgeh/rEeSlyc/GhQKKt5AjqQR13aBoPQ4dKgP94rQrrPez l7HGSrsjIrlU4KCMl0nEg9dShAkyeRj9ntlYXsjz/G5hed/x9aaHfikTwrUoC+Q9FU CjxEGGMlTnGUY9kfsrHNKfmTFKduG79TSRUTyoMM= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v4 5/7] ipa: rkisp1: algorithms: dpf: Use YamlObject::Getter for parsing Date: Sun, 7 Dec 2025 19:48:06 -0500 Message-ID: <20251208004808.1274417-6-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251208004808.1274417-1-rui.wang@ideasonboard.com> References: <20251208004808.1274417-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" Refactor DPF configuration parsing to use YamlObject::Getter specializations, similar to the approach used in pwl.cpp. This simplifies parseSingleConfig() by delegating the parsing logic to dedicated getter specializations. Implement two YamlObject::Getter specializations: - rkisp1_cif_isp_dpf_config: Parses filter and nll parameters - rkisp1_cif_isp_dpf_strength_config: Parses strength parameters The specializations are defined at the top of the file in the libcamera namespace. Remove LOG statements from the getter specializations to avoid namespace visibility issues, as the LOG macro requires access to the log category which is defined in a nested namespace. Signed-off-by: Rui Wang --- src/ipa/rkisp1/algorithms/dpf.cpp | 240 ++++++++++++++++-------------- 1 file changed, 125 insertions(+), 115 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp index dea04cc3..68a94afe 100644 --- a/src/ipa/rkisp1/algorithms/dpf.cpp +++ b/src/ipa/rkisp1/algorithms/dpf.cpp @@ -23,107 +23,31 @@ namespace libcamera { -namespace ipa::rkisp1::algorithms { - -/** - * \class Dpf - * \brief RkISP1 Denoise Pre-Filter control - * - * The denoise pre-filter algorithm is a bilateral filter which combines a - * range filter and a domain filter. The denoise pre-filter is applied before - * demosaicing. - */ - -LOG_DEFINE_CATEGORY(RkISP1Dpf) - -Dpf::Dpf() - : config_({}), strengthConfig_({}), - noiseReductionModes_({}), - runningMode_(controls::draft::NoiseReductionModeOff) -{ -} - -/** - * \copydoc libcamera::ipa::Algorithm::init - */ -int Dpf::init([[maybe_unused]] IPAContext &context, - const YamlObject &tuningData) -{ - /* Parse tuning block. */ - if (!parseConfig(tuningData)) { - return -EINVAL; - } - - return 0; -} - -bool Dpf::parseConfig(const YamlObject &tuningData) +template<> +std::optional +YamlObject::Getter::get(const YamlObject &obj) const { - /* Parse base config. */ - if (!parseSingleConfig(tuningData, config_, strengthConfig_)) { - return false; - } + rkisp1_cif_isp_dpf_strength_config config = {}; - /* Parse modes. */ - if (!parseModes(tuningData)) { - return false; - } + config.r = obj["r"].get().value_or(64); + config.g = obj["g"].get().value_or(64); + config.b = obj["b"].get().value_or(64); - return true; + return config; } -bool Dpf::parseModes(const YamlObject &tuningData) -{ - /* Parse noise reduction modes. */ - if (!tuningData.contains("modes")) { - return true; - } - - 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 false; - } - - int32_t modeValue = controls::draft::NoiseReductionModeOff; - if (*typeOpt == "minimal") { - modeValue = controls::draft::NoiseReductionModeMinimal; - } else if (*typeOpt == "fast") { - modeValue = controls::draft::NoiseReductionModeFast; - } else if (*typeOpt == "highquality") { - modeValue = controls::draft::NoiseReductionModeHighQuality; - } else if (*typeOpt == "zsl") { - modeValue = controls::draft::NoiseReductionModeZSL; - } else { - LOG(RkISP1Dpf, Error) << "Unknown mode type: " << *typeOpt; - return false; - } - - ModeConfig mode{}; - mode.modeValue = modeValue; - if (!parseSingleConfig(entry, mode.dpf, mode.strength)) { - return false; - } - noiseReductionModes_.push_back(mode); - } - - return true; -} - -bool Dpf::parseSingleConfig(const YamlObject &tuningData, - rkisp1_cif_isp_dpf_config &config, - rkisp1_cif_isp_dpf_strength_config &strengthConfig) +template<> +std::optional +YamlObject::Getter::get(const YamlObject &obj) const { + rkisp1_cif_isp_dpf_config config = {}; std::vector values; /* * 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["filter"]; + const YamlObject &dFObject = obj["filter"]; /* * For the green component, we have the 9x9 kernel specified @@ -144,11 +68,7 @@ bool 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 'filter:g': expected " - << RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS - << " elements, got " << values.size(); - return false; + return std::nullopt; } std::copy_n(values.begin(), values.size(), @@ -181,12 +101,7 @@ bool Dpf::parseSingleConfig(const YamlObject &tuningData, values = dFObject["rb"].getList().value_or(std::vector{}); if (values.size() != RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS && values.size() != RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS - 1) { - LOG(RkISP1Dpf, Error) - << "Invalid 'filter:rb': expected " - << RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS - 1 - << " or " << RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS - << " elements, got " << values.size(); - return false; + return std::nullopt; } config.rb_flt.fltsize = values.size() == RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS @@ -204,39 +119,134 @@ bool 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["nll"]; + const YamlObject &rFObject = obj["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 'nll:coeff': expected " - << RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS - << " elements, got " << nllValues.size(); - return false; + return std::nullopt; } std::copy_n(nllValues.begin(), nllValues.size(), std::begin(config.nll.coeff)); - std::string scaleMode = rFObject["scale-mode"].get(""); + std::string scaleMode = rFObject["scale-mode"].get().value_or(""); if (scaleMode == "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; } else { - LOG(RkISP1Dpf, Error) - << "Invalid 'nll:scale-mode': expected " - << "'linear' or 'logarithmic' value, got " - << scaleMode; + return std::nullopt; + } + + return config; +} + +namespace ipa::rkisp1::algorithms { + +/** + * \class Dpf + * \brief RkISP1 Denoise Pre-Filter control + * + * The denoise pre-filter algorithm is a bilateral filter which combines a + * range filter and a domain filter. The denoise pre-filter is applied before + * demosaicing. + */ + +LOG_DEFINE_CATEGORY(RkISP1Dpf) + +Dpf::Dpf() + : config_({}), strengthConfig_({}), + noiseReductionModes_({}), + runningMode_(controls::draft::NoiseReductionModeOff) +{ +} + +/** + * \copydoc libcamera::ipa::Algorithm::init + */ +int Dpf::init([[maybe_unused]] IPAContext &context, + const YamlObject &tuningData) +{ + /* Parse tuning block. */ + if (!parseConfig(tuningData)) { + return -EINVAL; + } + + return 0; +} + +bool Dpf::parseConfig(const YamlObject &tuningData) +{ + /* Parse base config. */ + if (!parseSingleConfig(tuningData, config_, strengthConfig_)) { + return false; + } + + /* Parse modes. */ + if (!parseModes(tuningData)) { return false; } - const YamlObject &fSObject = tuningData["strength"]; + return true; +} + +bool Dpf::parseModes(const YamlObject &tuningData) +{ + /* Parse noise reduction modes. */ + if (!tuningData.contains("modes")) { + return true; + } + + 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 false; + } + + int32_t modeValue = controls::draft::NoiseReductionModeOff; + if (*typeOpt == "minimal") { + modeValue = controls::draft::NoiseReductionModeMinimal; + } else if (*typeOpt == "fast") { + modeValue = controls::draft::NoiseReductionModeFast; + } else if (*typeOpt == "highquality") { + modeValue = controls::draft::NoiseReductionModeHighQuality; + } else if (*typeOpt == "zsl") { + modeValue = controls::draft::NoiseReductionModeZSL; + } else { + LOG(RkISP1Dpf, Error) << "Unknown mode type: " << *typeOpt; + return false; + } + + ModeConfig mode{}; + mode.modeValue = modeValue; + if (!parseSingleConfig(entry, mode.dpf, mode.strength)) { + return false; + } + noiseReductionModes_.push_back(mode); + } + + return true; +} + +bool Dpf::parseSingleConfig(const YamlObject &tuningData, + rkisp1_cif_isp_dpf_config &config, + rkisp1_cif_isp_dpf_strength_config &strengthConfig) +{ + auto dpfConfig = tuningData.get(); + if (!dpfConfig) + return false; + + config = *dpfConfig; + + auto strength = tuningData["strength"].get(); + if (!strength) + return false; - strengthConfig.r = fSObject["r"].get().value_or(64); - strengthConfig.g = fSObject["g"].get().value_or(64); - strengthConfig.b = fSObject["b"].get().value_or(64); + strengthConfig = *strength; return true; } From patchwork Mon Dec 8 00:48:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 25384 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 DA60CC3257 for ; Mon, 8 Dec 2025 00:48:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 885B161404; Mon, 8 Dec 2025 01:48:52 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="XcrOwqOx"; 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 B8D72613FD for ; Mon, 8 Dec 2025 01:48:50 +0100 (CET) Received: from localhost.localdomain (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 8A2851E29; Mon, 8 Dec 2025 01:46:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1765154792; bh=gmi1tgn8x7ljwfPqhn64IRN2T6Hb2MC9YZjmLRRkoEo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XcrOwqOxY5EzKw+bYt5CAb+kzZKmCRgMlEVxeKYjChmWTMv5WC/EV6LEBMKmVj7Ty yBB5FH+cKtyuTwTwzldKULtNLgc9/v+8VGPnrDFp+Hycn8+Sm2JqqxqDIB24CvfsTT zw9uGlbRze3yA7iOkkjuoULyuseXt8x5ob6XMfNI= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v4 6/7] ipa: rkisp1: algorithms: dpf: Add detailed config logging Date: Sun, 7 Dec 2025 19:48:07 -0500 Message-ID: <20251208004808.1274417-7-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251208004808.1274417-1-rui.wang@ideasonboard.com> References: <20251208004808.1274417-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 logConfigIfChanged() 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: -Move log information into a seperate patch in series src/ipa/rkisp1/algorithms/dpf.cpp | 49 +++++++++++++++++++++++++++++++ src/ipa/rkisp1/algorithms/dpf.h | 1 + 2 files changed, 50 insertions(+) diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp index 68a94afe..e2e5c7ca 100644 --- a/src/ipa/rkisp1/algorithms/dpf.cpp +++ b/src/ipa/rkisp1/algorithms/dpf.cpp @@ -274,6 +274,54 @@ bool Dpf::loadReductionConfig(int32_t mode) return true; } +void Dpf::logConfigIfChanged(const IPAFrameContext &frameContext) +{ + if (!frameContext.dpf.update) { + return; + } + + std::ostringstream ss; + + ss << "DPF config update: "; + ss << " control mode=" << static_cast(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, Info) << ss.str(); +} + /** * \copydoc libcamera::ipa::Algorithm::queueRequest */ @@ -386,6 +434,7 @@ void Dpf::prepareEnabledMode(IPAContext &context, strengthConfig.setEnabled(true); *strengthConfig = strengthConfig_; + logConfigIfChanged(frameContext); } REGISTER_IPA_ALGORITHM(Dpf, "Dpf") diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h index 99cdbdd3..6586256d 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 logConfigIfChanged(const IPAFrameContext &frameContext); void prepareDisabledMode(IPAContext &context, const uint32_t frame, From patchwork Mon Dec 8 00:48:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 25385 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 6B132C3257 for ; Mon, 8 Dec 2025 00:48:54 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 27D2E613FF; Mon, 8 Dec 2025 01:48:54 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="p/iBKyMZ"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F1184613F9 for ; Mon, 8 Dec 2025 01:48:52 +0100 (CET) Received: from localhost.localdomain (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id BD3B11E36; Mon, 8 Dec 2025 01:46:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1765154795; bh=6TETJ5b0qfLkko+/MlHg4beDW+GIXMFkWdenhwBouYM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=p/iBKyMZ90polDJvlInjirQjUaA48TCa/gxOxRVvC8739rL61/HFeJAE9ZnbwwdiU E6w3TxFfSEiEdUaSxO8VdxPu4rgEUiNP2RDLcng+Qqpb2NCHwiJumIapb+37QXrNyr dhcVUDkC3GsjMLMAAnsGzYQAP5KFPdxNUB7KC4+s= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v4 7/7] ipa: rkisp1: algorithms: data: imx219: enable DPF tuning for IMX219 Date: Sun, 7 Dec 2025 19:48:08 -0500 Message-ID: <20251208004808.1274417-8-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251208004808.1274417-1-rui.wang@ideasonboard.com> References: <20251208004808.1274417-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. Signed-off-by: Rui Wang --- changelog: - Yaml file only support dpf conifg and dpf strength config src/ipa/rkisp1/data/imx219.yaml | 60 +++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/ipa/rkisp1/data/imx219.yaml b/src/ipa/rkisp1/data/imx219.yaml index 0d99cb52..736b0bdb 100644 --- a/src/ipa/rkisp1/data/imx219.yaml +++ b/src/ipa/rkisp1/data/imx219.yaml @@ -111,4 +111,64 @@ 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 + - 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 ...