[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