From patchwork Mon Oct 24 00:03:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 17664 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 CDF7CBDB16 for ; Mon, 24 Oct 2022 00:04:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A30C062ED4; Mon, 24 Oct 2022 02:04:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1666569864; bh=vgw+hsZqZ1Sox8PqtwxEJBX1S5VSzB6m7IptRVqtDbg=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=Er3RzuO99oPSDiTF2DMso8UVo/S9RGYHG8OHtJZn9AA579OBTl6nTqmIQ0AQM4Zp9 bW0EWLJ8rBGpaLfL2OcHgp4v3hJJzdu4SeKv0uJkZ6EHFIppNgH2GHQ2gmTqht+yJf 7RbkxFkPuZlMHGYqWiZQqp60weSODND13B/3gMK9rB5Za0WiLnM131SFt4zyuN9KWW mN7QrGpwMYkTUBiQPWSzxF6r0/fSkyUGkNGPBl25/mSMFJtcoTy6T/GHfUmDMjdF3/ PEmdQxu52JTjBzyvkWBAgCl4Vb2kb/zimwamHG4DOwMDu+62eHFIocD31L0culPO4T KGWxekRv1dkVQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2309D62EA6 for ; Mon, 24 Oct 2022 02:04:23 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Uv+st2HS"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 99E24471; Mon, 24 Oct 2022 02:04:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1666569862; bh=vgw+hsZqZ1Sox8PqtwxEJBX1S5VSzB6m7IptRVqtDbg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Uv+st2HSKwaPsQmKLQgex1lPXmkahm+h5sTUqlRUNFdLcGD0DGIAwYTV+jNAOExKu 9ctGo8x4pV4sAUrtQNXB2sJUnfaLHjJo3SCBd0k6+GShu4doxSLoEjyS+eonlXfycO CCJeBkiMKmOTORqK7I2BMlEabeJZARGuUJdKnCzw= To: libcamera-devel@lists.libcamera.org Date: Mon, 24 Oct 2022 03:03:44 +0300 Message-Id: <20221024000356.29521-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.37.4 In-Reply-To: <20221024000356.29521-1-laurent.pinchart@ideasonboard.com> References: <20221024000356.29521-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 01/13] ipa: Sort algorithm operations based on calling order 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: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Reorder functions in the base ipa::Algorithm and its derived classes to match the calling order: queueRequest(), prepare() and process(). This makes the code flow easier to read. No functional change intended. Signed-off-by: Laurent Pinchart Reviewed-by: Paul Elder Reviewed-by: Jacopo Mondi --- src/ipa/ipu3/algorithms/af.cpp | 32 +++--- src/ipa/ipu3/algorithms/awb.cpp | 166 +++++++++++++++--------------- src/ipa/libipa/algorithm.cpp | 34 +++--- src/ipa/libipa/algorithm.h | 14 +-- src/ipa/rkisp1/algorithms/agc.cpp | 80 +++++++------- src/ipa/rkisp1/algorithms/awb.cpp | 94 ++++++++--------- src/ipa/rkisp1/algorithms/awb.h | 6 +- 7 files changed, 213 insertions(+), 213 deletions(-) diff --git a/src/ipa/ipu3/algorithms/af.cpp b/src/ipa/ipu3/algorithms/af.cpp index 5a0452a5719b..12927eecf613 100644 --- a/src/ipa/ipu3/algorithms/af.cpp +++ b/src/ipa/ipu3/algorithms/af.cpp @@ -113,22 +113,6 @@ Af::Af() { } -/** - * \copydoc libcamera::ipa::Algorithm::prepare - */ -void Af::prepare(IPAContext &context, - [[maybe_unused]] const uint32_t frame, - [[maybe_unused]] IPAFrameContext &frameContext, - ipu3_uapi_params *params) -{ - const struct ipu3_uapi_grid_config &grid = context.configuration.af.afGrid; - params->acc_param.af.grid_cfg = grid; - params->acc_param.af.filter_config = afFilterConfigDefault; - - /* Enable AF processing block */ - params->use.acc_af = 1; -} - /** * \brief Configure the Af given a configInfo * \param[in] context The shared IPA context @@ -197,6 +181,22 @@ int Af::configure(IPAContext &context, const IPAConfigInfo &configInfo) return 0; } +/** + * \copydoc libcamera::ipa::Algorithm::prepare + */ +void Af::prepare(IPAContext &context, + [[maybe_unused]] const uint32_t frame, + [[maybe_unused]] IPAFrameContext &frameContext, + ipu3_uapi_params *params) +{ + const struct ipu3_uapi_grid_config &grid = context.configuration.af.afGrid; + params->acc_param.af.grid_cfg = grid; + params->acc_param.af.filter_config = afFilterConfigDefault; + + /* Enable AF processing block */ + params->use.acc_af = 1; +} + /** * \brief AF coarse scan * \param[in] context The shared IPA context diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp index dd7ebc07c534..5abd46215833 100644 --- a/src/ipa/ipu3/algorithms/awb.cpp +++ b/src/ipa/ipu3/algorithms/awb.cpp @@ -218,6 +218,89 @@ int Awb::configure(IPAContext &context, return 0; } +constexpr uint16_t Awb::threshold(float value) +{ + /* AWB thresholds are in the range [0, 8191] */ + return value * 8191; +} + +constexpr uint16_t Awb::gainValue(double gain) +{ + /* + * The colour gains applied by the BNR for the four channels (Gr, R, B + * and Gb) are expressed in the parameters structure as 16-bit integers + * that store a fixed-point U3.13 value in the range [0, 8[. + * + * The real gain value is equal to the gain parameter plus one, i.e. + * + * Pout = Pin * (1 + gain / 8192) + * + * where 'Pin' is the input pixel value, 'Pout' the output pixel value, + * and 'gain' the gain in the parameters structure as a 16-bit integer. + */ + return std::clamp((gain - 1.0) * 8192, 0.0, 65535.0); +} + +/** + * \copydoc libcamera::ipa::Algorithm::prepare + */ +void Awb::prepare(IPAContext &context, + [[maybe_unused]] const uint32_t frame, + [[maybe_unused]] IPAFrameContext &frameContext, + ipu3_uapi_params *params) +{ + /* + * Green saturation thresholds are reduced because we are using the + * green channel only in the exposure computation. + */ + params->acc_param.awb.config.rgbs_thr_r = threshold(1.0); + params->acc_param.awb.config.rgbs_thr_gr = threshold(0.9); + params->acc_param.awb.config.rgbs_thr_gb = threshold(0.9); + params->acc_param.awb.config.rgbs_thr_b = threshold(1.0); + + /* + * Enable saturation inclusion on thr_b for ImgU to update the + * ipu3_uapi_awb_set_item->sat_ratio field. + */ + params->acc_param.awb.config.rgbs_thr_b |= IPU3_UAPI_AWB_RGBS_THR_B_INCL_SAT | + IPU3_UAPI_AWB_RGBS_THR_B_EN; + + const ipu3_uapi_grid_config &grid = context.configuration.grid.bdsGrid; + + params->acc_param.awb.config.grid = context.configuration.grid.bdsGrid; + + /* + * Optical center is column start (respectively row start) of the + * cell 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 = grid.x_start - (bdsOutputSize.width / 2); + params->acc_param.bnr.opt_center.y_reset = grid.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->acc_param.bnr.wb_gains.gr = gainValue(context.activeState.awb.gains.green); + params->acc_param.bnr.wb_gains.r = gainValue(context.activeState.awb.gains.red); + params->acc_param.bnr.wb_gains.b = gainValue(context.activeState.awb.gains.blue); + params->acc_param.bnr.wb_gains.gb = gainValue(context.activeState.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; +} + /** * The function estimates the correlated color temperature using * from RGB color space input. @@ -415,89 +498,6 @@ void Awb::process(IPAContext &context, [[maybe_unused]] const uint32_t frame, context.activeState.awb.temperatureK); } -constexpr uint16_t Awb::threshold(float value) -{ - /* AWB thresholds are in the range [0, 8191] */ - return value * 8191; -} - -constexpr uint16_t Awb::gainValue(double gain) -{ - /* - * The colour gains applied by the BNR for the four channels (Gr, R, B - * and Gb) are expressed in the parameters structure as 16-bit integers - * that store a fixed-point U3.13 value in the range [0, 8[. - * - * The real gain value is equal to the gain parameter plus one, i.e. - * - * Pout = Pin * (1 + gain / 8192) - * - * where 'Pin' is the input pixel value, 'Pout' the output pixel value, - * and 'gain' the gain in the parameters structure as a 16-bit integer. - */ - return std::clamp((gain - 1.0) * 8192, 0.0, 65535.0); -} - -/** - * \copydoc libcamera::ipa::Algorithm::prepare - */ -void Awb::prepare(IPAContext &context, - [[maybe_unused]] const uint32_t frame, - [[maybe_unused]] IPAFrameContext &frameContext, - ipu3_uapi_params *params) -{ - /* - * Green saturation thresholds are reduced because we are using the - * green channel only in the exposure computation. - */ - params->acc_param.awb.config.rgbs_thr_r = threshold(1.0); - params->acc_param.awb.config.rgbs_thr_gr = threshold(0.9); - params->acc_param.awb.config.rgbs_thr_gb = threshold(0.9); - params->acc_param.awb.config.rgbs_thr_b = threshold(1.0); - - /* - * Enable saturation inclusion on thr_b for ImgU to update the - * ipu3_uapi_awb_set_item->sat_ratio field. - */ - params->acc_param.awb.config.rgbs_thr_b |= IPU3_UAPI_AWB_RGBS_THR_B_INCL_SAT | - IPU3_UAPI_AWB_RGBS_THR_B_EN; - - const ipu3_uapi_grid_config &grid = context.configuration.grid.bdsGrid; - - params->acc_param.awb.config.grid = context.configuration.grid.bdsGrid; - - /* - * Optical center is column start (respectively row start) of the - * cell 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 = grid.x_start - (bdsOutputSize.width / 2); - params->acc_param.bnr.opt_center.y_reset = grid.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->acc_param.bnr.wb_gains.gr = gainValue(context.activeState.awb.gains.green); - params->acc_param.bnr.wb_gains.r = gainValue(context.activeState.awb.gains.red); - params->acc_param.bnr.wb_gains.b = gainValue(context.activeState.awb.gains.blue); - params->acc_param.bnr.wb_gains.gb = gainValue(context.activeState.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; -} - REGISTER_IPA_ALGORITHM(Awb, "Awb") } /* namespace ipa::ipu3::algorithms */ diff --git a/src/ipa/libipa/algorithm.cpp b/src/ipa/libipa/algorithm.cpp index 71f583840a5a..bc1c29a6dbcc 100644 --- a/src/ipa/libipa/algorithm.cpp +++ b/src/ipa/libipa/algorithm.cpp @@ -66,23 +66,6 @@ namespace ipa { * \return 0 if successful, an error code otherwise */ -/** - * \fn Algorithm::prepare() - * \brief Fill the \a params buffer with ISP processing parameters for a frame - * \param[in] context The shared IPA context - * \param[in] frame The frame context sequence number - * \param[in] frameContext The FrameContext for this frame - * \param[out] params The ISP specific parameters - * - * This function is called for every frame when the camera is running before it - * is processed by the ISP to prepare the ISP processing parameters for that - * frame. - * - * Algorithms shall fill in the parameter structure fields appropriately to - * configure the ISP processing blocks that they are responsible for. This - * includes setting fields and flags that enable those processing blocks. - */ - /** * \fn Algorithm::queueRequest() * \brief Provide control values to the algorithm @@ -100,6 +83,23 @@ namespace ipa { * use during frame processing. */ +/** + * \fn Algorithm::prepare() + * \brief Fill the \a params buffer with ISP processing parameters for a frame + * \param[in] context The shared IPA context + * \param[in] frame The frame context sequence number + * \param[in] frameContext The FrameContext for this frame + * \param[out] params The ISP specific parameters + * + * This function is called for every frame when the camera is running before it + * is processed by the ISP to prepare the ISP processing parameters for that + * frame. + * + * Algorithms shall fill in the parameter structure fields appropriately to + * configure the ISP processing blocks that they are responsible for. This + * includes setting fields and flags that enable those processing blocks. + */ + /** * \fn Algorithm::process() * \brief Process ISP statistics, and run algorithm operations diff --git a/src/ipa/libipa/algorithm.h b/src/ipa/libipa/algorithm.h index 38b3231c5d0e..987e3e4ce777 100644 --- a/src/ipa/libipa/algorithm.h +++ b/src/ipa/libipa/algorithm.h @@ -38,13 +38,6 @@ public: return 0; } - virtual void prepare([[maybe_unused]] typename Module::Context &context, - [[maybe_unused]] const uint32_t frame, - [[maybe_unused]] typename Module::FrameContext &frameContext, - [[maybe_unused]] typename Module::Params *params) - { - } - virtual void queueRequest([[maybe_unused]] typename Module::Context &context, [[maybe_unused]] const uint32_t frame, [[maybe_unused]] typename Module::FrameContext &frameContext, @@ -52,6 +45,13 @@ public: { } + virtual void prepare([[maybe_unused]] typename Module::Context &context, + [[maybe_unused]] const uint32_t frame, + [[maybe_unused]] typename Module::FrameContext &frameContext, + [[maybe_unused]] typename Module::Params *params) + { + } + virtual void process([[maybe_unused]] typename Module::Context &context, [[maybe_unused]] const uint32_t frame, [[maybe_unused]] typename Module::FrameContext &frameContext, diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp index a06e9f732a8f..3fcbfa608467 100644 --- a/src/ipa/rkisp1/algorithms/agc.cpp +++ b/src/ipa/rkisp1/algorithms/agc.cpp @@ -107,6 +107,46 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo) return 0; } +/** + * \copydoc libcamera::ipa::Algorithm::prepare + */ +void Agc::prepare(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, rkisp1_params_cfg *params) +{ + frameContext.agc.exposure = context.activeState.agc.exposure; + frameContext.agc.gain = context.activeState.agc.gain; + + if (frame > 0) + return; + + /* Configure the measurement window. */ + params->meas.aec_config.meas_window = context.configuration.agc.measureWindow; + /* Use a continuous method for measure. */ + params->meas.aec_config.autostop = RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0; + /* Estimate Y as (R + G + B) x (85/256). */ + params->meas.aec_config.mode = RKISP1_CIF_ISP_EXP_MEASURING_MODE_1; + + params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_AEC; + params->module_ens |= RKISP1_CIF_ISP_MODULE_AEC; + params->module_en_update |= RKISP1_CIF_ISP_MODULE_AEC; + + /* Configure histogram. */ + params->meas.hst_config.meas_window = context.configuration.agc.measureWindow; + /* Produce the luminance histogram. */ + params->meas.hst_config.mode = RKISP1_CIF_ISP_HISTOGRAM_MODE_Y_HISTOGRAM; + /* Set an average weighted histogram. */ + for (unsigned int histBin = 0; histBin < numHistBins_; histBin++) + params->meas.hst_config.hist_weight[histBin] = 1; + /* Step size can't be less than 3. */ + params->meas.hst_config.histogram_predivider = 4; + + /* Update the configuration for histogram. */ + params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_HST; + /* Enable the histogram measure unit. */ + params->module_ens |= RKISP1_CIF_ISP_MODULE_HST; + params->module_en_update |= RKISP1_CIF_ISP_MODULE_HST; +} + /** * \brief Apply a filter on the exposure value to limit the speed of changes * \param[in] exposureValue The target exposure from the AGC algorithm @@ -348,46 +388,6 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame, metadata.set(controls::FrameDuration, frameDuration.get()); } -/** - * \copydoc libcamera::ipa::Algorithm::prepare - */ -void Agc::prepare(IPAContext &context, const uint32_t frame, - IPAFrameContext &frameContext, rkisp1_params_cfg *params) -{ - frameContext.agc.exposure = context.activeState.agc.exposure; - frameContext.agc.gain = context.activeState.agc.gain; - - if (frame > 0) - return; - - /* Configure the measurement window. */ - params->meas.aec_config.meas_window = context.configuration.agc.measureWindow; - /* Use a continuous method for measure. */ - params->meas.aec_config.autostop = RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0; - /* Estimate Y as (R + G + B) x (85/256). */ - params->meas.aec_config.mode = RKISP1_CIF_ISP_EXP_MEASURING_MODE_1; - - params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_AEC; - params->module_ens |= RKISP1_CIF_ISP_MODULE_AEC; - params->module_en_update |= RKISP1_CIF_ISP_MODULE_AEC; - - /* Configure histogram. */ - params->meas.hst_config.meas_window = context.configuration.agc.measureWindow; - /* Produce the luminance histogram. */ - params->meas.hst_config.mode = RKISP1_CIF_ISP_HISTOGRAM_MODE_Y_HISTOGRAM; - /* Set an average weighted histogram. */ - for (unsigned int histBin = 0; histBin < numHistBins_; histBin++) - params->meas.hst_config.hist_weight[histBin] = 1; - /* Step size can't be less than 3. */ - params->meas.hst_config.histogram_predivider = 4; - - /* Update the configuration for histogram. */ - params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_HST; - /* Enable the histogram measure unit. */ - params->module_ens |= RKISP1_CIF_ISP_MODULE_HST; - params->module_en_update |= RKISP1_CIF_ISP_MODULE_HST; -} - REGISTER_IPA_ALGORITHM(Agc, "Agc") } /* namespace ipa::rkisp1::algorithms */ diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp index 083c2d982c52..744f4a386c1a 100644 --- a/src/ipa/rkisp1/algorithms/awb.cpp +++ b/src/ipa/rkisp1/algorithms/awb.cpp @@ -67,20 +67,41 @@ int Awb::configure(IPAContext &context, return 0; } -uint32_t Awb::estimateCCT(double red, double green, double blue) +/** + * \copydoc libcamera::ipa::Algorithm::queueRequest + */ +void Awb::queueRequest(IPAContext &context, + [[maybe_unused]] const uint32_t frame, + IPAFrameContext &frameContext, + const ControlList &controls) { - /* Convert the RGB values to CIE tristimulus values (XYZ) */ - double X = (-0.14282) * (red) + (1.54924) * (green) + (-0.95641) * (blue); - double Y = (-0.32466) * (red) + (1.57837) * (green) + (-0.73191) * (blue); - double Z = (-0.68202) * (red) + (0.77073) * (green) + (0.56332) * (blue); - - /* Calculate the normalized chromaticity values */ - double x = X / (X + Y + Z); - double y = Y / (X + Y + Z); - - /* Calculate CCT */ - double n = (x - 0.3320) / (0.1858 - y); - return 449 * n * n * n + 3525 * n * n + 6823.3 * n + 5520.33; + auto &awb = context.activeState.awb; + + const auto &awbEnable = controls.get(controls::AwbEnable); + if (awbEnable && *awbEnable != awb.autoEnabled) { + awb.autoEnabled = *awbEnable; + + LOG(RkISP1Awb, Debug) + << (*awbEnable ? "Enabling" : "Disabling") << " AWB"; + } + + const auto &colourGains = controls.get(controls::ColourGains); + if (colourGains && !awb.autoEnabled) { + awb.gains.manual.red = (*colourGains)[0]; + awb.gains.manual.blue = (*colourGains)[1]; + + LOG(RkISP1Awb, Debug) + << "Set colour gains to red: " << awb.gains.manual.red + << ", blue: " << awb.gains.manual.blue; + } + + frameContext.awb.autoEnabled = awb.autoEnabled; + + if (!awb.autoEnabled) { + frameContext.awb.gains.red = awb.gains.manual.red; + frameContext.awb.gains.green = 1.0; + frameContext.awb.gains.blue = awb.gains.manual.blue; + } } /** @@ -165,41 +186,20 @@ void Awb::prepare(IPAContext &context, const uint32_t frame, params->module_ens |= RKISP1_CIF_ISP_MODULE_AWB; } -/** - * \copydoc libcamera::ipa::Algorithm::queueRequest - */ -void Awb::queueRequest(IPAContext &context, - [[maybe_unused]] const uint32_t frame, - IPAFrameContext &frameContext, - const ControlList &controls) +uint32_t Awb::estimateCCT(double red, double green, double blue) { - auto &awb = context.activeState.awb; - - const auto &awbEnable = controls.get(controls::AwbEnable); - if (awbEnable && *awbEnable != awb.autoEnabled) { - awb.autoEnabled = *awbEnable; - - LOG(RkISP1Awb, Debug) - << (*awbEnable ? "Enabling" : "Disabling") << " AWB"; - } - - const auto &colourGains = controls.get(controls::ColourGains); - if (colourGains && !awb.autoEnabled) { - awb.gains.manual.red = (*colourGains)[0]; - awb.gains.manual.blue = (*colourGains)[1]; - - LOG(RkISP1Awb, Debug) - << "Set colour gains to red: " << awb.gains.manual.red - << ", blue: " << awb.gains.manual.blue; - } - - frameContext.awb.autoEnabled = awb.autoEnabled; - - if (!awb.autoEnabled) { - frameContext.awb.gains.red = awb.gains.manual.red; - frameContext.awb.gains.green = 1.0; - frameContext.awb.gains.blue = awb.gains.manual.blue; - } + /* Convert the RGB values to CIE tristimulus values (XYZ) */ + double X = (-0.14282) * (red) + (1.54924) * (green) + (-0.95641) * (blue); + double Y = (-0.32466) * (red) + (1.57837) * (green) + (-0.73191) * (blue); + double Z = (-0.68202) * (red) + (0.77073) * (green) + (0.56332) * (blue); + + /* Calculate the normalized chromaticity values */ + double x = X / (X + Y + Z); + double y = Y / (X + Y + Z); + + /* Calculate CCT */ + double n = (x - 0.3320) / (0.1858 - y); + return 449 * n * n * n + 3525 * n * n + 6823.3 * n + 5520.33; } /** diff --git a/src/ipa/rkisp1/algorithms/awb.h b/src/ipa/rkisp1/algorithms/awb.h index f5633b1171a0..9d45a442339c 100644 --- a/src/ipa/rkisp1/algorithms/awb.h +++ b/src/ipa/rkisp1/algorithms/awb.h @@ -20,12 +20,12 @@ public: ~Awb() = default; int configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override; - void prepare(IPAContext &context, const uint32_t frame, - IPAFrameContext &frameContext, - rkisp1_params_cfg *params) override; void queueRequest(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, const ControlList &controls) override; + void prepare(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + rkisp1_params_cfg *params) override; void process(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, const rkisp1_stat_buffer *stats,