[libcamera-devel,2/4] ipa: ipu3: Calculate line duration from IPACameraSensorInfo
diff mbox series

Message ID 20210602102326.106549-3-umang.jain@ideasonboard.com
State Superseded
Headers show
Series
  • IPAIPU3 drive-by improvements
Related show

Commit Message

Umang Jain June 2, 2021, 10:23 a.m. UTC
Squash \todo by calculating line duration from IPACameraSensorInfo,
now passed in, to IPU3Agc::initialise().

Since line duration is now calculated from real values, store it as a
private member in IPU3Agc class. As a further step, replace the
associated global constant, kMaxExposureTime, with a private IPU3Agc
class member as well, and assign its value correspondingly in
IPU3Agc::initialise(), similar to previous precedence.

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
---
 src/ipa/ipu3/ipu3.cpp     |  2 +-
 src/ipa/ipu3/ipu3_agc.cpp | 22 +++++++++++-----------
 src/ipa/ipu3/ipu3_agc.h   |  7 ++++++-
 3 files changed, 18 insertions(+), 13 deletions(-)

Comments

Kieran Bingham June 4, 2021, 9:27 a.m. UTC | #1
Hi Umang,

On 02/06/2021 11:23, Umang Jain wrote:
> Squash \todo by calculating line duration from IPACameraSensorInfo,
> now passed in, to IPU3Agc::initialise().
> 
> Since line duration is now calculated from real values, store it as a
> private member in IPU3Agc class. As a further step, replace the
> associated global constant, kMaxExposureTime, with a private IPU3Agc
> class member as well, and assign its value correspondingly in
> IPU3Agc::initialise(), similar to previous precedence.
> 
> Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>

This looks reasonable to me. I guess we could have moved the sensorInfo
 [3/4] first but that doesn't make much difference, and this way moves
it only where there is a user of it.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com

