[v1,05/16] ipa: rkisp1: algorithms: dpf: add Dpf parseSingleConfig helper
diff mbox series

Message ID 20251028170847.2673396-5-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
Rework domain filter, NLL, gain, and strength parsing into a
parseSingleConfig() helper. This extracts the parsing logic so it can be
reused for both the base tuning and per-ISO-level configuration blocks.

Signed-off-by: Rui Wang <rui.wang@ideasonboard.com>
---
 src/ipa/rkisp1/algorithms/dpf.cpp | 109 ++++++++++++++++++++++++++++++
 src/ipa/rkisp1/algorithms/dpf.h   |   7 +-
 2 files changed, 115 insertions(+), 1 deletion(-)

Patch
diff mbox series

diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp
index cb6095da..9d1e6435 100644
--- a/src/ipa/rkisp1/algorithms/dpf.cpp
+++ b/src/ipa/rkisp1/algorithms/dpf.cpp
@@ -171,6 +171,115 @@  int Dpf::init([[maybe_unused]] IPAContext &context,
 	return 0;
 }
 
+bool Dpf::parseSingleConfig(const YamlObject &config,
+			    rkisp1_cif_isp_dpf_config &cfg,
+			    rkisp1_cif_isp_dpf_strength_config &strength)
+{
+	/*
+	 * The domain kernel is configured with a 9x9 kernel for the green
+	 * pixels, and a 13x9 or 9x9 kernel for red and blue pixels.
+	 *
+	 * For the green component, we have the 9x9 kernel specified
+	 * as 6 coefficients:
+	 *    Y
+	 *    ^
+	 *  4 | 6   5   4   5   6
+	 *  3 |   5   3   3   5
+	 *  2 | 5   3   2   3   5
+	 *  1 |   3   1   1   3
+	 *  0 - 4   2   0   2   4
+	 * -1 |   3   1   1   3
+	 * -2 | 5   3   2   3   5
+	 * -3 |   5   3   3   5
+	 * -4 | 6   5   4   5   6
+	 *    +---------|--------> X
+	 *     -4....-1 0 1 2 3 4
+	 *
+	 * For the red and blue components, we have the 13x9 kernel specified
+	 * as 6 coefficients:
+	 *
+	 *    Y
+	 *    ^
+	 *  4 | 6   5   4   3   4   5   6
+	 *    |
+	 *  2 | 5   4   2   1   2   4   5
+	 *    |
+	 *  0 - 5   3   1   0   1   3   5
+	 *    |
+	 * -2 | 5   4   2   1   2   4   5
+	 *    |
+	 * -4 | 6   5   4   3   4   5   6
+	 *    +----------|-------------|---> X
+	 *              -6...........-1 0 1......6
+	 *
+	 * For a 9x9 kernel, columns -6 and 6 are dropped, so coefficient
+	 * number 6 is not used.
+	 */
+
+	if (!config.contains("DomainFilter")) {
+		LOG(RkISP1Dpf, Error) << "DomainFilter section missing";
+		return false;
+	}
+	const YamlObject &dFObject = config["DomainFilter"];
+
+	std::vector<uint8_t> gCoeffs;
+	if (!yamlHelper::optList8(dFObject, "g", gCoeffs, RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS))
+		return false;
+	std::copy_n(gCoeffs.begin(), gCoeffs.size(), std::begin(cfg.g_flt.spatial_coeff));
+	cfg.g_flt.gr_enable = true;
+	cfg.g_flt.gb_enable = true;
+
+	uint32_t rbFilterSize;
+	if (!yamlHelper::optFilterCoeffs(dFObject, "rb", cfg.rb_flt.spatial_coeff, rbFilterSize, RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS))
+		return false;
+	cfg.rb_flt.fltsize = rbFilterSize ? RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9 : RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9;
+	cfg.rb_flt.r_enable = true;
+	cfg.rb_flt.b_enable = true;
+
+	if (!config.contains("NoiseLevelFunction")) {
+		LOG(RkISP1Dpf, Error) << "NoiseLevelFunction section missing";
+		return false;
+	}
+	const YamlObject &rFObject = config["NoiseLevelFunction"];
+
+	std::vector<uint16_t> nllCoeffs;
+	if (!yamlHelper::optList16(rFObject, "coeff", nllCoeffs, RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS))
+		return false;
+	std::copy_n(nllCoeffs.begin(), nllCoeffs.size(), std::begin(cfg.nll.coeff));
+
+	const std::map<std::string, uint32_t> scaleModeMap = {
+		{ "linear", RKISP1_CIF_ISP_NLL_SCALE_LINEAR },
+		{ "logarithmic", RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC }
+	};
+	if (!yamlHelper::optEnum<uint32_t>(rFObject, "scale-mode", cfg.nll.scale_mode, RKISP1_CIF_ISP_NLL_SCALE_LINEAR, scaleModeMap)) {
+		LOG(RkISP1Dpf, Error) << "NoiseLevelFunction:scale-mode expected 'linear' or 'logarithmic'";
+		return false;
+	}
+
+	if (!config.contains("Gain")) {
+		LOG(RkISP1Dpf, Error) << "Gain section missing";
+		return false;
+	}
+	const YamlObject &gObject = config["Gain"];
+
+	yamlHelper::opt32(gObject, "gain_mode", cfg.gain.mode, RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS);
+	yamlHelper::opt16(gObject, "nf_r_gain", cfg.gain.nf_r_gain, 256);
+	yamlHelper::opt16(gObject, "nf_b_gain", cfg.gain.nf_b_gain, 256);
+	yamlHelper::opt16(gObject, "nf_gr_gain", cfg.gain.nf_gr_gain, 256);
+	yamlHelper::opt16(gObject, "nf_gb_gain", cfg.gain.nf_gb_gain, 256);
+
+	if (!config.contains("FilterStrength")) {
+		LOG(RkISP1Dpf, Error) << "FilterStrength section missing";
+		return false;
+	}
+	const YamlObject &fSObject = config["FilterStrength"];
+
+	yamlHelper::opt8(fSObject, "r", strength.r, 64);
+	yamlHelper::opt8(fSObject, "g", strength.g, 64);
+	yamlHelper::opt8(fSObject, "b", strength.b, 64);
+	return true;
+}
+
 /**
  * \copydoc libcamera::ipa::Algorithm::queueRequest
  */
diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h
index 2dd8cd36..cfd6ef44 100644
--- a/src/ipa/rkisp1/algorithms/dpf.h
+++ b/src/ipa/rkisp1/algorithms/dpf.h
@@ -10,12 +10,14 @@ 
 #include <sys/types.h>
 
 #include "algorithm.h"
+#include "denoise.h"
+#include "yaml_helper.h"
 
 namespace libcamera {
 
 namespace ipa::rkisp1::algorithms {
 
-class Dpf : public Algorithm
+class Dpf : public DenoiseBaseAlgorithm
 {
 public:
 	Dpf();
@@ -32,6 +34,9 @@  public:
 private:
 	struct rkisp1_cif_isp_dpf_config config_;
 	struct rkisp1_cif_isp_dpf_strength_config strengthConfig_;
+	bool parseSingleConfig(const YamlObject &config,
+			       rkisp1_cif_isp_dpf_config &cfg,
+			       rkisp1_cif_isp_dpf_strength_config &strength);
 };
 
 } /* namespace ipa::rkisp1::algorithms */