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

Message ID 20260911153918.96470-3-dmanresa@gmail.com
State New
Headers show
Series
  • ipa: ipu3: Take the OV5670 black level from the sensor helper
Related show

Commit Message

D. Manresa Sept. 11, 2026, 3:39 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>
---
 src/ipa/ipu3/algorithms/blc.cpp         | 53 ++++++++++++++++++++-----
 src/ipa/ipu3/algorithms/blc.h           |  5 +++
 src/ipa/libipa/camera_sensor_helper.cpp |  2 +-
 3 files changed, 50 insertions(+), 10 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 */
diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp
index eeb3277..3589b06 100644
--- a/src/ipa/libipa/camera_sensor_helper.cpp
+++ b/src/ipa/libipa/camera_sensor_helper.cpp
@@ -802,7 +802,7 @@  class CameraSensorHelperOv5670 : public CameraSensorHelper
 public:
 	CameraSensorHelperOv5670()
 	{
-		/* Default BLC target of 64 at 10bits, confirmed by measurement. */
+		/* From the OEM black level characterisation: 64 at 10bits. */
 		blackLevel_ = 4096;
 		gain_ = AnalogueGainLinear{ 1, 0, 0, 128 };
 	}