[v2,05/10] ipa: libipa: agc: Configure with frame duration
diff mbox series

Message ID 20251028-exposure-limits-v2-5-a8b5a318323e@ideasonboard.com
State New
Headers show
Series
  • libipa: agc: Calculate exposure limits
Related show

Commit Message

Jacopo Mondi Oct. 28, 2025, 9:31 a.m. UTC
Pass the maximum allowed 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
control in the context.

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

Patch
diff mbox series

diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp
index e303d724ab165bac03ac6bb9d3891a76049cff47..3a9cde22323719d73ac125179dbfcd5158b352ea 100644
--- a/src/ipa/ipu3/algorithms/agc.cpp
+++ b/src/ipa/ipu3/algorithms/agc.cpp
@@ -115,9 +115,13 @@  int Agc::configure(IPAContext &context,
 	context.activeState.agc.constraintMode = constraintModes().begin()->first;
 	context.activeState.agc.exposureMode = exposureModeHelpers().begin()->first;
 
+	ControlInfo &frameDurationLimits = context.ctrlMap[&controls::FrameDurationLimits];
+
 	AgcMeanLuminance::AgcSensorConfiguration sensorConfig;
 	sensorConfig.lineDuration = context.configuration.sensor.lineDuration;
 	sensorConfig.minExposureTime = minExposureTime_;
+	sensorConfig.maxFrameDuration =
+		std::chrono::microseconds(frameDurationLimits.max().get<int64_t>());
 	sensorConfig.maxExposureTime = maxExposureTime_;
 	sensorConfig.minAnalogueGain = minAnalogueGain_;
 	sensorConfig.maxAnalogueGain = maxAnalogueGain_;
diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
index 36d8f0da430a3d4f94e2a3f760850519742ea992..5e7a3d2e1bb8d33d88c5f721d4c25e041cfb2a6e 100644
--- a/src/ipa/ipu3/ipu3.cpp
+++ b/src/ipa/ipu3/ipu3.cpp
@@ -278,11 +278,10 @@  void IPAIPU3::updateControls(const IPACameraSensorInfo &sensorInfo,
 		frameDurations[i] = frameSize / (sensorInfo.pixelRate / 1000000U);
 	}
 
-	controls[&controls::FrameDurationLimits] = ControlInfo(frameDurations[0],
-							       frameDurations[1],
-							       frameDurations[2]);
+	context_.ctrlMap[&controls::FrameDurationLimits] =
+		ControlInfo(frameDurations[0], frameDurations[1], frameDurations[2]);
 
-	controls.merge(context_.ctrlMap);
+	controls.insert(context_.ctrlMap.begin(), context_.ctrlMap.end());
 	*ipaControls = ControlInfoMap(std::move(controls), controls::controls);
 }
 
diff --git a/src/ipa/libipa/agc_mean_luminance.cpp b/src/ipa/libipa/agc_mean_luminance.cpp
index 9886864fc42514040eadb4c0b424796df1f1b6e1..195de2f2e93ce229b8047909b949e1d06ef8d5bf 100644
--- a/src/ipa/libipa/agc_mean_luminance.cpp
+++ b/src/ipa/libipa/agc_mean_luminance.cpp
@@ -121,6 +121,11 @@  static constexpr double kMaxRelativeLuminanceTarget = 0.95;
  * \brief The sensor maximum exposure time in microseconds
  */
 
