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")