[libcamera-devel] [PATCH v3 17/23] ipa: ipu3: Configure IPA with libcamera controls

Jacopo Mondi jacopo at jmondi.org
Thu Jun 30 15:38:56 CEST 2022


Pass to the IPA configure() function the list of libcamera
controls::internal controls in place of sending to the IPA the
raw V4L2 control values.

As V4L2 controls are removed from the list of arguments passed to
IPA::configure(), fetch the vertical blanking value from the
CameraSensorInfo now that it is available there.

While at it, rationalize the sequence of operations IPA::configure() to:
- check the validity of the configuration
- update the session configuration
- configure algorithm
- assign class member variables

Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
---
 src/ipa/ipu3/ipa_context.cpp         |  4 +-
 src/ipa/ipu3/ipa_context.h           |  2 +-
 src/ipa/ipu3/ipu3.cpp                | 79 +++++++++++-----------------
 src/libcamera/pipeline/ipu3/ipu3.cpp |  2 +-
 4 files changed, 36 insertions(+), 51 deletions(-)

diff --git a/src/ipa/ipu3/ipa_context.cpp b/src/ipa/ipu3/ipa_context.cpp
index 13cdb835ef7f..06fdf2a1efc7 100644
--- a/src/ipa/ipu3/ipa_context.cpp
+++ b/src/ipa/ipu3/ipa_context.cpp
@@ -126,8 +126,8 @@ namespace libcamera::ipa::ipu3 {
  * \var IPASessionConfiguration::sensor.lineDuration
  * \brief Line duration in microseconds
  *
- * \var IPASessionConfiguration::sensor.defVBlank
- * \brief The default vblank value of the sensor
+ * \var IPASessionConfiguration::sensor.vBlank
+ * \brief The vertical blanking expressed in number of lines
  */
 
 /**
diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h
index 42e11141d3a1..a5b878ab7792 100644
--- a/src/ipa/ipu3/ipa_context.h
+++ b/src/ipa/ipu3/ipa_context.h
@@ -43,7 +43,7 @@ struct IPASessionConfiguration {
 	} agc;
 
 	struct {
-		int32_t defVBlank;
+		int32_t vBlank;
 		utils::Duration lineDuration;
 	} sensor;
 };
diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
index a6e5dcbaada9..44a7d13225df 100644
--- a/src/ipa/ipu3/ipu3.cpp
+++ b/src/ipa/ipu3/ipu3.cpp
@@ -28,6 +28,7 @@
 #include <libcamera/ipa/ipu3_ipa_interface.h>
 #include <libcamera/request.h>
 
+#include "libcamera/internal/control_ids.h"
 #include "libcamera/internal/mapped_framebuffer.h"
 
 #include "algorithms/af.h"
@@ -148,9 +149,9 @@ public:
 				const uint32_t bufferId,
 				const ControlList &sensorControls) override;
 private:
-	void updateSessionConfiguration(const ControlInfoMap &sensorControls);
+	void updateSessionConfiguration(const IPAConfigInfo &info);
 
-	bool validateSensorControls();
+	bool validateSensorControls(const ControlInfoMap &sensorControls);
 
 	void setControls(unsigned int frame);
 	void calculateBdsGrid(const Size &bdsOutputSize);
@@ -176,18 +177,12 @@ private:
  * \brief Compute IPASessionConfiguration using the sensor information and the
  * sensor V4L2 controls
  */
-void IPAIPU3::updateSessionConfiguration(const ControlInfoMap &sensorControls)
+void IPAIPU3::updateSessionConfiguration(const IPAConfigInfo &info)
 {
-	const ControlInfo vBlank = sensorControls.find(V4L2_CID_VBLANK)->second;
-	context_.configuration.sensor.defVBlank = vBlank.def().get<int32_t>();
+	const IPACameraSensorInfo &sensorInfo = info.sensorInfo;
+	context_.configuration.sensor.vBlank = sensorInfo.vblank;
 
-	const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second;
-	int32_t minExposure = v4l2Exposure.min().get<int32_t>();
-	int32_t maxExposure = v4l2Exposure.max().get<int32_t>();
-
-	const ControlInfo &v4l2Gain = sensorControls.find(V4L2_CID_ANALOGUE_GAIN)->second;
-	int32_t minGain = v4l2Gain.min().get<int32_t>();
-	int32_t maxGain = v4l2Gain.max().get<int32_t>();
+	const ControlInfoMap &sensorControls = info.sensorControls;
 
 	/*
 	 * When the AGC computes the new exposure values for a frame, it needs
@@ -196,27 +191,30 @@ void IPAIPU3::updateSessionConfiguration(const ControlInfoMap &sensorControls)
 	 *
 	 * \todo take VBLANK into account for maximum shutter speed
 	 */
-	context_.configuration.agc.minShutterSpeed = minExposure * context_.configuration.sensor.lineDuration;
-	context_.configuration.agc.maxShutterSpeed = maxExposure * context_.configuration.sensor.lineDuration;
-	context_.configuration.agc.minAnalogueGain = camHelper_->gain(minGain);
-	context_.configuration.agc.maxAnalogueGain = camHelper_->gain(maxGain);
+	const ControlInfo &exposure = sensorControls.at(&controls::internal::ExposureTime);
+	context_.configuration.agc.minShutterSpeed = exposure.min().get<int32_t>() * 1.0us;
+	context_.configuration.agc.maxShutterSpeed = exposure.max().get<int32_t>() * 1.0us;
+
+	const ControlInfo &gain = sensorControls.at(&controls::internal::AnalogueGain);
+	context_.configuration.agc.minAnalogueGain = gain.min().get<float>();
+	context_.configuration.agc.maxAnalogueGain = gain.max().get<float>();
 }
 
 /**
  * \brief Validate that the sensor controls mandatory for the IPA exists
  */
-bool IPAIPU3::validateSensorControls()
+bool IPAIPU3::validateSensorControls(const ControlInfoMap &sensorControls)
 {
-	static const uint32_t ctrls[] = {
-		V4L2_CID_ANALOGUE_GAIN,
-		V4L2_CID_EXPOSURE,
-		V4L2_CID_VBLANK,
+	static constexpr std::array<const ControlId *, 3> ctrls = {
+		&controls::internal::ExposureTime,
+		&controls::internal::FrameDuration,
+		&controls::internal::AnalogueGain,
 	};
 
-	for (auto c : ctrls) {
-		if (sensorCtrls_.find(c) == sensorCtrls_.end()) {
+	for (const ControlId *c : ctrls) {
+		if (sensorControls.find(c) == sensorControls.end()) {
 			LOG(IPAIPU3, Error) << "Unable to find sensor control "
-					    << utils::hex(c);
+					    << c->name();
 			return false;
 		}
 	}
@@ -362,35 +360,19 @@ void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize)
  */
 int IPAIPU3::configure(const IPAConfigInfo &configInfo)
 {
-	if (configInfo.sensorControls.empty()) {
-		LOG(IPAIPU3, Error) << "No sensor controls provided";
-		return -ENODATA;
+	if (!validateSensorControls(configInfo.sensorControls)) {
+		LOG(IPAIPU3, Error) << "Sensor control validation failed.";
+		return -EINVAL;
 	}
 
-	sensorInfo_ = configInfo.sensorInfo;
-
-	lensCtrls_ = configInfo.lensControls;
-
-	/*
-	 * Compute the sensor V4L2 controls to be used by the algorithms and
-	 * to be set on the sensor.
-	 */
-	sensorCtrls_ = configInfo.sensorControls;
-
-	calculateBdsGrid(configInfo.bdsOutputSize);
-
 	/* Clean IPAActiveState at each reconfiguration. */
 	context_.activeState = {};
 	IPAFrameContext initFrameContext;
 	context_.frameContexts.fill(initFrameContext);
 
-	if (!validateSensorControls()) {
-		LOG(IPAIPU3, Error) << "Sensor control validation failed.";
-		return -EINVAL;
-	}
-
 	/* Update the IPASessionConfiguration using the sensor settings. */
-	updateSessionConfiguration(sensorCtrls_);
+	updateSessionConfiguration(configInfo);
+	calculateBdsGrid(configInfo.bdsOutputSize);
 
 	for (auto const &algo : algorithms_) {
 		int ret = algo->configure(context_, configInfo);
@@ -398,6 +380,10 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo)
 			return ret;
 	}
 
+	sensorInfo_ = configInfo.sensorInfo;
+	lensCtrls_ = configInfo.lensControls;
+	sensorCtrls_ = configInfo.sensorControls;
+
 	return 0;
 }
 
@@ -500,7 +486,7 @@ void IPAIPU3::processStatsBuffer(const uint32_t frame,
 	frameContext.sensor.gain = camHelper_->gain(sensorControls.get(V4L2_CID_ANALOGUE_GAIN).get<int32_t>());
 
 	double lineDuration = context_.configuration.sensor.lineDuration.get<std::micro>();
-	int32_t vBlank = context_.configuration.sensor.defVBlank;
+	int32_t vBlank = context_.configuration.sensor.vBlank;
 	ControlList ctrls(controls::controls);
 
 	for (auto const &algo : algorithms_)
@@ -508,7 +494,6 @@ void IPAIPU3::processStatsBuffer(const uint32_t frame,
 
 	setControls(frame);
 
-	/* \todo Use VBlank value calculated from each frame exposure. */
 	int64_t frameDuration = (vBlank + sensorInfo_.outputSize.height) * lineDuration;
 	ctrls.set(controls::FrameDuration, frameDuration);
 
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 8c5b6c36ae0b..ce207c968075 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -659,7 +659,7 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)
 	}
 
 	ipa::ipu3::IPAConfigInfo configInfo;
-	configInfo.sensorControls = data->cio2_.sensor()->v4l2Controls();
+	configInfo.sensorControls = data->cio2_.sensor()->controls();
 
 	CameraLens *lens = data->cio2_.sensor()->focusLens();
 	if (lens)
-- 
2.36.1



More information about the libcamera-devel mailing list