> ---
>  src/ipa/ipu3/ipu3.cpp     |  2 +-
>  src/ipa/ipu3/ipu3_agc.cpp | 22 +++++++++++-----------
>  src/ipa/ipu3/ipu3_agc.h   |  7 ++++++-
>  3 files changed, 18 insertions(+), 13 deletions(-)
> 
> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
> index 700a5660..2496b0a0 100644
> --- a/src/ipa/ipu3/ipu3.cpp
> +++ b/src/ipa/ipu3/ipu3.cpp
> @@ -174,7 +174,7 @@ void IPAIPU3::configure(const IPAConfigInfo &configInfo)
>  	awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_);
>  
>  	agcAlgo_ = std::make_unique<IPU3Agc>();
> -	agcAlgo_->initialise(bdsGrid_);
> +	agcAlgo_->initialise(bdsGrid_, configInfo.sensorInfo);
>  }
>  
>  void IPAIPU3::mapBuffers(const std::vector<IPABuffer> &buffers)
> diff --git a/src/ipa/ipu3/ipu3_agc.cpp b/src/ipa/ipu3/ipu3_agc.cpp
> index 8bae423f..ccd01371 100644
> --- a/src/ipa/ipu3/ipu3_agc.cpp
> +++ b/src/ipa/ipu3/ipu3_agc.cpp
> @@ -39,11 +39,6 @@ static constexpr uint32_t kMaxGain = kMaxISO / 100;
>  static constexpr uint32_t kMinExposure = 1;
>  static constexpr uint32_t kMaxExposure = 1976;
>  
> -/* \todo those should be got from IPACameraSensorInfo ! */
> -/* line duration in microseconds */
> -static constexpr double kLineDuration = 16.8;
> -static constexpr double kMaxExposureTime = kMaxExposure * kLineDuration;
> -
>  /* Histogram constants */
>  static constexpr uint32_t knumHistogramBins = 256;
>  static constexpr double kEvGainTarget = 0.5;
> @@ -54,14 +49,19 @@ static constexpr uint8_t kCellSize = 8;
>  IPU3Agc::IPU3Agc()
>  	: frameCount_(0), lastFrame_(0), converged_(false),
>  	  updateControls_(false), iqMean_(0.0), gamma_(1.0),
> +	  lineDuration_(0.0), maxExposureTime_(0.0),
>  	  prevExposure_(0.0), prevExposureNoDg_(0.0),
>  	  currentExposure_(0.0), currentExposureNoDg_(0.0)
>  {
>  }
>  
> -void IPU3Agc::initialise(struct ipu3_uapi_grid_config &bdsGrid)
> +void IPU3Agc::initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo)
>  {
>  	aeGrid_ = bdsGrid;
> +
> +	/* line duration in microseconds */
> +	lineDuration_ = sensorInfo.lineLength / static_cast<double>(sensorInfo.pixelRate / 1000000);
> +	maxExposureTime_ = kMaxExposure * lineDuration_;
>  }
>  
>  void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats)
> @@ -160,13 +160,13 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, uint32_t &gain)
>  		double newGain = kEvGainTarget * knumHistogramBins / iqMean_;
>  
>  		/* extracted from Rpi::Agc::computeTargetExposure */
> -		double currentShutter = exposure * kLineDuration;
> +		double currentShutter = exposure * lineDuration_;
>  		currentExposureNoDg_ = currentShutter * gain;
>  		LOG(IPU3Agc, Debug) << "Actual total exposure " << currentExposureNoDg_
>  				    << " Shutter speed " << currentShutter
>  				    << " Gain " << gain;
>  		currentExposure_ = currentExposureNoDg_ * newGain;
> -		double maxTotalExposure = kMaxExposureTime * kMaxGain;
> +		double maxTotalExposure = maxExposureTime_ * kMaxGain;
>  		currentExposure_ = std::min(currentExposure_, maxTotalExposure);
>  		LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_;
>  
> @@ -174,18 +174,18 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, uint32_t &gain)
>  		filterExposure();
>  
>  		double newExposure = 0.0;
> -		if (currentShutter < kMaxExposureTime) {
> +		if (currentShutter < maxExposureTime_) {
>  			exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / currentExposureNoDg_), kMinExposure, kMaxExposure);
>  			newExposure = currentExposure_ / exposure;
>  			gain = std::clamp(static_cast<uint32_t>(gain * currentExposure_ / newExposure), kMinGain, kMaxGain);
>  			updateControls_ = true;
> -		} else if (currentShutter >= kMaxExposureTime) {
> +		} else if (currentShutter >= maxExposureTime_) {
>  			gain = std::clamp(static_cast<uint32_t>(gain * currentExposure_ / currentExposureNoDg_), kMinGain, kMaxGain);
>  			newExposure = currentExposure_ / gain;
>  			exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / newExposure), kMinExposure, kMaxExposure);
>  			updateControls_ = true;
>  		}
> -		LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * kLineDuration << " and gain " << gain;
> +		LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * lineDuration_ << " and gain " << gain;
>  	}
>  	lastFrame_ = frameCount_;
>  }
> diff --git a/src/ipa/ipu3/ipu3_agc.h b/src/ipa/ipu3/ipu3_agc.h
> index bfdf45d1..ae557bdd 100644
> --- a/src/ipa/ipu3/ipu3_agc.h
> +++ b/src/ipa/ipu3/ipu3_agc.h
> @@ -12,6 +12,8 @@
>  
>  #include <linux/intel-ipu3.h>
>  
> +#include <libcamera/ipa/ipu3_ipa_interface.h>
> +
>  #include <libcamera/geometry.h>
>  
>  #include "libipa/algorithm.h"
> @@ -26,7 +28,7 @@ public:
>  	IPU3Agc();
>  	~IPU3Agc() = default;
>  
> -	void initialise(struct ipu3_uapi_grid_config &bdsGrid);
> +	void initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo);
>  	void process(const ipu3_uapi_stats_3a *stats, uint32_t &exposure, uint32_t &gain);
>  	bool converged() { return converged_; }
>  	bool updateControls() { return updateControls_; }
> @@ -49,6 +51,9 @@ private:
>  	double iqMean_;
>  	double gamma_;
>  
> +	double lineDuration_;
> +	double maxExposureTime_;
> +
>  	double prevExposure_;
>  	double prevExposureNoDg_;
>  	double currentExposure_;
>
Kieran Bingham June 4, 2021, 9:39 a.m. UTC | #2
On 04/06/2021 10:27, Kieran Bingham wrote:
> Hi Umang,
> 
> On 02/06/2021 11:23, Umang Jain wrote:
>> Squash \todo by calculating line duration from IPACameraSensorInfo,
>> now passed in, to IPU3Agc::initialise().
>>
>> Since line duration is now calculated from real values, store it as a
>> private member in IPU3Agc class. As a further step, replace the
>> associated global constant, kMaxExposureTime, with a private IPU3Agc
>> class member as well, and assign its value correspondingly in
>> IPU3Agc::initialise(), similar to previous precedence.
>>
>> Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
> 
> This looks reasonable to me. I guess we could have moved the sensorInfo
>  [3/4] first but that doesn't make much difference, and this way moves
> it only where there is a user of it.
> 
> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com
> 
>> ---
>>  src/ipa/ipu3/ipu3.cpp     |  2 +-
>>  src/ipa/ipu3/ipu3_agc.cpp | 22 +++++++++++-----------
>>  src/ipa/ipu3/ipu3_agc.h   |  7 ++++++-
>>  3 files changed, 18 insertions(+), 13 deletions(-)
>>
>> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
>> index 700a5660..2496b0a0 100644
>> --- a/src/ipa/ipu3/ipu3.cpp
>> +++ b/src/ipa/ipu3/ipu3.cpp
>> @@ -174,7 +174,7 @@ void IPAIPU3::configure(const IPAConfigInfo &configInfo)
>>  	awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_);
>>  
>>  	agcAlgo_ = std::make_unique<IPU3Agc>();
>> -	agcAlgo_->initialise(bdsGrid_);
>> +	agcAlgo_->initialise(bdsGrid_, configInfo.sensorInfo);
>>  }
>>  
>>  void IPAIPU3::mapBuffers(const std::vector<IPABuffer> &buffers)
>> diff --git a/src/ipa/ipu3/ipu3_agc.cpp b/src/ipa/ipu3/ipu3_agc.cpp
>> index 8bae423f..ccd01371 100644
>> --- a/src/ipa/ipu3/ipu3_agc.cpp
>> +++ b/src/ipa/ipu3/ipu3_agc.cpp
>> @@ -39,11 +39,6 @@ static constexpr uint32_t kMaxGain = kMaxISO / 100;
>>  static constexpr uint32_t kMinExposure = 1;
>>  static constexpr uint32_t kMaxExposure = 1976;
>>  
>> -/* \todo those should be got from IPACameraSensorInfo ! */
>> -/* line duration in microseconds */
>> -static constexpr double kLineDuration = 16.8;
>> -static constexpr double kMaxExposureTime = kMaxExposure * kLineDuration;
>> -
>>  /* Histogram constants */
>>  static constexpr uint32_t knumHistogramBins = 256;
>>  static constexpr double kEvGainTarget = 0.5;
>> @@ -54,14 +49,19 @@ static constexpr uint8_t kCellSize = 8;
>>  IPU3Agc::IPU3Agc()
>>  	: frameCount_(0), lastFrame_(0), converged_(false),
>>  	  updateControls_(false), iqMean_(0.0), gamma_(1.0),
>> +	  lineDuration_(0.0), maxExposureTime_(0.0),
>>  	  prevExposure_(0.0), prevExposureNoDg_(0.0),
>>  	  currentExposure_(0.0), currentExposureNoDg_(0.0)
>>  {
>>  }
>>  
>> -void IPU3Agc::initialise(struct ipu3_uapi_grid_config &bdsGrid)
>> +void IPU3Agc::initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo)
>>  {
>>  	aeGrid_ = bdsGrid;
>> +
>> +	/* line duration in microseconds */
>> +	lineDuration_ = sensorInfo.lineLength / static_cast<double>(sensorInfo.pixelRate / 1000000);
>> +	maxExposureTime_ = kMaxExposure * lineDuration_;
>>  }
>>  
>>  void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats)
>> @@ -160,13 +160,13 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, uint32_t &gain)
>>  		double newGain = kEvGainTarget * knumHistogramBins / iqMean_;
>>  
>>  		/* extracted from Rpi::Agc::computeTargetExposure */
>> -		double currentShutter = exposure * kLineDuration;
>> +		double currentShutter = exposure * lineDuration_;
>>  		currentExposureNoDg_ = currentShutter * gain;
>>  		LOG(IPU3Agc, Debug) << "Actual total exposure " << currentExposureNoDg_
>>  				    << " Shutter speed " << currentShutter
>>  				    << " Gain " << gain;
>>  		currentExposure_ = currentExposureNoDg_ * newGain;
>> -		double maxTotalExposure = kMaxExposureTime * kMaxGain;
>> +		double maxTotalExposure = maxExposureTime_ * kMaxGain;
>>  		currentExposure_ = std::min(currentExposure_, maxTotalExposure);
>>  		LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_;
>>  
>> @@ -174,18 +174,18 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, uint32_t &gain)
>>  		filterExposure();
>>  
>>  		double newExposure = 0.0;
>> -		if (currentShutter < kMaxExposureTime) {
>> +		if (currentShutter < maxExposureTime_) {
>>  			exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / currentExposureNoDg_), kMinExposure, kMaxExposure);
>>  			newExposure = currentExposure_ / exposure;
>>  			gain = std::clamp(static_cast<uint32_t>(gain * currentExposure_ / newExposure), kMinGain, kMaxGain);
>>  			updateControls_ = true;
>> -		} else if (currentShutter >= kMaxExposureTime) {
>> +		} else if (currentShutter >= maxExposureTime_) {
>>  			gain = std::clamp(static_cast<uint32_t>(gain * currentExposure_ / currentExposureNoDg_), kMinGain, kMaxGain);
>>  			newExposure = currentExposure_ / gain;
>>  			exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / newExposure), kMinExposure, kMaxExposure);
>>  			updateControls_ = true;
>>  		}
>> -		LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * kLineDuration << " and gain " << gain;
>> +		LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * lineDuration_ << " and gain " << gain;
>>  	}
>>  	lastFrame_ = frameCount_;
>>  }
>> diff --git a/src/ipa/ipu3/ipu3_agc.h b/src/ipa/ipu3/ipu3_agc.h
>> index bfdf45d1..ae557bdd 100644
>> --- a/src/ipa/ipu3/ipu3_agc.h
>> +++ b/src/ipa/ipu3/ipu3_agc.h
>> @@ -12,6 +12,8 @@
>>  
>>  #include <linux/intel-ipu3.h>
>>  
>> +#include <libcamera/ipa/ipu3_ipa_interface.h>

