[libcamera-devel,v2,1/3] ipa: ipu3: Return filtered value
diff mbox series

Message ID 20220207135937.221226-2-jeanmichel.hautbois@ideasonboard.com
State Superseded
Headers show
Series
  • ipa: ipu3: Misc clean up
Related show

Commit Message

Jean-Michel Hautbois Feb. 7, 2022, 1:59 p.m. UTC
When the current exposure value is calculated, it is cached and used by
filterExposure(). Use private filteredExposure_ and pass currentExposure
as a parameter.

In order to limit the use of filteredExposure_, return the value from
filterExposure().

While at it, remove a stale comment.

Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 src/ipa/ipu3/algorithms/agc.cpp | 74 ++++++++++++++++++---------------
 src/ipa/ipu3/algorithms/agc.h   |  3 +-
 2 files changed, 41 insertions(+), 36 deletions(-)

Patch
diff mbox series

diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp
index 8d6f18f6..a929085c 100644
--- a/src/ipa/ipu3/algorithms/agc.cpp
+++ b/src/ipa/ipu3/algorithms/agc.cpp
@@ -72,7 +72,7 @@  static constexpr double kRelativeLuminanceTarget = 0.16;
 
 Agc::Agc()
 	: frameCount_(0), lineDuration_(0s), minShutterSpeed_(0s),
-	  maxShutterSpeed_(0s), filteredExposure_(0s), currentExposure_(0s)
+	  maxShutterSpeed_(0s), filteredExposure_(0s)
 {
 }
 
@@ -143,33 +143,37 @@  double Agc::measureBrightness(const ipu3_uapi_stats_3a *stats,
 
 /**
  * \brief Apply a filter on the exposure value to limit the speed of changes
+ * \param[in] exposureValue The target exposure from the AGC algorithm
+ *
+ * The speed of the filter is adaptive, and will produce the target quicker
+ * during startup, or when the target exposure is within 20% of the most recent
+ * filter output.
+ *
+ * \return The filtered exposure
  */
-void Agc::filterExposure()
+utils::Duration Agc::filterExposure(utils::Duration exposureValue)
 {
 	double speed = 0.2;
 
-	/* Adapt instantly if we are in startup phase */
+	/* Adapt instantly if we are in startup phase. */
 	if (frameCount_ < kNumStartupFrames)
 		speed = 1.0;
 
-	if (filteredExposure_ == 0s) {
-		/* DG stands for digital gain.*/
-		filteredExposure_ = currentExposure_;
-	} else {
-		/*
-		 * If we are close to the desired result, go faster to avoid making
-		 * multiple micro-adjustments.
-		 * \todo Make this customisable?
-		 */
-		if (filteredExposure_ < 1.2 * currentExposure_ &&
-		    filteredExposure_ > 0.8 * currentExposure_)
-			speed = sqrt(speed);
-
-		filteredExposure_ = speed * currentExposure_ +
-				filteredExposure_ * (1.0 - speed);
-	}
+	/*
+	 * If we are close to the desired result, go faster to avoid making
+	 * multiple micro-adjustments.
+	 * \todo Make this customisable?
+	 */
+	if (filteredExposure_ < 1.2 * exposureValue &&
+	    filteredExposure_ > 0.8 * exposureValue)
+		speed = sqrt(speed);
+
+	filteredExposure_ = speed * exposureValue +
+			    filteredExposure_ * (1.0 - speed);
 
-	LOG(IPU3Agc, Debug) << "After filtering, total_exposure " << filteredExposure_;
+	LOG(IPU3Agc, Debug) << "After filtering, exposure " << filteredExposure_;
+
+	return filteredExposure_;
 }
 
 /**
@@ -213,27 +217,29 @@  void Agc::computeExposure(IPAFrameContext &frameContext, double yGain,
 	 * Calculate the current exposure value for the scene as the latest
 	 * exposure value applied multiplied by the new estimated gain.
 	 */
-	currentExposure_ = effectiveExposureValue * evGain;
+	utils::Duration exposureValue = effectiveExposureValue * evGain;
 
 	/* Clamp the exposure value to the min and max authorized */
 	utils::Duration maxTotalExposure = maxShutterSpeed_ * maxAnalogueGain_;
-	currentExposure_ = std::min(currentExposure_, maxTotalExposure);
-	LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_
+	exposureValue = std::min(exposureValue, maxTotalExposure);
+	LOG(IPU3Agc, Debug) << "Target total exposure " << exposureValue
 			    << ", maximum is " << maxTotalExposure;
 
-	/* \todo: estimate if we need to desaturate */
-	filterExposure();
-
-	/* Divide the exposure value as new exposure and gain values */
-	utils::Duration exposureValue = filteredExposure_;
-	utils::Duration shutterTime;
+	/*
+	 * Filter the exposure.
+	 * \todo: estimate if we need to desaturate
+	 */
+	exposureValue = filterExposure(exposureValue);
 
 	/*
-	* Push the shutter time up to the maximum first, and only then
-	* increase the gain.
-	*/
-	shutterTime = std::clamp<utils::Duration>(exposureValue / minAnalogueGain_,
-						  minShutterSpeed_, maxShutterSpeed_);
+	 * Divide the exposure value as new exposure and gain values.
+	 *
+	 * Push the shutter time up to the maximum first, and only then
+	 * increase the gain.
+	 */
+	utils::Duration shutterTime =
+		std::clamp<utils::Duration>(exposureValue / minAnalogueGain_,
+					    minShutterSpeed_, maxShutterSpeed_);
 	double stepGain = std::clamp(exposureValue / shutterTime,
 				     minAnalogueGain_, maxAnalogueGain_);
 	LOG(IPU3Agc, Debug) << "Divided up shutter and gain are "
diff --git a/src/ipa/ipu3/algorithms/agc.h b/src/ipa/ipu3/algorithms/agc.h
index 96ec7005..84bfe045 100644
--- a/src/ipa/ipu3/algorithms/agc.h
+++ b/src/ipa/ipu3/algorithms/agc.h
@@ -33,7 +33,7 @@  public:
 private:
 	double measureBrightness(const ipu3_uapi_stats_3a *stats,
 				 const ipu3_uapi_grid_config &grid) const;
-	void filterExposure();
+	utils::Duration filterExposure(utils::Duration currentExposure);
 	void computeExposure(IPAFrameContext &frameContext, double yGain,
 			     double iqMeanGain);
 	double estimateLuminance(IPAFrameContext &frameContext,
@@ -51,7 +51,6 @@  private:
 	double maxAnalogueGain_;
 
 	utils::Duration filteredExposure_;
-	utils::Duration currentExposure_;
 
 	uint32_t stride_;
 };