[libcamera-devel] [PATCH v4 6/9] ipa: ipu3: convert AWB to the new algorithm interface

Laurent Pinchart laurent.pinchart at ideasonboard.com
Fri Aug 20 03:08:46 CEST 2021


Hi Jean-Michel,

Thank you for the patch.

On Thu, Aug 19, 2021 at 04:57:56PM +0200, Jean-Michel Hautbois wrote:
> When the stats are received, pass them with the context to the existing
> AWB algorithm. IPAFrameContext now has a new structure to store the
> gains calculated by the AWB algorithm.
> 
> When an EventFillParams event is received, call prepare() and set the new
> gains accordingly in the params structure.
> There is no more a need for the IPU3Awb::initialise() function, as the
> params are always set in prepare().
> 
> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
> Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>

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

> ---
>  src/ipa/ipu3/ipa_context.h |   8 +++
>  src/ipa/ipu3/ipu3.cpp      |  22 ++++++--
>  src/ipa/ipu3/ipu3_awb.cpp  | 107 ++++++++++++++++++-------------------
>  src/ipa/ipu3/ipu3_awb.h    |   6 +--
>  4 files changed, 82 insertions(+), 61 deletions(-)
> 
> diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h
> index 4b12f129..24dd8bf7 100644
> --- a/src/ipa/ipu3/ipa_context.h
> +++ b/src/ipa/ipu3/ipa_context.h
> @@ -24,6 +24,14 @@ struct IPASessionConfiguration {
>  };
>  
>  struct IPAFrameContext {
> +	struct {
> +		struct {
> +			double red;
> +			double green;
> +			double blue;
> +		} gains;
> +	} awb;
> +
>  	struct {
>  		struct ipu3_uapi_gamma_corr_lut gammaCorrection;
>  	} toneMapping;
> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
> index edc2d911..cede897e 100644
> --- a/src/ipa/ipu3/ipu3.cpp
> +++ b/src/ipa/ipu3/ipu3.cpp
> @@ -95,6 +95,23 @@ static constexpr uint32_t kMaxCellHeightPerSet = 56;
>   * \brief BDS output size configured by the pipeline handler
>   */
>  
> +/**
> + * \struct IPAFrameContext::awb
> + * \brief Context for the Automatic White Balance algorithm
> + *
> + * \struct IPAFrameContext::awb::gains
> + * \brief White balance gains
> + *
> + * \var IPAFrameContext::awb::gains::red
> + * \brief White balance gain for R channel
> + *
> + * \var IPAFrameContext::awb::gains::green
> + * \brief White balance gain for G channel
> + *
> + * \var IPAFrameContext::awb::gains::blue
> + * \brief White balance gain for B channel
> + */
> +
>  /**
>   * \struct IPAFrameContext::toneMapping
>   * \brief Context for ToneMapping and Gamma control
> @@ -357,7 +374,6 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo)
>  	}
>  
>  	awbAlgo_ = std::make_unique<IPU3Awb>();
> -	awbAlgo_->initialise(params_, context_.configuration.grid.bdsOutputSize, context_.configuration.grid.bdsGrid);
>  	agcAlgo_ = std::make_unique<IPU3Agc>();
>  	agcAlgo_->initialise(context_.configuration.grid.bdsGrid, sensorInfo_);
>  
> @@ -437,7 +453,7 @@ void IPAIPU3::fillParams(unsigned int frame, ipu3_uapi_params *params)
>  		algo->prepare(context_, params_);
>  
>  	if (agcAlgo_->updateControls())
> -		awbAlgo_->updateWbParameters(params_);
> +		awbAlgo_->prepare(context_, params_);
>  
>  	*params = params_;
>  
> @@ -460,7 +476,7 @@ void IPAIPU3::parseStatistics(unsigned int frame,
>  	agcAlgo_->process(stats, exposure_, gain);
>  	gain_ = camHelper_->gainCode(gain);
>  
> -	awbAlgo_->calculateWBGains(stats);
> +	awbAlgo_->process(context_, stats);
>  
>  	if (agcAlgo_->updateControls())
>  		setControls(frame);
> diff --git a/src/ipa/ipu3/ipu3_awb.cpp b/src/ipa/ipu3/ipu3_awb.cpp
> index c2d9e0c1..490bf514 100644
> --- a/src/ipa/ipu3/ipu3_awb.cpp
> +++ b/src/ipa/ipu3/ipu3_awb.cpp
> @@ -107,25 +107,6 @@ static const struct ipu3_uapi_bnr_static_config imguCssBnrDefaults = {
>  	.opt_center_sqr = { 419904, 133956 },
>  };
>  
> -/* Default settings for Auto White Balance replicated from the Kernel*/
> -static const struct ipu3_uapi_awb_config_s imguCssAwbDefaults = {
> -	.rgbs_thr_gr = 8191,
> -	.rgbs_thr_r = 8191,
> -	.rgbs_thr_gb = 8191,
> -	.rgbs_thr_b = 8191 | IPU3_UAPI_AWB_RGBS_THR_B_EN | IPU3_UAPI_AWB_RGBS_THR_B_INCL_SAT,
> -	.grid = {
> -		.width = 160,
> -		.height = 36,
> -		.block_width_log2 = 3,
> -		.block_height_log2 = 4,
> -		.height_per_slice = 1, /* Overridden by kernel. */
> -		.x_start = 0,
> -		.y_start = 0,
> -		.x_end = 0,
> -		.y_end = 0,
> -	},
> -};
> -
>  /* Default color correction matrix defined as an identity matrix */
>  static const struct ipu3_uapi_ccm_mat_config imguCssCcmDefault = {
>  	8191, 0, 0, 0,
> @@ -140,41 +121,12 @@ IPU3Awb::IPU3Awb()
>  	asyncResults_.greenGain = 1.0;
>  	asyncResults_.redGain = 1.0;
>  	asyncResults_.temperatureK = 4500;
> -}
> -
> -IPU3Awb::~IPU3Awb()
> -{
> -}
> -
> -void IPU3Awb::initialise(ipu3_uapi_params &params, const Size &bdsOutputSize, struct ipu3_uapi_grid_config &bdsGrid)
> -{
> -	params.use.acc_awb = 1;
> -	params.acc_param.awb.config = imguCssAwbDefaults;
> -
> -	awbGrid_ = bdsGrid;
> -	params.acc_param.awb.config.grid = awbGrid_;
> -
> -	params.use.acc_bnr = 1;
> -	params.acc_param.bnr = imguCssBnrDefaults;
> -	/**
> -	 * Optical center is column (respectively row) startminus X (respectively Y) center.
> -	 * For the moment use BDS as a first approximation, but it should
> -	 * be calculated based on Shading (SHD) parameters.
> -	 */
> -	params.acc_param.bnr.column_size = bdsOutputSize.width;
> -	params.acc_param.bnr.opt_center.x_reset = awbGrid_.x_start - (bdsOutputSize.width / 2);
> -	params.acc_param.bnr.opt_center.y_reset = awbGrid_.y_start - (bdsOutputSize.height / 2);
> -	params.acc_param.bnr.opt_center_sqr.x_sqr_reset = params.acc_param.bnr.opt_center.x_reset
> -							* params.acc_param.bnr.opt_center.x_reset;
> -	params.acc_param.bnr.opt_center_sqr.y_sqr_reset = params.acc_param.bnr.opt_center.y_reset
> -							* params.acc_param.bnr.opt_center.y_reset;
> -
> -	params.use.acc_ccm = 1;
> -	params.acc_param.ccm = imguCssCcmDefault;
>  
>  	zones_.reserve(kAwbStatsSizeX * kAwbStatsSizeY);
>  }
>  
> +IPU3Awb::~IPU3Awb() = default;
> +
>  /**
>   * The function estimates the correlated color temperature using
>   * from RGB color space input.
> @@ -321,22 +273,67 @@ void IPU3Awb::calculateWBGains(const ipu3_uapi_stats_3a *stats)
>  	}
>  }
>  
> -void IPU3Awb::updateWbParameters(ipu3_uapi_params &params)
> +void IPU3Awb::process(IPAContext &context, const ipu3_uapi_stats_3a *&stats)
> +{
> +	calculateWBGains(stats);
> +
> +	/*
> +	 * Gains are only recalculated if enough zones were detected.
> +	 * The results are cached, so if no results were calculated, we set the
> +	 * cached values from asyncResults_ here.
> +	 */
> +	context.frameContext.awb.gains.blue = asyncResults_.blueGain;
> +	context.frameContext.awb.gains.green = asyncResults_.greenGain;
> +	context.frameContext.awb.gains.red = asyncResults_.redGain;
> +}
> +
> +void IPU3Awb::prepare(IPAContext &context, ipu3_uapi_params &params)
>  {
> +	params.acc_param.awb.config.rgbs_thr_gr = 8191;
> +	params.acc_param.awb.config.rgbs_thr_r = 8191;
> +	params.acc_param.awb.config.rgbs_thr_gb = 8191;
> +	params.acc_param.awb.config.rgbs_thr_b = IPU3_UAPI_AWB_RGBS_THR_B_INCL_SAT
> +					       | IPU3_UAPI_AWB_RGBS_THR_B_EN
> +					       | 8191;
> +
> +	awbGrid_ = context.configuration.grid.bdsGrid;
> +
> +	params.acc_param.awb.config.grid = context.configuration.grid.bdsGrid;
> +
> +	/*
> +	 * Optical center is column start (respectively row start) of the
> +	 * region of interest minus its X center (respectively Y center).
> +	 *
> +	 * For the moment use BDS as a first approximation, but it should
> +	 * be calculated based on Shading (SHD) parameters.
> +	 */
> +	params.acc_param.bnr = imguCssBnrDefaults;
> +	Size &bdsOutputSize = context.configuration.grid.bdsOutputSize;
> +	params.acc_param.bnr.column_size = bdsOutputSize.width;
> +	params.acc_param.bnr.opt_center.x_reset = awbGrid_.x_start - (bdsOutputSize.width / 2);
> +	params.acc_param.bnr.opt_center.y_reset = awbGrid_.y_start - (bdsOutputSize.height / 2);
> +	params.acc_param.bnr.opt_center_sqr.x_sqr_reset = params.acc_param.bnr.opt_center.x_reset
> +							* params.acc_param.bnr.opt_center.x_reset;
> +	params.acc_param.bnr.opt_center_sqr.y_sqr_reset = params.acc_param.bnr.opt_center.y_reset
> +							* params.acc_param.bnr.opt_center.y_reset;
>  	/*
>  	 * 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
>  	 */
> -	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 = 16 * context.frameContext.awb.gains.green;
> +	params.acc_param.bnr.wb_gains.r = 4096 * context.frameContext.awb.gains.red;
> +	params.acc_param.bnr.wb_gains.b = 4096 * context.frameContext.awb.gains.blue;
> +	params.acc_param.bnr.wb_gains.gb = 16 * context.frameContext.awb.gains.green;
>  
>  	LOG(IPU3Awb, Debug) << "Color temperature estimated: " << asyncResults_.temperatureK;
>  
>  	/* The CCM matrix may change when color temperature will be used */
>  	params.acc_param.ccm = imguCssCcmDefault;
> +
> +	params.use.acc_awb = 1;
> +	params.use.acc_bnr = 1;
> +	params.use.acc_ccm = 1;
>  }
>  
>  } /* namespace ipa::ipu3 */
> diff --git a/src/ipa/ipu3/ipu3_awb.h b/src/ipa/ipu3/ipu3_awb.h
> index eeb2920b..81fe03b0 100644
> --- a/src/ipa/ipu3/ipu3_awb.h
> +++ b/src/ipa/ipu3/ipu3_awb.h
> @@ -29,9 +29,8 @@ public:
>  	IPU3Awb();
>  	~IPU3Awb();
>  
> -	void initialise(ipu3_uapi_params &params, const Size &bdsOutputSize, struct ipu3_uapi_grid_config &bdsGrid);
> -	void calculateWBGains(const ipu3_uapi_stats_3a *stats);
> -	void updateWbParameters(ipu3_uapi_params &params);
> +	void prepare(IPAContext &context, ipu3_uapi_params &params) override;
> +	void process(IPAContext &context, const ipu3_uapi_stats_3a *&stats) override;
>  
>  	struct Ipu3AwbCell {
>  		unsigned char greenRedAvg;
> @@ -72,6 +71,7 @@ public:
>  	};
>  
>  private:
> +	void calculateWBGains(const ipu3_uapi_stats_3a *stats);
>  	void generateZones(std::vector<RGB> &zones);
>  	void generateAwbStats(const ipu3_uapi_stats_3a *stats);
>  	void clearAwbStats();

-- 
Regards,

Laurent Pinchart


More information about the libcamera-devel mailing list