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