From patchwork Tue Nov 25 00:08:42 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 25172 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 0681CC3257 for ; Tue, 25 Nov 2025 00:09:16 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A103860A9E; Tue, 25 Nov 2025 01:09:15 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="jovDiWaF"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0EC55609D8 for ; Tue, 25 Nov 2025 01:09:13 +0100 (CET) Received: from rui-Precision-7560.local (unknown [IPv6:2607:fea8:935b:7220:cb34:a7b8:53d:5466]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4599F1785; Tue, 25 Nov 2025 01:07:04 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1764029224; bh=thdNjgp4sS/RLvisnBqyFOT/NN/VVpzP0EaqUwophK0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jovDiWaFTj/bq34xj3xNR3C68xtCBIeuhj7bxUilZVOtxazhYIVNyN1Ya+vVhJ/ft NUazNAH7tJwkj3clRKFc+ajnPW+uKjt5qcx+eR6tdsMWZjuA+kYbtOf3q3u8AJAG6S r1KeFT5FJ9rVWNAqBJDre1eGktx7t2/7zPrIRy+0= From: Rui Wang To: libcamera-devel@lists.libcamera.org Cc: Rui Wang Subject: [PATCH v1 05/11] ipa: rkisp1: algorithms: dpf: collect DPF manual overrides Date: Mon, 24 Nov 2025 19:08:42 -0500 Message-ID: <20251125000848.4103786-6-rui.wang@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251125000848.4103786-1-rui.wang@ideasonboard.com> References: <20251125000848.4103786-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 collectManualOverrides() to capture strength and developer-mode override arrays from control requests. Extend queueRequest() to collect overrides in manual mode and mark frames dirty when strength values differ from the active configuration. Developer mode controls (spatial coefficients, filter size, NLL tables) are only collected when devmode is enabled. The function populates the overrides_ structure which will be applied during prepare(). Signed-off-by: Rui Wang --- src/ipa/rkisp1/algorithms/denoise.h | 5 +- src/ipa/rkisp1/algorithms/dpf.cpp | 66 +++++++++++++++++++++++++ src/ipa/rkisp1/algorithms/dpf.h | 23 +++++++++ src/libcamera/control_ids_rkisp1.yaml | 71 +++++++++++++++++++++++++++ 4 files changed, 164 insertions(+), 1 deletion(-) diff --git a/src/ipa/rkisp1/algorithms/denoise.h b/src/ipa/rkisp1/algorithms/denoise.h index 660f648b..ffe27af8 100644 --- a/src/ipa/rkisp1/algorithms/denoise.h +++ b/src/ipa/rkisp1/algorithms/denoise.h @@ -22,6 +22,7 @@ protected: ~DenoiseBaseAlgorithm() = default; virtual void setDevMode(bool dev) { devMode_ = dev; } virtual bool isDevMode() const { return devMode_; } + virtual uint32_t computeExposureIndex(const IPAContext &context, const IPAFrameContext &frameContext) const; template @@ -31,6 +32,9 @@ protected: { return true; } + virtual void collectManualOverrides([[maybe_unused]] const ControlList &controls) + { + } virtual void handleReductionModeControl([[maybe_unused]] const ControlList &controls, [[maybe_unused]] IPAFrameContext &frameContext, [[maybe_unused]] IPAContext &context, @@ -39,7 +43,6 @@ protected: } virtual int32_t getRunningMode() const { return currentRunMode_; } virtual void setRunningMode(int32_t mode) { currentRunMode_ = mode; } - private: /**< Developer mode state for advanced controls */ bool devMode_ = false; diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp index c006fb5c..2d7d6414 100644 --- a/src/ipa/rkisp1/algorithms/dpf.cpp +++ b/src/ipa/rkisp1/algorithms/dpf.cpp @@ -358,6 +358,72 @@ void Dpf::loadReductionModeConfig(IPAFrameContext &frameContext) strengthConfig_ = it->strength; frameContext.dpf.update = true; } + +void Dpf::collectManualOverrides(const ControlList &controls) +{ + if (const auto &c = controls.get(controls::rkisp1::DpfChannelStrengths); c) { + if (c->size() == 3) { + overrides_.strength = DpfStrengthSettings{ + static_cast((*c)[0]), + static_cast((*c)[1]), + static_cast((*c)[2]) + }; + } + } + if (!isDevMode()) + return; + + if (const auto &c = controls.get(controls::rkisp1::DpfGreenSpatialCoefficients); c) { + if (c->size() == RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS) { + DpfSpatialGreenSettings green; + std::copy_n(c->begin(), RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS, + green.coeffs.begin()); + overrides_.spatialGreen = green; + } + } + if (const auto &c = + controls.get(controls::rkisp1::DpfRedBlueSpatialCoefficients); + c) { + if (c->size() == RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS) { + DpfSpatialRbSettings rb; + std::copy_n(c->begin(), RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS, + rb.coeffs.begin()); + rb.size = (config_.rb_flt.fltsize == + RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9) + ? 1 + : 0; + overrides_.spatialRb = rb; + } + } + if (const auto &c = controls.get(controls::rkisp1::DpfRbFilterSize); c) { + overrides_.rbSize = *c ? 1 : 0; + } + if (const auto &c = controls.get(controls::rkisp1::DpfNoiseLevelLookupCoefficients); c) { + if (c->size() == RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS) { + DpfNllSettings nll; + std::copy_n(c->begin(), RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS, + nll.coeffs.begin()); + nll.scaleMode = (config_.nll.scale_mode == + RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC) + ? 1 + : 0; + overrides_.nll = nll; + } + } + if (const auto &c = controls.get(controls::rkisp1::DpfNoiseLevelLookupScaleMode); c) { + if (overrides_.nll) { + overrides_.nll->scaleMode = *c ? 1 : 0; + } else { + DpfNllSettings nll; + std::copy_n(std::begin(config_.nll.coeff), + RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS, + nll.coeffs.begin()); + nll.scaleMode = *c ? 1 : 0; + overrides_.nll = nll; + } + } +} + /** * \copydoc libcamera::ipa::Algorithm::queueRequest */ diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h index 928e79d9..4cbd7414 100644 --- a/src/ipa/rkisp1/algorithms/dpf.h +++ b/src/ipa/rkisp1/algorithms/dpf.h @@ -35,6 +35,20 @@ private: struct rkisp1_cif_isp_dpf_strength_config strengthConfig_; struct rkisp1_cif_isp_dpf_config baseConfig_; struct rkisp1_cif_isp_dpf_strength_config baseStrengthConfig_; + struct DpfStrengthSettings { + uint16_t r, g, b; + }; + struct DpfSpatialGreenSettings { + std::array coeffs; + }; + struct DpfSpatialRbSettings { + std::array coeffs; + uint8_t size; /* 0=9x9, 1=13x9 */ + }; + struct DpfNllSettings { + std::array coeffs; + uint8_t scaleMode; /* 0 linear, 1 log */ + }; struct ExposureIndexLevelConfig { uint32_t maxExposureIndex; /* inclusive upper bound */ struct rkisp1_cif_isp_dpf_config dpf; @@ -45,6 +59,14 @@ private: struct rkisp1_cif_isp_dpf_config dpf; struct rkisp1_cif_isp_dpf_strength_config strength; }; + struct Overrides { + std::optional strength; + std::optional spatialGreen; + std::optional spatialRb; + std::optional rbSize; + std::optional nll; + void clear() { *this = Overrides{}; } + } overrides_; std::vector exposureIndexLevels_; std::vector modes_; @@ -56,6 +78,7 @@ private: IPAContext &context, uint32_t frame) override; void loadReductionModeConfig(IPAFrameContext &frameContext); + void collectManualOverrides(const ControlList &controls) override; bool parseConfig(const YamlObject &tuningData) override; bool parseSingleConfig(const YamlObject &tuningData, rkisp1_cif_isp_dpf_config &config, diff --git a/src/libcamera/control_ids_rkisp1.yaml b/src/libcamera/control_ids_rkisp1.yaml index 3e008ee4..bfd59925 100644 --- a/src/libcamera/control_ids_rkisp1.yaml +++ b/src/libcamera/control_ids_rkisp1.yaml @@ -70,4 +70,75 @@ controls: value: 3 description: | Reduction mode - uses predefined noise reduction settings from tuning data. + + - DpfChannelStrengths: + type: int32_t + direction: inout + description: | + Override filter strength for R,G,B channels. Values map to hardware + strength registers (0..255 typical). Size must be exactly 3 when set. + Order: R,G,B. If unset the tuning / exposure index level derived strengths apply. + size: [3] + + - DpfGreenSpatialCoefficients: + type: int32_t + direction: inout + description: | + Override 9x9 green spatial kernel coefficients (6 values). Order must + follow tuning file convention. Each value 0..63 typical. All 6 required + when provided; otherwise ignored. + size: [6] + + - DpfRedBlueSpatialCoefficients: + type: int32_t + direction: inout + description: | + Override Red/Blue spatial kernel coefficients (6 values). Applies to + either 9x9 or 13x9 depending on DpfRbFilterSize. For 9x9 the last + column pair is dropped in hardware. Values 0..63 typical. + size: [6] + + - DpfRbFilterSize: + type: int32_t + direction: inout + description: | + Override RB spatial filter size selection. + enum: + - name: DpfRbFilterSize9x9 + value: 0 + description: Use 9x9 RB domain filter. + - name: DpfRbFilterSize13x9 + value: 1 + description: Use 13x9 RB domain filter (if coefficients valid). + + - DpfNoiseLevelLookupCoefficients: + type: int32_t + direction: inout + description: | + Override Noise Level Lookup (NLL) piecewise-linear coefficients + (17 values). Must supply full set when used or override is ignored. + size: [17] + + - DpfNoiseLevelLookupScaleMode: + type: int32_t + direction: inout + description: | + Override NLL scale mode (0=linear,1=logarithmic). Matches hardware + RKISP1_CIF_ISP_NLL_SCALE_* constants. + enum: + - name: DpfNoiseLevelLookupScaleLinear + value: 0 + description: Linear scale. + - name: DpfNoiseLevelLookupScaleLogarithmic + value: 1 + description: Logarithmic scale. + + - ExposureGainIndex: + type: int32_t + direction: out + description: | + Estimated scene exposure gain index used for Denoise tuning selection. Derived + from analogue gain (approx index = gain * 100). Provided each frame + for client awareness and debugging. Range 0..409600. + ...