@@ -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;
@@ -92,6 +92,23 @@
* \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,8 +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_);
@@ -438,7 +453,7 @@ void IPAIPU3::fillParams(unsigned int frame, ipu3_uapi_params *params)
algo->prepare(context_, ¶ms_);
if (agcAlgo_->updateControls())
- awbAlgo_->updateWbParameters(params_);
+ awbAlgo_->prepare(context_, ¶ms_);
*params = params_;
@@ -461,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);
@@ -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 *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->acc_param.ccm = imguCssCcmDefault;
+
+ params->use.acc_awb = 1;
+ params->use.acc_bnr = 1;
+ params->use.acc_ccm = 1;
}
} /* namespace ipa::ipu3 */
@@ -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 *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();