From patchwork Fri Aug 20 06:53:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 13414 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 56E6AC3246 for ; Fri, 20 Aug 2021 06:53:32 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6D2EE68918; Fri, 20 Aug 2021 08:53:31 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="dKWYKVZR"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 389586891A for ; Fri, 20 Aug 2021 08:53:23 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:e43b:edb2:932:6b0a]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DD7368C8; Fri, 20 Aug 2021 08:53:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1629442402; bh=Kf8GtVvGycpEgCk/ah5RWS6GYVMnp4Lgo+I526NA+7M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dKWYKVZRTXyx1BgBJTUpyp3Wu9GhYeq9H6GDCApiy+rvjWKa+/CYS9Bk5h4h+8Nyk yNhwcr9lJ/r3C6BRqmpBoVb/kno6GNt2kJ8Tj1ynddSRMYkWHeuAHT5Nm45FnE29/Q Rrk9nqRnRzDe1II9vbvjTdMs7lSnGtKK0nMGGPoI= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 20 Aug 2021 08:53:13 +0200 Message-Id: <20210820065316.44343-7-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210820065316.44343-1-jeanmichel.hautbois@ideasonboard.com> References: <20210820065316.44343-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 6/9] ipa: ipu3: convert AWB to the new algorithm interface X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" 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 Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/ipa_context.h | 8 +++ src/ipa/ipu3/ipu3.cpp | 23 ++++++-- src/ipa/ipu3/ipu3_awb.cpp | 109 ++++++++++++++++++------------------- src/ipa/ipu3/ipu3_awb.h | 6 +- 4 files changed, 83 insertions(+), 63 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 3713b07b..823df34b 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -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(); - awbAlgo_->initialise(params_, context_.configuration.grid.bdsOutputSize, - context_.configuration.grid.bdsGrid); agcAlgo_ = std::make_unique(); 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); diff --git a/src/ipa/ipu3/ipu3_awb.cpp b/src/ipa/ipu3/ipu3_awb.cpp index c2d9e0c1..728162fe 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 *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 */ diff --git a/src/ipa/ipu3/ipu3_awb.h b/src/ipa/ipu3/ipu3_awb.h index eeb2920b..12703489 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 *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 &zones); void generateAwbStats(const ipu3_uapi_stats_3a *stats); void clearAwbStats();