[v3,18/19] ipa: libipa: agc: Initialize a sensible frame duration
diff mbox series

Message ID 20251114-exposure-limits-v3-18-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
The AGC algorithm implemented by AgcMeanLuminance splits the desired
exposure between shutter time, analogue and digital gains. It tries to
maximize the shutter time up to the specified limits and then increases
the gains.

When initializing the algorithm at configure() time the IPA modules
have access to the Camera's absolute limits, which might include
a very long maximum frame duration. If such duration is used to clamp
the maximum exposure, the algorithm will maximize the shutter time,
resulting in a very low frame rate.

Try to pick a slighlty saner default of 30, 15 or 10 fps to limit the
maximum shutter time with to provide a reasonable out-of-the-box
behaviour for users. The new frame duration limit calculated by the AGC
algorithm is passed back to the IPA module that shall use it to compute
the right blankings to configure the camera with.

At the moment, only the RkISP1 IPA actually controls the frame duration,
and so it is the only IPA that needs to use the frame duration as
computed by the AGC algorithm.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
---
 src/ipa/libipa/agc_mean_luminance.cpp | 27 ++++++++++++++++++++++++---
 src/ipa/libipa/agc_mean_luminance.h   |  4 ++--
 src/ipa/rkisp1/algorithms/agc.cpp     |  3 ++-
 3 files changed, 28 insertions(+), 6 deletions(-)

Patch
diff mbox series

diff --git a/src/ipa/libipa/agc_mean_luminance.cpp b/src/ipa/libipa/agc_mean_luminance.cpp
index b930e1f7240d4936aa8dc850657bbbf9c2f3a11f..f6768958c0d3d76108561b9455a15c715a89048e 100644
--- a/src/ipa/libipa/agc_mean_luminance.cpp
+++ b/src/ipa/libipa/agc_mean_luminance.cpp
@@ -353,10 +353,29 @@  int AgcMeanLuminance::parseExposureModes(const YamlObject &tuningData)
  * This function configures the exposure mode helpers by providing them the
  * sensor configuration parameters and the sensor helper, so they can correctly
  * take quantization effects into account.
+ *
+ * It computes a reasonable frame duration in the sensor's limits and returns it
+ * to the IPA for configuring the sensor's blankings.
+ *
  */
-void AgcMeanLuminance::configure(const SensorConfiguration &config,
-				 const CameraSensorHelper *sensorHelper)
+utils::Duration AgcMeanLuminance::configure(const SensorConfiguration &config,
+					    const CameraSensorHelper *sensorHelper)
 {
+
+	utils::Duration minFrameDuration = config.minFrameDuration;
+	utils::Duration maxFrameDuration = config.maxFrameDuration;
+
+	static constexpr utils::Duration duration30fps = 33333 * 1us;
+	static constexpr utils::Duration duration15fps = 66666 * 1us;
+	static constexpr utils::Duration duration10fps = 100000 * 1us;
+	utils::Duration frameDuration = minFrameDuration < duration30fps
+				      ? duration30fps
+				        : minFrameDuration < duration15fps
+					? duration15fps
+					  : minFrameDuration < duration10fps
+					  ? duration10fps : minFrameDuration;
+	frameDuration = std::min(frameDuration, maxFrameDuration);
+
 	for (auto &[id, helper] : exposureModeHelpers_) {
 		/*
 		 * Translate from the SensorConfiguration to the
@@ -370,7 +389,7 @@  void AgcMeanLuminance::configure(const SensorConfiguration &config,
 		sensorConfig.lineDuration_ = config.lineDuration;
 		sensorConfig.minExposureTime_ = config.minExposureTime;
 		sensorConfig.minFrameDuration_ = config.minFrameDuration;
-		sensorConfig.maxFrameDuration_ = config.maxFrameDuration;
+		sensorConfig.maxFrameDuration_ = frameDuration;
 		sensorConfig.minGain_ = config.minAnalogueGain;
 		sensorConfig.maxGain_ = config.maxAnalogueGain;
 
@@ -378,6 +397,8 @@  void AgcMeanLuminance::configure(const SensorConfiguration &config,
 	}
 
 	resetFrameCount();
+
+	return frameDuration;
 }
 
 /**
diff --git a/src/ipa/libipa/agc_mean_luminance.h b/src/ipa/libipa/agc_mean_luminance.h
index 93a0959bbd9e0d6ec42248f2d3b19253ad389ae6..d66da7671c313e5acb959018b08a82335b7170b8 100644
--- a/src/ipa/libipa/agc_mean_luminance.h
+++ b/src/ipa/libipa/agc_mean_luminance.h
@@ -51,8 +51,8 @@  public:
 		double maxAnalogueGain;
 	};
 
-	void configure(const SensorConfiguration &config,
-		       const CameraSensorHelper *sensorHelper);
+	utils::Duration configure(const SensorConfiguration &config,
+				  const CameraSensorHelper *sensorHelper);
 	int parseTuningData(const YamlObject &tuningData);
 
 	void setExposureCompensation(double gain)
diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp
index 10498eb6357d8917e299ac24f6c8ba8c33af4eae..eac193b9aadfb17b7b6a02dcff2f3aa0b56dff84 100644
--- a/src/ipa/rkisp1/algorithms/agc.cpp
+++ b/src/ipa/rkisp1/algorithms/agc.cpp
@@ -207,7 +207,8 @@  int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)
 	sensorConfig.minAnalogueGain = context.configuration.sensor.minAnalogueGain;
 	sensorConfig.maxAnalogueGain = context.configuration.sensor.maxAnalogueGain;
 
-	AgcMeanLuminance::configure(sensorConfig, context.camHelper.get());
+	context.activeState.agc.maxFrameDuration =
+		AgcMeanLuminance::configure(sensorConfig, context.camHelper.get());
 
 	context.activeState.agc.automatic.yTarget = effectiveYTarget();