In fact, the IPACameraSensorInfo comes from

libcamera/ipa/core_ipa_interface.h

Is there anything from ipu3_ipa_interface.h that will be needed in this
ipu3_agc component?

--
Kieran

>> +
>>  #include <libcamera/geometry.h>
>>  
>>  #include "libipa/algorithm.h"
>> @@ -26,7 +28,7 @@ public:
>>  	IPU3Agc();
>>  	~IPU3Agc() = default;
>>  
>> -	void initialise(struct ipu3_uapi_grid_config &bdsGrid);
>> +	void initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo);
>>  	void process(const ipu3_uapi_stats_3a *stats, uint32_t &exposure, uint32_t &gain);
>>  	bool converged() { return converged_; }
>>  	bool updateControls() { return updateControls_; }
>> @@ -49,6 +51,9 @@ private:
>>  	double iqMean_;
>>  	double gamma_;
>>  
>> +	double lineDuration_;
>> +	double maxExposureTime_;
>> +
>>  	double prevExposure_;
>>  	double prevExposureNoDg_;
>>  	double currentExposure_;
>>
>
Laurent Pinchart June 7, 2021, 10:46 p.m. UTC | #3
Hi Umang,

Thank you for the patch.

On Wed, Jun 02, 2021 at 03:53:24PM +0530, Umang Jain wrote:
> Squash \todo by calculating line duration from IPACameraSensorInfo,
> now passed in, to IPU3Agc::initialise().
> 
> Since line duration is now calculated from real values, store it as a
> private member in IPU3Agc class. As a further step, replace the
> associated global constant, kMaxExposureTime, with a private IPU3Agc
> class member as well, and assign its value correspondingly in
> IPU3Agc::initialise(), similar to previous precedence.
> 
> Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
> ---
>  src/ipa/ipu3/ipu3.cpp     |  2 +-
>  src/ipa/ipu3/ipu3_agc.cpp | 22 +++++++++++-----------
>  src/ipa/ipu3/ipu3_agc.h   |  7 ++++++-
>  3 files changed, 18 insertions(+), 13 deletions(-)
> 
> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
> index 700a5660..2496b0a0 100644
> --- a/src/ipa/ipu3/ipu3.cpp
> +++ b/src/ipa/ipu3/ipu3.cpp
> @@ -174,7 +174,7 @@ void IPAIPU3::configure(const IPAConfigInfo &configInfo)
>  	awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_);
>  
>  	agcAlgo_ = std::make_unique<IPU3Agc>();
> -	agcAlgo_->initialise(bdsGrid_);
> +	agcAlgo_->initialise(bdsGrid_, configInfo.sensorInfo);
>  }
>  
>  void IPAIPU3::mapBuffers(const std::vector<IPABuffer> &buffers)
> diff --git a/src/ipa/ipu3/ipu3_agc.cpp b/src/ipa/ipu3/ipu3_agc.cpp
> index 8bae423f..ccd01371 100644
> --- a/src/ipa/ipu3/ipu3_agc.cpp
> +++ b/src/ipa/ipu3/ipu3_agc.cpp
> @@ -39,11 +39,6 @@ static constexpr uint32_t kMaxGain = kMaxISO / 100;
>  static constexpr uint32_t kMinExposure = 1;
>  static constexpr uint32_t kMaxExposure = 1976;
>  
> -/* \todo those should be got from IPACameraSensorInfo ! */
> -/* line duration in microseconds */
> -static constexpr double kLineDuration = 16.8;
> -static constexpr double kMaxExposureTime = kMaxExposure * kLineDuration;
> -
>  /* Histogram constants */
>  static constexpr uint32_t knumHistogramBins = 256;
>  static constexpr double kEvGainTarget = 0.5;
> @@ -54,14 +49,19 @@ static constexpr uint8_t kCellSize = 8;
>  IPU3Agc::IPU3Agc()
>  	: frameCount_(0), lastFrame_(0), converged_(false),
>  	  updateControls_(false), iqMean_(0.0), gamma_(1.0),
> +	  lineDuration_(0.0), maxExposureTime_(0.0),
>  	  prevExposure_(0.0), prevExposureNoDg_(0.0),
>  	  currentExposure_(0.0), currentExposureNoDg_(0.0)
>  {
>  }
>  
> -void IPU3Agc::initialise(struct ipu3_uapi_grid_config &bdsGrid)
> +void IPU3Agc::initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo)
>  {
>  	aeGrid_ = bdsGrid;
> +
> +	/* line duration in microseconds */
> +	lineDuration_ = sensorInfo.lineLength / static_cast<double>(sensorInfo.pixelRate / 1000000);

Let's try to avoid losing precision.

	lineDuration_ = sensorInfo.lineLength * 1000000ULL
		      / static_cast<double>(sensorInfo.pixelRate);

On a side note, we should really move to std::chrono types at some
point.

> +	maxExposureTime_ = kMaxExposure * lineDuration_;
>  }
>  
>  void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats)
> @@ -160,13 +160,13 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, uint32_t &gain)
>  		double newGain = kEvGainTarget * knumHistogramBins / iqMean_;
>  
>  		/* extracted from Rpi::Agc::computeTargetExposure */
> -		double currentShutter = exposure * kLineDuration;
> +		double currentShutter = exposure * lineDuration_;
>  		currentExposureNoDg_ = currentShutter * gain;
>  		LOG(IPU3Agc, Debug) << "Actual total exposure " << currentExposureNoDg_
>  				    << " Shutter speed " << currentShutter
>  				    << " Gain " << gain;
>  		currentExposure_ = currentExposureNoDg_ * newGain;
> -		double maxTotalExposure = kMaxExposureTime * kMaxGain;
> +		double maxTotalExposure = maxExposureTime_ * kMaxGain;
>  		currentExposure_ = std::min(currentExposure_, maxTotalExposure);
>  		LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_;
>  
> @@ -174,18 +174,18 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, uint32_t &gain)
>  		filterExposure();
>  
>  		double newExposure = 0.0;
> -		if (currentShutter < kMaxExposureTime) {
> +		if (currentShutter < maxExposureTime_) {
>  			exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / currentExposureNoDg_), kMinExposure, kMaxExposure);
>  			newExposure = currentExposure_ / exposure;
>  			gain = std::clamp(static_cast<uint32_t>(gain * currentExposure_ / newExposure), kMinGain, kMaxGain);
>  			updateControls_ = true;
> -		} else if (currentShutter >= kMaxExposureTime) {
> +		} else if (currentShutter >= maxExposureTime_) {
>  			gain = std::clamp(static_cast<uint32_t>(gain * currentExposure_ / currentExposureNoDg_), kMinGain, kMaxGain);
>  			newExposure = currentExposure_ / gain;
>  			exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / newExposure), kMinExposure, kMaxExposure);
>  			updateControls_ = true;
>  		}
> -		LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * kLineDuration << " and gain " << gain;
> +		LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * lineDuration_ << " and gain " << gain;
>  	}
>  	lastFrame_ = frameCount_;
>  }
> diff --git a/src/ipa/ipu3/ipu3_agc.h b/src/ipa/ipu3/ipu3_agc.h
> index bfdf45d1..ae557bdd 100644
> --- a/src/ipa/ipu3/ipu3_agc.h
> +++ b/src/ipa/ipu3/ipu3_agc.h
> @@ -12,6 +12,8 @@
>  
>  #include <linux/intel-ipu3.h>
>  
> +#include <libcamera/ipa/ipu3_ipa_interface.h>
> +

