[v1,16/16] ipa: rkisp1: algorithms: dpf: publish DPF metadata
diff mbox series

Message ID 20251028170847.2673396-16-rui.wang@ideasonboard.com
State New
Headers show
Series
  • [v1,01/16] ipa: rkisp1: algorithms: add Denoise base class shell
Related show

Commit Message

Rui Wang Oct. 28, 2025, 5:08 p.m. UTC
Implement process() and fillMetadata() to publish DPF status and current
configuration values in frame metadata. This allows applications to read
back the active DPF settings.

Metadata published every frame:
- DpfIso: Current ISO value computed from AGC gains
- DpfMode: Current mode (auto/manual)
- DpfChannelStrengths: Active R/G/B strength values

Developer mode metadata (when enabled):
- DpfGreenSpatialCoefficients: Green spatial filter coefficients
- DpfRedBlueSpatialCoefficients: RB spatial filter coefficients
- DpfRbFilterSize: RB filter size (9x9 or 13x9)
- DpfNoiseLevelLookupCoefficients: NLL coefficients
- DpfNoiseLevelLookupScaleMode: NLL scale mode (linear/log)

The metadata acts as control reflection, showing applications what
settings are actually active in the hardware.

Signed-off-by: Rui Wang <rui.wang@ideasonboard.com>
---
 src/ipa/rkisp1/algorithms/denoise.h |  2 +
 src/ipa/rkisp1/algorithms/dpf.cpp   | 58 +++++++++++++++++++++++++++++
 src/ipa/rkisp1/algorithms/dpf.h     |  6 +++
 3 files changed, 66 insertions(+)

Patch
diff mbox series

diff --git a/src/ipa/rkisp1/algorithms/denoise.h b/src/ipa/rkisp1/algorithms/denoise.h
index 53a0b642..fdbf3445 100644
--- a/src/ipa/rkisp1/algorithms/denoise.h
+++ b/src/ipa/rkisp1/algorithms/denoise.h
@@ -62,6 +62,8 @@  protected:
 
 	virtual ControlInfoMap::Map getControlMap() const = 0;
 
+	virtual void fillMetadata(IPAContext &context, IPAFrameContext &frameContext, ControlList &metadata) = 0;
+
 private:
 	bool manualMode_ = false; /**< Current manual/auto mode state */
 	bool devMode_ = false; /**< Developer mode state for advanced controls */
diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp
index 0bbcc9be..734f751e 100644
--- a/src/ipa/rkisp1/algorithms/dpf.cpp
+++ b/src/ipa/rkisp1/algorithms/dpf.cpp
@@ -76,6 +76,10 @@  int Dpf::init([[maybe_unused]] IPAContext &context,
 			<< "DPF init: loaded " << isoLevels_.size()
 			<< " ISO level(s) from tuning";
 	}
+
+	// init controls value from Yaml
+	auto dpfMap = getControlMap();
+	context.ctrlMap.insert(dpfMap.begin(), dpfMap.end());
 	return 0;
 }
 
@@ -665,6 +669,60 @@  void Dpf::prepareManualMode(IPAContext &context, const uint32_t frame,
 	}
 }
 
+/**
+ * \copydoc libcamera::ipa::Algorithm::process
+ */
+void Dpf::process(IPAContext &context, const uint32_t frame [[maybe_unused]],
+		  IPAFrameContext &frameContext,
+		  const rkisp1_stat_buffer *stats [[maybe_unused]],
+		  ControlList &metadata)
+{
+	fillMetadata(context, frameContext, metadata);
+}
+
+void Dpf::fillMetadata(IPAContext &context, IPAFrameContext &frameContext, ControlList &metadata)
+{
+	unsigned iso = computeIso(context, frameContext);
+	metadata.set(controls::rkisp1::DpfIso, static_cast<int32_t>(iso));
+	metadata.set(controls::rkisp1::DpfMode, isManualMode() ? controls::rkisp1::DpfModeManual : controls::rkisp1::DpfModeAuto);
+
+	/* Publish current values every frame (acts like controls.set reflection). */
+
+	/* Strength (R,G,B) - always available */
+	int32_t strength[3] = { (int32_t)strengthConfig_.r,
+				(int32_t)strengthConfig_.g,
+				(int32_t)strengthConfig_.b };
+	metadata.set(controls::rkisp1::DpfChannelStrengths, Span<const int32_t, 3>(strength));
+
+	if (isDevMode()) {
+		/* Advanced controls only in devmode */
+		/* Spatial kernels */
+		int32_t gCoeffs[RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS];
+		int32_t rbCoeffs[RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS];
+		for (unsigned i = 0; i < RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS; ++i) {
+			gCoeffs[i] = config_.g_flt.spatial_coeff[i];
+			rbCoeffs[i] = config_.rb_flt.spatial_coeff[i];
+		}
+		metadata.set(controls::rkisp1::DpfGreenSpatialCoefficients,
+			     Span<const int32_t, RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS>(gCoeffs));
+		metadata.set(controls::rkisp1::DpfRedBlueSpatialCoefficients,
+			     Span<const int32_t, RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS>(rbCoeffs));
+
+		/* RB filter size (0=9x9,1=13x9) */
+		int32_t fltSize = (config_.rb_flt.fltsize == RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9) ? 1 : 0;
+		metadata.set(controls::rkisp1::DpfRbFilterSize, fltSize);
+
+		/* NLL coefficients and scale */
+		int32_t nll[RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS];
+		for (unsigned i = 0; i < RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS; ++i)
+			nll[i] = config_.nll.coeff[i];
+		metadata.set(controls::rkisp1::DpfNoiseLevelLookupCoefficients,
+			     Span<const int32_t, RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS>(nll));
+		int32_t scaleMode = (config_.nll.scale_mode == RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC) ? 1 : 0;
+		metadata.set(controls::rkisp1::DpfNoiseLevelLookupScaleMode, scaleMode);
+	}
+}
+
 REGISTER_IPA_ALGORITHM(Dpf, "Dpf")
 
 } /* namespace ipa::rkisp1::algorithms */
diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h
index 5db50143..02f02869 100644
--- a/src/ipa/rkisp1/algorithms/dpf.h
+++ b/src/ipa/rkisp1/algorithms/dpf.h
@@ -30,6 +30,10 @@  public:
 	void prepare(IPAContext &context, const uint32_t frame,
 		     IPAFrameContext &frameContext,
 		     RkISP1Params *params) override;
+	void process(IPAContext &context, const uint32_t frame [[maybe_unused]],
+		     IPAFrameContext &frameContext,
+		     const rkisp1_stat_buffer *stats [[maybe_unused]],
+		     ControlList &metadata) override;
 
 private:
 	struct rkisp1_cif_isp_dpf_config config_ {
@@ -113,6 +117,8 @@  private:
 			       IPAFrameContext &frameContext, RkISP1Params *params) override;
 
 	ControlInfoMap::Map getControlMap() const override;
+
+	void fillMetadata(IPAContext &context, IPAFrameContext &frameContext, ControlList &metadata) override;
 };
 
 } /* namespace ipa::rkisp1::algorithms */