[libcamera-devel,v2,1/3] ipa: ipu3: agc: AGC exposure stability test
diff mbox series

Message ID 20220506051841.70792-2-hpa@redhat.com
State New
Headers show
Series
  • ipa: ipu3: af: Temporarily suspend AWB during AF scanning
Related show

Commit Message

Kate Hsuan May 6, 2022, 5:18 a.m. UTC
The average exposure value is determined to be a baseline for the
stability testing and is formed by the moving average. If the latest
estimated exposure value is in the 90% confidence interval of average
exposure, the stable status will be set to true.

Signed-off-by: Kate Hsuan<hpa@redhat.com>
---
 src/ipa/ipu3/algorithms/agc.cpp | 22 +++++++++++++++++++++-
 src/ipa/ipu3/algorithms/agc.h   |  3 +++
 src/ipa/ipu3/ipa_context.h      |  1 +
 3 files changed, 25 insertions(+), 1 deletion(-)

Patch
diff mbox series

diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp
index 7d4b3503..c115f3bc 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), minShutterSpeed_(0s),
-	  maxShutterSpeed_(0s), filteredExposure_(0s)
+	  maxShutterSpeed_(0s), filteredExposure_(0s), avgExposure_(0)
 {
 }
 
@@ -102,6 +102,8 @@  int Agc::configure(IPAContext &context,
 	frameContext.agc.gain = std::max(minAnalogueGain_, kMinAnalogueGain);
 	frameContext.agc.exposure = 10ms / configuration.sensor.lineDuration;
 
+	frameContext.agc.stable = false;
+
 	frameCount_ = 0;
 	return 0;
 }
@@ -314,6 +316,23 @@  double Agc::estimateLuminance(IPAFrameContext &frameContext,
 	return ySum / (grid.height * grid.width) / 255;
 }
 
+void Agc::evaluateStable(IPAContext &context)
+{
+	uint32_t latestExposure = context.frameContext.agc.exposure;
+	uint32_t upperEx = avgExposure_ + (avgExposure_ * 0.1);
+	uint32_t lowerEx = avgExposure_ - (avgExposure_ * 0.1);
+
+	if (context.frameContext.af.stable) {
+		avgExposure_ = (0.2 * avgExposure_) + ((1 - 0.2) * latestExposure);
+		if (latestExposure > lowerEx && latestExposure < upperEx)
+			context.frameContext.agc.stable = true;
+		else {
+			if (context.frameContext.af.stable)
+				context.frameContext.agc.stable = false;
+		}
+	}
+}
+
 /**
  * \brief Process IPU3 statistics, and run AGC operations
  * \param[in] context The shared IPA context
@@ -359,6 +378,7 @@  void Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats)
 
 	computeExposure(context, yGain, iqMeanGain);
 	frameCount_++;
+	evaluateStable(context);
 }
 
 } /* namespace ipa::ipu3::algorithms */
diff --git a/src/ipa/ipu3/algorithms/agc.h b/src/ipa/ipu3/algorithms/agc.h
index ad705605..56ef2c10 100644
--- a/src/ipa/ipu3/algorithms/agc.h
+++ b/src/ipa/ipu3/algorithms/agc.h
@@ -40,6 +40,7 @@  private:
 				 const ipu3_uapi_grid_config &grid,
 				 const ipu3_uapi_stats_3a *stats,
 				 double gain);
+	void evaluateStable(IPAContext &context);
 
 	uint64_t frameCount_;
 
@@ -51,6 +52,8 @@  private:
 
 	utils::Duration filteredExposure_;
 
+	uint32_t avgExposure_;
+
 	uint32_t stride_;
 };
 
diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h
index 103498ef..ddef4e74 100644
--- a/src/ipa/ipu3/ipa_context.h
+++ b/src/ipa/ipu3/ipa_context.h
@@ -52,6 +52,7 @@  struct IPAFrameContext {
 	struct {
 		uint32_t exposure;
 		double gain;
+		bool stable;
 	} agc;
 
 	struct {