From patchwork Fri Oct 22 07:32:36 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: 14237 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 197CBBF415 for ; Fri, 22 Oct 2021 07:33:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BF5A268F67; Fri, 22 Oct 2021 09:32:57 +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="bVGV73do"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 63A9E68F57 for ; Fri, 22 Oct 2021 09:32:54 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:22cc:3af6:5ccb:8367]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id EFDA389A; Fri, 22 Oct 2021 09:32:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634887974; bh=oX2f7LaB6UO3edalXFu0y5aT46U54qw8zfT+MGW4tEM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bVGV73doJdNyzEkUvIwwaFPflyJRT8PTQKIkjKRyA4pybhjjYzNNdsAY/TKaPg1Bq T6a4gje/1NnsSkNX2ZxPhP84mOG3XZbiWCFycR69tSoDhrvu1n2TAv9/grsoB9jjGS /IJsYW+01zFvM5QUOnMV4t7Q6RShG25duIUaNO/I= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 22 Oct 2021 09:32:36 +0200 Message-Id: <20211022073249.35084-2-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> References: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 01/14] 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 Reviewed-by: Kieran Bingham --- src/ipa/ipu3/algorithms/awb.cpp | 27 +++++++++++++++++++++------ src/ipa/ipu3/algorithms/awb.h | 1 + 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp index 809de66a..4364928c 100644 --- a/src/ipa/ipu3/algorithms/awb.cpp +++ b/src/ipa/ipu3/algorithms/awb.cpp @@ -328,14 +328,29 @@ 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] */ + return value * 8191; +} + 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..0c81e39e 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); + static constexpr uint16_t threshold(float value); std::vector zones_; Accumulator awbStats_[kAwbStatsSizeX * kAwbStatsSizeY]; From patchwork Fri Oct 22 07:32:37 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: 14238 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 08B94BF415 for ; Fri, 22 Oct 2021 07:33:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CFC3668F6C; Fri, 22 Oct 2021 09:32:58 +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="DkNvciga"; 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 8F1AF68F58 for ; Fri, 22 Oct 2021 09:32:54 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:22cc:3af6:5ccb:8367]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2FC011908; Fri, 22 Oct 2021 09:32:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634887974; bh=WLcW3EpAUw6mRn12xBZYoxaEM+cAJa/igT+LGrJx8M8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DkNvcigaTE9eSfWbXyKER/NTcDVr3Uqtz5pDbyseWANCSkYIM2LLekGEakDPAz3/T 4+5LAITCWjdDuDEb2veHRbfWSYyRdbbEmYvATXr/qSpgQ6ewvPMj5ANvCeTolzgsoV mu03owMoPQe94rzSw/H2q27ZTg/ZBqzi+fEpF0nI= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 22 Oct 2021 09:32:37 +0200 Message-Id: <20211022073249.35084-3-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> References: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 02/14] 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. Until now, the IPA uses the minimum exposure and gain values and caches those in local variables. In order to give the sensor limits to AGC, create a new structure in IPASessionConfiguration. Store the exposure in time (and not line duration) and the analogue gain after CameraSensorHelper conversion. Set the gain and exposure appropriately to the current values known to the IPA and remove the setting of exposure and gain in IPAIPU3 as those are now fully controlled by IPU3Agc. 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..828e822c 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..65d3fd2c 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 Fri Oct 22 07:32:38 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: 14239 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 ED415BF415 for ; Fri, 22 Oct 2021 07:33:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 897F568F6F; Fri, 22 Oct 2021 09:33:00 +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="NdkJBo7I"; 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 B02D668F59 for ; Fri, 22 Oct 2021 09:32:54 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:22cc:3af6:5ccb:8367]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 63B6B51D; Fri, 22 Oct 2021 09:32:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634887974; bh=ci6wDe8/MtW8Q5DOJdQzKY9fV2P2g7YSDJJKKmgmQHI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NdkJBo7Irs3JAX/D2DVA3kudqSTst2/P3J8TZIVEUYO0/e3qcV7j7e4h5mTAaiGf2 lOTinwsQCauQx6wTWbbeNfhFC4n5eJN3R7SUqDuwmPb5LDtKTYJ/inF6yE/pJjwsN9 zHMDG3UakmUztgEYsKyueSh7nAgNFBiFEd9506Ws= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 22 Oct 2021 09:32:38 +0200 Message-Id: <20211022073249.35084-4-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> References: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 03/14] 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 Reviewed-by: Kieran Bingham --- src/ipa/ipu3/algorithms/awb.cpp | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp index 4364928c..c5976c6f 100644 --- a/src/ipa/ipu3/algorithms/awb.cpp +++ b/src/ipa/ipu3/algorithms/awb.cpp @@ -19,6 +19,18 @@ LOG_DEFINE_CATEGORY(IPU3Awb) static constexpr uint32_t kMinGreenLevelInZone = 32; +/* + * Minimum proportion of non-saturated cells in a zone for the zone to be used + * by the AWB algorithm. + */ +static constexpr double kMaxCellSaturationRatio = 0.8; + +/* + * Maximum ratio of saturated pixels in a cell for the cell to be considered + * non-saturated and counted by the AWB algorithm. + */ +static constexpr uint32_t kMinCellsPerZoneRatio = 255 * 90 / 100; + /** * \struct Accumulator * \brief RGB statistics for a given zone @@ -160,7 +172,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_ * kMaxCellSaturationRatio; + LOG(IPU3Awb, Debug) << "Threshold for AWB is set to " << cellsPerZoneThreshold_; return 0; } @@ -234,7 +247,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 <= kMinCellsPerZoneRatio) { /* The cell is not saturated, use the current cell */ awbStats_[awbZonePosition].counted++; uint32_t greenValue = currentCell->Gr_avg + currentCell->Gb_avg; From patchwork Fri Oct 22 07:32:39 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: 14240 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 BDC2CC324E for ; Fri, 22 Oct 2021 07:33:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 88F3868F70; Fri, 22 Oct 2021 09:33:01 +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="qrtTONJy"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E3F8968F5B for ; Fri, 22 Oct 2021 09:32:54 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:22cc:3af6:5ccb:8367]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 970EC89A; Fri, 22 Oct 2021 09:32:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634887974; bh=lNJYWZ32b26zSrgbjCIddUZ/9wlJ8wdRHrYYB6zdqRc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qrtTONJy+fGsNCHto9OSeY7pcL9j0Zyjr7IGqMer+AhQxBLws+/eD655comV4D3i7 FDKxB789mckvr0SzXXIcZaJBkEli86Pm84k17Ty9iseF4mHpfTgEnM6vHYar7XvD7b 9AudOAo8lqDhkkhWzgm7I6i4cY2KRLisM+kS6ry8= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 22 Oct 2021 09:32:39 +0200 Message-Id: <20211022073249.35084-5-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> References: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 04/14] 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 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp index c5976c6f..91364a04 100644 --- a/src/ipa/ipu3/algorithms/awb.cpp +++ b/src/ipa/ipu3/algorithms/awb.cpp @@ -17,7 +17,14 @@ 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 (after black level subtraction) + * 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 non-saturated cells in a zone for the zone to be used From patchwork Fri Oct 22 07:32:40 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: 14241 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 95665BF415 for ; Fri, 22 Oct 2021 07:33:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 171B968F68; Fri, 22 Oct 2021 09:33:03 +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="Z6MIjKJx"; 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 23B1F60128 for ; Fri, 22 Oct 2021 09:32:55 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:22cc:3af6:5ccb:8367]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id CC0451908; Fri, 22 Oct 2021 09:32:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634887974; bh=l+Mz/wHRifSiN6OzVUIf7GYOxdpXJIVhxxPXpPt0Sko=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Z6MIjKJxpcIdCQfK0ObD8FlyApHuE68abQVuIEzYfQW1PRolBV2ghFp7gLKGBPPWV m6xDVkSxMevSpVWGdRJmBYd/3JQ7q50h7OWwMW7Rcmz30q5trtVM+7lrqiLZaMcs9J C2GQoa3kSDRBwL8/0Yb6HUJF3HJ7UEh74MhjMOPQ= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 22 Oct 2021 09:32:40 +0200 Message-Id: <20211022073249.35084-6-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> References: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 05/14] 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 828e822c..62ea0916 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 Fri Oct 22 07:32:41 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: 14243 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 C8279BF415 for ; Fri, 22 Oct 2021 07:33:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1747768F73; Fri, 22 Oct 2021 09:33:05 +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="eB3Ou34h"; 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 5666F68F5A for ; Fri, 22 Oct 2021 09:32:55 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:22cc:3af6:5ccb:8367]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 093D651D; Fri, 22 Oct 2021 09:32:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634887975; bh=Hy+TDqG/3B5iRlX4WoQ7KJSk+yCGiD9F16WtlbDpCyw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eB3Ou34hI2KQwlseaAY6/orRqiyMCGbmWxSK/bUQBszOOZvaPW4/1S93fl6rFUz5G VpXnOS4KVWEz0UcrIzZpB+a5O6ahtxeiIGFYg/o3GsluDvJ2IoDcIPTNT/vx8sLteI wvMccH4GJh9OH6gHzQVyfkIGjgYnFL5Q4Cep3ej4= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 22 Oct 2021 09:32:41 +0200 Message-Id: <20211022073249.35084-7-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> References: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 06/14] 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" We are using arbitrary constants for the exposure limit in a number of lines. Instead of using static constants for those, use the limits of the sensor passed in IPASessionConfiguration and cache those. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/algorithms/agc.cpp | 35 +++++++++++++++++++-------------- src/ipa/ipu3/algorithms/agc.h | 3 ++- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index 62ea0916..58872410 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,15 @@ int Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo) lineDuration_ = configInfo.sensorInfo.lineLength * 1.0s / configInfo.sensorInfo.pixelRate; - maxExposureTime_ = context.configuration.agc.maxShutterSpeed; + + /* \todo replace the exposure in lines storage with time based ones. */ + minExposureLines_ = context.configuration.agc.minShutterSpeed / lineDuration_; + maxExposureLines_ = context.configuration.agc.maxShutterSpeed / lineDuration_; /* 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_; return 0; } @@ -151,23 +149,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 { 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 Fri Oct 22 07:32:42 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: 14242 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 4B3B0C324E for ; Fri, 22 Oct 2021 07:33:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1924F68F6E; Fri, 22 Oct 2021 09:33:04 +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="U8CwYvZw"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 824FE68F57 for ; Fri, 22 Oct 2021 09:32:55 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:22cc:3af6:5ccb:8367]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3C5BB89A; Fri, 22 Oct 2021 09:32:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634887975; bh=6jyQp2VcDpoE14IpVTi4Vd171ozQMo+DRVnwXyo9WIA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=U8CwYvZw4LrUuL+bdYRFGCTh5QzpcWvJZSFDgmC36DWnMyJY3fNIZRqHN15b7V4QI BPVryRw08Qm+OZ9WAxSMn+GlfZKZdFgvM82bFtluujrOT+3WVKaTrDW2aZsz6lCoH0 RwUPRQuLaVBr+KIC0BJacQ+yESCkJrSuu/fqJ/sY= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 22 Oct 2021 09:32:42 +0200 Message-Id: <20211022073249.35084-8-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> References: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 07/14] 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 are 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 58872410..984aed53 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; @@ -166,9 +162,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 { - 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 Fri Oct 22 07:32:43 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: 14244 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 74416BF415 for ; Fri, 22 Oct 2021 07:33:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0D5AA68F5C; Fri, 22 Oct 2021 09:33:06 +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="TofM8+Gp"; 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 BF4F668F5F for ; Fri, 22 Oct 2021 09:32:55 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:22cc:3af6:5ccb:8367]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6F24F51D; Fri, 22 Oct 2021 09:32:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634887975; bh=OhFZNy72TZun+WkypWA4XRCIcYlrh0lqNLNyg/J5reI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TofM8+GpL44t/Tx6HEoBD9Tuvjbf9Ada561a91Zw80vxdQ9vlrrv+KXYK3lGe/mAx DDFxOGJu+0GApFEaZtQvdTxaJ2admSz8KwHUHKiiTHQQycqHz8vX3ULRRf/li3CN9G vZBsmJNl/34m4oNhdJPi3EkEaEvzTcyvKeeoBHbs= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 22 Oct 2021 09:32:43 +0200 Message-Id: <20211022073249.35084-9-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> References: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 08/14] ipa: ipu3: agc: Use filtered exposure values 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 are filtering the exposure value to limit the gain to apply, but we are not using the result. Fix it. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/algorithms/agc.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index 984aed53..f5bb3328 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -158,17 +158,17 @@ void Agc::lockExposureGain(uint32_t &exposure, double &gain) utils::Duration newExposure = 0.0s; if (currentShutter < maxShutterSpeed) { - exposure = std::clamp(exposure * currentExposure_ / currentExposureNoDg_, + exposure = std::clamp(exposure * filteredExposure_ / currentExposureNoDg_, minExposureLines_, maxExposureLines_); - newExposure = currentExposure_ / exposure; - gain = std::clamp(gain * currentExposure_ / newExposure, + newExposure = filteredExposure_ / exposure; + gain = std::clamp(gain * filteredExposure_ / newExposure, kMinGain, kMaxGain); } else { - gain = std::clamp(gain * currentExposure_ / currentExposureNoDg_, + gain = std::clamp(gain * filteredExposure_ / currentExposureNoDg_, kMinGain, kMaxGain); - newExposure = currentExposure_ / gain; - exposure = std::clamp(exposure * currentExposure_ / newExposure, + newExposure = filteredExposure_ / gain; + exposure = std::clamp(exposure * filteredExposure_ / newExposure, minExposureLines_, maxExposureLines_); } From patchwork Fri Oct 22 07:32:44 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: 14245 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 6FF37BF415 for ; Fri, 22 Oct 2021 07:33:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 31A5C68F78; Fri, 22 Oct 2021 09:33:07 +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="RjVZq14w"; 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 00A6B68F61 for ; Fri, 22 Oct 2021 09:32:55 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:22cc:3af6:5ccb:8367]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A29C289A; Fri, 22 Oct 2021 09:32:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634887975; bh=XX4YejTj/2VsEWRl3/FpFC7fzwcgGBNu0KEzB+XHSX8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RjVZq14wOGEezN5FyyRfN6FgQhWH2JQ1JSK/oQbchIiRIWIYqZBwDnHiVBojzq3XO gD36xiONe5TlRvoBhThsorrv858hfszMOYYHG0U6vK4oEbPLwB+0KPd2Ka64HnOAXW fCnw8wOuFS38acMSV12BNlFD/e34myKgeKfk7mGs= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 22 Oct 2021 09:32:44 +0200 Message-Id: <20211022073249.35084-10-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> References: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 09/14] 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. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- 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 f5bb3328..6f5b6a45 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -147,7 +147,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_ @@ -156,23 +158,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 * filteredExposure_ / currentExposureNoDg_, - minExposureLines_, - maxExposureLines_); - newExposure = filteredExposure_ / exposure; - gain = std::clamp(gain * filteredExposure_ / newExposure, - kMinGain, kMaxGain); - } else { - gain = std::clamp(gain * filteredExposure_ / currentExposureNoDg_, - kMinGain, kMaxGain); - newExposure = filteredExposure_ / gain; - exposure = std::clamp(exposure * filteredExposure_ / 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 Fri Oct 22 07:32:45 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: 14246 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 22694BF415 for ; Fri, 22 Oct 2021 07:33:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9A4C268F81; Fri, 22 Oct 2021 09:33:07 +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="gQNbafr6"; 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 4237468F63 for ; Fri, 22 Oct 2021 09:32:56 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:22cc:3af6:5ccb:8367]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D5C341908; Fri, 22 Oct 2021 09:32:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634887975; bh=95b+8gHG7d1Chs0ugj5CAFjD02nbkB4j+53yWcB6gEg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gQNbafr6LHVDCDEehJ9lvMclRD4MWlTP4iDaTnyh20lQHD/uP7PE2PUeFlG5sjUkT YTTcF9ZXvkFranKBaxofJTh61cYaCqSf25vwIfkQzYww0Fvxq8ws/WV1PeEbR4Ouyx GHfQ8Ncx8dY4xOKmzzNn5U8Leh8wOYJA4+Ki1r4A= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 22 Oct 2021 09:32:45 +0200 Message-Id: <20211022073249.35084-11-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> References: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 10/14] 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 6f5b6a45..e7c59f3d 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -125,7 +125,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 ? @@ -137,16 +137,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_; @@ -174,7 +175,7 @@ void Agc::lockExposureGain(uint32_t &exposure, double &gain) << stepGain; exposure = shutterTime / lineDuration_; - gain = stepGain; + analogueGain = stepGain; } lastFrame_ = frameCount_; } @@ -182,9 +183,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 Fri Oct 22 07:32:46 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: 14247 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 BBBDEBF415 for ; Fri, 22 Oct 2021 07:33:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 53CF468F68; Fri, 22 Oct 2021 09:33:08 +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="XAcpcDy3"; 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 777D968F5C for ; Fri, 22 Oct 2021 09:32:56 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:22cc:3af6:5ccb:8367]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 158FB51D; Fri, 22 Oct 2021 09:32:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634887976; bh=svqh+A4Ef6cG7H2+0geRHj5YGbf2ySWXbeprnI7qqEA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XAcpcDy3XPFAn+p2iaBvsjTdyQQ3uGk9CmOEEiQdonYb0pj8piXSa0+WcwVFIjkq/ twVPXKRWLJEg98QyQnH5gCHkZRVQxjmlu5Se4F8OVwX19BEl1xF07jWBPrvA/Njjgc DYRo8AOxd6IzZaQO99lNNQosufP7KV2/p7YBKPEQ= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 22 Oct 2021 09:32:46 +0200 Message-Id: <20211022073249.35084-12-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> References: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 11/14] 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 | 19 +++++++++++++++++-- src/ipa/ipu3/algorithms/agc.h | 1 + 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index e7c59f3d..43ef89df 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) { } @@ -62,6 +63,10 @@ int Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo) context.configuration.agc.minAnalogueGain; context.frameContext.agc.exposure = minExposureLines_; + prevExposureValue_ = context.frameContext.agc.gain + * context.frameContext.agc.exposure + * lineDuration_; + return 0; } @@ -147,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_; @@ -176,6 +181,16 @@ void Agc::lockExposureGain(uint32_t &exposure, double &analogueGain) exposure = shutterTime / lineDuration_; analogueGain = stepGain; + + /* + * Update the exposure value for the next process call. + * + * \todo Obtain the values of the exposure time and analog gain + * that were actually used by the sensor, either from embedded + * data when available, or from the delayed controls + * infrastructure in case a slow down caused a mismatch. + */ + 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 Fri Oct 22 07:32:47 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: 14248 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 5CFFFBF415 for ; Fri, 22 Oct 2021 07:33:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0989668F67; Fri, 22 Oct 2021 09:33:09 +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="XUpIQ16r"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9A32A68F5D for ; Fri, 22 Oct 2021 09:32:56 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:22cc:3af6:5ccb:8367]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4940789A; Fri, 22 Oct 2021 09:32:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634887976; bh=6UbDx1V9SPNEbV3UPzZHxU/3XI46hEN93pGA/Pa4uSE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XUpIQ16rXz+tN7VRDLmonNJzmKFH64th8TjzsDpmUAqoji64E5KhacVI7V9Kk+EMZ oNICy1Aku/XWXDT1SFI+dN6pBbuuEgBnen4PXIKNKdw7RESFhUwKdeojngGRb0pTCW 2D2z82PAu9HJhdOqipcp/daPhpMZe0FFCCSomFLs= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 22 Oct 2021 09:32:47 +0200 Message-Id: <20211022073249.35084-13-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> References: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 12/14] ipa: ipu3: agc: Refactor 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" Simplify the reading by removing one level of indentation to return early when the change is small between two calls. Reword the LOG() message when we are correctly exposed, and move the lastFrame_ variable to update it even if the change is small. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/algorithms/agc.cpp | 93 +++++++++++++++++---------------- 1 file changed, 48 insertions(+), 45 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index 43ef89df..feee7939 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -138,61 +138,64 @@ void Agc::lockExposureGain(uint32_t &exposure, double &analogueGain) if ((frameCount_ < kInitialFrameMinAECount) || (frameCount_ - lastFrame_ < kFrameSkipCount)) return; + lastFrame_ = frameCount_; + /* 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_; + LOG(IPU3Agc, Debug) << "We are well exposed (iqMean = " + << iqMean_ << ")"; + return; + } - /* 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; + double evGain = kEvGainTarget * knumHistogramBins / iqMean_; - currentExposure_ = prevExposureValue_ * evGain; - utils::Duration minShutterSpeed = minExposureLines_ * lineDuration_; - utils::Duration maxShutterSpeed = maxExposureLines_ * lineDuration_; + /* 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; - utils::Duration maxTotalExposure = maxShutterSpeed * kMaxGain; - currentExposure_ = std::min(currentExposure_, maxTotalExposure); - LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_ - << ", maximum is " << maxTotalExposure; + currentExposure_ = prevExposureValue_ * evGain; + utils::Duration minShutterSpeed = minExposureLines_ * lineDuration_; + utils::Duration maxShutterSpeed = maxExposureLines_ * lineDuration_; - /* \todo: estimate if we need to desaturate */ - filterExposure(); + utils::Duration maxTotalExposure = maxShutterSpeed * kMaxGain; + currentExposure_ = std::min(currentExposure_, maxTotalExposure); + LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_ + << ", maximum is " << maxTotalExposure; - utils::Duration exposureValue = filteredExposure_; - utils::Duration shutterTime = minShutterSpeed; + /* \todo: estimate if we need to desaturate */ + filterExposure(); - /* - * 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; + utils::Duration exposureValue = filteredExposure_; + utils::Duration shutterTime = minShutterSpeed; - exposure = shutterTime / lineDuration_; - analogueGain = stepGain; + /* + * 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. - * - * \todo Obtain the values of the exposure time and analog gain - * that were actually used by the sensor, either from embedded - * data when available, or from the delayed controls - * infrastructure in case a slow down caused a mismatch. - */ - prevExposureValue_ = shutterTime * analogueGain; - } - lastFrame_ = frameCount_; + /* + * Update the exposure value for the next process call. + * + * \todo Obtain the values of the exposure time and analog gain + * that were actually used by the sensor, either from embedded + * data when available, or from the delayed controls + * infrastructure in case a slow down caused a mismatch. + */ + prevExposureValue_ = shutterTime * analogueGain; } void Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) From patchwork Fri Oct 22 07:32:48 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: 14249 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 ED271BF415 for ; Fri, 22 Oct 2021 07:33:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A8F2F68F70; Fri, 22 Oct 2021 09:33:09 +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="jVFVPBMn"; 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 CA7BB68F66 for ; Fri, 22 Oct 2021 09:32:56 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:22cc:3af6:5ccb:8367]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7D6AF1908; Fri, 22 Oct 2021 09:32:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634887976; bh=sQBXdASOfH7zqUQGSMUUvUiC4f/ZV5bAj5rT4ZO/pYw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jVFVPBMncABBdpwlHeM9N29HJaEer1hzExGG8WGQlGRIFbF+gJLeY8OCO0XDTvc/m 2FhnyTSp33ql7Z56LB73cDLBQvW6thAuNi0LFW1ePLEuOaNDL3pzdnjuBYw+WiJjsx aedXCdm5vbPWNOKnk3HeGVwcvAOF+ScDlyPJ1x1k= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 22 Oct 2021 09:32:48 +0200 Message-Id: <20211022073249.35084-14-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> References: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 13/14] 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 Reviewed-by: Kieran Bingham --- 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 feee7939..74e94544 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_; } @@ -151,8 +139,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 Fri Oct 22 07:32:49 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: 14250 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 96CDFBF415 for ; Fri, 22 Oct 2021 07:33:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 40DC668F65; Fri, 22 Oct 2021 09:33:10 +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="qHWUY568"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0543A68F69 for ; Fri, 22 Oct 2021 09:32:57 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:22cc:3af6:5ccb:8367]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B0C5851D; Fri, 22 Oct 2021 09:32:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634887976; bh=AkwM/bbwVrcAmX7XtfmikA5MEkZF6SJiOIk/rB4RiVQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qHWUY568POA1/9rD8KrqTrnF/grDA1iVaLP/34XO6ydEoNvek25thXUTE4v5DdM1R xvhFW1SYyMeMcGmJYRN4yHeLotyeEIi+EAs3DWjI79mmrpnVYMiB8LeXqYTf4rAakh KS7a3GXFJWc86qWBXxfEoySo5swdcyhDp1uhFIEI= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 22 Oct 2021 09:32:49 +0200 Message-Id: <20211022073249.35084-15-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> References: <20211022073249.35084-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 14/14] 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 Reviewed-by: Kieran Bingham --- src/ipa/ipu3/algorithms/agc.cpp | 19 ++++++++++--------- src/ipa/ipu3/algorithms/agc.h | 3 +++ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index 74e94544..6c151232 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 = 8.0; /* Histogram constants */ static constexpr uint32_t knumHistogramBins = 256; @@ -57,9 +56,11 @@ int Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo) 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 = - context.configuration.agc.minAnalogueGain; + context.frameContext.agc.gain = minAnalogueGain_; context.frameContext.agc.exposure = minExposureLines_; prevExposureValue_ = context.frameContext.agc.gain @@ -148,7 +149,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; @@ -163,10 +164,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_;