[v5,2/2] ipa: ipu3: blc: Use the black level from the camera sensor helper
diff mbox series

Message ID 20261005152231.2024537-2-dmanresa@gmail.com
State New
Headers show
Series
  • [v5,1/2] ipa: libipa: camera_sensor_helper: Add OV5670 black level
Related show

Commit Message

D. Manresa Oct. 5, 2026, 3:22 p.m. UTC
The black level correction algorithm hard-codes an optical black level of
64 for the four Bayer channels. Take it from the camera sensor helper
instead, like the RkISP1 IPA does, falling back to the historical value
with a warning when the helper does not provide one.

Signed-off-by: D. Manresa <dmanresa@gmail.com>
---
Written with the assistance of an AI tool (Claude). libcamera has no
trailer for this and checkstyle.py rejects unknown trailer keys, so it is
noted here rather than in the commit message.

v5: move the camera_sensor_helper comment to 1/2, per Barnabás Pőcze's
review of v4 2/2. The src/ipa/libipa/camera_sensor_helper.cpp hunk is
gone from this patch. No functional change.

 src/ipa/ipu3/algorithms/blc.cpp | 53 +++++++++++++++++++++++++++------
 src/ipa/ipu3/algorithms/blc.h   |  5 ++++
 2 files changed, 49 insertions(+), 9 deletions(-)

Patch
diff mbox series

diff --git a/src/ipa/ipu3/algorithms/blc.cpp b/src/ipa/ipu3/algorithms/blc.cpp
index 35748fb..65ee822 100644
--- a/src/ipa/ipu3/algorithms/blc.cpp
+++ b/src/ipa/ipu3/algorithms/blc.cpp
@@ -7,6 +7,10 @@ 
 
 #include "blc.h"
 
+#include <libcamera/base/log.h>
+
+#include "libipa/camera_sensor_helper.h"
+
 /**
  * \file blc.h
  * \brief IPU3 Black Level Correction control
@@ -30,10 +34,45 @@  namespace ipa::ipu3::algorithms {
  * isn't currently supported.
  */
 
+LOG_DEFINE_CATEGORY(IPU3Blc)
+
+/* Historical value, used when the camera sensor helper has no black level. */
+static constexpr uint16_t kDefaultBlackLevel = 64;
+
 BlackLevelCorrection::BlackLevelCorrection()
+	: blackLevel_(kDefaultBlackLevel)
 {
 }
 
+/**
+ * \copydoc libcamera::ipa::Algorithm::init
+ */
+int BlackLevelCorrection::init(IPAContext &context,
+			       [[maybe_unused]] const ValueNode &tuningData)
+{
+	std::optional<int16_t> blackLevel = context.camHelper->blackLevel();
+	if (!blackLevel) {
+		LOG(IPU3Blc, Warning)
+			<< "No black level provided by camera sensor helper"
+			<< ", please fix";
+		blackLevel_ = kDefaultBlackLevel;
+	} else {
+		/*
+		 * CameraSensorHelper reports the black level as a 16-bit
+		 * value, while experimentation has shown that the ImgU OB grid
+		 * expects it in units of half a 10-bit pixel value: to cancel a
+		 * data pedestal of 16 the ISP has to be configured with 32, and
+		 * to cancel a pedestal of 64 with 128. The 16-bit value is
+		 * therefore shifted right by 5.
+		 */
+		blackLevel_ = *blackLevel >> 5;
+	}
+
+	LOG(IPU3Blc, Debug) << "Black level " << blackLevel_;
+
+	return 0;
+}
+
 /**
  * \brief Fill in the parameter structure, and enable black level correction
  * \param[in] context The shared IPA context
@@ -49,15 +88,11 @@  void BlackLevelCorrection::prepare([[maybe_unused]] IPAContext &context,
 				   [[maybe_unused]] IPAFrameContext &frameContext,
 				   ipu3_uapi_params *params)
 {
-	/*
-	 * The Optical Black Level correction values
-	 * \todo The correction values should come from sensor specific
-	 * tuning processes. This is a first rough approximation.
-	 */
-	params->obgrid_param.gr = 64;
-	params->obgrid_param.r = 64;
-	params->obgrid_param.b = 64;
-	params->obgrid_param.gb = 64;
+	/* The Optical Black Level correction values */
+	params->obgrid_param.gr = blackLevel_;
+	params->obgrid_param.r = blackLevel_;
+	params->obgrid_param.b = blackLevel_;
+	params->obgrid_param.gb = blackLevel_;
 
 	/* Enable the custom black level correction processing */
 	params->use.obgrid = 1;
diff --git a/src/ipa/ipu3/algorithms/blc.h b/src/ipa/ipu3/algorithms/blc.h
index 6274804..bef756f 100644
--- a/src/ipa/ipu3/algorithms/blc.h
+++ b/src/ipa/ipu3/algorithms/blc.h
@@ -18,9 +18,14 @@  class BlackLevelCorrection : public Algorithm
 public:
 	BlackLevelCorrection();
 
+	int init(IPAContext &context, const ValueNode &tuningData) override;
+
 	void prepare(IPAContext &context, const uint32_t frame,
 		     IPAFrameContext &frameContext,
 		     ipu3_uapi_params *params) override;
+
+private:
+	uint16_t blackLevel_;
 };
 
 } /* namespace ipa::ipu3::algorithms */