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