No need for a blank line, and you can swap the two headers to order them
alphabetically. As Kieran mentioned, you can include
core_ipa_interface.h instead, or, possibly better, forward-declare the
IPACameraSensorInfo struct and include core_ipa_interface.h in
ipu3_agc.cpp.

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

>  #include <libcamera/geometry.h>
>  
>  #include "libipa/algorithm.h"
> @@ -26,7 +28,7 @@ public:
>  	IPU3Agc();
>  	~IPU3Agc() = default;
>  
> -	void initialise(struct ipu3_uapi_grid_config &bdsGrid);
> +	void initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo);
>  	void process(const ipu3_uapi_stats_3a *stats, uint32_t &exposure, uint32_t &gain);
>  	bool converged() { return converged_; }
>  	bool updateControls() { return updateControls_; }
> @@ -49,6 +51,9 @@ private:
>  	double iqMean_;
>  	double gamma_;
>  
> +	double lineDuration_;
> +	double maxExposureTime_;
> +
>  	double prevExposure_;
>  	double prevExposureNoDg_;
>  	double currentExposure_;

Patch
diff mbox series

diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
index 700a5660..2496b0a0 100644
--- a/src/ipa/ipu3/ipu3.cpp
+++ b/src/ipa/ipu3/ipu3.cpp
@@ -174,7 +174,7 @@  void IPAIPU3::configure(const IPAConfigInfo &configInfo)
 	awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_);
 
 	agcAlgo_ = std::make_unique<IPU3Agc>();
