[libcamera-devel] [PATCH 5/5] ipa: rkisp1: Add support of Defect Pixel Cluster Correction control

Florian Sylvestre fsylvestre at baylibre.com
Wed Jun 22 17:19:18 CEST 2022


The Defect Pixel Cluster Correction algorithm is responsible to minimize
the impact of defective pixels. The on-the-fly method is actually used,
based on coefficient provided by the tuning file.

Signed-off-by: Florian Sylvestre <fsylvestre at baylibre.com>
---
 src/ipa/rkisp1/algorithms/dpcc.cpp    | 273 ++++++++++++++++++++++++++
 src/ipa/rkisp1/algorithms/dpcc.h      |  35 ++++
 src/ipa/rkisp1/algorithms/meson.build |   1 +
 src/ipa/rkisp1/data/ov5640.yaml       |  60 ++++++
 src/ipa/rkisp1/rkisp1.cpp             |   1 +
 5 files changed, 370 insertions(+)
 create mode 100644 src/ipa/rkisp1/algorithms/dpcc.cpp
 create mode 100644 src/ipa/rkisp1/algorithms/dpcc.h

diff --git a/src/ipa/rkisp1/algorithms/dpcc.cpp b/src/ipa/rkisp1/algorithms/dpcc.cpp
new file mode 100644
index 00000000..0c78ba9d
--- /dev/null
+++ b/src/ipa/rkisp1/algorithms/dpcc.cpp
@@ -0,0 +1,273 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021-2022, Ideas On Board
+ *
+ * lsc.cpp - RkISP1 Defect Pixel Cluster Correction control
+ */
+
+#include "dpcc.h"
+
+#include <libcamera/base/log.h>
+
+#include "libcamera/internal/yaml_parser.h"
+#include "linux/rkisp1-config.h"
+
+/**
+ * \file dpcc.h
+ */
+
+namespace libcamera {
+
+namespace ipa::rkisp1::algorithms {
+
+/**
+ * \class DefectPixelClusterCorrection
+ * \brief RkISP1 Defect Pixel Cluster Correction control
+ *
+ * Depending of the sensor quality, some pixels can be defective and then
+ * appear significantly brighter or darker than the other pixels.
+ *
+ * The Defect Pixel Cluster Correction algorithms is responsible to minimize
+ * the impact of the pixels.
+ * This can be done with algorithms applied at run time (on-the-fly method) or
+ * with a table of defective pixels. Only first method is supported for the
+ * moment.
+ */
+
+LOG_DEFINE_CATEGORY(RkISP1Dpcc)
+
+DefectPixelClusterCorrection::DefectPixelClusterCorrection()
+	: tuningParameters_(false)
+{
+}
+
+/**
+ * \copydoc libcamera::ipa::Algorithm::init
+ */
+int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
+				       const YamlObject &tuningData)
+{
+	bool fixedSet = tuningData["fixed-set"].get<bool>(true);
+	tuning_.set_use =
+		fixedSet ? RKISP1_CIF_ISP_DPCC_SET_USE_STAGE1_USE_FIX_SET : 0;
+
+	/* Get all defined sets to apply (up to 3). */
+	const YamlObject &setsObject = tuningData["sets"];
+	if (!setsObject.isList()) {
+		LOG(RkISP1Dpcc, Error)
+			<< "'sets' list parameternot found in tuning file";
+		return -EINVAL;
+	}
+
+	if (setsObject.size() > RKISP1_CIF_ISP_DPCC_METHODS_MAX) {
+		LOG(RkISP1Dpcc, Error)
+			<< "'sets' size in tuning file (" << setsObject.size()
+			<< ") exceed HW maximum capacity(3)";
+		return -EINVAL;
+	}
+
+	tuning_.ro_limits = 0;
+	tuning_.rnd_offs = 0;
+
+	for (std::size_t i = 0; i < setsObject.size(); ++i) {
+		uint16_t value;
+
+		/* Enable set if described in Yaml tuning file. */
+		tuning_.set_use |= 0x1 << i;
+
+		/* Disable all methods by default. */
+		tuning_.methods[i].method = 0;
+
+		/* PG Method */
+		const YamlObject &pgObject = setsObject[i]["pg-factor"];
+		tuning_.methods[i].pg_fac = 0;
+
+		if (pgObject.contains("green")) {
+			tuning_.methods[i].method |=
+				RKISP1_CIF_ISP_DPCC_METHODS_SET_PG_GREEN_ENABLE;
+
+			value = pgObject["green"].get<uint16_t>(0);
+			tuning_.methods[i].pg_fac |=
+				RKISP1_CIF_ISP_DPCC_PG_FAC_G(value);
+		}
+
+		if (pgObject.contains("red-blue")) {
+			tuning_.methods[i].method |=
+				RKISP1_CIF_ISP_DPCC_METHODS_SET_PG_RED_BLUE_ENABLE;
+
+			value = pgObject["red-blue"].get<uint16_t>(0);
+			tuning_.methods[i].pg_fac |=
+				RKISP1_CIF_ISP_DPCC_PG_FAC_RB(value);
+		}
+
+		/* RO Method */
+		const YamlObject &roObject = setsObject[i]["ro-limits"];
+
+		if (roObject.contains("green")) {
+			tuning_.methods[i].method |=
+				RKISP1_CIF_ISP_DPCC_METHODS_SET_RO_GREEN_ENABLE;
+
+			value = roObject["green"].get<uint16_t>(0);
+			tuning_.ro_limits |=
+				RKISP1_CIF_ISP_DPCC_RO_LIMITS_n_G(i, value);
+		}
+
+		if (roObject.contains("red-blue")) {
+			tuning_.methods[i].method |=
+				RKISP1_CIF_ISP_DPCC_METHODS_SET_RO_RED_BLUE_ENABLE;
+
+			value = roObject["red-blue"].get<uint16_t>(0);
+			tuning_.ro_limits |=
+				RKISP1_CIF_ISP_DPCC_RO_LIMITS_n_RB(i, value);
+		}
+
+		/* RG Method */
+		const YamlObject &rgObject = setsObject[i]["rg-factor"];
+		tuning_.methods[i].rg_fac = 0;
+
+		if (rgObject.contains("green")) {
+			tuning_.methods[i].method |=
+				RKISP1_CIF_ISP_DPCC_METHODS_SET_RG_GREEN_ENABLE;
+
+			value = rgObject["green"].get<uint16_t>(0);
+			tuning_.methods[i].rg_fac |=
+				RKISP1_CIF_ISP_DPCC_RG_FAC_G(value);
+		}
+
+		if (rgObject.contains("red-blue")) {
+			tuning_.methods[i].method |=
+				RKISP1_CIF_ISP_DPCC_METHODS_SET_RG_RED_BLUE_ENABLE;
+
+			value = rgObject["red-blue"].get<uint16_t>(0);
+			tuning_.methods[i].rg_fac |=
+				RKISP1_CIF_ISP_DPCC_RG_FAC_RB(value);
+		}
+
+		/* RND Method */
+		const YamlObject &rndOffsetsObject = setsObject[i]["rnd-offsets"];
+
+		if (rndOffsetsObject.contains("green")) {
+			tuning_.methods[i].method |=
+				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE;
+
+			value = rndOffsetsObject["green"].get<uint16_t>(0);
+			tuning_.rnd_offs |=
+				RKISP1_CIF_ISP_DPCC_RND_OFFS_n_G(i, value);
+		}
+
+		if (rndOffsetsObject.contains("red-blue")) {
+			tuning_.methods[i].method |=
+				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE;
+
+			value = rndOffsetsObject["red-blue"].get<uint16_t>(0);
+			tuning_.rnd_offs |=
+				RKISP1_CIF_ISP_DPCC_RND_OFFS_n_RB(i, value);
+		}
+
+		const YamlObject &rndThresholdObject = setsObject[i]["rnd-threshold"];
+		tuning_.methods[i].rnd_thresh = 0;
+
+		if (rndThresholdObject.contains("green")) {
+			tuning_.methods[i].method |=
+				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE;
+
+			value = rndThresholdObject["green"].get<uint16_t>(0);
+			tuning_.methods[i].rnd_thresh |=
+				RKISP1_CIF_ISP_DPCC_RND_THRESH_G(value);
+		}
+
+		if (rndThresholdObject.contains("red-blue")) {
+			tuning_.methods[i].method |=
+				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE;
+
+			value = rndThresholdObject["red-blue"].get<uint16_t>(0);
+			tuning_.methods[i].rnd_thresh |=
+				RKISP1_CIF_ISP_DPCC_RND_THRESH_RB(value);
+		}
+
+		/* LC Method */
+		const YamlObject &lcThresholdObject = setsObject[i]["line-threshold"];
+		tuning_.methods[i].line_thresh = 0;
+
+		if (lcThresholdObject.contains("green")) {
+			tuning_.methods[i].method |=
+				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE;
+
+			value = lcThresholdObject["green"].get<uint16_t>(0);
+			tuning_.methods[i].line_thresh |=
+				RKISP1_CIF_ISP_DPCC_LINE_THRESH_G(value);
+		}
+
+		if (lcThresholdObject.contains("red-blue")) {
+			tuning_.methods[i].method |=
+				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE;
+
+			value = lcThresholdObject["red-blue"].get<uint16_t>(0);
+			tuning_.methods[i].line_thresh |=
+				RKISP1_CIF_ISP_DPCC_LINE_THRESH_RB(value);
+		}
+
+		const YamlObject &lcTMadFactorObject = setsObject[i]["line-mad-factor"];
+		tuning_.methods[i].line_mad_fac = 0;
+
+		if (lcTMadFactorObject.contains("green")) {
+			tuning_.methods[i].method |=
+				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE;
+
+			value = lcTMadFactorObject["green"].get<uint16_t>(0);
+			tuning_.methods[i].line_mad_fac |=
+				RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_G(value);
+		}
+
+		if (lcTMadFactorObject.contains("red-blue")) {
+			tuning_.methods[i].method |=
+				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE;
+
+			value = lcTMadFactorObject["red-blue"].get<uint16_t>(0);
+			tuning_.methods[i].line_mad_fac |=
+				RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_RB(value);
+		}
+	}
+
+	tuningParameters_ = true;
+
+	return 0;
+}
+
+/**
+ * \copydoc libcamera::ipa::Algorithm::prepare
+ */
+void DefectPixelClusterCorrection::prepare(IPAContext &context,
+					   rkisp1_params_cfg *params)
+{
+	if (context.frameContext.frameCount > 0)
+		return;
+
+	if (!tuningParameters_)
+		return;
+
+	params->others.dpcc_config.mode =
+		RKISP1_CIF_ISP_DPCC_MODE_STAGE1_ENABLE;
+	params->others.dpcc_config.output_mode =
+		RKISP1_CIF_ISP_DPCC_OUTPUT_MODE_STAGE1_INCL_G_CENTER |
+		RKISP1_CIF_ISP_DPCC_OUTPUT_MODE_STAGE1_INCL_RB_CENTER;
+	params->others.dpcc_config.rnd_offs = tuning_.rnd_offs;
+	params->others.dpcc_config.ro_limits = tuning_.ro_limits;
+	params->others.dpcc_config.set_use = tuning_.set_use;
+
+	for (std::size_t i = 0; i < RKISP1_CIF_ISP_DPCC_METHODS_MAX; ++i) {
+		memcpy(&params->others.dpcc_config.methods[i],
+		       &tuning_.methods[i],
+		       sizeof(rkisp1_cif_isp_dpcc_methods_config));
+	}
+
+	params->module_en_update |= RKISP1_CIF_ISP_MODULE_DPCC;
+	params->module_ens |= RKISP1_CIF_ISP_MODULE_DPCC;
+	params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_DPCC;
+}
+
+REGISTER_IPA_ALGORITHM(DefectPixelClusterCorrection)
+
+} /* namespace ipa::rkisp1::algorithms */
+
+} /* namespace libcamera */
diff --git a/src/ipa/rkisp1/algorithms/dpcc.h b/src/ipa/rkisp1/algorithms/dpcc.h
new file mode 100644
index 00000000..6c6c6aaa
--- /dev/null
+++ b/src/ipa/rkisp1/algorithms/dpcc.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021-2022, Ideas On Board
+ *
+ * dpcc.h - RkISP1 Defect Pixel Cluster Correction  control
+ */
+
+#pragma once
+
+#include <linux/rkisp1-config.h>
+
+#include "algorithm.h"
+
+namespace libcamera {
+
+struct IPACameraSensorInfo;
+
+namespace ipa::rkisp1::algorithms {
+
+class DefectPixelClusterCorrection : public Algorithm
+{
+public:
+	DefectPixelClusterCorrection();
+	~DefectPixelClusterCorrection() = default;
+
+	int init(IPAContext &context, const YamlObject &tuningData) override;
+	void prepare(IPAContext &context, rkisp1_params_cfg *params) override;
+
+private:
+	bool tuningParameters_;
+	rkisp1_cif_isp_dpcc_config tuning_;
+};
+
+} /* namespace ipa::rkisp1::algorithms */
+} /* namespace libcamera */
diff --git a/src/ipa/rkisp1/algorithms/meson.build b/src/ipa/rkisp1/algorithms/meson.build
index 64e11dce..87007493 100644
--- a/src/ipa/rkisp1/algorithms/meson.build
+++ b/src/ipa/rkisp1/algorithms/meson.build
@@ -4,6 +4,7 @@ rkisp1_ipa_algorithms = files([
     'agc.cpp',
     'awb.cpp',
     'blc.cpp',
+    'dpcc.cpp',
     'gsl.cpp',
     'lsc.cpp',
 ])
