[libcamera-devel,16/20] ipa: rpi: agc: Add an AGC stable region
diff mbox series

Message ID 20231006132000.23504-17-naush@raspberrypi.com
State Superseded
Headers show
Series
  • Raspberry Pi: Preliminary PiSP support
Related show

Commit Message

Naushir Patuck Oct. 6, 2023, 1:19 p.m. UTC
From: David Plowman <david.plowman@raspberrypi.com>

Add a small "stable region" parameter (defaulting to 2%) within which
the AGC will not adjust the exposure it requests. It allows
applications to configure the AGC to avoid continual micro-adjustments
of exposure values if they are somehow sensitive to it.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
---
 src/ipa/rpi/controller/rpi/agc_channel.cpp | 7 +++++++
 src/ipa/rpi/controller/rpi/agc_channel.h   | 1 +
 2 files changed, 8 insertions(+)

Comments

Jacopo Mondi Oct. 12, 2023, 10:47 a.m. UTC | #1
Hi Naush

On Fri, Oct 06, 2023 at 02:19:56PM +0100, Naushir Patuck via libcamera-devel wrote:
> From: David Plowman <david.plowman@raspberrypi.com>
>
> Add a small "stable region" parameter (defaulting to 2%) within which
> the AGC will not adjust the exposure it requests. It allows
> applications to configure the AGC to avoid continual micro-adjustments
> of exposure values if they are somehow sensitive to it.
>
> Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
> Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
> ---
>  src/ipa/rpi/controller/rpi/agc_channel.cpp | 7 +++++++
>  src/ipa/rpi/controller/rpi/agc_channel.h   | 1 +
>  2 files changed, 8 insertions(+)
>
> diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp
> index 3957dbc3fa32..1e7eae06d425 100644
> --- a/src/ipa/rpi/controller/rpi/agc_channel.cpp
> +++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp
> @@ -251,6 +251,8 @@ int AgcConfig::read(const libcamera::YamlObject &params)
>  	defaultExposureTime = params["default_exposure_time"].get<double>(1000) * 1us;
>  	defaultAnalogueGain = params["default_analogue_gain"].get<double>(1.0);
>
> +	stableRegion = params["stable_region"].get<double>(0.02);
> +
>  	return 0;
>  }
>
> @@ -871,6 +873,8 @@ bool AgcChannel::applyDigitalGain(double gain, double targetY, bool channelBound
>  void AgcChannel::filterExposure()
>  {
>  	double speed = config_.speed;
> +	double stableRegion = config_.stableRegion;
> +
>  	/*
>  	 * AGC adapts instantly if both shutter and gain are directly specified
>  	 * or we're in the startup phase.
> @@ -880,6 +884,9 @@ void AgcChannel::filterExposure()
>  		speed = 1.0;
>  	if (!filtered_.totalExposure) {
>  		filtered_.totalExposure = target_.totalExposure;
> +	} else if (filtered_.totalExposure * (1.0 - stableRegion) < target_.totalExposure &&
> +		   filtered_.totalExposure * (1.0 + stableRegion) > target_.totalExposure) {
> +		/* Total exposure must change by more than this or we leave it alone. */

I was a bit confused as just here below we have:

                /*
                 * If close to the result go faster, to save making so many
                 * micro-adjustments on the way. (Make this customisable?)
                 */
                if (filtered_.totalExposure < 1.2 * target_.totalExposure &&
                    filtered_.totalExposure > 0.8 * target_.totalExposure)

Which does more or less the same thing but with a larger 20% interval

        if (0.8 * target < filtered < 1.2 * target)

While I read your above check, assuming stableRegion = 0.02 as

        if (filtered * 0.98 < target < filtered * 1.02)

I guess both ways of expressing this work

Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>

Thanks
  j



>  	} else {
>  		/*
>  		 * If close to the result go faster, to save making so many
> diff --git a/src/ipa/rpi/controller/rpi/agc_channel.h b/src/ipa/rpi/controller/rpi/agc_channel.h
> index ae826fa8097f..c1808422498a 100644
> --- a/src/ipa/rpi/controller/rpi/agc_channel.h
> +++ b/src/ipa/rpi/controller/rpi/agc_channel.h
> @@ -75,6 +75,7 @@ struct AgcConfig {
>  	double baseEv;
>  	libcamera::utils::Duration defaultExposureTime;
>  	double defaultAnalogueGain;
> +	double stableRegion;
>  };
>
>  class AgcChannel
> --
> 2.34.1
>

Patch
diff mbox series

diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp
index 3957dbc3fa32..1e7eae06d425 100644
--- a/src/ipa/rpi/controller/rpi/agc_channel.cpp
+++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp
@@ -251,6 +251,8 @@  int AgcConfig::read(const libcamera::YamlObject &params)
 	defaultExposureTime = params["default_exposure_time"].get<double>(1000) * 1us;
 	defaultAnalogueGain = params["default_analogue_gain"].get<double>(1.0);
 
+	stableRegion = params["stable_region"].get<double>(0.02);
+
 	return 0;
 }
 
@@ -871,6 +873,8 @@  bool AgcChannel::applyDigitalGain(double gain, double targetY, bool channelBound
 void AgcChannel::filterExposure()
 {
 	double speed = config_.speed;
+	double stableRegion = config_.stableRegion;
+
 	/*
 	 * AGC adapts instantly if both shutter and gain are directly specified
 	 * or we're in the startup phase.
@@ -880,6 +884,9 @@  void AgcChannel::filterExposure()
 		speed = 1.0;
 	if (!filtered_.totalExposure) {
 		filtered_.totalExposure = target_.totalExposure;
+	} else if (filtered_.totalExposure * (1.0 - stableRegion) < target_.totalExposure &&
+		   filtered_.totalExposure * (1.0 + stableRegion) > target_.totalExposure) {
+		/* Total exposure must change by more than this or we leave it alone. */
 	} else {
 		/*
 		 * If close to the result go faster, to save making so many
diff --git a/src/ipa/rpi/controller/rpi/agc_channel.h b/src/ipa/rpi/controller/rpi/agc_channel.h
index ae826fa8097f..c1808422498a 100644
--- a/src/ipa/rpi/controller/rpi/agc_channel.h
+++ b/src/ipa/rpi/controller/rpi/agc_channel.h
@@ -75,6 +75,7 @@  struct AgcConfig {
 	double baseEv;
 	libcamera::utils::Duration defaultExposureTime;
 	double defaultAnalogueGain;
+	double stableRegion;
 };
 
 class AgcChannel