Message ID | 20210819145759.184192-7-jeanmichel.hautbois@ideasonboard.com |
---|---|
State | Superseded |
Headers | show |
Series |
|
Related | show |
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@ideasonboard.com> > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@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 ¶ms, 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 ¶ms) > +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 ¶ms) > { > + 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 ¶ms, const Size &bdsOutputSize, struct ipu3_uapi_grid_config &bdsGrid); > - void calculateWBGains(const ipu3_uapi_stats_3a *stats); > - void updateWbParameters(ipu3_uapi_params ¶ms); > + void prepare(IPAContext &context, ipu3_uapi_params ¶ms) 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();
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 ¶ms, 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 ¶ms) +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 ¶ms) { + 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 ¶ms, const Size &bdsOutputSize, struct ipu3_uapi_grid_config &bdsGrid); - void calculateWBGains(const ipu3_uapi_stats_3a *stats); - void updateWbParameters(ipu3_uapi_params ¶ms); + void prepare(IPAContext &context, ipu3_uapi_params ¶ms) 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();