diff --git a/src/ipa/rkisp1/data/ov5640.yaml b/src/ipa/rkisp1/data/ov5640.yaml
index 154ed3b5..51228218 100644
--- a/src/ipa/rkisp1/data/ov5640.yaml
+++ b/src/ipa/rkisp1/data/ov5640.yaml
@@ -97,4 +97,64 @@ algorithms:
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           ]
+  - DefectPixelClusterCorrection:
+      fixed-set: false
+      sets:
+        # PG, LC, RO, RND, RG
+        - line-threshold:
+            green: 8
+            red-blue: 8
+          line-mad-factor:
+            green: 4
+            red-blue: 4
+          pg-factor:
+            green: 8
+            red-blue: 8
+          rnd-threshold:
+            green: 10
+            red-blue: 10
+          rg-factor:
+            green: 32
+            red-blue: 32
+          ro-limits:
+            green: 1
+            red-blue: 1
+          rnd-offsets:
+            green: 2
+            red-blue: 2
+        # PG, LC, RO
+        - line-threshold:
+            green: 24
+            red-blue: 32
+          line-mad-factor:
+            green: 16
+            red-blue: 24
+          pg-factor:
+            green: 6
+            red-blue: 8
+          ro-limits:
+            green: 2
+            red-blue: 2
+        # PG, LC, RO, RND, RG
+        - line-threshold:
+            green: 32
+            red-blue: 32
+          line-mad-factor:
+            green: 4
+            red-blue: 4
+          pg-factor:
+            green: 10
+            red-blue: 10
+          rnd-threshold:
+            green: 6
+            red-blue: 8
+          rg-factor:
+            green: 4
+            red-blue: 4
+          ro-limits:
+            green: 1
+            red-blue: 2
+          rnd-offsets:
+            green: 2
+            red-blue: 2
 ...
diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
index 996edc0a..a32bb9d1 100644
--- a/src/ipa/rkisp1/rkisp1.cpp
+++ b/src/ipa/rkisp1/rkisp1.cpp
@@ -31,6 +31,7 @@
 #include "algorithms/algorithm.h"
 #include "algorithms/awb.h"
 #include "algorithms/blc.h"
+#include "algorithms/dpcc.h"
 #include "algorithms/gsl.h"
 #include "algorithms/lsc.h"
 #include "libipa/camera_sensor_helper.h"
-- 
2.34.1



More information about the libcamera-devel mailing list