+/**
+ * \var AgcMeanLuminance::AgcSensorConfiguration::maxFrameDuration
+ * \brief The sensor maximum frame duration in microseconds
+ */
+
 /**
  * \var AgcMeanLuminance::AgcSensorConfiguration::minAnalogueGain
  * \brief The sensor minimum analogue gain absolute value
@@ -363,6 +368,7 @@  void AgcMeanLuminance::configure(const AgcSensorConfiguration &config,
 	for (auto &[id, helper] : exposureModeHelpers_)
 		helper->configure(config.lineDuration,
 				  config.minExposureTime, config.maxExposureTime,
+				  config.maxFrameDuration,
 				  config.minAnalogueGain, config.maxAnalogueGain,
 				  sensorHelper);
 }
diff --git a/src/ipa/libipa/agc_mean_luminance.h b/src/ipa/libipa/agc_mean_luminance.h
index 5ab75a3ac6c550a655f4bb7c8c30419ad8249183..c3d52c0b1cba23af14135dace8b3c13da4ae3e4b 100644
--- a/src/ipa/libipa/agc_mean_luminance.h
+++ b/src/ipa/libipa/agc_mean_luminance.h
@@ -46,6 +46,7 @@  public:
 		utils::Duration lineDuration;
 		utils::Duration minExposureTime;
 		utils::Duration maxExposureTime;
+		utils::Duration maxFrameDuration;
 		double minAnalogueGain;
 		double maxAnalogueGain;
 	};
diff --git a/src/ipa/libipa/exposure_mode_helper.cpp b/src/ipa/libipa/exposure_mode_helper.cpp
index 557e14230ba4e0f120653bc09ea23a29a54cb4c8..edb8f04b245f01119d0d0b0917d10f98c7172dc0 100644
--- a/src/ipa/libipa/exposure_mode_helper.cpp
+++ b/src/ipa/libipa/exposure_mode_helper.cpp
@@ -84,6 +84,7 @@  ExposureModeHelper::ExposureModeHelper(const Span<std::pair<utils::Duration, dou
  * \param[in] lineDuration The current line length of the sensor
  * \param[in] minExposureTime The minimum exposure time supported
  * \param[in] maxExposureTime The maximum exposure time supported
+ * \param[in] maxFrameDuration The maximum frame duration
  * \param[in] minGain The minimum analogue gain supported
  * \param[in] maxGain The maximum analogue gain supported
  * \param[in] sensorHelper The sensor helper
@@ -100,12 +101,14 @@  ExposureModeHelper::ExposureModeHelper(const Span<std::pair<utils::Duration, dou
 void ExposureModeHelper::configure(utils::Duration lineDuration,
 				   utils::Duration minExposureTime,
 				   utils::Duration maxExposureTime,
+				   utils::Duration maxFrameDuration,
 				   double minGain, double maxGain,
 				   const CameraSensorHelper *sensorHelper)
 {
 	lineDuration_ = lineDuration;
 	minExposureTime_ = minExposureTime;
 	maxExposureTime_ = maxExposureTime;
+	maxFrameDuration_ = maxFrameDuration;
 	minGain_ = minGain;
 	maxGain_ = maxGain;
 	sensorHelper_ = sensorHelper;
@@ -289,6 +292,12 @@  ExposureModeHelper::splitExposure(utils::Duration exposure) const
  * \return The maxExposureTime_ value
  */
 