-	agcAlgo_->initialise(bdsGrid_);
+	agcAlgo_->initialise(bdsGrid_, configInfo.sensorInfo);
 }
 
 void IPAIPU3::mapBuffers(const std::vector<IPABuffer> &buffers)
diff --git a/src/ipa/ipu3/ipu3_agc.cpp b/src/ipa/ipu3/ipu3_agc.cpp
index 8bae423f..ccd01371 100644
--- a/src/ipa/ipu3/ipu3_agc.cpp
+++ b/src/ipa/ipu3/ipu3_agc.cpp
@@ -39,11 +39,6 @@  static constexpr uint32_t kMaxGain = kMaxISO / 100;
 static constexpr uint32_t kMinExposure = 1;
 static constexpr uint32_t kMaxExposure = 1976;
 
-/* \todo those should be got from IPACameraSensorInfo ! */
-/* line duration in microseconds */
-static constexpr double kLineDuration = 16.8;
-static constexpr double kMaxExposureTime = kMaxExposure * kLineDuration;
-
 /* Histogram constants */
 static constexpr uint32_t knumHistogramBins = 256;
 static constexpr double kEvGainTarget = 0.5;
@@ -54,14 +49,19 @@  static constexpr uint8_t kCellSize = 8;
 IPU3Agc::IPU3Agc()
 	: frameCount_(0), lastFrame_(0), converged_(false),
 	  updateControls_(false), iqMean_(0.0), gamma_(1.0),
