[libcamera-devel,v1,5/7] ipa: ipu3: rename AGC algorithm
diff mbox series

Message ID 20210823124937.253539-6-jeanmichel.hautbois@ideasonboard.com
State Superseded
Headers show
Series
  • IPU3: AWB and AGC improvements
Related show

Commit Message

Jean-Michel Hautbois Aug. 23, 2021, 12:49 p.m. UTC
The initial AGC algorithm is a simple one, which calculates the exposure
and gain values by trying to have a mean histogram value to 128.
Rename it as "AgcMean" to make it easy to distinguish.

Now that we are modular, we can have multiple algorithms for one
functionnality (here, AGC). Naming those algorithms makes it easier to
chose between them.

Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
---
 .../ipu3/algorithms/{agc.cpp => agc_mean.cpp} | 31 +++++++++----------
 src/ipa/ipu3/algorithms/{agc.h => agc_mean.h} |  8 ++---
 src/ipa/ipu3/algorithms/meson.build           |  2 +-
 src/ipa/ipu3/ipu3.cpp                         |  4 +--
 4 files changed, 22 insertions(+), 23 deletions(-)
 rename src/ipa/ipu3/algorithms/{agc.cpp => agc_mean.cpp} (87%)
 rename src/ipa/ipu3/algorithms/{agc.h => agc_mean.h} (90%)

Comments

Laurent Pinchart Aug. 23, 2021, 4:52 p.m. UTC | #1
Hi Jean-Michel,

Thank you for the patch.

On Mon, Aug 23, 2021 at 02:49:35PM +0200, Jean-Michel Hautbois wrote:
> The initial AGC algorithm is a simple one, which calculates the exposure
> and gain values by trying to have a mean histogram value to 128.

Is this right ? I'm reading the code as targetting a value of 128 (maybe
we should say 0.5 instead, to avoid depending on the number of bits per
pixel in comments) for the mean of the top 2% of the histogram.

> Rename it as "AgcMean" to make it easy to distinguish.
> 
> Now that we are modular, we can have multiple algorithms for one
> functionnality (here, AGC). Naming those algorithms makes it easier to

s/functionnality/functionality/

