[v3,11/19] ipa: libipa: agc: Pass the frame duration to configure()
diff mbox series

Message ID 20251114-exposure-limits-v3-11-b7c07feba026@ideasonboard.com
State New
Headers show
Series
  • libipa: agc: Calculate exposure limits
Related show

Commit Message

Jacopo Mondi Nov. 14, 2025, 2:17 p.m. UTC
Pass the min/max sensor frame duration to the AGC configure()
operation.

This prepares for limiting the exposure time to the frame duration.

In order to be able to provide to the AGC the frame duration in the IPU3
and Mali-C55 IPAs it is necessary to store the FrameDurationLimits in
the context sensor configuration, like it was already done for the
RkISP1 IPA.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
---
 src/ipa/ipu3/algorithms/agc.cpp       |  2 ++
 src/ipa/ipu3/ipa_context.h            |  4 ++++
 src/ipa/ipu3/ipu3.cpp                 | 18 +++++++++++++++---
 src/ipa/libipa/agc_mean_luminance.cpp |  8 ++++++++
 src/ipa/libipa/agc_mean_luminance.h   |  2 ++
 src/ipa/mali-c55/algorithms/agc.cpp   |  6 ++++++
 src/ipa/mali-c55/ipa_context.h        |  4 ++++
 src/ipa/mali-c55/mali-c55.cpp         | 17 ++++++++++++-----
 src/ipa/rkisp1/algorithms/agc.cpp     |  2 ++
 9 files changed, 55 insertions(+), 8 deletions(-)

Patch
diff mbox series

diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp
index 5c72806dede5f55459bde69ab8cfaebc495c7560..002ee574c02b79c25834a9d87a5881a9de52e39e 100644
--- a/src/ipa/ipu3/algorithms/agc.cpp
+++ b/src/ipa/ipu3/algorithms/agc.cpp
@@ -118,6 +118,8 @@  int Agc::configure(IPAContext &context,
 	AgcMeanLuminance::SensorConfiguration sensorConfig;
 	sensorConfig.lineDuration = context.configuration.sensor.lineDuration;
 	sensorConfig.minExposureTime = minExposureTime_;
+	sensorConfig.minFrameDuration = context.configuration.sensor.minFrameDuration;
+	sensorConfig.maxFrameDuration = context.configuration.sensor.maxFrameDuration;
 	sensorConfig.maxExposureTime = maxExposureTime_;
 	sensorConfig.minAnalogueGain = minAnalogueGain_;
 	sensorConfig.maxAnalogueGain = maxAnalogueGain_;
diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h
index baf84b8cbc9a1ff9411c0a994e35317b613580dd..33f3fe3ae1b503d47887873046def0835cd53894 100644
--- a/src/ipa/ipu3/ipa_context.h
+++ b/src/ipa/ipu3/ipa_context.h
@@ -39,6 +39,8 @@  struct IPASessionConfiguration {
 		Size size;
 		utils::Duration minExposureTime;
 		utils::Duration maxExposureTime;
+		utils::Duration minFrameDuration;
+		utils::Duration maxFrameDuration;
 		double minAnalogueGain;
 		double maxAnalogueGain;
 	} sensor;
@@ -56,6 +58,8 @@  struct IPAActiveState {
 		double gain;
 		uint32_t constraintMode;
 		uint32_t exposureMode;
+		utils::Duration minFrameDuration;
+		utils::Duration maxFrameDuration;
 	} agc;
 
 	struct {
diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
index 60f22727a0f75e374b53fb6d3185946b70c25582..0c8651c5235f9e4e9944eb88595aeef41f016310 100644
--- a/src/ipa/ipu3/ipu3.cpp
+++ b/src/ipa/ipu3/ipu3.cpp
@@ -167,7 +167,8 @@  private:
 	void updateControls(const IPACameraSensorInfo &sensorInfo,
 			    const ControlInfoMap &sensorControls,
 			    ControlInfoMap *ipaControls);
-	void updateSessionConfiguration(const ControlInfoMap &sensorControls);
+	void updateSessionConfiguration(const IPACameraSensorInfo &sensorInfo,
+					const ControlInfoMap &sensorControls);
 
 	void setControls(unsigned int frame);
 	void calculateBdsGrid(const Size &bdsOutputSize);
@@ -197,7 +198,8 @@  std::string IPAIPU3::logPrefix() const
  * \brief Compute IPASessionConfiguration using the sensor information and the
  * sensor V4L2 controls
  */
-void IPAIPU3::updateSessionConfiguration(const ControlInfoMap &sensorControls)
+void IPAIPU3::updateSessionConfiguration(const IPACameraSensorInfo &sensorInfo,
+					 const ControlInfoMap &sensorControls)
 {
 	const ControlInfo vBlank = sensorControls.find(V4L2_CID_VBLANK)->second;
 	context_.configuration.sensor.defVBlank = vBlank.def().get<int32_t>();
@@ -210,6 +212,12 @@  void IPAIPU3::updateSessionConfiguration(const ControlInfoMap &sensorControls)
 	int32_t minGain = v4l2Gain.min().get<int32_t>();
 	int32_t maxGain = v4l2Gain.max().get<int32_t>();
 
+	const ControlInfo &v4l2VBlank = sensorControls.find(V4L2_CID_VBLANK)->second;
+	std::array<uint32_t, 2> frameHeights{
+		v4l2VBlank.min().get<int32_t>() + sensorInfo.outputSize.height,
+		v4l2VBlank.max().get<int32_t>() + sensorInfo.outputSize.height,
+	};
+
 	/*
 	 * When the AGC computes the new exposure values for a frame, it needs
 	 * to know the limits for exposure time and analogue gain.
@@ -219,6 +227,10 @@  void IPAIPU3::updateSessionConfiguration(const ControlInfoMap &sensorControls)
 	 */
 	context_.configuration.sensor.minExposureTime = minExposure * context_.configuration.sensor.lineDuration;
 	context_.configuration.sensor.maxExposureTime = maxExposure * context_.configuration.sensor.lineDuration;
+	context_.configuration.sensor.minFrameDuration = frameHeights[0] *
+							 context_.configuration.sensor.lineDuration;
+	context_.configuration.sensor.maxFrameDuration = frameHeights[1] *
+							 context_.configuration.sensor.lineDuration;
 	context_.configuration.sensor.minAnalogueGain = context_.camHelper->gain(minGain);
 	context_.configuration.sensor.maxAnalogueGain = context_.camHelper->gain(maxGain);
 }
@@ -488,7 +500,7 @@  int IPAIPU3::configure(const IPAConfigInfo &configInfo,
 	updateControls(sensorInfo_, sensorCtrls_, ipaControls);
 
 	/* Update the IPASessionConfiguration using the sensor settings. */
-	updateSessionConfiguration(sensorCtrls_);
+	updateSessionConfiguration(sensorInfo_, sensorCtrls_);
 
 	for (auto const &algo : algorithms()) {
 		int ret = algo->configure(context_, configInfo);
diff --git a/src/ipa/libipa/agc_mean_luminance.cpp b/src/ipa/libipa/agc_mean_luminance.cpp
index 512e153791f5b98da01efad6675192a5358e7698..602050729fd08649e2db8d07623a8a39e7a53a77 100644
--- a/src/ipa/libipa/agc_mean_luminance.cpp
+++ b/src/ipa/libipa/agc_mean_luminance.cpp
@@ -117,6 +117,12 @@  static constexpr double kMaxRelativeLuminanceTarget = 0.95;
  * \var AgcMeanLuminance::SensorConfiguration::maxExposureTime
  * \brief The sensor maximum exposure time in microseconds
  *
+ * \var AgcMeanLuminance::SensorConfiguration::minFrameDuration
+ * \brief The sensor minimum frame duration in microseconds
+ *
+ * \var AgcMeanLuminance::SensorConfiguration::maxFrameDuration
+ * \brief The sensor maximum frame duration in microseconds
+ *
  * \var AgcMeanLuminance::SensorConfiguration::minAnalogueGain
  * \brief The sensor minimum analogue gain absolute value
  *
@@ -366,6 +372,8 @@  void AgcMeanLuminance::configure(const SensorConfiguration &config,
 		sensorConfig.lineDuration_ = config.lineDuration;
 		sensorConfig.minExposureTime_ = config.minExposureTime;
 		sensorConfig.maxExposureTime_ = config.maxExposureTime;
+		sensorConfig.minFrameDuration_ = config.minFrameDuration;
+		sensorConfig.maxFrameDuration_ = config.maxFrameDuration;
 		sensorConfig.minGain_ = config.minAnalogueGain;
 		sensorConfig.maxGain_ = config.maxAnalogueGain;
 
diff --git a/src/ipa/libipa/agc_mean_luminance.h b/src/ipa/libipa/agc_mean_luminance.h
index 42ead74b0cdc197bc2b27aee16918e2b42ea3d08..c3c8ce1cdda9229eca400b730f2ee896e9a0af93 100644
--- a/src/ipa/libipa/agc_mean_luminance.h
+++ b/src/ipa/libipa/agc_mean_luminance.h
@@ -46,6 +46,8 @@  public:
 		utils::Duration lineDuration;
 		utils::Duration minExposureTime;
 		utils::Duration maxExposureTime;
+		utils::Duration minFrameDuration;
+		utils::Duration maxFrameDuration;
 		double minAnalogueGain;
 		double maxAnalogueGain;
 	};
diff --git a/src/ipa/mali-c55/algorithms/agc.cpp b/src/ipa/mali-c55/algorithms/agc.cpp
index d6a1ff5aaca136c387feb8c948053fc83bb664ee..731b29ced1030ecb3f44b83ad28a0691dd5d2f0d 100644
--- a/src/ipa/mali-c55/algorithms/agc.cpp
+++ b/src/ipa/mali-c55/algorithms/agc.cpp
@@ -168,11 +168,17 @@  int Agc::configure(IPAContext &context,
 	context.activeState.agc.manual.ispGain = kMinDigitalGain;
 	context.activeState.agc.constraintMode = constraintModes().begin()->first;
 	context.activeState.agc.exposureMode = exposureModeHelpers().begin()->first;
+	context.activeState.agc.minFrameDuration =
+				context.configuration.sensor.minFrameDuration;
+	context.activeState.agc.maxFrameDuration =
+				context.configuration.sensor.maxFrameDuration;
 
 	AgcMeanLuminance::SensorConfiguration sensorConfig;
 	sensorConfig.lineDuration = context.configuration.sensor.lineDuration;
 	sensorConfig.minExposureTime = context.configuration.sensor.minShutterSpeed;
 	sensorConfig.maxExposureTime = context.configuration.sensor.maxShutterSpeed;
+	sensorConfig.minFrameDuration = context.configuration.sensor.minFrameDuration;
+	sensorConfig.maxFrameDuration = context.configuration.sensor.maxFrameDuration;
 	sensorConfig.minAnalogueGain = context.configuration.sensor.minAnalogueGain;
 	sensorConfig.maxAnalogueGain = context.configuration.sensor.maxAnalogueGain;
 
diff --git a/src/ipa/mali-c55/ipa_context.h b/src/ipa/mali-c55/ipa_context.h
index fe75590ec93302e61a31e4832f5c497aab80cf4d..3b64cb7571729d4af162def5b2316331b3561af1 100644
--- a/src/ipa/mali-c55/ipa_context.h
+++ b/src/ipa/mali-c55/ipa_context.h
@@ -30,6 +30,8 @@  struct IPASessionConfiguration {
 		uint32_t blackLevel;
 		utils::Duration minShutterSpeed;
 		utils::Duration maxShutterSpeed;
+		utils::Duration minFrameDuration;
+		utils::Duration maxFrameDuration;
 		double minAnalogueGain;
 		double maxAnalogueGain;
 	} sensor;
@@ -51,6 +53,8 @@  struct IPAActiveState {
 		uint32_t constraintMode;
 		uint32_t exposureMode;
 		uint32_t temperatureK;
+		utils::Duration minFrameDuration;
+		utils::Duration maxFrameDuration;
 	} agc;
 
 	struct {
diff --git a/src/ipa/mali-c55/mali-c55.cpp b/src/ipa/mali-c55/mali-c55.cpp
index 9375facf7ab559853986f66634d4e36b896361c8..491ae71a06dbede967bfbe1bcdcab25d177ad691 100644
--- a/src/ipa/mali-c55/mali-c55.cpp
+++ b/src/ipa/mali-c55/mali-c55.cpp
@@ -177,16 +177,23 @@  void IPAMaliC55::updateSessionConfiguration(const IPACameraSensorInfo &info,
 	int32_t minGain = v4l2Gain.min().get<int32_t>();
 	int32_t maxGain = v4l2Gain.max().get<int32_t>();
 
+	const ControlInfo &v4l2VBlank = sensorControls.find(V4L2_CID_VBLANK)->second;
+	std::array<uint32_t, 2> frameHeights{
+		v4l2VBlank.min().get<int32_t>() + info.outputSize.height,
+		v4l2VBlank.max().get<int32_t>() + info.outputSize.height,
+	};
+
 	/*
 	 * When the AGC computes the new exposure values for a frame, it needs
 	 * to know the limits for shutter speed and analogue gain.
 	 * As it depends on the sensor, update it with the controls.
-	 *
-	 * \todo take VBLANK into account for maximum shutter speed
 	 */
-	context_.configuration.sensor.lineDuration = info.minLineLength * 1.0s / info.pixelRate;
-	context_.configuration.sensor.minShutterSpeed = minExposure * context_.configuration.sensor.lineDuration;
-	context_.configuration.sensor.maxShutterSpeed = maxExposure * context_.configuration.sensor.lineDuration;
+	utils::Duration lineDuration = info.minLineLength * 1.0s / info.pixelRate;
+	context_.configuration.sensor.lineDuration = lineDuration;
+	context_.configuration.sensor.minShutterSpeed = minExposure * lineDuration;
+	context_.configuration.sensor.maxShutterSpeed = maxExposure * lineDuration;
+	context_.configuration.sensor.minFrameDuration = frameHeights[0] * lineDuration;
+	context_.configuration.sensor.maxFrameDuration = frameHeights[1] * lineDuration;
 	context_.configuration.sensor.minAnalogueGain = context_.camHelper->gain(minGain);
 	context_.configuration.sensor.maxAnalogueGain = context_.camHelper->gain(maxGain);
 
diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp
index b0c8966eea63901640bbe16af2a5d8a303c63ece..de2980485f2d3a8973f065981f8cdd520e3dfc47 100644
--- a/src/ipa/rkisp1/algorithms/agc.cpp
+++ b/src/ipa/rkisp1/algorithms/agc.cpp
@@ -204,6 +204,8 @@  int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)
 	sensorConfig.lineDuration = context.configuration.sensor.lineDuration;
 	sensorConfig.minExposureTime = context.configuration.sensor.minExposureTime;
 	sensorConfig.maxExposureTime = context.configuration.sensor.maxExposureTime;
+	sensorConfig.minFrameDuration = context.configuration.sensor.minFrameDuration;
+	sensorConfig.maxFrameDuration = context.configuration.sensor.maxFrameDuration;
 	sensorConfig.minAnalogueGain = context.configuration.sensor.minAnalogueGain;
 	sensorConfig.maxAnalogueGain = context.configuration.sensor.maxAnalogueGain;