+	  lineDuration_(0.0), maxExposureTime_(0.0),
 	  prevExposure_(0.0), prevExposureNoDg_(0.0),
 	  currentExposure_(0.0), currentExposureNoDg_(0.0)
 {
 }
 
-void IPU3Agc::initialise(struct ipu3_uapi_grid_config &bdsGrid)
+void IPU3Agc::initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo)
 {
 	aeGrid_ = bdsGrid;
+
+	/* line duration in microseconds */
+	lineDuration_ = sensorInfo.lineLength / static_cast<double>(sensorInfo.pixelRate / 1000000);
+	maxExposureTime_ = kMaxExposure * lineDuration_;
 }
 
 void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats)
@@ -160,13 +160,13 @@  void IPU3Agc::lockExposureGain(uint32_t &exposure, uint32_t &gain)
 		double newGain = kEvGainTarget * knumHistogramBins / iqMean_;
 
 		/* extracted from Rpi::Agc::computeTargetExposure */
-		double currentShutter = exposure * kLineDuration;
+		double currentShutter = exposure * lineDuration_;
 		currentExposureNoDg_ = currentShutter * gain;
 		LOG(IPU3Agc, Debug) << "Actual total exposure " << currentExposureNoDg_
 				    << " Shutter speed " << currentShutter
 				    << " Gain " << gain;
 		currentExposure_ = currentExposureNoDg_ * newGain;
