[RFC,v3,29/50] ipa: libipa: agc: Calculate vblank and frame duration sooner
diff mbox series

Message ID 20260803131435.153927-30-barnabas.pocze@ideasonboard.com
State New
Headers show
Series
  • ipa: libipa: agc rework
Related show

Commit Message

Barnabás Pőcze Aug. 3, 2026, 1:14 p.m. UTC
Calculating the vblank and frame duration is problematic in `process()`
because at the moment it is calculated for an already finished frame
based on the new suggested exposure time.

Instead, move the calculation to `prepare()` where the frame's
exposure and gain are finalized.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
---
 src/ipa/libipa/agc.cpp | 29 ++++++++++++++---------------
 src/ipa/libipa/agc.h   |  3 ++-
 2 files changed, 16 insertions(+), 16 deletions(-)

Patch
diff mbox series

diff --git a/src/ipa/libipa/agc.cpp b/src/ipa/libipa/agc.cpp
index f420dfdce4..69f731569e 100644
--- a/src/ipa/libipa/agc.cpp
+++ b/src/ipa/libipa/agc.cpp
@@ -502,7 +502,7 @@  void AgcAlgorithm::queueRequest(const agc::Session &session, agc::ActiveState &s
 /**
  * \brief Handle a \a prepare operation
  */
-void AgcAlgorithm::prepare(agc::ActiveState &state, agc::FrameContext &frameContext)
+void AgcAlgorithm::prepare(const agc::Session &session, agc::ActiveState &state, agc::FrameContext &frameContext)
 {
 	uint32_t activeAutoExposure = state.automatic.exposure;
 	double activeAutoGain = state.automatic.gain;
@@ -533,6 +533,19 @@  void AgcAlgorithm::prepare(agc::ActiveState &state, agc::FrameContext &frameCont
 	}
 
 	frameContext.yTarget = state.automatic.yTarget;
+
+	/*
+	 * Expand the target frame duration so that we do not run faster than
+	 * the minimum frame duration when we have short exposures.
+	 */
+	const auto frameDuration = std::max<uint32_t>(
+		frameContext.minFrameDuration / session.lineDuration,
+		frameContext.exposure);
+	frameContext.vblank = frameDuration - session.sensor.outputSize.height;
+
+	/* Update frame duration accounting for line length quantization. */
+	frameContext.frameDuration =
+		(session.sensor.outputSize.height + frameContext.vblank) * session.lineDuration;
 }
 
 /**
@@ -543,7 +556,6 @@  void AgcAlgorithm::process(const agc::Session &session, agc::ActiveState &state,
 			   ControlList &metadata)
 {
 	const utils::Duration &lineDuration = session.lineDuration;
-	utils::Duration newExposureTime = {};
 
 	if (params) {
 		ASSERT(session.autoAllowed);
@@ -603,8 +615,6 @@  void AgcAlgorithm::process(const agc::Session &session, agc::ActiveState &state,
 		state.automatic.digitalGain = newEv.digitalGain;
 		state.automatic.yTarget = newEv.yTarget;
 
-		newExposureTime = newEv.exposureTime;
-
 		LOG(Agc, Debug)
 			<< "exposure-time:" << utils::Duration(state.automatic.exposure * lineDuration)
 			<< " analogue-gain:" << state.automatic.gain
@@ -612,17 +622,6 @@  void AgcAlgorithm::process(const agc::Session &session, agc::ActiveState &state,
 			<< " digital-gain:" << state.automatic.digitalGain;
 	}
 
-	/*
-	 * Expand the target frame duration so that we do not run faster than
-	 * the minimum frame duration when we have short exposures.
-	 */
-	const auto frameDuration = std::max(frameContext.minFrameDuration, newExposureTime);
-	frameContext.vblank = (frameDuration / lineDuration) - session.sensor.outputSize.height;
-
-	/* Update frame duration accounting for line length quantization. */
-	frameContext.frameDuration =
-		(session.sensor.outputSize.height + frameContext.vblank) * lineDuration;
-
 	metadata.set(controls::AnalogueGain, frameContext.gain);
 	metadata.set(controls::ExposureTime,
 		     utils::Duration(lineDuration * frameContext.exposure).get<std::micro>());
diff --git a/src/ipa/libipa/agc.h b/src/ipa/libipa/agc.h
index b0f811e93d..e96c6926b2 100644
--- a/src/ipa/libipa/agc.h
+++ b/src/ipa/libipa/agc.h
@@ -126,7 +126,8 @@  public:
 	void queueRequest(const agc::Session &session, agc::ActiveState &state,
 			  agc::FrameContext &frameContext, const ControlList &controls);
 
-	void prepare(agc::ActiveState &state, agc::FrameContext &frameContext);
+	void prepare(const agc::Session &session, agc::ActiveState &state,
+		     agc::FrameContext &frameContext);
 
 	struct ProcessParams {
 		const AgcMeanLuminance::Traits &traits;