[v3,40/41] libipa: agc: Make startup frames and regulations speed configurable
diff mbox series

Message ID 20260914140309.3354666-41-stefan.klug@ideasonboard.com
State New
Headers show
Series
  • rkisp1: pipeline rework for PFC
Related show

Commit Message

Stefan Klug Sept. 14, 2026, 2:02 p.m. UTC
The rkisp1 has now a good synchronization between sensor settings/isp
params and stats. It can therefore benefit from a faster regulation. To
do that without breaking other IPAs that use AgcMeanLuminance, move
regulation speed and startup frames into configuration parameters that
can be set at runtime.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
---
 src/ipa/libipa/agc.cpp                | 14 ++++++++++++++
 src/ipa/libipa/agc.h                  |  2 ++
 src/ipa/libipa/agc_mean_luminance.cpp | 25 +++++++++++++++++++++----
 src/ipa/libipa/agc_mean_luminance.h   |  3 +++
 4 files changed, 40 insertions(+), 4 deletions(-)

Patch
diff mbox series

diff --git a/src/ipa/libipa/agc.cpp b/src/ipa/libipa/agc.cpp
index a2438cb49d1b..5c06ca475926 100644
--- a/src/ipa/libipa/agc.cpp
+++ b/src/ipa/libipa/agc.cpp
@@ -262,6 +262,15 @@  namespace agc {
  * control only, without automatic adjustments. In this mode statistics
  * must not be provided to AgcAlgorithm::process(), and ExposureTimeMode
  * and AnalogueGainMode will only advertise manual control.
+ *
+ * \var AgcAlgorithm::ConfigurationParams::numStartupFrames
+ * \brief Number of startup frames
+ *
+ * During these frame the regulation speed is set to 1.0 to reach faster
+ * convergence.
+ *
+ * \var AgcAlgorithm::ConfigurationParams::regulationSpeed
+ * \brief The regulation speed
  */
 
 /**
@@ -513,6 +522,11 @@  int AgcAlgorithm::configure(agc::Session &session, agc::ActiveState &state,
 			state.automatic.yTarget = impl.effectiveYTarget(0, 1);
 
 			impl.configure(session.lineDuration, sensor_);
+			if (config.numStartupFrames)
+				impl.numStartupFrames_ = config.numStartupFrames.value();
+
+			if (config.regulationSpeed)
+				impl.regulationSpeed_ = config.regulationSpeed.value();
 
 			if (!session.autoAllowed)
 				return;
diff --git a/src/ipa/libipa/agc.h b/src/ipa/libipa/agc.h
index 4914c9cee24b..a9140e7a3e61 100644
--- a/src/ipa/libipa/agc.h
+++ b/src/ipa/libipa/agc.h
@@ -126,6 +126,8 @@  public:
 		const ControlInfoMap &sensorControls;
 		ControlInfoMap::Map &ctrlMap;
 		bool autoAllowed = true;
+		std::optional<uint32_t> numStartupFrames = std::nullopt;
+		std::optional<double> regulationSpeed = std::nullopt;
 	};
 
 	struct ProcessParams {
diff --git a/src/ipa/libipa/agc_mean_luminance.cpp b/src/ipa/libipa/agc_mean_luminance.cpp
index 72833247c5fd..3244e631517b 100644
--- a/src/ipa/libipa/agc_mean_luminance.cpp
+++ b/src/ipa/libipa/agc_mean_luminance.cpp
@@ -37,7 +37,7 @@  namespace ipa {
  * Number of frames for which to run the algorithm at full speed, before slowing
  * down to prevent large and jarring changes in exposure from frame to frame.
  */
-static constexpr uint32_t kNumStartupFrames = 10;
+static constexpr uint32_t kDefaultNumStartupFrames = 10;
 
 /*
  * Default relative luminance target
@@ -178,7 +178,8 @@  static constexpr unsigned int kDefaultLuxLevel = 500;
  */
 
 AgcMeanLuminance::AgcMeanLuminance()
-	: filteredExposure_(0s), luxWarningEnabled_(true), frameCount_(0)
+	: numStartupFrames_(kDefaultNumStartupFrames), regulationSpeed_(0.2),
+	  filteredExposure_(0s), luxWarningEnabled_(true), frameCount_(0)
 {
 }
 
@@ -587,10 +588,10 @@  double AgcMeanLuminance::effectiveYTarget(double lux, double exposureCompensatio
  */
 utils::Duration AgcMeanLuminance::filterExposure(utils::Duration exposureValue)
 {
-	double speed = 0.2;
+	double speed = regulationSpeed_;
 
 	/* Adapt instantly if we are in startup phase. */
-	if (frameCount_ < kNumStartupFrames)
+	if (frameCount_ < numStartupFrames_)
 		speed = 1.0;
 
 	/*
@@ -701,6 +702,22 @@  AgcMeanLuminance::calculateNewEv(const Params &params)
 	return { exposureModeHelper.splitExposure(newExposureValue), yTarget };
 }
 
+/**
+ * \var AgcMeanLuminance::numStartupFrames_
+ * \brief The number of startup frames
+ *
+ * During this number of frames after startup, the regulation is very aggressive
+ * to reach the target value within one or two cycles.
+ *
+ * \var AgcMeanLuminance::regulationSpeed_
+ * The regulation speed. This controls the speed at which new target values are
+ * applied. The new target value is calculated as:
+ *
+ * \code{.unparsed}
+ * value = target * speed + oldValue * (1.0 - speed)
+ * \endcode
+ */
+
 } /* namespace ipa */
 
 } /* namespace libcamera */
diff --git a/src/ipa/libipa/agc_mean_luminance.h b/src/ipa/libipa/agc_mean_luminance.h
index f799618ffc2c..b7df7ea03702 100644
--- a/src/ipa/libipa/agc_mean_luminance.h
+++ b/src/ipa/libipa/agc_mean_luminance.h
@@ -79,6 +79,9 @@  public:
 
 	double effectiveYTarget(double lux, double exposureCompensation) const;
 
+	uint32_t numStartupFrames_;
+	double regulationSpeed_;
+
 private:
 	int parseRelativeLuminanceTarget(const ValueNode &tuningData);
 	int parseConstraint(const ValueNode &modeDict, int32_t id);