[libcamera-devel] [PATCH v1 5/7] ipa: ipu3: Improve AWB behaviour

Laurent Pinchart laurent.pinchart at ideasonboard.com
Thu Jul 8 14:58:57 CEST 2021


Hi Jean-Michel,

Thank you for the patch.

On Mon, Jun 28, 2021 at 10:22:53PM +0200, Jean-Michel Hautbois wrote:
> In order to use a better grid, clamp the values calculated from the BDS
> resolution to at least 2 times the minimum grid size.
> The number of zones needed to have sufficiently relevant statistics is
> now based on the region sizes and not on an arbitrary value.
> Last, the default green gains where not properly used, it should be 8192
> and not 4096 to have a multiplier of 1.0 on the R/G/B gains.

Sounds like this should be split in two patches.

> The default CCM is adjusted for Surface Go2 only, and should eventually be
> calculated in the CameraSensorHelper class.

How do you envision the CameraSensorHelper class calculating this ?

> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
> ---
>  src/ipa/ipu3/ipu3.cpp     | 12 ++++++++----
>  src/ipa/ipu3/ipu3_awb.cpp | 23 +++++++++++------------
>  src/ipa/ipu3/ipu3_awb.h   |  1 +
>  3 files changed, 20 insertions(+), 16 deletions(-)
> 
> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
> index 4466391a..9a2def64 100644
> --- a/src/ipa/ipu3/ipu3.cpp
> +++ b/src/ipa/ipu3/ipu3.cpp
> @@ -123,12 +123,16 @@ void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize)
>  	bdsGrid_ = {};
>  
>  	for (uint32_t widthShift = 3; widthShift <= 7; ++widthShift) {
> -		uint32_t width = std::min(kMaxCellWidthPerSet,
> -					  bdsOutputSize.width >> widthShift);
> +		uint32_t width = std::clamp(bdsOutputSize.width >> widthShift,
> +					    2 * kAwbStatsSizeX,
> +					    kMaxCellWidthPerSet);
> +
>  		width = width << widthShift;
>  		for (uint32_t heightShift = 3; heightShift <= 7; ++heightShift) {
> -			int32_t height = std::min(kMaxCellHeightPerSet,
> -						  bdsOutputSize.height >> heightShift);
> +			uint32_t height = std::clamp(bdsOutputSize.height >> heightShift,
> +						     2 * kAwbStatsSizeY,
> +						     kMaxCellHeightPerSet);
> +
>  			height = height << heightShift;
>  			uint32_t error  = std::abs(static_cast<int>(width - bdsOutputSize.width))
>  							+ std::abs(static_cast<int>(height - bdsOutputSize.height));
> diff --git a/src/ipa/ipu3/ipu3_awb.cpp b/src/ipa/ipu3/ipu3_awb.cpp
> index a94935c5..a39536b0 100644
> --- a/src/ipa/ipu3/ipu3_awb.cpp
> +++ b/src/ipa/ipu3/ipu3_awb.cpp
> @@ -18,9 +18,6 @@ namespace ipa::ipu3 {
>  
>  LOG_DEFINE_CATEGORY(IPU3Awb)
>  
> -static constexpr uint32_t kMinZonesCounted = 16;
> -static constexpr uint32_t kMinGreenLevelInZone = 32;
> -
>  /**
>   * \struct IspStatsRegion
>   * \brief RGB statistics for a given region
> @@ -92,7 +89,7 @@ static constexpr uint32_t kMinGreenLevelInZone = 32;
>  
>  /* Default settings for Bayer noise reduction replicated from the Kernel */
>  static const struct ipu3_uapi_bnr_static_config imguCssBnrDefaults = {
> -	.wb_gains = { 16, 16, 16, 16 },
> +	.wb_gains = { 8192, 8192, 8192, 8192 },

Does the kernel report 8192 as a default value ?

>  	.wb_gains_thr = { 255, 255, 255, 255 },
>  	.thr_coeffs = { 1700, 0, 31, 31, 0, 16 },
>  	.thr_ctrl_shd = { 26, 26, 26, 26 },
> @@ -130,7 +127,7 @@ static const struct ipu3_uapi_awb_config_s imguCssAwbDefaults = {
>  /* Default color correction matrix defined as an identity matrix */
>  static const struct ipu3_uapi_ccm_mat_config imguCssCcmDefault = {
>  	8191, 0, 0, 0,
> -	0, 8191, 0, 0,
> +	0, 6000, 0, 0,

that's not an identify matrix anymore.

>  	0, 0, 8191, 0
>  };
>  
> @@ -166,6 +163,7 @@ IPU3Awb::IPU3Awb()
>  	asyncResults_.greenGain = 1.0;
>  	asyncResults_.redGain = 1.0;
>  	asyncResults_.temperatureK = 4500;
> +	minZonesCounted_ = 0;
>  }
>  
>  IPU3Awb::~IPU3Awb()
> @@ -241,7 +239,7 @@ void IPU3Awb::generateZones(std::vector<RGB> &zones)
>  	for (unsigned int i = 0; i < kAwbStatsSizeX * kAwbStatsSizeY; i++) {
>  		RGB zone;
>  		double counted = awbStats_[i].counted;
> -		if (counted >= kMinZonesCounted) {
> +		if (counted >= minZonesCounted_) {
>  			zone.G = awbStats_[i].gSum / counted;
>  			if (zone.G >= kMinGreenLevelInZone) {
>  				zone.R = awbStats_[i].rSum / counted;
> @@ -258,6 +256,7 @@ void IPU3Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats)
>  	uint32_t regionWidth = round(awbGrid_.width / static_cast<double>(kAwbStatsSizeX));
>  	uint32_t regionHeight = round(awbGrid_.height / static_cast<double>(kAwbStatsSizeY));
>  
> +	minZonesCounted_ = ((regionWidth * regionHeight) * 4) / 5;
>  	/*
>  	 * Generate a (kAwbStatsSizeX x kAwbStatsSizeY) array from the IPU3 grid which is
>  	 * (awbGrid_.width x awbGrid_.height).
> @@ -269,7 +268,7 @@ void IPU3Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats)
>  			uint32_t cellY = ((cellPosition / awbGrid_.width) / regionHeight) % kAwbStatsSizeY;
>  
>  			uint32_t awbRegionPosition = cellY * kAwbStatsSizeX + cellX;
> -			cellPosition *= 8;
> +			cellPosition *= sizeof(Ipu3AwbCell);
>  
>  			/* Cast the initial IPU3 structure to simplify the reading */
>  			Ipu3AwbCell *currentCell = reinterpret_cast<Ipu3AwbCell *>(const_cast<uint8_t *>(&stats->awb_raw_buffer.meta_data[cellPosition]));
> @@ -361,12 +360,12 @@ void IPU3Awb::updateWbParameters(ipu3_uapi_params &params, double agcGamma)
>  	/*
>  	 * Green gains should not be touched and considered 1.
>  	 * Default is 16, so do not change it at all.
> -	 * 4096 is the value for a gain of 1.0
> +	 * 8192 is the value for a gain of 1.0
>  	 */
> -	params.acc_param.bnr.wb_gains.gr = 16;
> -	params.acc_param.bnr.wb_gains.r = 4096 * asyncResults_.redGain;
> -	params.acc_param.bnr.wb_gains.b = 4096 * asyncResults_.blueGain;
> -	params.acc_param.bnr.wb_gains.gb = 16;
> +	params.acc_param.bnr.wb_gains.gr = 8192;
> +	params.acc_param.bnr.wb_gains.r = 8192 * asyncResults_.redGain;
> +	params.acc_param.bnr.wb_gains.b = 8192 * asyncResults_.blueGain;
> +	params.acc_param.bnr.wb_gains.gb = 8192;
>  
>  	LOG(IPU3Awb, Debug) << "Color temperature estimated: " << asyncResults_.temperatureK
>  			    << " and gamma calculated: " << agcGamma;
> diff --git a/src/ipa/ipu3/ipu3_awb.h b/src/ipa/ipu3/ipu3_awb.h
> index 795e32e3..23865c21 100644
> --- a/src/ipa/ipu3/ipu3_awb.h
> +++ b/src/ipa/ipu3/ipu3_awb.h
> @@ -49,6 +49,7 @@ private:
>  	std::vector<RGB> zones_;
>  	IspStatsRegion awbStats_[kAwbStatsSizeX * kAwbStatsSizeY];
>  	AwbStatus asyncResults_;
> +	uint32_t minZonesCounted_;
>  };
>  
>  } /* namespace ipa::ipu3 */

-- 
Regards,

Laurent Pinchart


More information about the libcamera-devel mailing list