From patchwork Fri Feb 20 22:16:30 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 26217 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 ABACEC31E9 for ; Fri, 20 Feb 2026 22:16:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9FF1562275; Fri, 20 Feb 2026 23:16:55 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="NTik3Bjr"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8393161FBF for ; Fri, 20 Feb 2026 23:16:53 +0100 (CET) Received: from rui-Precision-7560.tail5b760b.ts.net (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 20637502; Fri, 20 Feb 2026 23:15:58 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1771625759; bh=GauuDHtv0Vz48pGtsUQv+Z1WpKO5Ya6jB6yxkg+1kRw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NTik3Bjrc/YyLdrCO9S6QSZkYWcFirh1AuN6AK7Z6Vyimh7uV+sWcJ2FDiJsO8PGs AgegbSnYSLw1LcHPag1xsSCtDlJRXzKo+KHxSAW9oefjl95hyyCXJ0xpotripk8Z8o Pm/k31uAjz9c4yucpfEKxJ+jvTwaR5COvwj8QVqI= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v2 1/7] ipa: rkisp1: filter: Parse tuning modes/sharpness from config Date: Fri, 20 Feb 2026 17:16:30 -0500 Message-ID: <20260220221636.216353-2-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260220221636.216353-1-rui.wang@ideasonboard.com> References: <20260220221636.216353-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 Filter tuning parsers for NoiseReductionModes and Sharpness, - Validate keys during parsing, and store parsed values in unordered_map/unordered_set-based containers for faster lookup and simpler key-based access. Sample format in YAML: - Filter: NoiseReductionModes: NoiseReductionModeFast: [thresh_sh0: 18, thresh_sh1: 33, thresh_bl0: 8, thresh_bl1: 2, mode: 1, lum_weight: 2, grn_stage1: 4, chr_v_mode: 3, chr_h_mode: 3, fac_sh0: 4, fac_sh1: 4, fac_mid: 4, fac_bl0: 2, fac_bl1:0] Sharpness: - [fac_sh0: 4, fac_sh1: 4, fac_mid: 4, fac_bl0: 2, fac_bl1: 0] Signed-off-by: Rui Wang --- src/ipa/rkisp1/algorithms/filter.cpp | 128 +++++++++++++++++++++++++++ src/ipa/rkisp1/algorithms/filter.h | 10 +++ 2 files changed, 138 insertions(+) diff --git a/src/ipa/rkisp1/algorithms/filter.cpp b/src/ipa/rkisp1/algorithms/filter.cpp index 8ad79801..85963f8c 100644 --- a/src/ipa/rkisp1/algorithms/filter.cpp +++ b/src/ipa/rkisp1/algorithms/filter.cpp @@ -8,6 +8,7 @@ #include "filter.h" #include +#include #include @@ -39,6 +40,18 @@ LOG_DEFINE_CATEGORY(RkISP1Filter) static constexpr uint32_t kFiltLumWeightDefault = 0x00022040; static constexpr uint32_t kFiltModeDefault = 0x000004f2; +namespace { +const std::unordered_set kSharpnessKeyNames = { + "fac_sh0", "fac_sh1", "fac_mid", "fac_bl0", "fac_bl1" +}; + +const std::unordered_set kFilterKeyNames = { + "thresh_sh0", "thresh_sh1", "thresh_bl0", "thresh_bl1", + "mode", "lum_weight", "grn_stage1", "chr_v_mode", "chr_h_mode", + "fac_sh0", "fac_sh1", "fac_mid", "fac_bl0", "fac_bl1" +}; +} /* namespace */ + /** * \copydoc libcamera::ipa::Algorithm::init */ @@ -50,6 +63,121 @@ int Filter::init(IPAContext &context, return 0; } + +int Filter::parseConfig(const YamlObject &tuningData) +{ + if (!tuningData.contains("NoiseReductionModes")) { + LOG(RkISP1Filter, Error) << "Missing NoiseReductionModes in Filter tuning data"; + return -EINVAL; + } + + const YamlObject &modesObject = tuningData["NoiseReductionModes"]; + if (!modesObject.isDictionary()) { + LOG(RkISP1Filter, Error) << "NoiseReductionModes must be a dictionary"; + return -EINVAL; + } + + for (const auto &[modeName, modeData] : modesObject.asDict()) { + auto it = controls::draft::NoiseReductionModeNameValueMap.find(modeName); + if (it == controls::draft::NoiseReductionModeNameValueMap.end()) { + LOG(RkISP1Filter, Error) << "Unknown mode: " << modeName; + return -EINVAL; + } + + int ret = parseModeConfig(modeData, modes_[it->second]); + if (ret) + return ret; + } + + if (!tuningData.contains("Sharpness")) { + LOG(RkISP1Filter, Error) << "Missing Sharpness in Filter tuning data"; + return -EINVAL; + } + + const YamlObject &sharpnessObject = tuningData["Sharpness"]; + if (!sharpnessObject.isList()) { + LOG(RkISP1Filter, Error) << "Sharpness must be a list"; + return -EINVAL; + } + + const size_t sharpnessLevels = sharpnessObject.size(); + if (!sharpnessLevels) { + LOG(RkISP1Filter, Error) << "Sharpness must not be empty"; + return -EINVAL; + } + + sharpness_.assign(sharpnessLevels, {}); + + for (size_t i = 0; i < sharpnessLevels; i++) { + int ret = parseSharpnessConfig(sharpnessObject[i], sharpness_[i]); + if (ret) + return ret; + } + + return 0; +} + +int Filter::parseModeConfig(const YamlObject &modeData, + std::unordered_map &modeParams) +{ + if (!modeData.isList()) { + LOG(RkISP1Filter, Error) << "Mode config must be a list"; + return -EINVAL; + } + + for (const auto &entry : modeData.asList()) { + for (const auto &[key, val] : entry.asDict()) { + if (kFilterKeyNames.find(key) == kFilterKeyNames.end()) { + LOG(RkISP1Filter, Error) + << "Unknown mode key '" << key << "'"; + return -EINVAL; + } + + auto v = val.get(); + if (!v) { + LOG(RkISP1Filter, Error) + << "Invalid value for key '" << key << "'"; + return -EINVAL; + } + modeParams[key] = *v; + } + } + + return 0; +} + +int Filter::parseSharpnessConfig(const YamlObject &data, + std::unordered_map &sharpParams) +{ + if (!data.isList()) { + LOG(RkISP1Filter, Error) << "Sharpness entry must be a list"; + return -EINVAL; + } + + sharpParams.clear(); + + for (const auto &entry : data.asList()) { + for (const auto &[key, val] : entry.asDict()) { + if (kSharpnessKeyNames.find(key) == kSharpnessKeyNames.end()) { + LOG(RkISP1Filter, Error) + << "Unknown sharpness key '" << key << "'"; + return -EINVAL; + } + + auto v = val.get(); + if (!v) { + LOG(RkISP1Filter, Error) + << "Invalid value for key '" << key << "'"; + return -EINVAL; + } + + sharpParams[key] = *v; + } + } + + return 0; +} + /** * \copydoc libcamera::ipa::Algorithm::queueRequest */ diff --git a/src/ipa/rkisp1/algorithms/filter.h b/src/ipa/rkisp1/algorithms/filter.h index 37d8938d..83b90ef3 100644 --- a/src/ipa/rkisp1/algorithms/filter.h +++ b/src/ipa/rkisp1/algorithms/filter.h @@ -28,6 +28,16 @@ public: void prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, RkISP1Params *params) override; + +private: + int parseConfig(const YamlObject &tuningData); + int parseModeConfig(const YamlObject &modeData, + std::unordered_map &modeParams); + int parseSharpnessConfig(const YamlObject &data, + std::unordered_map &sharpParams); + + std::unordered_map> modes_; + std::vector> sharpness_; }; } /* namespace ipa::rkisp1::algorithms */ From patchwork Fri Feb 20 22:16:31 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 26218 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 45E49C3240 for ; Fri, 20 Feb 2026 22:17:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2EFDE6228B; Fri, 20 Feb 2026 23:16:57 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Savrw4Qh"; 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 3EAB96226A for ; Fri, 20 Feb 2026 23:16:54 +0100 (CET) Received: from rui-Precision-7560.tail5b760b.ts.net (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DECE5371; Fri, 20 Feb 2026 23:15:59 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1771625760; bh=GvPUZfcy7pWFiVaaaKZ2q4Lc6/G5mnV3eW8ChAEXksI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Savrw4QhjpHuReKfpuall5Q4/VHSuk705CH423NncVKNnqOznl2qkQuc5877Gyc5o XyVMlVmKyWj8sUg72cJ+Kn6pEILQ2wBWLIYsl1HkvbUwHA7HZZNR998j+UlYumavmw VOIgzktTg5UwxjqXDPGSAEtAKyDvixFC98ntspbg= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v2 2/7] ipa: rkisp1: filter: Apply tuning-based sharpness and filter Date: Fri, 20 Feb 2026 17:16:31 -0500 Message-ID: <20260220221636.216353-3-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260220221636.216353-1-rui.wang@ideasonboard.com> References: <20260220221636.216353-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" -Simplify denoise mode handling by storing the control value directly -Rework prepare() to load filter registers from parsed mode tuning data, -Disable filter when NoiseReductionModeOff, -Override fac_* from sharpness tuning levels when valid. Signed-off-by: Rui Wang --- src/ipa/rkisp1/algorithms/filter.cpp | 158 ++++++++------------------- 1 file changed, 43 insertions(+), 115 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/filter.cpp b/src/ipa/rkisp1/algorithms/filter.cpp index 85963f8c..739a0c4d 100644 --- a/src/ipa/rkisp1/algorithms/filter.cpp +++ b/src/ipa/rkisp1/algorithms/filter.cpp @@ -205,31 +205,10 @@ void Filter::queueRequest(IPAContext &context, if (denoise) { LOG(RkISP1Filter, Debug) << "Set denoise to " << *denoise; - switch (*denoise) { - case controls::draft::NoiseReductionModeOff: - if (filter.denoise != 0) { - filter.denoise = 0; - update = true; - } - break; - case controls::draft::NoiseReductionModeMinimal: - if (filter.denoise != 1) { - filter.denoise = 1; - update = true; - } - break; - case controls::draft::NoiseReductionModeHighQuality: - case controls::draft::NoiseReductionModeFast: - if (filter.denoise != 3) { - filter.denoise = 3; - update = true; - } - break; - default: - LOG(RkISP1Filter, Error) - << "Unsupported denoise value " - << *denoise; - break; + uint8_t value = static_cast(*denoise); + if (filter.denoise != value) { + filter.denoise = value; + update = true; } } @@ -242,108 +221,57 @@ void Filter::queueRequest(IPAContext &context, * \copydoc libcamera::ipa::Algorithm::prepare */ void Filter::prepare([[maybe_unused]] IPAContext &context, - [[maybe_unused]] const uint32_t frame, + const uint32_t frame, IPAFrameContext &frameContext, RkISP1Params *params) { /* Check if the algorithm configuration has been updated. */ - if (!frameContext.filter.update) + if (!frameContext.filter.update && frame > 0) return; - static constexpr uint16_t filt_fac_sh0[] = { - 0x04, 0x07, 0x0a, 0x0c, 0x10, 0x14, 0x1a, 0x1e, 0x24, 0x2a, 0x30 - }; - - static constexpr uint16_t filt_fac_sh1[] = { - 0x04, 0x08, 0x0c, 0x10, 0x16, 0x1b, 0x20, 0x26, 0x2c, 0x30, 0x3f - }; - - static constexpr uint16_t filt_fac_mid[] = { - 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x10, 0x13, 0x17, 0x1d, 0x22, 0x28 - }; - - static constexpr uint16_t filt_fac_bl0[] = { - 0x02, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x10, 0x15, 0x1a, 0x24 - }; - - static constexpr uint16_t filt_fac_bl1[] = { - 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x06, 0x08, 0x0d, 0x14, 0x20 - }; - - static constexpr uint16_t filt_thresh_sh0[] = { - 0, 18, 26, 36, 41, 75, 90, 120, 170, 250, 1023 - }; - - static constexpr uint16_t filt_thresh_sh1[] = { - 0, 33, 44, 51, 67, 100, 120, 150, 200, 300, 1023 - }; - - static constexpr uint16_t filt_thresh_bl0[] = { - 0, 8, 13, 23, 26, 50, 60, 80, 140, 180, 1023 - }; - - static constexpr uint16_t filt_thresh_bl1[] = { - 0, 2, 5, 10, 15, 20, 26, 51, 100, 150, 1023 - }; - - static constexpr uint16_t stage1_select[] = { - 6, 6, 4, 4, 3, 3, 2, 2, 2, 1, 0 - }; - - static constexpr uint16_t filt_chr_v_mode[] = { - 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 - }; - - static constexpr uint16_t filt_chr_h_mode[] = { - 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 - }; - uint8_t denoise = frameContext.filter.denoise; uint8_t sharpness = frameContext.filter.sharpness; - auto config = params->block(); + if (denoise == controls::draft::NoiseReductionModeOff) { + config.setEnabled(false); + return; + } config.setEnabled(true); - config->fac_sh0 = filt_fac_sh0[sharpness]; - config->fac_sh1 = filt_fac_sh1[sharpness]; - config->fac_mid = filt_fac_mid[sharpness]; - config->fac_bl0 = filt_fac_bl0[sharpness]; - config->fac_bl1 = filt_fac_bl1[sharpness]; - - config->lum_weight = kFiltLumWeightDefault; - config->mode = kFiltModeDefault; - config->thresh_sh0 = filt_thresh_sh0[denoise]; - config->thresh_sh1 = filt_thresh_sh1[denoise]; - config->thresh_bl0 = filt_thresh_bl0[denoise]; - config->thresh_bl1 = filt_thresh_bl1[denoise]; - config->grn_stage1 = stage1_select[denoise]; - config->chr_v_mode = filt_chr_v_mode[denoise]; - config->chr_h_mode = filt_chr_h_mode[denoise]; - - /* - * Combined high denoising and high sharpening requires some - * adjustments to the configuration of the filters. A first stage - * filter with a lower strength must be selected, and the blur factors - * must be decreased. - */ - if (denoise == 9) { - if (sharpness > 3) - config->grn_stage1 = 2; - } else if (denoise == 10) { - if (sharpness > 5) - config->grn_stage1 = 2; - else if (sharpness > 3) - config->grn_stage1 = 1; + auto it = modes_.find(denoise); + if (it == modes_.end()) { + LOG(RkISP1Filter, Warning) << "No filter config for mode " << denoise; + return; } - - if (denoise > 7) { - if (sharpness > 7) { - config->fac_bl0 /= 2; - config->fac_bl1 /= 4; - } else if (sharpness > 4) { - config->fac_bl0 = config->fac_bl0 * 3 / 4; - config->fac_bl1 /= 2; - } + auto &modeParams = it->second; + + config->thresh_sh0 = modeParams["thresh_sh0"]; + config->thresh_sh1 = modeParams["thresh_sh1"]; + config->thresh_bl0 = modeParams["thresh_bl0"]; + config->thresh_bl1 = modeParams["thresh_bl1"]; + config->mode = modeParams["mode"]; + config->lum_weight = modeParams["lum_weight"]; + config->grn_stage1 = modeParams["grn_stage1"]; + config->chr_v_mode = modeParams["chr_v_mode"]; + config->chr_h_mode = modeParams["chr_h_mode"]; + config->fac_sh0 = modeParams["fac_sh0"]; + config->fac_sh1 = modeParams["fac_sh1"]; + config->fac_mid = modeParams["fac_mid"]; + config->fac_bl0 = modeParams["fac_bl0"]; + config->fac_bl1 = modeParams["fac_bl1"]; + + if (sharpness == 0 or sharpness >= sharpness_.size()) { + LOG(RkISP1Filter, Debug) + << "Sharpness value out of range: " << static_cast(sharpness); + return; } + + /* sharpness override filter register .*/ + const auto &sharp = sharpness_[sharpness]; + config->fac_sh0 = sharp.at("fac_sh0"); + config->fac_sh1 = sharp.at("fac_sh1"); + config->fac_mid = sharp.at("fac_mid"); + config->fac_bl0 = sharp.at("fac_bl0"); + config->fac_bl1 = sharp.at("fac_bl1"); } REGISTER_IPA_ALGORITHM(Filter, "Filter") From patchwork Fri Feb 20 22:16:32 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 26219 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 416B3C31E9 for ; Fri, 20 Feb 2026 22:17:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0B91962287; Fri, 20 Feb 2026 23:16:58 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="VFxVFjAZ"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 82DC262271 for ; Fri, 20 Feb 2026 23:16:55 +0100 (CET) Received: from rui-Precision-7560.tail5b760b.ts.net (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id BC5D5371; Fri, 20 Feb 2026 23:16:00 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1771625761; bh=8dZW7fY38FjRivg92D/ZB/b9tj+rzvrN4ZWHuhS96aY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VFxVFjAZ31cEQtbOc4StNF20ozhLi22hKFlj3SbHOmdb6uKSOMl/ecieGvUUqMr4m RpAWC7W4EKWbl5gNS3YRRt2vz8uoSiewstzVKSHXPMiAl3nrWnAT5vhLsuprngIh9/ GxeaYt1Mn9R2q9kRGcG2L58nxbTXeKMrvbWHWMUM= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v2 3/7] libcamera: Add rkisp1 vendor control definitions Date: Fri, 20 Feb 2026 17:16:32 -0500 Message-ID: <20260220221636.216353-4-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260220221636.216353-1-rui.wang@ideasonboard.com> References: <20260220221636.216353-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 rkisp1 control in meson. -Define rkisp1 filter controls in a new control_ids_rkisp1.yaml. -Reserve the rkisp1 vendor range in control_ranges.yaml. Signed-off-by: Rui Wang --- include/libcamera/meson.build | 1 + src/libcamera/control_ids_rkisp1.yaml | 151 ++++++++++++++++++++++++++ src/libcamera/control_ranges.yaml | 4 +- 3 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 src/libcamera/control_ids_rkisp1.yaml diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build index 30ea76f9..3fd7ef94 100644 --- a/include/libcamera/meson.build +++ b/include/libcamera/meson.build @@ -39,6 +39,7 @@ controls_map = { 'draft': 'control_ids_draft.yaml', 'rpi/pisp': 'control_ids_rpi.yaml', 'rpi/vc4': 'control_ids_rpi.yaml', + 'rkisp1': 'control_ids_rkisp1.yaml', }, 'properties': { diff --git a/src/libcamera/control_ids_rkisp1.yaml b/src/libcamera/control_ids_rkisp1.yaml new file mode 100644 index 00000000..1fe92e45 --- /dev/null +++ b/src/libcamera/control_ids_rkisp1.yaml @@ -0,0 +1,151 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# Copyright (C) 2026, Ideas On Board +# +# RkISP1 specific control definitions +--- +vendor: rkisp1 +controls: + # --- RkISP1 Filter controls --- + - FilterEnable: + type: int32_t + direction: inout + description: | + Enable or disable the Filter processing. + When disabled (false) the hardware filter is forced off regardless of + filter mode selection. When enabled (true) the algorithm may + program parameters and adapt them from manual mode overrides. + Reported in metadata as an int32_t. + enum: + - name: FilterEnableOff + value: 0 + description: The filter is disabled. + - name: FilterEnableOn + value: 1 + description: The filter is enabled. + + - FilterFacSh0: + type: int32_t + direction: inout + description: | + Sets the fac_sh0 sharpness factor. + Value maps to hardware filter register (typically 0..63). + minimum: 0 + maximum: 63 + + - FilterFacSh1: + type: int32_t + direction: inout + description: | + Sets the fac_sh1 sharpness factor. + Value maps to hardware filter register (typically 0..63). + minimum: 0 + maximum: 63 + + - FilterFacMid: + type: int32_t + direction: inout + description: | + Sets the fac_mid sharpness factor. + Value maps to hardware filter register (typically 0..63). + minimum: 0 + maximum: 63 + + - FilterFacBl0: + type: int32_t + direction: inout + description: | + Sets the fac_bl0 sharpness factor. + Value maps to hardware filter register (typically 0..63). + minimum: 0 + maximum: 63 + + - FilterFacBl1: + type: int32_t + direction: inout + description: | + Sets the fac_bl1 sharpness factor. + Value maps to hardware filter register (typically 0..63). + minimum: 0 + maximum: 63 + + - FilterThreshSh0: + type: int32_t + direction: inout + description: | + Sets the thresh_sh0 denoise threshold. + Value maps to hardware threshold register (typically 0..255). + minimum: 0 + maximum: 255 + + - FilterThreshSh1: + type: int32_t + direction: inout + description: | + Sets the thresh_sh1 denoise threshold. + Value maps to hardware threshold register (typically 0..255). + minimum: 0 + maximum: 255 + + - FilterThreshBl0: + type: int32_t + direction: inout + description: | + Sets the thresh_bl0 denoise threshold. + Value maps to hardware threshold register (typically 0..255). + minimum: 0 + maximum: 255 + + - FilterThreshBl1: + type: int32_t + direction: inout + description: | + Sets the thresh_bl1 denoise threshold. + Value maps to hardware threshold register (typically 0..255). + minimum: 0 + maximum: 255 + + - FilterDenoiseMode: + type: int32_t + direction: inout + description: | + Sets the denoise mode for the filter. + Value maps to hardware mode register (typically 0..255). + minimum: 0 + maximum: 255 + + - FilterDenoiseLumWeight: + type: int32_t + direction: inout + description: | + Sets the luminance weight for denoise. + Value maps to hardware lum_weight register (typically 0..255). + minimum: 0 + maximum: 255 + + - FilterDenoiseGreenStage1: + type: int32_t + direction: inout + description: | + Sets the green stage 1 filter for denoise. + Value maps to hardware grn_stage1 register (typically 0..7). + minimum: 0 + maximum: 7 + + - FilterDenoiseChrVMode: + type: int32_t + direction: inout + description: | + Sets the chroma vertical mode for denoise. + Value maps to hardware chr_v_mode register (typically 0..3). + minimum: 0 + maximum: 3 + + - FilterDenoiseChrHMode: + type: int32_t + direction: inout + description: | + Sets the chroma horizontal mode for denoise. + Value maps to hardware chr_h_mode register (typically 0..3). + minimum: 0 + maximum: 3 diff --git a/src/libcamera/control_ranges.yaml b/src/libcamera/control_ranges.yaml index 6752eb98..4964894b 100644 --- a/src/libcamera/control_ranges.yaml +++ b/src/libcamera/control_ranges.yaml @@ -15,6 +15,8 @@ ranges: rpi: 20000 # Controls for debug metadata debug: 30000 - # Next range starts at 40000 + # Rockchip ISP1 vendor controls + rkisp1: 40000 + # Next range starts at 50000 ... From patchwork Fri Feb 20 22:16:33 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 26220 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 01B1AC32EA for ; Fri, 20 Feb 2026 22:17:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A2B7862294; Fri, 20 Feb 2026 23:17:00 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ATlEuL/0"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 87AB06226E for ; Fri, 20 Feb 2026 23:16:56 +0100 (CET) Received: from rui-Precision-7560.tail5b760b.ts.net (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C224A591; Fri, 20 Feb 2026 23:16:01 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1771625762; bh=Kiv3luX1+gEPMuFr1RDU3895jHt07sXhsdVl1FvvTSM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ATlEuL/0FcLujRgCPzh7W+VGFx0MTXqMvENu4D/rV38zaKDTVLJOxt/FAAAuEm6IZ FaO5UTQu1nkjeWIzBvFtTHgpfhRGNAn4Dhx54sUXtVHimoO+V7IxY6CQ7zHQ0z1yDH XGItJHElqoMaVX1xf1cIMOcXBCy1U/mfF13CGwl8= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v2 4/7] ipa: rkisp1: filter: Add manual denoise mode and manual filter controls Date: Fri, 20 Feb 2026 17:16:33 -0500 Message-ID: <20260220221636.216353-5-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260220221636.216353-1-rui.wang@ideasonboard.com> References: <20260220221636.216353-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 NoiseReductionModeManual to draft controls. -Implement rkisp1 filter control registration from tuning data -Add manual-mode control parsing for filter parameters. Signed-off-by: Rui Wang --- src/ipa/rkisp1/algorithms/filter.cpp | 134 +++++++++++++++++++++++++++ src/ipa/rkisp1/algorithms/filter.h | 2 + src/libcamera/control_ids_draft.yaml | 4 + 3 files changed, 140 insertions(+) diff --git a/src/ipa/rkisp1/algorithms/filter.cpp b/src/ipa/rkisp1/algorithms/filter.cpp index 739a0c4d..62d470f4 100644 --- a/src/ipa/rkisp1/algorithms/filter.cpp +++ b/src/ipa/rkisp1/algorithms/filter.cpp @@ -178,6 +178,140 @@ int Filter::parseSharpnessConfig(const YamlObject &data, return 0; } +void Filter::registerControls([[maybe_unused]] IPAContext &context) +{ + auto &cmap = context.ctrlMap; + + if (modes_.empty() or sharpness_.empty()) { + LOG(RkISP1Filter, Warning) + << "No NoiseReductionModes or Sharpness levels parsed, filter controls not registered"; + return; + } + + /* Register sharpness control value from tuning data size*/ + const size_t sharpnessLevels = sharpness_.size(); + cmap[&controls::Sharpness] = ControlInfo(0.0f, static_cast(sharpnessLevels - 1), 1.0f); + + const auto manualMode = static_cast(controls::draft::NoiseReductionModeManual); + auto selectedMode = modes_.find(manualMode); + if (selectedMode == modes_.end()) + selectedMode = modes_.begin(); + + const auto &modeParams = selectedMode->second; + + LOG(RkISP1Filter, Debug) + << "Initial NoiseReductionMode set to " << selectedMode->first; + + /* Register rkisp1-specific filter control values. */ + cmap[&controls::rkisp1::FilterDenoiseMode] = + ControlInfo(0, 255, static_cast(modeParams.at("mode"))); + cmap[&controls::rkisp1::FilterDenoiseLumWeight] = + ControlInfo(0, 255, static_cast(modeParams.at("lum_weight"))); + cmap[&controls::rkisp1::FilterDenoiseGreenStage1] = + ControlInfo(0, 7, static_cast(modeParams.at("grn_stage1"))); + cmap[&controls::rkisp1::FilterDenoiseChrVMode] = + ControlInfo(0, 3, static_cast(modeParams.at("chr_v_mode"))); + cmap[&controls::rkisp1::FilterDenoiseChrHMode] = + ControlInfo(0, 3, static_cast(modeParams.at("chr_h_mode"))); + cmap[&controls::rkisp1::FilterFacSh0] = + ControlInfo(0, 63, static_cast(modeParams.at("fac_sh0"))); + cmap[&controls::rkisp1::FilterFacSh1] = + ControlInfo(0, 63, static_cast(modeParams.at("fac_sh1"))); + cmap[&controls::rkisp1::FilterFacMid] = + ControlInfo(0, 63, static_cast(modeParams.at("fac_mid"))); + cmap[&controls::rkisp1::FilterFacBl0] = + ControlInfo(0, 63, static_cast(modeParams.at("fac_bl0"))); + cmap[&controls::rkisp1::FilterFacBl1] = + ControlInfo(0, 63, static_cast(modeParams.at("fac_bl1"))); + cmap[&controls::rkisp1::FilterThreshSh0] = + ControlInfo(0, 255, static_cast(modeParams.at("thresh_sh0"))); + cmap[&controls::rkisp1::FilterThreshSh1] = + ControlInfo(0, 255, static_cast(modeParams.at("thresh_sh1"))); + cmap[&controls::rkisp1::FilterThreshBl0] = + ControlInfo(0, 255, static_cast(modeParams.at("thresh_bl0"))); + cmap[&controls::rkisp1::FilterThreshBl1] = + ControlInfo(0, 255, static_cast(modeParams.at("thresh_bl1"))); +} + +bool Filter::parseControls(const ControlList &controls) +{ + bool updated = false; + constexpr auto manual = controls::draft::NoiseReductionModeManual; + auto ¶ms = modes_[manual]; + + if (const auto &c = controls.get(controls::rkisp1::FilterFacSh0); c) { + params["fac_sh0"] = *c; + updated = true; + } + + if (const auto &c = controls.get(controls::rkisp1::FilterFacSh1); c) { + params["fac_sh1"] = *c; + updated = true; + } + + if (const auto &c = controls.get(controls::rkisp1::FilterFacMid); c) { + params["fac_mid"] = *c; + updated = true; + } + + if (const auto &c = controls.get(controls::rkisp1::FilterFacBl0); c) { + params["fac_bl0"] = *c; + updated = true; + } + + if (const auto &c = controls.get(controls::rkisp1::FilterFacBl1); c) { + params["fac_bl1"] = *c; + updated = true; + } + + if (const auto &c = controls.get(controls::rkisp1::FilterThreshSh0); c) { + params["thresh_sh0"] = *c; + updated = true; + } + + if (const auto &c = controls.get(controls::rkisp1::FilterThreshSh1); c) { + params["thresh_sh1"] = *c; + updated = true; + } + + if (const auto &c = controls.get(controls::rkisp1::FilterThreshBl0); c) { + params["thresh_bl0"] = *c; + updated = true; + } + + if (const auto &c = controls.get(controls::rkisp1::FilterThreshBl1); c) { + params["thresh_bl1"] = *c; + updated = true; + } + + if (const auto &c = controls.get(controls::rkisp1::FilterDenoiseMode); c) { + params["mode"] = *c; + updated = true; + } + + if (const auto &c = controls.get(controls::rkisp1::FilterDenoiseLumWeight); c) { + params["lum_weight"] = *c; + updated = true; + } + + if (const auto &c = controls.get(controls::rkisp1::FilterDenoiseGreenStage1); c) { + params["grn_stage1"] = *c; + updated = true; + } + + if (const auto &c = controls.get(controls::rkisp1::FilterDenoiseChrVMode); c) { + params["chr_v_mode"] = *c; + updated = true; + } + + if (const auto &c = controls.get(controls::rkisp1::FilterDenoiseChrHMode); c) { + params["chr_h_mode"] = *c; + updated = true; + } + + return updated; +} + /** * \copydoc libcamera::ipa::Algorithm::queueRequest */ diff --git a/src/ipa/rkisp1/algorithms/filter.h b/src/ipa/rkisp1/algorithms/filter.h index 83b90ef3..e6f36df3 100644 --- a/src/ipa/rkisp1/algorithms/filter.h +++ b/src/ipa/rkisp1/algorithms/filter.h @@ -35,6 +35,8 @@ private: std::unordered_map &modeParams); int parseSharpnessConfig(const YamlObject &data, std::unordered_map &sharpParams); + void registerControls(IPAContext &context); + bool parseControls(const ControlList &controls); std::unordered_map> modes_; std::vector> sharpness_; diff --git a/src/libcamera/control_ids_draft.yaml b/src/libcamera/control_ids_draft.yaml index 03309eea..97ccda1c 100644 --- a/src/libcamera/control_ids_draft.yaml +++ b/src/libcamera/control_ids_draft.yaml @@ -58,6 +58,10 @@ controls: value: 4 description: | Noise reduction is applied at different levels to different streams. + - name: NoiseReductionModeManual + value: 5 + description: | + Manual control all noise reduction parameters. - ColorCorrectionAberrationMode: type: int32_t From patchwork Fri Feb 20 22:16:34 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 26221 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 CA67DC3240 for ; Fri, 20 Feb 2026 22:17:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4CFF162290; Fri, 20 Feb 2026 23:17:01 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="WHXZT8/n"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 492F66228C for ; Fri, 20 Feb 2026 23:16:57 +0100 (CET) Received: from rui-Precision-7560.tail5b760b.ts.net (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id ED64F63B; Fri, 20 Feb 2026 23:16:02 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1771625763; bh=f8zYxdK2G/Tij2aWtdJGssJG2KAyVeggyeEttcAt/8g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WHXZT8/n4YmLuOGTLHFAJrRnnTX9+78L1dV5sMri+QwZHY7qgTRRblYc/i+5jbye7 gNcfrylNR9XM+Oi0z7Sx+Kn4ckxIjI/itSSPUY+i4xmhCUWn3AAAER1/jTDjGSu8wj w7wfXaQQJIB0trwMEvI+JS5VkD4fnmsHcqfiOeKY= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v2 5/7] ipa: rkisp1: filter: Parse tuning at init and active manual-mode Date: Fri, 20 Feb 2026 17:16:34 -0500 Message-ID: <20260220221636.216353-6-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260220221636.216353-1-rui.wang@ideasonboard.com> References: <20260220221636.216353-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" -Initialize Filter from tuning data in init() via parseConfig/registerControls. -Route manual mode requests through parseControls(). -Clamp Sharpness using tuning-defined levels. -Skip sharpness table override in prepare() when NoiseReductionModeManual is active. Signed-off-by: Rui Wang --- src/ipa/rkisp1/algorithms/filter.cpp | 40 +++++++++++++++++----------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/filter.cpp b/src/ipa/rkisp1/algorithms/filter.cpp index 62d470f4..48831791 100644 --- a/src/ipa/rkisp1/algorithms/filter.cpp +++ b/src/ipa/rkisp1/algorithms/filter.cpp @@ -56,10 +56,13 @@ const std::unordered_set kFilterKeyNames = { * \copydoc libcamera::ipa::Algorithm::init */ int Filter::init(IPAContext &context, - [[maybe_unused]] const YamlObject &tuningData) + const YamlObject &tuningData) { - auto &cmap = context.ctrlMap; - cmap[&controls::Sharpness] = ControlInfo(0.0f, 10.0f, 1.0f); + int ret = parseConfig(tuningData); + if (ret) + return ret; + + registerControls(context); return 0; } @@ -323,18 +326,6 @@ void Filter::queueRequest(IPAContext &context, auto &filter = context.activeState.filter; bool update = false; - const auto &sharpness = controls.get(controls::Sharpness); - if (sharpness) { - unsigned int value = std::round(std::clamp(*sharpness, 0.0f, 10.0f)); - - if (filter.sharpness != value) { - filter.sharpness = value; - update = true; - } - - LOG(RkISP1Filter, Debug) << "Set sharpness to " << *sharpness; - } - const auto &denoise = controls.get(controls::draft::NoiseReductionMode); if (denoise) { LOG(RkISP1Filter, Debug) << "Set denoise to " << *denoise; @@ -346,6 +337,22 @@ void Filter::queueRequest(IPAContext &context, } } + if (filter.denoise == controls::draft::NoiseReductionModeManual) { + update |= parseControls(controls); + } else { + const auto &sharpness = controls.get(controls::Sharpness); + if (sharpness) { + unsigned int value = std::round(std::clamp(*sharpness, 0.0f, static_cast(sharpness_.size() - 1))); + + if (filter.sharpness != value) { + filter.sharpness = value; + update = true; + } + + LOG(RkISP1Filter, Debug) << "Set sharpness to " << *sharpness; + } + } + frameContext.filter.denoise = filter.denoise; frameContext.filter.sharpness = filter.sharpness; frameContext.filter.update = update; @@ -399,6 +406,9 @@ void Filter::prepare([[maybe_unused]] IPAContext &context, return; } + if (denoise == controls::draft::NoiseReductionModeManual) + return; + /* sharpness override filter register .*/ const auto &sharp = sharpness_[sharpness]; config->fac_sh0 = sharp.at("fac_sh0"); From patchwork Fri Feb 20 22:16:35 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 26222 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 45D36C32EF for ; Fri, 20 Feb 2026 22:17:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E5ACF62280; Fri, 20 Feb 2026 23:17:03 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="gyWY9vlb"; 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 133B262288 for ; Fri, 20 Feb 2026 23:16:58 +0100 (CET) Received: from rui-Precision-7560.tail5b760b.ts.net (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A4DA4591; Fri, 20 Feb 2026 23:16:03 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1771625764; bh=FoxKhw+6ex2K6FH+ROijqZo5uUc7tOtAWVaIW4+Pn0I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gyWY9vlbTpxgHF+ec9khT/D2oVJUQvlSfrT1G5a3dy1xr80n+m5iaeafZ+X5rRELS 9W64JcPITWwK3Zr8q02cgkD4zOJudk062R8hGO5CKE2oSS9/pRV+pA092z8sTwUR5P tkJEfwKNBQwffwynoBw4rJrI1PZtBsMrh5iklnl0= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v2 6/7] ipa: rkisp1: filter: add metadata reporting and config logging Date: Fri, 20 Feb 2026 17:16:35 -0500 Message-ID: <20260220221636.216353-7-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260220221636.216353-1-rui.wang@ideasonboard.com> References: <20260220221636.216353-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" -Implement filter metadata reporting in process() with fillMetadata(), -Add detailed logConfig() dump on updates, -Metadata now exports denoise/fac parameters from mode config with sharpness override when valid. Signed-off-by: Rui Wang --- src/ipa/rkisp1/algorithms/filter.cpp | 118 +++++++++++++++++++++++++++ src/ipa/rkisp1/algorithms/filter.h | 7 ++ 2 files changed, 125 insertions(+) diff --git a/src/ipa/rkisp1/algorithms/filter.cpp b/src/ipa/rkisp1/algorithms/filter.cpp index 48831791..0ac186f8 100644 --- a/src/ipa/rkisp1/algorithms/filter.cpp +++ b/src/ipa/rkisp1/algorithms/filter.cpp @@ -400,6 +400,9 @@ void Filter::prepare([[maybe_unused]] IPAContext &context, config->fac_bl0 = modeParams["fac_bl0"]; config->fac_bl1 = modeParams["fac_bl1"]; + if (frameContext.filter.update) + logConfig(frameContext); + if (sharpness == 0 or sharpness >= sharpness_.size()) { LOG(RkISP1Filter, Debug) << "Sharpness value out of range: " << static_cast(sharpness); @@ -418,6 +421,121 @@ void Filter::prepare([[maybe_unused]] IPAContext &context, config->fac_bl1 = sharp.at("fac_bl1"); } +void Filter::logConfig(const IPAFrameContext &frameContext) const +{ + uint8_t denoise = frameContext.filter.denoise; + uint8_t sharpness = frameContext.filter.sharpness; + + std::ostringstream ss; + ss << "Filter config: mode=" << static_cast(denoise) + << ", sharpness=" << static_cast(sharpness); + + /* Log denoise values from mode config. */ + auto it = modes_.find(denoise); + if (it != modes_.end()) { + const auto &modeParams = it->second; + for (const auto &key : kFilterKeyNames) { + auto keyIt = modeParams.find(key); + if (keyIt != modeParams.end()) + ss << ", " << key << "=" << keyIt->second; + else + ss << ", " << key << "="; + } + } + + /* No sharpness factors need to be logged. */ + if (sharpness == 0 or sharpness >= sharpness_.size()) { + LOG(RkISP1Filter, Debug) << ss.str(); + return; + } + + /* Log sharpness factors. */ + if (sharpness < sharpness_.size()) { + const auto &sharp = sharpness_[sharpness]; + for (const auto &key : kSharpnessKeyNames) { + auto keyIt = sharp.find(key); + if (keyIt != sharp.end()) + ss << ", " << key << "=" << keyIt->second; + else + ss << ", " << key << "="; + } + } + + LOG(RkISP1Filter, Debug) << ss.str(); +} + +void Filter::fillMetadata(IPAFrameContext &frameContext, + ControlList &metadata) +{ + uint8_t denoise = frameContext.filter.denoise; + uint8_t sharpness = frameContext.filter.sharpness; + + if (denoise == controls::draft::NoiseReductionModeOff) + return; + + /* Report denoise values from mode config. */ + auto it = modes_.find(denoise); + if (it == modes_.end()) + return; + + const auto &modeParams = it->second; + metadata.set(controls::rkisp1::FilterThreshSh0, + static_cast(modeParams.at("thresh_sh0"))); + metadata.set(controls::rkisp1::FilterThreshSh1, + static_cast(modeParams.at("thresh_sh1"))); + metadata.set(controls::rkisp1::FilterThreshBl0, + static_cast(modeParams.at("thresh_bl0"))); + metadata.set(controls::rkisp1::FilterThreshBl1, + static_cast(modeParams.at("thresh_bl1"))); + metadata.set(controls::rkisp1::FilterDenoiseMode, + static_cast(modeParams.at("mode"))); + metadata.set(controls::rkisp1::FilterDenoiseLumWeight, + static_cast(modeParams.at("lum_weight"))); + metadata.set(controls::rkisp1::FilterDenoiseGreenStage1, + static_cast(modeParams.at("grn_stage1"))); + metadata.set(controls::rkisp1::FilterDenoiseChrVMode, + static_cast(modeParams.at("chr_v_mode"))); + metadata.set(controls::rkisp1::FilterDenoiseChrHMode, + static_cast(modeParams.at("chr_h_mode"))); + metadata.set(controls::rkisp1::FilterFacSh0, + static_cast(modeParams.at("fac_sh0"))); + metadata.set(controls::rkisp1::FilterFacSh1, + static_cast(modeParams.at("fac_sh1"))); + metadata.set(controls::rkisp1::FilterFacMid, + static_cast(modeParams.at("fac_mid"))); + metadata.set(controls::rkisp1::FilterFacBl0, + static_cast(modeParams.at("fac_bl0"))); + metadata.set(controls::rkisp1::FilterFacBl1, + static_cast(modeParams.at("fac_bl1"))); + + if (sharpness == 0 or sharpness >= sharpness_.size()) + return; + + const auto &sharp = sharpness_[sharpness]; + + metadata.set(controls::rkisp1::FilterFacSh0, + static_cast(sharp.at("fac_sh0"))); + metadata.set(controls::rkisp1::FilterFacSh1, + static_cast(sharp.at("fac_sh1"))); + metadata.set(controls::rkisp1::FilterFacMid, + static_cast(sharp.at("fac_mid"))); + metadata.set(controls::rkisp1::FilterFacBl0, + static_cast(sharp.at("fac_bl0"))); + metadata.set(controls::rkisp1::FilterFacBl1, + static_cast(sharp.at("fac_bl1"))); +} + +/** + * \copydoc libcamera::ipa::Algorithm::process + */ +void Filter::process([[maybe_unused]] IPAContext &context, [[maybe_unused]] const uint32_t frame, + IPAFrameContext &frameContext, + [[maybe_unused]] const rkisp1_stat_buffer *stats, + ControlList &metadata) +{ + fillMetadata(frameContext, metadata); +} + REGISTER_IPA_ALGORITHM(Filter, "Filter") } /* namespace ipa::rkisp1::algorithms */ diff --git a/src/ipa/rkisp1/algorithms/filter.h b/src/ipa/rkisp1/algorithms/filter.h index e6f36df3..58df3d8d 100644 --- a/src/ipa/rkisp1/algorithms/filter.h +++ b/src/ipa/rkisp1/algorithms/filter.h @@ -28,6 +28,10 @@ public: void prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, RkISP1Params *params) override; + void process(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + const rkisp1_stat_buffer *stats, + ControlList &metadata) override; private: int parseConfig(const YamlObject &tuningData); @@ -37,6 +41,9 @@ private: std::unordered_map &sharpParams); void registerControls(IPAContext &context); bool parseControls(const ControlList &controls); + void fillMetadata(IPAFrameContext &frameContext, + ControlList &metadata); + void logConfig(const IPAFrameContext &frameContext) const; std::unordered_map> modes_; std::vector> sharpness_; From patchwork Fri Feb 20 22:16:36 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 26223 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 0CABDC31E9 for ; Fri, 20 Feb 2026 22:17:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BADA662275; Fri, 20 Feb 2026 23:17:04 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="b6qkVRcg"; 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 034E362295 for ; Fri, 20 Feb 2026 23:16:59 +0100 (CET) Received: from rui-Precision-7560.tail5b760b.ts.net (unknown [209.216.103.65]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7171AD2D; Fri, 20 Feb 2026 23:16:04 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1771625765; bh=oeF574Cvf3st9OG5vkqJ6WwZj8dnMf4GTLONG+JKoEc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=b6qkVRcg69EDJ9V2QEDrMfGUY6n3CDvIOTJqJUb9aHCAsvkKj9V4QmxgSHcCNc1qe ul2IBXTYiaSSsjpOoQ/SpN+9LoHHpy1hAugDZ2RMRzj4EH7WmfEa8zJ71TgZTuUuZM U+0XBnvBJDDtZmlVhuxn62aFVnmIBPZawvq1Df4I= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v2 7/7] ipa: rkisp1: imx219: Add Filter tuning with manual noise reduction mode Date: Fri, 20 Feb 2026 17:16:36 -0500 Message-ID: <20260220221636.216353-8-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260220221636.216353-1-rui.wang@ideasonboard.com> References: <20260220221636.216353-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 Filter tuning section to imx219 with NoiseReductionModes (including Manual) - AddSharpness levels, Signed-off-by: Rui Wang --- src/ipa/rkisp1/data/imx219.yaml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/ipa/rkisp1/data/imx219.yaml b/src/ipa/rkisp1/data/imx219.yaml index 0d99cb52..a3b5b0d2 100644 --- a/src/ipa/rkisp1/data/imx219.yaml +++ b/src/ipa/rkisp1/data/imx219.yaml @@ -111,4 +111,29 @@ algorithms: 1438, 1226, 1059, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1025, 1054, 1185, 1326, 1334, 1334, ] + + - Filter: + NoiseReductionModes: + NoiseReductionModeFast: + [mode: 1, lum_weight: 2, thresh_sh0: 36, thresh_sh1: 51, thresh_bl0: 23, thresh_bl1: 10, grn_stage1: 4, chr_v_mode: 3, chr_h_mode: 3, fac_sh0: 4, fac_sh1: 4, fac_mid: 4, fac_bl0: 2, fac_bl1: 0] + NoiseReductionModeHighQuality: + [mode: 1, lum_weight: 2, thresh_sh0: 36, thresh_sh1: 51, thresh_bl0: 23, thresh_bl1: 10, grn_stage1: 4, chr_v_mode: 3, chr_h_mode: 3, fac_sh0: 4, fac_sh1: 4, fac_mid: 4, fac_bl0: 2, fac_bl1: 0] + NoiseReductionModeMinimal: + [mode: 1, lum_weight: 2, thresh_sh0: 18, thresh_sh1: 33, thresh_bl0: 8, thresh_bl1: 2, grn_stage1: 6, chr_v_mode: 3, chr_h_mode: 3, fac_sh0: 4, fac_sh1: 4, fac_mid: 4, fac_bl0: 2, fac_bl1: 0] + NoiseReductionModeManual: + [mode: 1, lum_weight: 2, thresh_sh0: 36, thresh_sh1: 51, thresh_bl0: 23, thresh_bl1: 10, grn_stage1: 4, chr_v_mode: 3, chr_h_mode: 3, fac_sh0: 4, fac_sh1: 4, fac_mid: 4, fac_bl0: 2, fac_bl1: 0] + NoiseReductionModeZSL: + [mode: 1, lum_weight: 2, thresh_sh0: 36, thresh_sh1: 51, thresh_bl0: 23, thresh_bl1: 10, grn_stage1: 4, chr_v_mode: 3, chr_h_mode: 3, fac_sh0: 4, fac_sh1: 4, fac_mid: 4, fac_bl0: 2, fac_bl1: 0] + Sharpness: + - [fac_sh0: 4, fac_sh1: 4, fac_mid: 4, fac_bl0: 2, fac_bl1: 0] # level 0 + - [fac_sh0: 7, fac_sh1: 8, fac_mid: 6, fac_bl0: 2, fac_bl1: 0] # level 1 + - [fac_sh0: 10, fac_sh1: 12, fac_mid: 8, fac_bl0: 4, fac_bl1: 0] # level 2 + - [fac_sh0: 12, fac_sh1: 16, fac_mid: 10, fac_bl0: 6, fac_bl1: 2] # level 3 + - [fac_sh0: 16, fac_sh1: 22, fac_mid: 12, fac_bl0: 8, fac_bl1: 4] # level 4 + - [fac_sh0: 20, fac_sh1: 27, fac_mid: 16, fac_bl0: 10, fac_bl1: 4] # level 5 + - [fac_sh0: 26, fac_sh1: 32, fac_mid: 19, fac_bl0: 12, fac_bl1: 6] # level 6 + - [fac_sh0: 30, fac_sh1: 38, fac_mid: 23, fac_bl0: 16, fac_bl1: 8] # level 7 + - [fac_sh0: 36, fac_sh1: 44, fac_mid: 29, fac_bl0: 21, fac_bl1: 13] # level 8 + - [fac_sh0: 42, fac_sh1: 48, fac_mid: 34, fac_bl0: 26, fac_bl1: 20] # level 9 + - [fac_sh0: 48, fac_sh1: 63, fac_mid: 40, fac_bl0: 36, fac_bl1: 32] # level 10 ...