> chose between them.
> 
> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
> ---
>  .../ipu3/algorithms/{agc.cpp => agc_mean.cpp} | 31 +++++++++----------
>  src/ipa/ipu3/algorithms/{agc.h => agc_mean.h} |  8 ++---
>  src/ipa/ipu3/algorithms/meson.build           |  2 +-
>  src/ipa/ipu3/ipu3.cpp                         |  4 +--
>  4 files changed, 22 insertions(+), 23 deletions(-)
>  rename src/ipa/ipu3/algorithms/{agc.cpp => agc_mean.cpp} (87%)
>  rename src/ipa/ipu3/algorithms/{agc.h => agc_mean.h} (90%)
> 
> diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc_mean.cpp
> similarity index 87%
> rename from src/ipa/ipu3/algorithms/agc.cpp
> rename to src/ipa/ipu3/algorithms/agc_mean.cpp
> index 5ff50f4a..193f6e9a 100644
> --- a/src/ipa/ipu3/algorithms/agc.cpp
> +++ b/src/ipa/ipu3/algorithms/agc_mean.cpp
> @@ -2,10 +2,10 @@
>  /*
>   * Copyright (C) 2021, Ideas On Board
>   *
> - * ipu3_agc.cpp - AGC/AEC control algorithm
> + * agc_mean.cpp - AGC/AEC control algorithm

"AGC/AEC mean-based control algorithm" ?

I'm not sure if mean vs. metering are the most descriptive names, but I
don't have better proposals at this point.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

>   */
>  
> -#include "agc.h"
> +#include "agc_mean.h"
>  
>  #include <algorithm>
>  #include <chrono>
> @@ -23,7 +23,7 @@ using namespace std::literals::chrono_literals;
>  
>  namespace ipa::ipu3::algorithms {
>  
> -LOG_DEFINE_CATEGORY(IPU3Agc)
> +LOG_DEFINE_CATEGORY(IPU3AgcMean)
>  
>  /* Number of frames to wait before calculating stats on minimum exposure */
>  static constexpr uint32_t kInitialFrameMinAECount = 4;
> @@ -50,16 +50,15 @@ static constexpr double kEvGainTarget = 0.5;
>  /* A cell is 8 bytes and contains averages for RGB values and saturation ratio */
>  static constexpr uint8_t kCellSize = 8;
>  
> -Agc::Agc()
> +AgcMean::AgcMean()
>  	: frameCount_(0), lastFrame_(0), iqMean_(0.0), lineDuration_(0s),
>  	  maxExposureTime_(0s), prevExposure_(0s), prevExposureNoDg_(0s),
>  	  currentExposure_(0s), currentExposureNoDg_(0s)
>  {
>  }
>  
> -int Agc::configure([[maybe_unused]] IPAContext &context,
> -		   const IPAConfigInfo &configInfo)
> -{
> +int AgcMean::configure([[maybe_unused]] IPAContext &context,
> +		        const IPAConfigInfo &configInfo){
>  	lineDuration_ = configInfo.sensorInfo.lineLength * 1.0s
>  		      / configInfo.sensorInfo.pixelRate;
>  	maxExposureTime_ = kMaxExposure * lineDuration_;
> @@ -67,7 +66,7 @@ int Agc::configure([[maybe_unused]] IPAContext &context,
>  	return 0;
>  }
>  
> -void Agc::processBrightness(const ipu3_uapi_stats_3a *stats,
> +void AgcMean::processBrightness(const ipu3_uapi_stats_3a *stats,
>  			    const ipu3_uapi_grid_config &grid)
>  {
>  	const struct ipu3_uapi_grid_config statsAeGrid = stats->stats_4a_config.awb_config.grid;
> @@ -109,7 +108,7 @@ void Agc::processBrightness(const ipu3_uapi_stats_3a *stats,
>  	iqMean_ = Histogram(Span<uint32_t>(hist)).interQuantileMean(0.98, 1.0);
>  }
>  
> -void Agc::filterExposure()
> +void AgcMean::filterExposure()
>  {
>  	double speed = 0.2;
>  	if (prevExposure_ == 0s) {
> @@ -140,10 +139,10 @@ void Agc::filterExposure()
>  	if (prevExposureNoDg_ <
>  	    prevExposure_ * fastReduceThreshold)
>  		prevExposureNoDg_ = prevExposure_ * fastReduceThreshold;
> -	LOG(IPU3Agc, Debug) << "After filtering, total_exposure " << prevExposure_;
> +	LOG(IPU3AgcMean, Debug) << "After filtering, total_exposure " << prevExposure_;
>  }
>  
> -void Agc::lockExposureGain(uint32_t &exposure, double &gain)
> +void AgcMean::lockExposureGain(uint32_t &exposure, double &gain)
>  {
>  	/* Algorithm initialization should wait for first valid frames */
>  	/* \todo - have a number of frames given by DelayedControls ?
> @@ -153,20 +152,20 @@ void Agc::lockExposureGain(uint32_t &exposure, double &gain)
>  
>  	/* Are we correctly exposed ? */
>  	if (std::abs(iqMean_ - kEvGainTarget * knumHistogramBins) <= 1) {
> -		LOG(IPU3Agc, Debug) << "!!! Good exposure with iqMean = " << iqMean_;
> +		LOG(IPU3AgcMean, Debug) << "!!! Good exposure with iqMean = " << iqMean_;
>  	} else {
>  		double newGain = kEvGainTarget * knumHistogramBins / iqMean_;
>  
>  		/* extracted from Rpi::Agc::computeTargetExposure */
>  		libcamera::utils::Duration currentShutter = exposure * lineDuration_;
>  		currentExposureNoDg_ = currentShutter * gain;
> -		LOG(IPU3Agc, Debug) << "Actual total exposure " << currentExposureNoDg_
> +		LOG(IPU3AgcMean, Debug) << "Actual total exposure " << currentExposureNoDg_
>  				    << " Shutter speed " << currentShutter
>  				    << " Gain " << gain;
>  		currentExposure_ = currentExposureNoDg_ * newGain;
>  		libcamera::utils::Duration maxTotalExposure = maxExposureTime_ * kMaxGain;
>  		currentExposure_ = std::min(currentExposure_, maxTotalExposure);
> -		LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_;
> +		LOG(IPU3AgcMean, Debug) << "Target total exposure " << currentExposure_;
>  
>  		/* \todo: estimate if we need to desaturate */
>  		filterExposure();
> @@ -181,12 +180,12 @@ void Agc::lockExposureGain(uint32_t &exposure, double &gain)
>  			newExposure = currentExposure_ / gain;
>  			exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / newExposure), kMinExposure, kMaxExposure);
>  		}
> -		LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * lineDuration_ << " and gain " << gain;
> +		LOG(IPU3AgcMean, Debug) << "Adjust exposure " << exposure * lineDuration_ << " and gain " << gain;
>  	}
>  	lastFrame_ = frameCount_;
>  }
>  
> -void Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats)
> +void AgcMean::process(IPAContext &context, const ipu3_uapi_stats_3a *stats)
>  {
>  	uint32_t &exposure = context.frameContext.agc.exposure;
>  	double &gain = context.frameContext.agc.gain;
> diff --git a/src/ipa/ipu3/algorithms/agc.h b/src/ipa/ipu3/algorithms/agc_mean.h
> similarity index 90%
> rename from src/ipa/ipu3/algorithms/agc.h
> rename to src/ipa/ipu3/algorithms/agc_mean.h
> index e36797d3..97114121 100644
> --- a/src/ipa/ipu3/algorithms/agc.h
> +++ b/src/ipa/ipu3/algorithms/agc_mean.h
> @@ -2,7 +2,7 @@
>  /*
>   * Copyright (C) 2021, Ideas On Board
>   *
> - * agc.h - IPU3 AGC/AEC control algorithm
> + * agc_mean.h - IPU3 AGC/AEC control algorithm
>   */
>  #ifndef __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__
>  #define __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__
> @@ -23,11 +23,11 @@ namespace ipa::ipu3::algorithms {
>  
>  using utils::Duration;
>  
> -class Agc : public Algorithm
> +class AgcMean : public Algorithm
>  {
>  public:
> -	Agc();
> -	~Agc() = default;
> +	AgcMean();
> +	~AgcMean() = default;
>  
>  	int configure(IPAContext &context, const IPAConfigInfo &configInfo) override;
>  	void process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override;
> diff --git a/src/ipa/ipu3/algorithms/meson.build b/src/ipa/ipu3/algorithms/meson.build
> index deae225b..807b53ea 100644
> --- a/src/ipa/ipu3/algorithms/meson.build
> +++ b/src/ipa/ipu3/algorithms/meson.build
> @@ -1,7 +1,7 @@
>  # SPDX-License-Identifier: CC0-1.0
>  
>  ipu3_ipa_algorithms = files([
> -    'agc.cpp',
> +    'agc_mean.cpp',
>      'algorithm.cpp',
>      'awb.cpp',
>      'tone_mapping.cpp',
> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
> index 0ed0a6f1..b73c4f7b 100644
> --- a/src/ipa/ipu3/ipu3.cpp
> +++ b/src/ipa/ipu3/ipu3.cpp
> @@ -29,7 +29,7 @@
>  
>  #include "libcamera/internal/mapped_framebuffer.h"
>  
> -#include "algorithms/agc.h"
> +#include "algorithms/agc_mean.h"
>  #include "algorithms/algorithm.h"
>  #include "algorithms/awb.h"
>  #include "algorithms/tone_mapping.h"
> @@ -266,7 +266,7 @@ int IPAIPU3::init(const IPASettings &settings,
>  	*ipaControls = ControlInfoMap(std::move(controls), controls::controls);
>  
>  	/* Construct our Algorithms */
> -	algorithms_.push_back(std::make_unique<algorithms::Agc>());
> +	algorithms_.push_back(std::make_unique<algorithms::AgcMean>());
>  	algorithms_.push_back(std::make_unique<algorithms::Awb>());
>  	algorithms_.push_back(std::make_unique<algorithms::ToneMapping>());
>

Patch
diff mbox series

diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc_mean.cpp
similarity index 87%
rename from src/ipa/ipu3/algorithms/agc.cpp
rename to src/ipa/ipu3/algorithms/agc_mean.cpp
index 5ff50f4a..193f6e9a 100644
--- a/src/ipa/ipu3/algorithms/agc.cpp
+++ b/src/ipa/ipu3/algorithms/agc_mean.cpp
@@ -2,10 +2,10 @@ 
 /*
  * Copyright (C) 2021, Ideas On Board
  *
- * ipu3_agc.cpp - AGC/AEC control algorithm
+ * agc_mean.cpp - AGC/AEC control algorithm
  */
 
-#include "agc.h"
+#include "agc_mean.h"
 
 #include <algorithm>
 #include <chrono>
@@ -23,7 +23,7 @@  using namespace std::literals::chrono_literals;
 
 namespace ipa::ipu3::algorithms {
 
-LOG_DEFINE_CATEGORY(IPU3Agc)
+LOG_DEFINE_CATEGORY(IPU3AgcMean)
 
 /* Number of frames to wait before calculating stats on minimum exposure */
 static constexpr uint32_t kInitialFrameMinAECount = 4;
@@ -50,16 +50,15 @@  static constexpr double kEvGainTarget = 0.5;
 /* A cell is 8 bytes and contains averages for RGB values and saturation ratio */
 static constexpr uint8_t kCellSize = 8;
 
-Agc::Agc()
+AgcMean::AgcMean()
 	: frameCount_(0), lastFrame_(0), iqMean_(0.0), lineDuration_(0s),
 	  maxExposureTime_(0s), prevExposure_(0s), prevExposureNoDg_(0s),
 	  currentExposure_(0s), currentExposureNoDg_(0s)
 {
 }
 
-int Agc::configure([[maybe_unused]] IPAContext &context,
-		   const IPAConfigInfo &configInfo)
-{
+int AgcMean::configure([[maybe_unused]] IPAContext &context,
+		        const IPAConfigInfo &configInfo){
 	lineDuration_ = configInfo.sensorInfo.lineLength * 1.0s
 		      / configInfo.sensorInfo.pixelRate;
 	maxExposureTime_ = kMaxExposure * lineDuration_;
@@ -67,7 +66,7 @@  int Agc::configure([[maybe_unused]] IPAContext &context,
 	return 0;
 }
 
-void Agc::processBrightness(const ipu3_uapi_stats_3a *stats,
+void AgcMean::processBrightness(const ipu3_uapi_stats_3a *stats,
 			    const ipu3_uapi_grid_config &grid)
 {
 	const struct ipu3_uapi_grid_config statsAeGrid = stats->stats_4a_config.awb_config.grid;
@@ -109,7 +108,7 @@  void Agc::processBrightness(const ipu3_uapi_stats_3a *stats,
 	iqMean_ = Histogram(Span<uint32_t>(hist)).interQuantileMean(0.98, 1.0);
 }
 
-void Agc::filterExposure()
+void AgcMean::filterExposure()
 {
 	double speed = 0.2;
 	if (prevExposure_ == 0s) {
@@ -140,10 +139,10 @@  void Agc::filterExposure()
 	if (prevExposureNoDg_ <
 	    prevExposure_ * fastReduceThreshold)
 		prevExposureNoDg_ = prevExposure_ * fastReduceThreshold;
-	LOG(IPU3Agc, Debug) << "After filtering, total_exposure " << prevExposure_;
+	LOG(IPU3AgcMean, Debug) << "After filtering, total_exposure " << prevExposure_;
 }
 
-void Agc::lockExposureGain(uint32_t &exposure, double &gain)
+void AgcMean::lockExposureGain(uint32_t &exposure, double &gain)
 {
 	/* Algorithm initialization should wait for first valid frames */
 	/* \todo - have a number of frames given by DelayedControls ?
@@ -153,20 +152,20 @@  void Agc::lockExposureGain(uint32_t &exposure, double &gain)
 
 	/* Are we correctly exposed ? */
 	if (std::abs(iqMean_ - kEvGainTarget * knumHistogramBins) <= 1) {
-		LOG(IPU3Agc, Debug) << "!!! Good exposure with iqMean = " << iqMean_;
+		LOG(IPU3AgcMean, Debug) << "!!! Good exposure with iqMean = " << iqMean_;
 	} else {
 		double newGain = kEvGainTarget * knumHistogramBins / iqMean_;
 
 		/* extracted from Rpi::Agc::computeTargetExposure */
 		libcamera::utils::Duration currentShutter = exposure * lineDuration_;
 		currentExposureNoDg_ = currentShutter * gain;
-		LOG(IPU3Agc, Debug) << "Actual total exposure " << currentExposureNoDg_
+		LOG(IPU3AgcMean, Debug) << "Actual total exposure " << currentExposureNoDg_
 				    << " Shutter speed " << currentShutter
 				    << " Gain " << gain;
 		currentExposure_ = currentExposureNoDg_ * newGain;
 		libcamera::utils::Duration maxTotalExposure = maxExposureTime_ * kMaxGain;
 		currentExposure_ = std::min(currentExposure_, maxTotalExposure);
-		LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_;
+		LOG(IPU3AgcMean, Debug) << "Target total exposure " << currentExposure_;
 
 		/* \todo: estimate if we need to desaturate */
 		filterExposure();
@@ -181,12 +180,12 @@  void Agc::lockExposureGain(uint32_t &exposure, double &gain)
 			newExposure = currentExposure_ / gain;
 			exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / newExposure), kMinExposure, kMaxExposure);
 		}
-		LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * lineDuration_ << " and gain " << gain;
+		LOG(IPU3AgcMean, Debug) << "Adjust exposure " << exposure * lineDuration_ << " and gain " << gain;
 	}
 	lastFrame_ = frameCount_;
 }
 
-void Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats)
+void AgcMean::process(IPAContext &context, const ipu3_uapi_stats_3a *stats)
 {
 	uint32_t &exposure = context.frameContext.agc.exposure;
 	double &gain = context.frameContext.agc.gain;
diff --git a/src/ipa/ipu3/algorithms/agc.h b/src/ipa/ipu3/algorithms/agc_mean.h
similarity index 90%
rename from src/ipa/ipu3/algorithms/agc.h
rename to src/ipa/ipu3/algorithms/agc_mean.h
index e36797d3..97114121 100644
--- a/src/ipa/ipu3/algorithms/agc.h
+++ b/src/ipa/ipu3/algorithms/agc_mean.h
@@ -2,7 +2,7 @@ 
 /*
  * Copyright (C) 2021, Ideas On Board
  *
- * agc.h - IPU3 AGC/AEC control algorithm
+ * agc_mean.h - IPU3 AGC/AEC control algorithm
  */
 #ifndef __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__
 #define __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__
@@ -23,11 +23,11 @@  namespace ipa::ipu3::algorithms {
 
 using utils::Duration;
 
-class Agc : public Algorithm
+class AgcMean : public Algorithm
 {
 public:
-	Agc();
-	~Agc() = default;
+	AgcMean();
+	~AgcMean() = default;
 
 	int configure(IPAContext &context, const IPAConfigInfo &configInfo) override;
 	void process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override;
diff --git a/src/ipa/ipu3/algorithms/meson.build b/src/ipa/ipu3/algorithms/meson.build
index deae225b..807b53ea 100644
--- a/src/ipa/ipu3/algorithms/meson.build
+++ b/src/ipa/ipu3/algorithms/meson.build
@@ -1,7 +1,7 @@ 
 # SPDX-License-Identifier: CC0-1.0
 
 ipu3_ipa_algorithms = files([
-    'agc.cpp',
+    'agc_mean.cpp',
     'algorithm.cpp',
     'awb.cpp',
     'tone_mapping.cpp',
diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
index 0ed0a6f1..b73c4f7b 100644
--- a/src/ipa/ipu3/ipu3.cpp
+++ b/src/ipa/ipu3/ipu3.cpp
@@ -29,7 +29,7 @@ 
 
 #include "libcamera/internal/mapped_framebuffer.h"
 
-#include "algorithms/agc.h"
+#include "algorithms/agc_mean.h"
 #include "algorithms/algorithm.h"
 #include "algorithms/awb.h"
 #include "algorithms/tone_mapping.h"
@@ -266,7 +266,7 @@  int IPAIPU3::init(const IPASettings &settings,
 	*ipaControls = ControlInfoMap(std::move(controls), controls::controls);
 
 	/* Construct our Algorithms */
-	algorithms_.push_back(std::make_unique<algorithms::Agc>());
+	algorithms_.push_back(std::make_unique<algorithms::AgcMean>());
 	algorithms_.push_back(std::make_unique<algorithms::Awb>());
 	algorithms_.push_back(std::make_unique<algorithms::ToneMapping>());