+/**
+ * \fn ExposureModeHelper::maxFrameDuration()
+ * \brief Retrieve the configured maximum frame duration set through setLimits()
+ * \return The maxFrameDuration_ value
+ */
+
 /**
  * \fn ExposureModeHelper::minGain()
  * \brief Retrieve the configured minimum gain set through setLimits()
diff --git a/src/ipa/libipa/exposure_mode_helper.h b/src/ipa/libipa/exposure_mode_helper.h
index bb0a692c99b3128a2ee3f15304f125e073721536..8a7d2161912d318c2d1c5c8d009edc8a2d0c0427 100644
--- a/src/ipa/libipa/exposure_mode_helper.h
+++ b/src/ipa/libipa/exposure_mode_helper.h
@@ -27,7 +27,8 @@  public:
 	~ExposureModeHelper() = default;
 
 	void configure(utils::Duration lineLength, utils::Duration minExposureTime,
-		       utils::Duration maxExposureTime, double minGain, double maxGain,
+		       utils::Duration maxExposureTime, utils::Duration maxFrameDuration,
+		       double minGain, double maxGain,
 		       const CameraSensorHelper *sensorHelper);
 	void setLimits(utils::Duration minExposureTime, utils::Duration maxExposureTime,
 		       double minGain, double maxGain);
@@ -37,6 +38,7 @@  public:
 
 	utils::Duration minExposureTime() const { return minExposureTime_; }
 	utils::Duration maxExposureTime() const { return maxExposureTime_; }
+	utils::Duration maxFrameDuration() const { return maxFrameDuration_; }
 	double minGain() const { return minGain_; }
 	double maxGain() const { return maxGain_; }
 
@@ -51,6 +53,7 @@  private:
 	utils::Duration lineDuration_;
 	utils::Duration minExposureTime_;
 	utils::Duration maxExposureTime_;
+	utils::Duration maxFrameDuration_;
 	double minGain_;
 	double maxGain_;
 	const CameraSensorHelper *sensorHelper_;
diff --git a/src/ipa/mali-c55/algorithms/agc.cpp b/src/ipa/mali-c55/algorithms/agc.cpp
index ccf72cc9e8c33b1a516322c2445efa1684b7f751..5bfb4ab17ecb3814a10baec0f619267772ed8b3f 100644
--- a/src/ipa/mali-c55/algorithms/agc.cpp
+++ b/src/ipa/mali-c55/algorithms/agc.cpp
@@ -169,10 +169,14 @@  int Agc::configure(IPAContext &context,
 	context.activeState.agc.constraintMode = constraintModes().begin()->first;
 	context.activeState.agc.exposureMode = exposureModeHelpers().begin()->first;
 
+	ControlInfo &frameDurationLimits = context.ctrlMap[&controls::FrameDurationLimits];
+
 	AgcMeanLuminance::AgcSensorConfiguration sensorConfig;
 	sensorConfig.lineDuration = context.configuration.sensor.lineDuration;
 	sensorConfig.minExposureTime = context.configuration.agc.minShutterSpeed;
 	sensorConfig.maxExposureTime = context.configuration.agc.maxShutterSpeed;
+	sensorConfig.maxFrameDuration =
+		std::chrono::microseconds(frameDurationLimits.max().get<int64_t>());
 	sensorConfig.minAnalogueGain = context.configuration.agc.minAnalogueGain;
 	sensorConfig.maxAnalogueGain = context.configuration.agc.maxAnalogueGain;
 
diff --git a/src/ipa/mali-c55/ipa_context.h b/src/ipa/mali-c55/ipa_context.h
index bfa805c7b93f313dda2497365e83542bbc39e291..ecb2f79c0dca0e41166b88f2608c22aa72adcf8a 100644
--- a/src/ipa/mali-c55/ipa_context.h
+++ b/src/ipa/mali-c55/ipa_context.h
@@ -10,6 +10,8 @@ 
 #include <libcamera/base/utils.h>
 #include <libcamera/controls.h>
 
+#include <libcamera/ipa/core_ipa_interface.h>
+
 #include "libcamera/internal/bayer_format.h"
 
 #include <libipa/camera_sensor_helper.h>
diff --git a/src/ipa/mali-c55/mali-c55.cpp b/src/ipa/mali-c55/mali-c55.cpp
index 0751513dc584ca84dd212bf8c1469dd4b40c053d..12cad7374520db8c6fa5ca233a0ef33dc7b2f287 100644
--- a/src/ipa/mali-c55/mali-c55.cpp
+++ b/src/ipa/mali-c55/mali-c55.cpp
@@ -231,9 +231,8 @@  void IPAMaliC55::updateControls(const IPACameraSensorInfo &sensorInfo,
 		frameDurations[i] = frameSize / (sensorInfo.pixelRate / 1000000U);
 	}
 
-	ctrlMap[&controls::FrameDurationLimits] = ControlInfo(frameDurations[0],
-							      frameDurations[1],
-							      frameDurations[2]);
+	context_.ctrlMap[&controls::FrameDurationLimits] =
+		ControlInfo(frameDurations[0], frameDurations[1], frameDurations[2]);
 
 	/*
 	 * Compute exposure time limits from the V4L2_CID_EXPOSURE control
@@ -258,7 +257,7 @@  void IPAMaliC55::updateControls(const IPACameraSensorInfo &sensorInfo,
 	 * Merge in any controls that we support either statically or from the
 	 * algorithms.
 	 */
-	ctrlMap.merge(context_.ctrlMap);
+	ctrlMap.insert(context_.ctrlMap.begin(), context_.ctrlMap.end());
 
 	*ipaControls = ControlInfoMap(std::move(ctrlMap), controls::controls);
 }
diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp
index 8c07e6a6eac091d949ad71ee967c893897313cc8..121e75449a6985f951c50fdc85b0298026344297 100644
--- a/src/ipa/rkisp1/algorithms/agc.cpp
+++ b/src/ipa/rkisp1/algorithms/agc.cpp
@@ -204,6 +204,7 @@  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.maxFrameDuration = context.activeState.agc.maxFrameDuration;
 	sensorConfig.minAnalogueGain = context.configuration.sensor.minAnalogueGain;
 	sensorConfig.maxAnalogueGain = context.configuration.sensor.maxAnalogueGain;