-		double maxTotalExposure = kMaxExposureTime * kMaxGain;
+		double maxTotalExposure = maxExposureTime_ * kMaxGain;
 		currentExposure_ = std::min(currentExposure_, maxTotalExposure);
 		LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_;
 
@@ -174,18 +174,18 @@  void IPU3Agc::lockExposureGain(uint32_t &exposure, uint32_t &gain)
 		filterExposure();
 
 		double newExposure = 0.0;
-		if (currentShutter < kMaxExposureTime) {
+		if (currentShutter < maxExposureTime_) {
 			exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / currentExposureNoDg_), kMinExposure, kMaxExposure);
 			newExposure = currentExposure_ / exposure;
 			gain = std::clamp(static_cast<uint32_t>(gain * currentExposure_ / newExposure), kMinGain, kMaxGain);
 			updateControls_ = true;
-		} else if (currentShutter >= kMaxExposureTime) {
+		} else if (currentShutter >= maxExposureTime_) {
 			gain = std::clamp(static_cast<uint32_t>(gain * currentExposure_ / currentExposureNoDg_), kMinGain, kMaxGain);
 			newExposure = currentExposure_ / gain;
 			exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / newExposure), kMinExposure, kMaxExposure);
 			updateControls_ = true;
 		}
-		LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * kLineDuration << " and gain " << gain;
+		LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * lineDuration_ << " and gain " << gain;
 	}
 	lastFrame_ = frameCount_;
 }
diff --git a/src/ipa/ipu3/ipu3_agc.h b/src/ipa/ipu3/ipu3_agc.h
index bfdf45d1..ae557bdd 100644
--- a/src/ipa/ipu3/ipu3_agc.h
+++ b/src/ipa/ipu3/ipu3_agc.h
@@ -12,6 +12,8 @@ 
 
 #include <linux/intel-ipu3.h>
 
+#include <libcamera/ipa/ipu3_ipa_interface.h>
+
 #include <libcamera/geometry.h>
 
 #include "libipa/algorithm.h"
@@ -26,7 +28,7 @@  public:
 	IPU3Agc();
 	~IPU3Agc() = default;
 
-	void initialise(struct ipu3_uapi_grid_config &bdsGrid);
+	void initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo);
 	void process(const ipu3_uapi_stats_3a *stats, uint32_t &exposure, uint32_t &gain);
 	bool converged() { return converged_; }
 	bool updateControls() { return updateControls_; }
@@ -49,6 +51,9 @@  private:
 	double iqMean_;
 	double gamma_;
 
+	double lineDuration_;
+	double maxExposureTime_;
+
 	double prevExposure_;
 	double prevExposureNoDg_;
 	double currentExposure_;