From patchwork Wed Oct 20 15:45:55 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: 14208 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 3C8C9BDB1C for ; Wed, 20 Oct 2021 15:46:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7BE5568F62; Wed, 20 Oct 2021 17:46:16 +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="bsHjMOWY"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 842C568F57 for ; Wed, 20 Oct 2021 17:46:13 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce4b:1c5f:7302:b899]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2D7193F6; Wed, 20 Oct 2021 17:46:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634744773; bh=vU2pCf9T2ejVdVBtlvoymIzr3HD/bNv9RwSkDdhxFws=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bsHjMOWY8gMiVn7P0voHVVWkz9eG35eTRyChYrIkmN8AUmA6GqhCH3qVsyOY+edxi sIMc7XpS1hyXVGA18NcIgqMtb8o+F4oDJ9zO6ormQf+Yewx8szhcC97GrGJ3aBqQ2r +jG7SDJoVn3wOJiRecEuy5PhcD02HQIZvn+xZ9gA= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Oct 2021 17:45:55 +0200 Message-Id: <20211020154607.180161-2-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> References: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 01/13] ipa: ipu3: awb: Set a threshold for the green saturation 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" We can have a saturation ratio per cell, giving the percentage of pixels over a threshold within a cell where 100% is set to 0xff. The parameter structure 'ipu3_uapi_awb_config_s' contains four fields to set the threshold, one per channel. The blue field is also used to configure the ImgU and make it calculate the saturation ratio or not. Set a green value saturated when it is more than 230 (90% of the maximum value 255, coded as 8191). As this is the only channel used for AGC, there is no need to apply it to the other ones. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/algorithms/awb.cpp | 29 +++++++++++++++++++++++------ src/ipa/ipu3/algorithms/awb.h | 1 + 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp index 809de66a..e44bbd6c 100644 --- a/src/ipa/ipu3/algorithms/awb.cpp +++ b/src/ipa/ipu3/algorithms/awb.cpp @@ -328,14 +328,31 @@ void Awb::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) context.frameContext.awb.gains.red = asyncResults_.redGain; } +constexpr uint16_t Awb::Threshold(float value) +{ + /* AWB Thresholds are in the range [0, 8191] */ + constexpr uint16_t kMaxThreshold = 8191; + + return value * kMaxThreshold; +} + void Awb::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; + /* + * 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; diff --git a/src/ipa/ipu3/algorithms/awb.h b/src/ipa/ipu3/algorithms/awb.h index 3b81f600..b02d6b6c 100644 --- a/src/ipa/ipu3/algorithms/awb.h +++ b/src/ipa/ipu3/algorithms/awb.h @@ -70,6 +70,7 @@ private: void clearAwbStats(); void awbGreyWorld(); uint32_t estimateCCT(double red, double green, double blue); + constexpr uint16_t Threshold(float value); std::vector zones_; Accumulator awbStats_[kAwbStatsSizeX * kAwbStatsSizeY]; From patchwork Wed Oct 20 15:45:56 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: 14209 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 E95FFBDB1C for ; Wed, 20 Oct 2021 15:46:20 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 87F1868F6B; Wed, 20 Oct 2021 17:46:17 +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="i15+H9ND"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A44FA68F58 for ; Wed, 20 Oct 2021 17:46:13 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce4b:1c5f:7302:b899]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 564224A0; Wed, 20 Oct 2021 17:46:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634744773; bh=L5ufunWOH5Fu6bhjrBtMchLEPZGadrcBMb+m+59/cVY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=i15+H9NDowTkGfHyOb164vSrMGXSShaW4luze1HknyG2fkIZSbgwDuX1GKiFIUD+r z/dV/kLLKloLQMld5C9s2R9j5Pk0HC0fxdaNxZkLanEz/mgNEPdOhcZLjO8GwE+x2w wX0PPSVIpSNd3QXCWjUAB9dSndc02Na0oTfKQuxo= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Oct 2021 17:45:56 +0200 Message-Id: <20211020154607.180161-3-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> References: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 02/13] ipa: ipu3: set frameContext before controls 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" The AGC frame context needs to be initialised correctly for the first iteration. Set the gain and exposure appropriately to the current values known to the IPA. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/algorithms/agc.cpp | 8 ++++- src/ipa/ipu3/ipa_context.h | 9 +++++ src/ipa/ipu3/ipu3.cpp | 64 +++++++++++++++++++++++++++++---- 3 files changed, 73 insertions(+), 8 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index 970ec424..a001e349 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -60,7 +60,13 @@ int Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo) lineDuration_ = configInfo.sensorInfo.lineLength * 1.0s / configInfo.sensorInfo.pixelRate; - maxExposureTime_ = kMaxExposure * lineDuration_; + maxExposureTime_ = context.configuration.agc.maxShutterSpeed; + + /* Configure the default exposure and gain */ + context.frameContext.agc.gain = + context.configuration.agc.minAnalogueGain; + context.frameContext.agc.exposure = + context.configuration.agc.minShutterSpeed / lineDuration_; return 0; } diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h index 5bab684c..847c03fe 100644 --- a/src/ipa/ipu3/ipa_context.h +++ b/src/ipa/ipu3/ipa_context.h @@ -10,6 +10,8 @@ #include +#include + #include namespace libcamera { @@ -22,6 +24,13 @@ struct IPASessionConfiguration { Size bdsOutputSize; uint32_t stride; } grid; + + struct { + utils::Duration minShutterSpeed; + utils::Duration maxShutterSpeed; + double minAnalogueGain; + double maxAnalogueGain; + } agc; }; struct IPAFrameContext { diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 388f1902..36ca83f5 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -97,6 +97,23 @@ * \brief Number of cells on one line including the ImgU padding */ +/** + * \struct IPASessionConfiguration::agc + * \brief AGC parameters configuration of the IPA + * + * \var IPASessionConfiguration::agc::minShutterSpeed + * \brief Minimum shutter speed supported with the configured sensor + * + * \var IPASessionConfiguration::grid::maxShutterSpeed + * \brief Maximum shutter speed supported with the configured sensor + * + * \var IPASessionConfiguration::grid::minAnalogueGain + * \brief Minimum analogue gain supported with the configured sensor + * + * \var IPASessionConfiguration::grid::maxAnalogueGain + * \brief Maximum analogue gain supported with the configured sensor + */ + /** * \struct IPAFrameContext::agc * \brief Context for the Automatic Gain Control algorithm @@ -158,6 +175,8 @@ namespace libcamera { LOG_DEFINE_CATEGORY(IPAIPU3) +using namespace std::literals::chrono_literals; + namespace ipa::ipu3 { class IPAIPU3 : public IPAIPU3Interface @@ -182,6 +201,8 @@ private: void updateControls(const IPACameraSensorInfo &sensorInfo, const ControlInfoMap &sensorControls, ControlInfoMap *ipaControls); + void updateSessionConfiguration(const IPACameraSensorInfo &sensorInfo, + const ControlInfoMap &sensorControls); void processControls(unsigned int frame, const ControlList &controls); void fillParams(unsigned int frame, ipu3_uapi_params *params); void parseStatistics(unsigned int frame, @@ -216,6 +237,36 @@ private: struct IPAContext context_; }; +/* + * Compute IPASessionConfiguration using the sensor information and the sensor + * v4l2 controls. + */ +void IPAIPU3::updateSessionConfiguration(const IPACameraSensorInfo &sensorInfo, + const ControlInfoMap &sensorControls) +{ + const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second; + int32_t minExposure = v4l2Exposure.min().get(); + int32_t maxExposure = v4l2Exposure.max().get(); + + utils::Duration lineDuration = sensorInfo.lineLength * 1.0s + / sensorInfo.pixelRate; + + const ControlInfo &v4l2Gain = sensorControls.find(V4L2_CID_ANALOGUE_GAIN)->second; + int32_t minGain = v4l2Gain.min().get(); + int32_t maxGain = v4l2Gain.max().get(); + + /* + * When the AGC computes the new exposure values for a frame, it needs + * to know the limits for shutter speed and analogue gain. + * As it depends on the sensor, update it with the controls. + * + * \todo take VBLANK into account for maximum shutter speed + */ + context_.configuration.agc.minShutterSpeed = minExposure * lineDuration; + context_.configuration.agc.maxShutterSpeed = maxExposure * lineDuration; + context_.configuration.agc.minAnalogueGain = camHelper_->gain(minGain); + context_.configuration.agc.maxAnalogueGain = camHelper_->gain(maxGain); +} /* * Compute camera controls using the sensor information and the sensor @@ -436,15 +487,18 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo, calculateBdsGrid(configInfo.bdsOutputSize); + /* Update the camera controls using the new sensor settings. */ + updateControls(sensorInfo_, ctrls_, ipaControls); + + /* Update the IPASessionConfiguration using the sensor settings */ + updateSessionConfiguration(sensorInfo_, ctrls_); + for (auto const &algo : algorithms_) { int ret = algo->configure(context_, configInfo); if (ret) return ret; } - /* Update the camera controls using the new sensor settings. */ - updateControls(sensorInfo_, ctrls_, ipaControls); - return 0; } @@ -543,10 +597,6 @@ void IPAIPU3::parseStatistics(unsigned int frame, { ControlList ctrls(controls::controls); - /* \todo These fields should not be written by the IPAIPU3 layer */ - context_.frameContext.agc.gain = camHelper_->gain(gain_); - context_.frameContext.agc.exposure = exposure_; - for (auto const &algo : algorithms_) algo->process(context_, stats); From patchwork Wed Oct 20 15:45:57 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: 14210 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 E2858BDB1C for ; Wed, 20 Oct 2021 15:46:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2D93A68F66; Wed, 20 Oct 2021 17:46:19 +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="CpzobZ24"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C3C5C68F5A for ; Wed, 20 Oct 2021 17:46:13 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce4b:1c5f:7302:b899]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 82F852A5; Wed, 20 Oct 2021 17:46:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634744773; bh=VyawnqAtBI7O7x84f+93SWS7bCNTq5+BA5dB1OpS82A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CpzobZ24ZKi73uBiZ1Y51VsawU9fBA2HNHv0mTvK67gfuC6KQ3iJ10uqqRwydZEZl 3znnag+lNT6991ZW97PAD7A9+OMs0qVjeTd3keO26U2UsekEOsRssE9amwBYg6zLLz BPuKInjJSHdghFPdScsG95bDiJ4wmR0rGLXAfeys= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Oct 2021 17:45:57 +0200 Message-Id: <20211020154607.180161-4-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> References: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 03/13] ipa: ipu3: awb: Use saturation under 90% 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" The AWB grey world algorithm tries to find a grey value and it can't do it on over-exposed images. To exclude those, the saturation ratio is used for each cell, and the cell is included only if this ratio is 0. Now that we have changed the threshold, more cells may be considered as partially saturated and excluded, preventing the algorithm from running efficiently. Change that behaviour, and consider 90% as a good enough ratio. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/algorithms/awb.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp index e44bbd6c..62c72cce 100644 --- a/src/ipa/ipu3/algorithms/awb.cpp +++ b/src/ipa/ipu3/algorithms/awb.cpp @@ -19,6 +19,12 @@ LOG_DEFINE_CATEGORY(IPU3Awb) static constexpr uint32_t kMinGreenLevelInZone = 32; +/* Minimum proportion of cells counted within a zone for it to be relevant */ +static constexpr double kMinRelevantCellsRatio = 0.8; + +/* Number of cells below the saturation ratio */ +static constexpr uint32_t kSaturationThreshold = 255 * 90 / 100; + /** * \struct Accumulator * \brief RGB statistics for a given zone @@ -160,7 +166,8 @@ int Awb::configure(IPAContext &context, * for it to be relevant for the grey world algorithm. * \todo This proportion could be configured. */ - cellsPerZoneThreshold_ = cellsPerZoneX_ * cellsPerZoneY_ * 80 / 100; + cellsPerZoneThreshold_ = cellsPerZoneX_ * cellsPerZoneY_ * kMinRelevantCellsRatio; + LOG(IPU3Awb, Debug) << "Threshold for AWB is set to " << cellsPerZoneThreshold_; return 0; } @@ -234,7 +241,18 @@ void Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats) reinterpret_cast( &stats->awb_raw_buffer.meta_data[cellPosition] ); - if (currentCell->sat_ratio == 0) { + + /* + * Use cells which have less than 90% + * saturation as an initial means to include + * otherwise bright cells which are not fully + * saturated. + * + * \todo The 90% saturation rate may require + * further empirical measurements and + * optimisation during camera tuning phases. + */ + if (currentCell->sat_ratio <= kSaturationThreshold) { /* The cell is not saturated, use the current cell */ awbStats_[awbZonePosition].counted++; uint32_t greenValue = currentCell->Gr_avg + currentCell->Gb_avg; From patchwork Wed Oct 20 15:45:58 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: 14211 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 96B81C324E for ; Wed, 20 Oct 2021 15:46:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 24C8668F67; Wed, 20 Oct 2021 17:46:20 +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="HqnMqL/V"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EE8DE6023A for ; Wed, 20 Oct 2021 17:46:13 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce4b:1c5f:7302:b899]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id AB3D83F6; Wed, 20 Oct 2021 17:46:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634744773; bh=Pz0NTXrbv9zGzkgSSvnGR/+tUESSHcG6lnJnrkgMAv0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HqnMqL/VeJ10/dsds5FvYKPaz3n/MhqdSNcUMZl9zjjm2nPP5RmlT1oPiojVcJMK/ vbW94bb6ymMmpPp9cVtnip4sHv5vftEdo/RQhSumYYd2JzppKBumps4bqRwxQjnqVo Bd9G4UqSQxek2BlQLoq7OR0StIl/tj8naohA9nVo= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Oct 2021 17:45:58 +0200 Message-Id: <20211020154607.180161-5-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> References: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 04/13] ipa: ipu3: awb: Change minimal green threshold value 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 zones are used for the grey world algorithm, they are only considered if their average green value is at least 32/255 to exclude zones that are too dark and don't provide relevant colour information (on the opposite side of the spectrum, saturated regions are excluded by the ImgU statistics engine). The algorithm requires a minimal number of zones that meet this criteria in order to run. Now that we correct the black level, the 32/255 minimal value is a bit high and prevents the algorithm for running in low-light conditions. Lower the value to 16/255 to fix it. Signed-off-by: Jean-Michel Hautbois Acked-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/algorithms/awb.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp index 62c72cce..1ffb431b 100644 --- a/src/ipa/ipu3/algorithms/awb.cpp +++ b/src/ipa/ipu3/algorithms/awb.cpp @@ -17,7 +17,13 @@ namespace ipa::ipu3::algorithms { LOG_DEFINE_CATEGORY(IPU3Awb) -static constexpr uint32_t kMinGreenLevelInZone = 32; +/* + * When zones are used for the grey world algorithm, they are only considered if + * their average green value is at least 16/255 to exclude zones that are too + * dark and don't provide relevant colour information (on the opposite side of + * the spectrum, saturated regions are excluded by the ImgU statistics engine). + */ +static constexpr uint32_t kMinGreenLevelInZone = 16; /* Minimum proportion of cells counted within a zone for it to be relevant */ static constexpr double kMinRelevantCellsRatio = 0.8; From patchwork Wed Oct 20 15:45:59 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: 14212 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 174AEBDB1C for ; Wed, 20 Oct 2021 15:46:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9DEA168F58; Wed, 20 Oct 2021 17:46:21 +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="STH4QMz7"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3518268F59 for ; Wed, 20 Oct 2021 17:46:14 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce4b:1c5f:7302:b899]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DE9B52A5; Wed, 20 Oct 2021 17:46:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634744774; bh=Nki5LU1fli8jgQo9YfkBS9IiX3kEcDW26jUr/DQrR2o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=STH4QMz7Iv21oMhAS1VcMgvhW5iEUj5XjGknJQjOIEYrjvj+/BLwMLSgNGazPeIxb YuYBoR70Izmh71WOVkASLxZjjhbXPqQBepfy6IB3Y7l1ZTZ93zjLYv5ht5KkcdrrRF zmGb+H2gL+YwbiR/XbbHu4z8+rlCg7wsZSg+EO2o= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Oct 2021 17:45:59 +0200 Message-Id: <20211020154607.180161-6-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> References: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 05/13] ipa: ipu3: agc: Rename exposure values properly 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" The exposure value is filtered in filterExposure() using the currentExposure_ and setting a prevExposure_ variable. This is misnamed as it is not the previous exposure, but a filtered value. Rename it accordingly. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/algorithms/agc.cpp | 28 ++++++++++++++-------------- src/ipa/ipu3/algorithms/agc.h | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index a001e349..b1757b91 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -49,7 +49,7 @@ static constexpr double kEvGainTarget = 0.5; Agc::Agc() : frameCount_(0), lastFrame_(0), iqMean_(0.0), lineDuration_(0s), - maxExposureTime_(0s), prevExposure_(0s), prevExposureNoDg_(0s), + maxExposureTime_(0s), filteredExposure_(0s), filteredExposureNoDg_(0s), currentExposure_(0s), currentExposureNoDg_(0s) { } @@ -100,24 +100,24 @@ void Agc::processBrightness(const ipu3_uapi_stats_3a *stats, void Agc::filterExposure() { double speed = 0.2; - if (prevExposure_ == 0s) { + if (filteredExposure_ == 0s) { /* DG stands for digital gain.*/ - prevExposure_ = currentExposure_; - prevExposureNoDg_ = currentExposureNoDg_; + filteredExposure_ = currentExposure_; + filteredExposureNoDg_ = currentExposureNoDg_; } else { /* * If we are close to the desired result, go faster to avoid making * multiple micro-adjustments. * \ todo: Make this customisable? */ - if (prevExposure_ < 1.2 * currentExposure_ && - prevExposure_ > 0.8 * currentExposure_) + if (filteredExposure_ < 1.2 * currentExposure_ && + filteredExposure_ > 0.8 * currentExposure_) speed = sqrt(speed); - prevExposure_ = speed * currentExposure_ + - prevExposure_ * (1.0 - speed); - prevExposureNoDg_ = speed * currentExposureNoDg_ + - prevExposureNoDg_ * (1.0 - speed); + filteredExposure_ = speed * currentExposure_ + + filteredExposure_ * (1.0 - speed); + filteredExposureNoDg_ = speed * currentExposureNoDg_ + + filteredExposureNoDg_ * (1.0 - speed); } /* * We can't let the no_dg exposure deviate too far below the @@ -125,10 +125,10 @@ void Agc::filterExposure() * in the ISP to hide it (which will cause nasty oscillation). */ double fastReduceThreshold = 0.4; - if (prevExposureNoDg_ < - prevExposure_ * fastReduceThreshold) - prevExposureNoDg_ = prevExposure_ * fastReduceThreshold; - LOG(IPU3Agc, Debug) << "After filtering, total_exposure " << prevExposure_; + if (filteredExposureNoDg_ < + filteredExposure_ * fastReduceThreshold) + filteredExposureNoDg_ = filteredExposure_ * fastReduceThreshold; + LOG(IPU3Agc, Debug) << "After filtering, total_exposure " << filteredExposure_; } void Agc::lockExposureGain(uint32_t &exposure, double &gain) diff --git a/src/ipa/ipu3/algorithms/agc.h b/src/ipa/ipu3/algorithms/agc.h index e0c315fc..16b9fa0a 100644 --- a/src/ipa/ipu3/algorithms/agc.h +++ b/src/ipa/ipu3/algorithms/agc.h @@ -44,8 +44,8 @@ private: utils::Duration lineDuration_; utils::Duration maxExposureTime_; - utils::Duration prevExposure_; - utils::Duration prevExposureNoDg_; + utils::Duration filteredExposure_; + utils::Duration filteredExposureNoDg_; utils::Duration currentExposure_; utils::Duration currentExposureNoDg_; From patchwork Wed Oct 20 15:46:00 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: 14213 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 7120BC324E for ; Wed, 20 Oct 2021 15:46:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 18A5B68F7D; Wed, 20 Oct 2021 17:46:22 +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="sf6iwMou"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 618F668F5E for ; Wed, 20 Oct 2021 17:46:14 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce4b:1c5f:7302:b899]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1D1C04A0; Wed, 20 Oct 2021 17:46:14 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634744774; bh=kMx+moPIPwfRFCviOp2uzuJPIwzKQjAIh25QfCJjcGA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sf6iwMouaJgcO/Kx7i5f0zWqtcL+HLAWfR/DlRXXO/ujthwmPwqBdWB1g+b26eqYM EeZ3DTkpudpkwO48L9b2JGp9hopK7rEOfVGIllIVuDinB2PYgS6xgBgji4Q9PeIxcV vR4+OEx0gdmFeHKO+w0NCTQMGsFtcWJlGMOhPY5I= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Oct 2021 17:46:00 +0200 Message-Id: <20211020154607.180161-7-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> References: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 06/13] ipa: ipu3: agc: Change exposure limits 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" The exposure limits are set for one sensor until now, in a number of lines. We should not use those, but exposure limits in a time unit. Introduce default limits which with a default minimum of 20ms. This value should be given by the IPAIPU3. Use cached values expressed as a number of lines in the configure() call. Adapt the process() call accordingly. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/algorithms/agc.cpp | 34 ++++++++++++++++++--------------- src/ipa/ipu3/algorithms/agc.h | 3 ++- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index b1757b91..8e1b6d8c 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -39,18 +39,14 @@ static constexpr uint32_t kMaxISO = 1500; static constexpr uint32_t kMinGain = kMinISO / 100; static constexpr uint32_t kMaxGain = kMaxISO / 100; -/* \todo use calculated value based on sensor */ -static constexpr uint32_t kMinExposure = 1; -static constexpr uint32_t kMaxExposure = 1976; - /* Histogram constants */ static constexpr uint32_t knumHistogramBins = 256; static constexpr double kEvGainTarget = 0.5; Agc::Agc() : frameCount_(0), lastFrame_(0), iqMean_(0.0), lineDuration_(0s), - maxExposureTime_(0s), filteredExposure_(0s), filteredExposureNoDg_(0s), - currentExposure_(0s), currentExposureNoDg_(0s) + minExposureLines_(0), maxExposureLines_(0), filteredExposure_(0s), + filteredExposureNoDg_(0s), currentExposure_(0s), currentExposureNoDg_(0s) { } @@ -60,13 +56,14 @@ int Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo) lineDuration_ = configInfo.sensorInfo.lineLength * 1.0s / configInfo.sensorInfo.pixelRate; - maxExposureTime_ = context.configuration.agc.maxShutterSpeed; /* Configure the default exposure and gain */ context.frameContext.agc.gain = context.configuration.agc.minAnalogueGain; - context.frameContext.agc.exposure = - context.configuration.agc.minShutterSpeed / lineDuration_; + context.frameContext.agc.exposure = minExposureLines_; + + minExposureLines_ = context.configuration.agc.minShutterSpeed / lineDuration_; + maxExposureLines_ = context.configuration.agc.maxShutterSpeed / lineDuration_; return 0; } @@ -151,23 +148,30 @@ void Agc::lockExposureGain(uint32_t &exposure, double &gain) LOG(IPU3Agc, Debug) << "Actual total exposure " << currentExposureNoDg_ << " Shutter speed " << currentShutter << " Gain " << gain; + currentExposure_ = currentExposureNoDg_ * newGain; - utils::Duration maxTotalExposure = maxExposureTime_ * kMaxGain; + utils::Duration maxShutterSpeed = maxExposureLines_ * lineDuration_; + utils::Duration maxTotalExposure = maxShutterSpeed * kMaxGain; currentExposure_ = std::min(currentExposure_, maxTotalExposure); - LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_; + LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_ + << ", maximum is " << maxTotalExposure; /* \todo: estimate if we need to desaturate */ filterExposure(); utils::Duration newExposure = 0.0s; - if (currentShutter < maxExposureTime_) { - exposure = std::clamp(static_cast(exposure * currentExposure_ / currentExposureNoDg_), kMinExposure, kMaxExposure); + if (currentShutter < maxShutterSpeed) { + exposure = std::clamp(exposure * currentExposure_ / currentExposureNoDg_, + minExposureLines_, + maxExposureLines_); newExposure = currentExposure_ / exposure; gain = std::clamp(static_cast(gain * currentExposure_ / newExposure), kMinGain, kMaxGain); - } else if (currentShutter >= maxExposureTime_) { + } else if (currentShutter >= maxShutterSpeed) { gain = std::clamp(static_cast(gain * currentExposure_ / currentExposureNoDg_), kMinGain, kMaxGain); newExposure = currentExposure_ / gain; - exposure = std::clamp(static_cast(exposure * currentExposure_ / newExposure), kMinExposure, kMaxExposure); + exposure = std::clamp(exposure * currentExposure_ / newExposure, + minExposureLines_, + maxExposureLines_); } LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * lineDuration_ << " and gain " << gain; } diff --git a/src/ipa/ipu3/algorithms/agc.h b/src/ipa/ipu3/algorithms/agc.h index 16b9fa0a..cd26d08c 100644 --- a/src/ipa/ipu3/algorithms/agc.h +++ b/src/ipa/ipu3/algorithms/agc.h @@ -42,7 +42,8 @@ private: double iqMean_; utils::Duration lineDuration_; - utils::Duration maxExposureTime_; + uint32_t minExposureLines_; + uint32_t maxExposureLines_; utils::Duration filteredExposure_; utils::Duration filteredExposureNoDg_; From patchwork Wed Oct 20 15:46:01 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: 14214 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 CB4CBC324F for ; Wed, 20 Oct 2021 15:46:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7766868F63; Wed, 20 Oct 2021 17:46:22 +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="i3jhckUQ"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A0CDC68F57 for ; Wed, 20 Oct 2021 17:46:14 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce4b:1c5f:7302:b899]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 49BA62A5; Wed, 20 Oct 2021 17:46:14 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634744774; bh=B/VsM9zQtm7SbexqWytoAdNcJXlyttyznXLHwU8UZLo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=i3jhckUQO59x5QyhRNeUgd1mqnRcqzOPJTkJBlYYaPcflIvCNhYLcYkxs5VILMEZt tH0jlngY9zYqXVL36VvKn38kw0YzEvH4EHyfnJ2O8BdDMqt0GAlqKMQhr9tpYjLB4m CXgDVnEaKmjuHyGER0nfYc7srBjfl15C3lb3aVd8= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Oct 2021 17:46:01 +0200 Message-Id: <20211020154607.180161-8-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> References: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 07/13] ipa: ipu3: agc: Change analogue gain limits 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" The gains is currently set as a uint32_t while the analogue gain is passed as a double. We also have a default maximum analogue gain of 15 which is quite high for a number of sensors. Use a maximum value of 8 which should really be configured by the IPA and not fixed as it is now. While at it make it a double. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/algorithms/agc.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index 8e1b6d8c..1bae1eb9 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -30,14 +30,10 @@ static constexpr uint32_t kInitialFrameMinAECount = 4; /* Number of frames to wait between new gain/exposure estimations */ static constexpr uint32_t kFrameSkipCount = 6; -/* Maximum ISO value for analogue gain */ -static constexpr uint32_t kMinISO = 100; -static constexpr uint32_t kMaxISO = 1500; - /* Maximum analogue gain value * \todo grab it from a camera helper */ -static constexpr uint32_t kMinGain = kMinISO / 100; -static constexpr uint32_t kMaxGain = kMaxISO / 100; +static constexpr double kMinGain = 1.0; +static constexpr double kMaxGain = 8.0; /* Histogram constants */ static constexpr uint32_t knumHistogramBins = 256; @@ -165,9 +161,11 @@ void Agc::lockExposureGain(uint32_t &exposure, double &gain) minExposureLines_, maxExposureLines_); newExposure = currentExposure_ / exposure; - gain = std::clamp(static_cast(gain * currentExposure_ / newExposure), kMinGain, kMaxGain); + gain = std::clamp(gain * currentExposure_ / newExposure, + kMinGain, kMaxGain); } else if (currentShutter >= maxShutterSpeed) { - gain = std::clamp(static_cast(gain * currentExposure_ / currentExposureNoDg_), kMinGain, kMaxGain); + gain = std::clamp(gain * currentExposure_ / currentExposureNoDg_, + kMinGain, kMaxGain); newExposure = currentExposure_ / gain; exposure = std::clamp(exposure * currentExposure_ / newExposure, minExposureLines_, From patchwork Wed Oct 20 15:46:02 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: 14215 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 57CE9BDB1C for ; Wed, 20 Oct 2021 15:46:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D766068F7B; Wed, 20 Oct 2021 17:46:22 +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="v/UXFwCZ"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C260968F5F for ; Wed, 20 Oct 2021 17:46:14 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce4b:1c5f:7302:b899]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7D3103F6; Wed, 20 Oct 2021 17:46:14 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634744774; bh=toWzcZBpc4oJgr6YCZ0DAsAD/LTK7GTdpHYKEHtxRN0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=v/UXFwCZ7xtFqZVRR/A5UZ+4Np94r1raRU0MZDHhdaqly8BKJ5nrh0NaKEz6sfJf2 j+bwKge0DGkQR+lKCxVO9cYyR7sQHq4D5v7MynXO09zO9HpvbO/7z1dNFVfo2JWUPo 6D5ieNy0aOCsq7AN0aT0UtgsYwbLzrqpa0LeOs8Q= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Oct 2021 17:46:02 +0200 Message-Id: <20211020154607.180161-9-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> References: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 08/13] ipa: ipu3: agc: Simplify division of exposure/gain 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" Until now, the algorithm makes complex assumptions when dividing the exposure and analogue gain values. Instead, use a simpler clamping of the shutter speed first, and then of the analogue gain, based on the limits configured. While at it, correct a bug which makes the algorithm not use the filtered result from filterExposure(). Signed-off-by: Jean-Michel Hautbois Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/algorithms/agc.cpp | 36 +++++++++++++++++---------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index 1bae1eb9..84e41834 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -146,7 +146,9 @@ void Agc::lockExposureGain(uint32_t &exposure, double &gain) << " Gain " << gain; currentExposure_ = currentExposureNoDg_ * newGain; + utils::Duration minShutterSpeed = minExposureLines_ * lineDuration_; utils::Duration maxShutterSpeed = maxExposureLines_ * lineDuration_; + utils::Duration maxTotalExposure = maxShutterSpeed * kMaxGain; currentExposure_ = std::min(currentExposure_, maxTotalExposure); LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_ @@ -155,23 +157,23 @@ void Agc::lockExposureGain(uint32_t &exposure, double &gain) /* \todo: estimate if we need to desaturate */ filterExposure(); - utils::Duration newExposure = 0.0s; - if (currentShutter < maxShutterSpeed) { - exposure = std::clamp(exposure * currentExposure_ / currentExposureNoDg_, - minExposureLines_, - maxExposureLines_); - newExposure = currentExposure_ / exposure; - gain = std::clamp(gain * currentExposure_ / newExposure, - kMinGain, kMaxGain); - } else if (currentShutter >= maxShutterSpeed) { - gain = std::clamp(gain * currentExposure_ / currentExposureNoDg_, - kMinGain, kMaxGain); - newExposure = currentExposure_ / gain; - exposure = std::clamp(exposure * currentExposure_ / newExposure, - minExposureLines_, - maxExposureLines_); - } - LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * lineDuration_ << " and gain " << gain; + utils::Duration exposureValue = filteredExposure_; + utils::Duration shutterTime = minShutterSpeed; + + /* + * Push the shutter time up to the maximum first, and only then + * increase the gain. + */ + shutterTime = std::clamp(exposureValue / kMinGain, + minShutterSpeed, maxShutterSpeed); + double stepGain = std::clamp(exposureValue / shutterTime, + kMinGain, kMaxGain); + LOG(IPU3Agc, Debug) << "Divided up shutter and gain are " + << shutterTime << " and " + << stepGain; + + exposure = shutterTime / lineDuration_; + gain = stepGain; } lastFrame_ = frameCount_; } From patchwork Wed Oct 20 15:46:03 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: 14216 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 D0035C324E for ; Wed, 20 Oct 2021 15:46:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5BD2768F81; Wed, 20 Oct 2021 17:46:23 +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="W13VEesL"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0127C68F61 for ; Wed, 20 Oct 2021 17:46:15 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce4b:1c5f:7302:b899]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A7CB64A0; Wed, 20 Oct 2021 17:46:14 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634744774; bh=Q4oa2FGvAXp7qsBCMU9rJT2TJ7+g1rDYDmzAVxPEWQk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=W13VEesLdjNyS0RACW0advbXLxxvp7vPb/WeyTRU8d0j0JyYTKu3NtehJfBf5eJEI fXWnTwWHwEgjfSRQ0Osx/elNwNt+yD/7JkJd8PJ73fKByfqokp9NWicfsKOoLYP+Zr CjJ3wyba9Amghi9XXQSVNbuWRxGr9pdDhp7ZfSOg= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Oct 2021 17:46:03 +0200 Message-Id: <20211020154607.180161-10-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> References: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 09/13] ipa: ipu3: agc: Rename gains properly 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" We have mixed terms between gain, analogue gain and the exposure value gain. Make it clear when we are using the analogue gain from the sensor, and when we are using the calculated gain to be applied to the exposure value to reach the target. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/algorithms/agc.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index 84e41834..eec77378 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -124,7 +124,7 @@ void Agc::filterExposure() LOG(IPU3Agc, Debug) << "After filtering, total_exposure " << filteredExposure_; } -void Agc::lockExposureGain(uint32_t &exposure, double &gain) +void Agc::lockExposureGain(uint32_t &exposure, double &analogueGain) { /* Algorithm initialization should wait for first valid frames */ /* \todo - have a number of frames given by DelayedControls ? @@ -136,16 +136,17 @@ void Agc::lockExposureGain(uint32_t &exposure, double &gain) if (std::abs(iqMean_ - kEvGainTarget * knumHistogramBins) <= 1) { LOG(IPU3Agc, Debug) << "!!! Good exposure with iqMean = " << iqMean_; } else { - double newGain = kEvGainTarget * knumHistogramBins / iqMean_; + double evGain = kEvGainTarget * knumHistogramBins / iqMean_; /* extracted from Rpi::Agc::computeTargetExposure */ utils::Duration currentShutter = exposure * lineDuration_; - currentExposureNoDg_ = currentShutter * gain; + currentExposureNoDg_ = currentShutter * analogueGain; LOG(IPU3Agc, Debug) << "Actual total exposure " << currentExposureNoDg_ << " Shutter speed " << currentShutter - << " Gain " << gain; + << " Gain " << analogueGain + << " Needed ev gain " << evGain; - currentExposure_ = currentExposureNoDg_ * newGain; + currentExposure_ = currentExposureNoDg_ * evGain; utils::Duration minShutterSpeed = minExposureLines_ * lineDuration_; utils::Duration maxShutterSpeed = maxExposureLines_ * lineDuration_; @@ -173,7 +174,7 @@ void Agc::lockExposureGain(uint32_t &exposure, double &gain) << stepGain; exposure = shutterTime / lineDuration_; - gain = stepGain; + analogueGain = stepGain; } lastFrame_ = frameCount_; } @@ -181,9 +182,9 @@ void Agc::lockExposureGain(uint32_t &exposure, double &gain) void Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) { uint32_t &exposure = context.frameContext.agc.exposure; - double &gain = context.frameContext.agc.gain; + double &analogueGain = context.frameContext.agc.gain; processBrightness(stats, context.configuration.grid.bdsGrid); - lockExposureGain(exposure, gain); + lockExposureGain(exposure, analogueGain); frameCount_++; } From patchwork Wed Oct 20 15:46:04 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: 14217 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 3D81DC324F for ; Wed, 20 Oct 2021 15:46:25 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2B32368F72; Wed, 20 Oct 2021 17:46:24 +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="mU6nvnPj"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3168068F63 for ; Wed, 20 Oct 2021 17:46:15 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce4b:1c5f:7302:b899]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DA7982A5; Wed, 20 Oct 2021 17:46:14 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634744774; bh=WQdHNjuZ38BqrUJ1EzXIwk0iS6RCaASC1C/w4W+XxC0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mU6nvnPj205UVW6tKCrwKCoqPQc7B9/TysVIaFy972X1cqt3ELmNk+36D0FTWQZbT 5k1W912ku8q5FGobn72mqC9HnTYkWqd4Z8VFyRyTjx1YNRnJhl1sV8/FJgoscznFoi oeSRe7tIFNVWo0G1gLftC1a9E5lYsSYagumSF3nI= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Oct 2021 17:46:04 +0200 Message-Id: <20211020154607.180161-11-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> References: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 10/13] ipa: ipu3: agc: Introduce previous exposure value 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" We need to calculate the gain on the previous exposure value calculated. Now that we initialise the exposure and gain values in configure(), we know the initial exposure value, and we can set it before any loop is running. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/algorithms/agc.cpp | 13 +++++++++++-- src/ipa/ipu3/algorithms/agc.h | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index eec77378..19f3a420 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -42,7 +42,8 @@ static constexpr double kEvGainTarget = 0.5; Agc::Agc() : frameCount_(0), lastFrame_(0), iqMean_(0.0), lineDuration_(0s), minExposureLines_(0), maxExposureLines_(0), filteredExposure_(0s), - filteredExposureNoDg_(0s), currentExposure_(0s), currentExposureNoDg_(0s) + filteredExposureNoDg_(0s), currentExposure_(0s), + currentExposureNoDg_(0s), prevExposureValue_(0s) { } @@ -58,9 +59,14 @@ int Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo) context.configuration.agc.minAnalogueGain; context.frameContext.agc.exposure = minExposureLines_; + /* \todo replace the exposure in lines storage with time based ones */ minExposureLines_ = context.configuration.agc.minShutterSpeed / lineDuration_; maxExposureLines_ = context.configuration.agc.maxShutterSpeed / lineDuration_; + prevExposureValue_ = context.frameContext.agc.gain + * context.frameContext.agc.exposure + * lineDuration_; + return 0; } @@ -146,7 +152,7 @@ void Agc::lockExposureGain(uint32_t &exposure, double &analogueGain) << " Gain " << analogueGain << " Needed ev gain " << evGain; - currentExposure_ = currentExposureNoDg_ * evGain; + currentExposure_ = prevExposureValue_ * evGain; utils::Duration minShutterSpeed = minExposureLines_ * lineDuration_; utils::Duration maxShutterSpeed = maxExposureLines_ * lineDuration_; @@ -175,6 +181,9 @@ void Agc::lockExposureGain(uint32_t &exposure, double &analogueGain) exposure = shutterTime / lineDuration_; analogueGain = stepGain; + + /* Update the exposure value for the next process call */ + prevExposureValue_ = shutterTime * analogueGain; } lastFrame_ = frameCount_; } diff --git a/src/ipa/ipu3/algorithms/agc.h b/src/ipa/ipu3/algorithms/agc.h index cd26d08c..2ae88e9f 100644 --- a/src/ipa/ipu3/algorithms/agc.h +++ b/src/ipa/ipu3/algorithms/agc.h @@ -49,6 +49,7 @@ private: utils::Duration filteredExposureNoDg_; utils::Duration currentExposure_; utils::Duration currentExposureNoDg_; + utils::Duration prevExposureValue_; uint32_t stride_; }; From patchwork Wed Oct 20 15:46:05 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: 14219 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 ACA39C324E for ; Wed, 20 Oct 2021 15:46:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 50CDB68F60; Wed, 20 Oct 2021 17:46:26 +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="eZyzpbgz"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6011968F58 for ; Wed, 20 Oct 2021 17:46:15 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce4b:1c5f:7302:b899]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 13F5C3F6; Wed, 20 Oct 2021 17:46:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634744775; bh=w7fjAlq+LLKYhHuPWeL/CdYSaCl9VC9fZy49ZbmKwXk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eZyzpbgz43xjgrKlzMrfHrDihMcqP1LGJFBXs3DuuQdljyp0LWgNUCsdf/4UjiEyi +9PCX77yQBdTgPWP1IEsjjjvyW2JFO2VNr8lOAr5A0aFTplwccFxDDjPuFYs+EZH1E L0H7V5Q+hhmO1eaRKZfQtVQDZXFcIAE0P6ThlYcY= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Oct 2021 17:46:05 +0200 Message-Id: <20211020154607.180161-12-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> References: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 11/13] ipa: ipu3: agc: Remove condition on exposure correction 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" Until now, we can't know when the exposure and gains applied in the IPAIPU3::setControls() are really applied (it can be several frames). We don't want to use the values calculated as if they are already applied, and this is done by testing the frame number. When the exposure is estimated, we verify if it changed enough for exposure and gain to be updated. There is no need for that because we are now filtering the value with the previous one correctly, so if the change is very small the exposure and analogue gain my evolve a bit but it should not be visible to the user. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham --- src/ipa/ipu3/algorithms/agc.cpp | 78 ++++++++++++++++----------------- 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index 19f3a420..0417dc99 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -138,53 +138,49 @@ void Agc::lockExposureGain(uint32_t &exposure, double &analogueGain) if ((frameCount_ < kInitialFrameMinAECount) || (frameCount_ - lastFrame_ < kFrameSkipCount)) return; - /* Are we correctly exposed ? */ - if (std::abs(iqMean_ - kEvGainTarget * knumHistogramBins) <= 1) { - LOG(IPU3Agc, Debug) << "!!! Good exposure with iqMean = " << iqMean_; - } else { - double evGain = kEvGainTarget * knumHistogramBins / iqMean_; + double evGain = kEvGainTarget * knumHistogramBins / iqMean_; - /* extracted from Rpi::Agc::computeTargetExposure */ - utils::Duration currentShutter = exposure * lineDuration_; - currentExposureNoDg_ = currentShutter * analogueGain; - LOG(IPU3Agc, Debug) << "Actual total exposure " << currentExposureNoDg_ - << " Shutter speed " << currentShutter - << " Gain " << analogueGain - << " Needed ev gain " << evGain; + /* extracted from Rpi::Agc::computeTargetExposure */ + utils::Duration currentShutter = exposure * lineDuration_; + currentExposureNoDg_ = currentShutter * analogueGain; + LOG(IPU3Agc, Debug) << "Actual total exposure " << currentExposureNoDg_ + << " Shutter speed " << currentShutter + << " Gain " << analogueGain + << " Needed ev gain " << evGain; - currentExposure_ = prevExposureValue_ * evGain; - utils::Duration minShutterSpeed = minExposureLines_ * lineDuration_; - utils::Duration maxShutterSpeed = maxExposureLines_ * lineDuration_; + currentExposure_ = prevExposureValue_ * evGain; + utils::Duration minShutterSpeed = minExposureLines_ * lineDuration_; + utils::Duration maxShutterSpeed = maxExposureLines_ * lineDuration_; - utils::Duration maxTotalExposure = maxShutterSpeed * kMaxGain; - currentExposure_ = std::min(currentExposure_, maxTotalExposure); - LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_ - << ", maximum is " << maxTotalExposure; + utils::Duration maxTotalExposure = maxShutterSpeed * kMaxGain; + currentExposure_ = std::min(currentExposure_, maxTotalExposure); + LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_ + << ", maximum is " << maxTotalExposure; - /* \todo: estimate if we need to desaturate */ - filterExposure(); + /* \todo: estimate if we need to desaturate */ + filterExposure(); - utils::Duration exposureValue = filteredExposure_; - utils::Duration shutterTime = minShutterSpeed; + utils::Duration exposureValue = filteredExposure_; + utils::Duration shutterTime = minShutterSpeed; + + /* + * Push the shutter time up to the maximum first, and only then + * increase the gain. + */ + shutterTime = std::clamp(exposureValue / kMinGain, + minShutterSpeed, maxShutterSpeed); + double stepGain = std::clamp(exposureValue / shutterTime, + kMinGain, kMaxGain); + LOG(IPU3Agc, Debug) << "Divided up shutter and gain are " + << shutterTime << " and " + << stepGain; + + exposure = shutterTime / lineDuration_; + analogueGain = stepGain; + + /* Update the exposure value for the next process call */ + prevExposureValue_ = shutterTime * analogueGain; - /* - * Push the shutter time up to the maximum first, and only then - * increase the gain. - */ - shutterTime = std::clamp(exposureValue / kMinGain, - minShutterSpeed, maxShutterSpeed); - double stepGain = std::clamp(exposureValue / shutterTime, - kMinGain, kMaxGain); - LOG(IPU3Agc, Debug) << "Divided up shutter and gain are " - << shutterTime << " and " - << stepGain; - - exposure = shutterTime / lineDuration_; - analogueGain = stepGain; - - /* Update the exposure value for the next process call */ - prevExposureValue_ = shutterTime * analogueGain; - } lastFrame_ = frameCount_; } From patchwork Wed Oct 20 15:46:06 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: 14218 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 ED27CBDB1C for ; Wed, 20 Oct 2021 15:46:25 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AE36B68F71; Wed, 20 Oct 2021 17:46:25 +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="iWc7sYOr"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 809E068F65 for ; Wed, 20 Oct 2021 17:46:15 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce4b:1c5f:7302:b899]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 410074A0; Wed, 20 Oct 2021 17:46:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634744775; bh=ue4gnKDNfBWRHNBbFAcHKK6MsVpAwzIwj9X60jF9+/Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iWc7sYOr0TLfCPFDf1+LzNJkGXLnQxnGAXub15MdeIuW63EmbTp9augbKeQYJdA43 B/ZXotm1Qriyqa3HygberpVqh8syv2Q4hovEoq04N/xXTzjySBw26sAfPgRFBamihF 7L45DxgEV/t8q99Ika6f2QfZpOBOGCpBBPG6xwnM= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Oct 2021 17:46:06 +0200 Message-Id: <20211020154607.180161-13-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> References: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 12/13] ipa: ipu3: agc: Remove unused variables 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" We currently control the exposure value by the shutter speed and the analogue gain. We can't use the digital gain to have more than the maximum exposure value calculated because we are not controlling it. Remove unused code associated with this digital gain. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/algorithms/agc.cpp | 19 +++---------------- src/ipa/ipu3/algorithms/agc.h | 2 -- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index 0417dc99..fc37eca4 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -42,8 +42,7 @@ static constexpr double kEvGainTarget = 0.5; Agc::Agc() : frameCount_(0), lastFrame_(0), iqMean_(0.0), lineDuration_(0s), minExposureLines_(0), maxExposureLines_(0), filteredExposure_(0s), - filteredExposureNoDg_(0s), currentExposure_(0s), - currentExposureNoDg_(0s), prevExposureValue_(0s) + currentExposure_(0s), prevExposureValue_(0s) { } @@ -102,7 +101,6 @@ void Agc::filterExposure() if (filteredExposure_ == 0s) { /* DG stands for digital gain.*/ filteredExposure_ = currentExposure_; - filteredExposureNoDg_ = currentExposureNoDg_; } else { /* * If we are close to the desired result, go faster to avoid making @@ -115,18 +113,8 @@ void Agc::filterExposure() filteredExposure_ = speed * currentExposure_ + filteredExposure_ * (1.0 - speed); - filteredExposureNoDg_ = speed * currentExposureNoDg_ + - filteredExposureNoDg_ * (1.0 - speed); } - /* - * We can't let the no_dg exposure deviate too far below the - * total exposure, as there might not be enough digital gain available - * in the ISP to hide it (which will cause nasty oscillation). - */ - double fastReduceThreshold = 0.4; - if (filteredExposureNoDg_ < - filteredExposure_ * fastReduceThreshold) - filteredExposureNoDg_ = filteredExposure_ * fastReduceThreshold; + LOG(IPU3Agc, Debug) << "After filtering, total_exposure " << filteredExposure_; } @@ -142,8 +130,7 @@ void Agc::lockExposureGain(uint32_t &exposure, double &analogueGain) /* extracted from Rpi::Agc::computeTargetExposure */ utils::Duration currentShutter = exposure * lineDuration_; - currentExposureNoDg_ = currentShutter * analogueGain; - LOG(IPU3Agc, Debug) << "Actual total exposure " << currentExposureNoDg_ + LOG(IPU3Agc, Debug) << "Actual total exposure " << currentShutter * analogueGain << " Shutter speed " << currentShutter << " Gain " << analogueGain << " Needed ev gain " << evGain; diff --git a/src/ipa/ipu3/algorithms/agc.h b/src/ipa/ipu3/algorithms/agc.h index 2ae88e9f..ad133b98 100644 --- a/src/ipa/ipu3/algorithms/agc.h +++ b/src/ipa/ipu3/algorithms/agc.h @@ -46,9 +46,7 @@ private: uint32_t maxExposureLines_; utils::Duration filteredExposure_; - utils::Duration filteredExposureNoDg_; utils::Duration currentExposure_; - utils::Duration currentExposureNoDg_; utils::Duration prevExposureValue_; uint32_t stride_; From patchwork Wed Oct 20 15:46:07 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: 14220 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 A7CC0BDB1C for ; Wed, 20 Oct 2021 15:46:27 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6C66B68F6D; Wed, 20 Oct 2021 17:46:27 +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="VuEDqKv7"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AD34D68F60 for ; Wed, 20 Oct 2021 17:46:15 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce4b:1c5f:7302:b899]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6B5972A5; Wed, 20 Oct 2021 17:46:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634744775; bh=lUXBJBpzamqtmw8hOTzG6XENC1rbf9+VtCPn2jRXSjE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VuEDqKv7uqHzLR7DfwyNzZc0xN2xTn91Q3PDSCCIAsnb5w2mUccMxEMCSB6iznC1m vMKNyckS1NsBUDUEdU5wkBqiicjqMti8ok6EB1iAti9/QodmvywFJXanbZwZWuOq4D no5HtitTVEWogDyNZ5keFIGzzHqFA9cxjSqHeXAA= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Oct 2021 17:46:07 +0200 Message-Id: <20211020154607.180161-14-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> References: <20211020154607.180161-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 13/13] ipa: ipu3: Use sensor limits for analogue gain 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" Instead of using constants for the analogue gains limits, use the minimum and maximum from the configured sensor. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/algorithms/agc.cpp | 25 +++++++++++++------------ src/ipa/ipu3/algorithms/agc.h | 3 +++ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index fc37eca4..690ad7e6 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -30,10 +30,9 @@ static constexpr uint32_t kInitialFrameMinAECount = 4; /* Number of frames to wait between new gain/exposure estimations */ static constexpr uint32_t kFrameSkipCount = 6; -/* Maximum analogue gain value - * \todo grab it from a camera helper */ -static constexpr double kMinGain = 1.0; -static constexpr double kMaxGain = 8.0; +/* Limits for analogue gain values */ +static constexpr double kMinAnalogueGain = 1.0; +static constexpr double kMaxAnalogueGain = 16.0; /* Histogram constants */ static constexpr uint32_t knumHistogramBins = 256; @@ -53,15 +52,17 @@ int Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo) lineDuration_ = configInfo.sensorInfo.lineLength * 1.0s / configInfo.sensorInfo.pixelRate; - /* Configure the default exposure and gain */ - context.frameContext.agc.gain = - context.configuration.agc.minAnalogueGain; - context.frameContext.agc.exposure = minExposureLines_; - /* \todo replace the exposure in lines storage with time based ones */ minExposureLines_ = context.configuration.agc.minShutterSpeed / lineDuration_; maxExposureLines_ = context.configuration.agc.maxShutterSpeed / lineDuration_; + minAnalogueGain_ = std::max(context.configuration.agc.minAnalogueGain, kMinAnalogueGain); + maxAnalogueGain_ = std::min(context.configuration.agc.maxAnalogueGain, kMaxAnalogueGain); + + /* Configure the default exposure and gain */ + context.frameContext.agc.gain = minAnalogueGain_; + context.frameContext.agc.exposure = minExposureLines_; + prevExposureValue_ = context.frameContext.agc.gain * context.frameContext.agc.exposure * lineDuration_; @@ -139,7 +140,7 @@ void Agc::lockExposureGain(uint32_t &exposure, double &analogueGain) utils::Duration minShutterSpeed = minExposureLines_ * lineDuration_; utils::Duration maxShutterSpeed = maxExposureLines_ * lineDuration_; - utils::Duration maxTotalExposure = maxShutterSpeed * kMaxGain; + utils::Duration maxTotalExposure = maxShutterSpeed * maxAnalogueGain_; currentExposure_ = std::min(currentExposure_, maxTotalExposure); LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_ << ", maximum is " << maxTotalExposure; @@ -154,10 +155,10 @@ void Agc::lockExposureGain(uint32_t &exposure, double &analogueGain) * Push the shutter time up to the maximum first, and only then * increase the gain. */ - shutterTime = std::clamp(exposureValue / kMinGain, + shutterTime = std::clamp(exposureValue / minAnalogueGain_, minShutterSpeed, maxShutterSpeed); double stepGain = std::clamp(exposureValue / shutterTime, - kMinGain, kMaxGain); + minAnalogueGain_, maxAnalogueGain_); LOG(IPU3Agc, Debug) << "Divided up shutter and gain are " << shutterTime << " and " << stepGain; diff --git a/src/ipa/ipu3/algorithms/agc.h b/src/ipa/ipu3/algorithms/agc.h index ad133b98..1840205b 100644 --- a/src/ipa/ipu3/algorithms/agc.h +++ b/src/ipa/ipu3/algorithms/agc.h @@ -45,6 +45,9 @@ private: uint32_t minExposureLines_; uint32_t maxExposureLines_; + double minAnalogueGain_; + double maxAnalogueGain_; + utils::Duration filteredExposure_; utils::Duration currentExposure_; utils::Duration prevExposureValue_;