@@ -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
*/
@@ -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 */
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(-)