From patchwork Thu Feb 24 15:11:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 15385 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 259AEBE08A for ; Thu, 24 Feb 2022 15:11:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6E2DB6116B; Thu, 24 Feb 2022 16:11:21 +0100 (CET) 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="Yxa6vKwC"; 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 098BE610F9 for ; Thu, 24 Feb 2022 16:11:19 +0100 (CET) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce74:6df2:4b76:b230]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 95813484; Thu, 24 Feb 2022 16:11:18 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1645715478; bh=z1Qs1WSEcAbn5T1b4eUCbDKEh5hHF8+OExTPMAF16CA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Yxa6vKwCmB87VIWurGxVhrfmduTOAMxT5NjjSvQzxRAe4Jdn1vrXz5OyvNw9acpFT 3vn98J6PMTtjqxL6wz/d6/XitlN4gf3p2nW8PTj+bzecQARLLj7qxrxLS3lQDDIZs8 2i3iX/S2Iu/hdpw0W2NOqWEGa/5PzRRrSOGZGiyk= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Thu, 24 Feb 2022 16:11:10 +0100 Message-Id: <20220224151113.109858-2-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220224151113.109858-1-jeanmichel.hautbois@ideasonboard.com> References: <20220224151113.109858-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 1/4] ipa: ipu3: Return filtered 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 the current exposure value is calculated, it is cached and used by filterExposure(). Use private filteredExposure_ and pass currentExposure as a parameter. In order to limit the use of filteredExposure_, return the value from filterExposure(). While at it, remove a stale comment. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/algorithms/agc.cpp | 74 ++++++++++++++++++--------------- src/ipa/ipu3/algorithms/agc.h | 3 +- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index 8d6f18f6..a929085c 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -72,7 +72,7 @@ static constexpr double kRelativeLuminanceTarget = 0.16; Agc::Agc() : frameCount_(0), lineDuration_(0s), minShutterSpeed_(0s), - maxShutterSpeed_(0s), filteredExposure_(0s), currentExposure_(0s) + maxShutterSpeed_(0s), filteredExposure_(0s) { } @@ -143,33 +143,37 @@ double Agc::measureBrightness(const ipu3_uapi_stats_3a *stats, /** * \brief Apply a filter on the exposure value to limit the speed of changes + * \param[in] exposureValue The target exposure from the AGC algorithm + * + * The speed of the filter is adaptive, and will produce the target quicker + * during startup, or when the target exposure is within 20% of the most recent + * filter output. + * + * \return The filtered exposure */ -void Agc::filterExposure() +utils::Duration Agc::filterExposure(utils::Duration exposureValue) { double speed = 0.2; - /* Adapt instantly if we are in startup phase */ + /* Adapt instantly if we are in startup phase. */ if (frameCount_ < kNumStartupFrames) speed = 1.0; - if (filteredExposure_ == 0s) { - /* DG stands for digital gain.*/ - filteredExposure_ = currentExposure_; - } else { - /* - * If we are close to the desired result, go faster to avoid making - * multiple micro-adjustments. - * \todo Make this customisable? - */ - if (filteredExposure_ < 1.2 * currentExposure_ && - filteredExposure_ > 0.8 * currentExposure_) - speed = sqrt(speed); - - filteredExposure_ = speed * currentExposure_ + - filteredExposure_ * (1.0 - speed); - } + /* + * If we are close to the desired result, go faster to avoid making + * multiple micro-adjustments. + * \todo Make this customisable? + */ + if (filteredExposure_ < 1.2 * exposureValue && + filteredExposure_ > 0.8 * exposureValue) + speed = sqrt(speed); + + filteredExposure_ = speed * exposureValue + + filteredExposure_ * (1.0 - speed); - LOG(IPU3Agc, Debug) << "After filtering, total_exposure " << filteredExposure_; + LOG(IPU3Agc, Debug) << "After filtering, exposure " << filteredExposure_; + + return filteredExposure_; } /** @@ -213,27 +217,29 @@ void Agc::computeExposure(IPAFrameContext &frameContext, double yGain, * Calculate the current exposure value for the scene as the latest * exposure value applied multiplied by the new estimated gain. */ - currentExposure_ = effectiveExposureValue * evGain; + utils::Duration exposureValue = effectiveExposureValue * evGain; /* Clamp the exposure value to the min and max authorized */ utils::Duration maxTotalExposure = maxShutterSpeed_ * maxAnalogueGain_; - currentExposure_ = std::min(currentExposure_, maxTotalExposure); - LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_ + exposureValue = std::min(exposureValue, maxTotalExposure); + LOG(IPU3Agc, Debug) << "Target total exposure " << exposureValue << ", maximum is " << maxTotalExposure; - /* \todo: estimate if we need to desaturate */ - filterExposure(); - - /* Divide the exposure value as new exposure and gain values */ - utils::Duration exposureValue = filteredExposure_; - utils::Duration shutterTime; + /* + * Filter the exposure. + * \todo: estimate if we need to desaturate + */ + exposureValue = filterExposure(exposureValue); /* - * Push the shutter time up to the maximum first, and only then - * increase the gain. - */ - shutterTime = std::clamp(exposureValue / minAnalogueGain_, - minShutterSpeed_, maxShutterSpeed_); + * Divide the exposure value as new exposure and gain values. + * + * Push the shutter time up to the maximum first, and only then + * increase the gain. + */ + utils::Duration shutterTime = + std::clamp(exposureValue / minAnalogueGain_, + minShutterSpeed_, maxShutterSpeed_); double stepGain = std::clamp(exposureValue / shutterTime, minAnalogueGain_, maxAnalogueGain_); LOG(IPU3Agc, Debug) << "Divided up shutter and gain are " diff --git a/src/ipa/ipu3/algorithms/agc.h b/src/ipa/ipu3/algorithms/agc.h index 96ec7005..84bfe045 100644 --- a/src/ipa/ipu3/algorithms/agc.h +++ b/src/ipa/ipu3/algorithms/agc.h @@ -33,7 +33,7 @@ public: private: double measureBrightness(const ipu3_uapi_stats_3a *stats, const ipu3_uapi_grid_config &grid) const; - void filterExposure(); + utils::Duration filterExposure(utils::Duration currentExposure); void computeExposure(IPAFrameContext &frameContext, double yGain, double iqMeanGain); double estimateLuminance(IPAFrameContext &frameContext, @@ -51,7 +51,6 @@ private: double maxAnalogueGain_; utils::Duration filteredExposure_; - utils::Duration currentExposure_; uint32_t stride_; }; From patchwork Thu Feb 24 15:11:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 15386 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 21AB9C3261 for ; Thu, 24 Feb 2022 15:11:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 372196115A; Thu, 24 Feb 2022 16:11:22 +0100 (CET) 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="JGHgLBVl"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 31C5761145 for ; Thu, 24 Feb 2022 16:11:19 +0100 (CET) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce74:6df2:4b76:b230]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id CBAD8E70; Thu, 24 Feb 2022 16:11:18 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1645715478; bh=ZDm9VKGFF43duA1wbbFF797P0YbVhnM4JL6qJmSB5V4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JGHgLBVlKc56jczH70m/LK/PVmqbKCwDbtTVzZ9LgcJNRv292RvkDMvVhTjRVo2uT bq9Han9051zvG6B9vLR+szdi8soj2tkO5D/5Da9WRCiD2VFufYQvvBP0t8RMa548XL s+9Iwp7FuaorHqnF5ADzrSWx5PgD/JXYaCZ3sNxo= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Thu, 24 Feb 2022 16:11:11 +0100 Message-Id: <20220224151113.109858-3-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220224151113.109858-1-jeanmichel.hautbois@ideasonboard.com> References: <20220224151113.109858-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 2/4] ipa: ipu3: Shorten exposure and gain lines X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" When the effective sensor values are stored during the EventStatReady event, the lines are long. Fix it. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/ipu3.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 3d307708..c0c29416 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -547,8 +547,11 @@ void IPAIPU3::processEvent(const IPU3Event &event) const ipu3_uapi_stats_3a *stats = reinterpret_cast(mem.data()); - context_.frameContext.sensor.exposure = event.sensorControls.get(V4L2_CID_EXPOSURE).get(); - context_.frameContext.sensor.gain = camHelper_->gain(event.sensorControls.get(V4L2_CID_ANALOGUE_GAIN).get()); + int32_t exposure = event.sensorControls.get(V4L2_CID_EXPOSURE).get(); + int32_t gain = event.sensorControls.get(V4L2_CID_ANALOGUE_GAIN).get(); + + context_.frameContext.sensor.exposure = exposure; + context_.frameContext.sensor.gain = camHelper_->gain(gain); parseStatistics(event.frame, event.frameTimestamp, stats); break; From patchwork Thu Feb 24 15:11:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 15387 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 A85DABE08A for ; Thu, 24 Feb 2022 15:11:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3872661171; Thu, 24 Feb 2022 16:11:23 +0100 (CET) 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="aJlmCMh1"; 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 51D18601F9 for ; Thu, 24 Feb 2022 16:11:19 +0100 (CET) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce74:6df2:4b76:b230]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0C028DD; Thu, 24 Feb 2022 16:11:19 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1645715479; bh=n5QPgWclO0qm8W+7GNMpPbp87qN4EuquLsw0CtQJ0Q0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aJlmCMh1EEA/o4huYJP8kjxObzqhT/Zqp31dbUj8PmhgRcFMyn/jwEIZWDdDrLfyd Cfx/zNl8KDycvUHhokdpVZqQVPnfjaAJoHvZuC2bnm8zuUWpF/pGGux8593Sii0eNk QS8dTUpwH+HGY1WFbEoVgNX9NIhYiq2qOnZ5b0mE= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Thu, 24 Feb 2022 16:11:12 +0100 Message-Id: <20220224151113.109858-4-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220224151113.109858-1-jeanmichel.hautbois@ideasonboard.com> References: <20220224151113.109858-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 3/4] ipa: ipu3: agc: Introduce lineDuration in IPASessionConfiguration 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 having a local cached value for line duration, store it in the IPASessionConfiguration::sensor structure. While at it, configure the default analogue gain and shutter speed to controlled fixed values. The latter is set to be 10ms as it will in most cases be close to the one needed, making the AGC faster to converge. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham Reviewed-by: Umang Jain --- v4: clean only frameContext at configure call. [Kieran, I took your R-b if you are ok ?] --- src/ipa/ipu3/algorithms/agc.cpp | 26 ++++++++++++++------------ src/ipa/ipu3/algorithms/agc.h | 3 +-- src/ipa/ipu3/ipa_context.cpp | 8 ++++++++ src/ipa/ipu3/ipa_context.h | 4 ++++ src/ipa/ipu3/ipu3.cpp | 28 +++++++++++++++------------- 5 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index a929085c..1eb1bcef 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -71,7 +71,7 @@ static constexpr uint32_t kNumStartupFrames = 10; static constexpr double kRelativeLuminanceTarget = 0.16; Agc::Agc() - : frameCount_(0), lineDuration_(0s), minShutterSpeed_(0s), + : frameCount_(0), minShutterSpeed_(0s), maxShutterSpeed_(0s), filteredExposure_(0s) { } @@ -83,13 +83,13 @@ Agc::Agc() * * \return 0 */ -int Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo) +int Agc::configure(IPAContext &context, + [[maybe_unused]] const IPAConfigInfo &configInfo) { - stride_ = context.configuration.grid.stride; + IPASessionConfiguration &configuration = context.configuration; + IPAFrameContext &frameContext = context.frameContext; - /* \todo use the IPAContext to provide the limits */ - lineDuration_ = configInfo.sensorInfo.lineLength * 1.0s - / configInfo.sensorInfo.pixelRate; + stride_ = configuration.grid.stride; minShutterSpeed_ = context.configuration.agc.minShutterSpeed; maxShutterSpeed_ = std::min(context.configuration.agc.maxShutterSpeed, @@ -99,8 +99,8 @@ int Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo) maxAnalogueGain_ = std::min(context.configuration.agc.maxAnalogueGain, kMaxAnalogueGain); /* Configure the default exposure and gain. */ - context.frameContext.agc.gain = minAnalogueGain_; - context.frameContext.agc.exposure = minShutterSpeed_ / lineDuration_; + frameContext.agc.gain = std::max(minAnalogueGain_, kMinAnalogueGain); + frameContext.agc.exposure = 10ms / configuration.sensor.lineDuration; return 0; } @@ -182,9 +182,11 @@ utils::Duration Agc::filterExposure(utils::Duration exposureValue) * \param[in] yGain The gain calculated based on the relative luminance target * \param[in] iqMeanGain The gain calculated based on the relative luminance target */ -void Agc::computeExposure(IPAFrameContext &frameContext, double yGain, +void Agc::computeExposure(IPAContext &context, double yGain, double iqMeanGain) { + const IPASessionConfiguration &configuration = context.configuration; + IPAFrameContext &frameContext = context.frameContext; /* Get the effective exposure and gain applied on the sensor. */ uint32_t exposure = frameContext.sensor.exposure; double analogueGain = frameContext.sensor.gain; @@ -200,7 +202,7 @@ void Agc::computeExposure(IPAFrameContext &frameContext, double yGain, /* extracted from Rpi::Agc::computeTargetExposure */ /* Calculate the shutter time in seconds */ - utils::Duration currentShutter = exposure * lineDuration_; + utils::Duration currentShutter = exposure * configuration.sensor.lineDuration; /* * Update the exposure value for the next computation using the values @@ -247,7 +249,7 @@ void Agc::computeExposure(IPAFrameContext &frameContext, double yGain, << stepGain; /* Update the estimated exposure and gain. */ - frameContext.agc.exposure = shutterTime / lineDuration_; + frameContext.agc.exposure = shutterTime / configuration.sensor.lineDuration; frameContext.agc.gain = stepGain; } @@ -354,7 +356,7 @@ void Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) break; } - computeExposure(context.frameContext, yGain, iqMeanGain); + computeExposure(context, yGain, iqMeanGain); frameCount_++; } diff --git a/src/ipa/ipu3/algorithms/agc.h b/src/ipa/ipu3/algorithms/agc.h index 84bfe045..ad705605 100644 --- a/src/ipa/ipu3/algorithms/agc.h +++ b/src/ipa/ipu3/algorithms/agc.h @@ -34,7 +34,7 @@ private: double measureBrightness(const ipu3_uapi_stats_3a *stats, const ipu3_uapi_grid_config &grid) const; utils::Duration filterExposure(utils::Duration currentExposure); - void computeExposure(IPAFrameContext &frameContext, double yGain, + void computeExposure(IPAContext &context, double yGain, double iqMeanGain); double estimateLuminance(IPAFrameContext &frameContext, const ipu3_uapi_grid_config &grid, @@ -43,7 +43,6 @@ private: uint64_t frameCount_; - utils::Duration lineDuration_; utils::Duration minShutterSpeed_; utils::Duration maxShutterSpeed_; diff --git a/src/ipa/ipu3/ipa_context.cpp b/src/ipa/ipu3/ipa_context.cpp index 86794ac1..9c4ec936 100644 --- a/src/ipa/ipu3/ipa_context.cpp +++ b/src/ipa/ipu3/ipa_context.cpp @@ -86,6 +86,14 @@ namespace libcamera::ipa::ipu3 { * \brief Maximum analogue gain supported with the configured sensor */ +/** + * \var IPASessionConfiguration::sensor + * \brief Sensor-specific configuration of the IPA + * + * \var IPASessionConfiguration::sensor.lineDuration + * \brief Line duration in microseconds + */ + /** * \var IPAFrameContext::agc * \brief Context for the Automatic Gain Control algorithm diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h index c6dc0814..e7c49828 100644 --- a/src/ipa/ipu3/ipa_context.h +++ b/src/ipa/ipu3/ipa_context.h @@ -31,6 +31,10 @@ struct IPASessionConfiguration { double minAnalogueGain; double maxAnalogueGain; } agc; + + struct { + utils::Duration lineDuration; + } sensor; }; struct IPAFrameContext { diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index c0c29416..17324616 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -173,8 +173,6 @@ private: uint32_t minGain_; uint32_t maxGain_; - utils::Duration lineDuration_; - /* Interface to the Camera Helper */ std::unique_ptr camHelper_; @@ -206,8 +204,8 @@ void IPAIPU3::updateSessionConfiguration(const ControlInfoMap &sensorControls) * * \todo take VBLANK into account for maximum shutter speed */ - context_.configuration.agc.minShutterSpeed = minExposure * lineDuration_; - context_.configuration.agc.maxShutterSpeed = maxExposure * lineDuration_; + context_.configuration.agc.minShutterSpeed = minExposure * context_.configuration.sensor.lineDuration; + context_.configuration.agc.maxShutterSpeed = maxExposure * context_.configuration.sensor.lineDuration; context_.configuration.agc.minAnalogueGain = camHelper_->gain(minGain); context_.configuration.agc.maxAnalogueGain = camHelper_->gain(maxGain); } @@ -229,6 +227,7 @@ void IPAIPU3::updateControls(const IPACameraSensorInfo &sensorInfo, ControlInfoMap *ipaControls) { ControlInfoMap::Map controls{}; + double lineDuration = context_.configuration.sensor.lineDuration.get(); /* * Compute exposure time limits by using line length and pixel rate @@ -237,9 +236,9 @@ void IPAIPU3::updateControls(const IPACameraSensorInfo &sensorInfo, * microseconds. */ const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second; - int32_t minExposure = v4l2Exposure.min().get() * lineDuration_.get(); - int32_t maxExposure = v4l2Exposure.max().get() * lineDuration_.get(); - int32_t defExposure = v4l2Exposure.def().get() * lineDuration_.get(); + int32_t minExposure = v4l2Exposure.min().get() * lineDuration; + int32_t maxExposure = v4l2Exposure.max().get() * lineDuration; + int32_t defExposure = v4l2Exposure.def().get() * lineDuration; controls[&controls::ExposureTime] = ControlInfo(minExposure, maxExposure, defExposure); @@ -293,6 +292,10 @@ int IPAIPU3::init(const IPASettings &settings, return -ENODEV; } + /* Clean context */ + context_ = {}; + context_.configuration.sensor.lineDuration = sensorInfo.lineLength * 1.0s / sensorInfo.pixelRate; + /* Construct our Algorithms */ algorithms_.push_back(std::make_unique()); algorithms_.push_back(std::make_unique()); @@ -454,12 +457,10 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo, defVBlank_ = itVBlank->second.def().get(); - /* Clean context at configuration */ - context_ = {}; - calculateBdsGrid(configInfo.bdsOutputSize); - lineDuration_ = sensorInfo_.lineLength * 1.0s / sensorInfo_.pixelRate; + /* Clean frameContext at each reconfiguration. */ + context_.frameContext = {}; /* Update the camera controls using the new sensor settings. */ updateControls(sensorInfo_, ctrls_, ipaControls); @@ -620,6 +621,7 @@ void IPAIPU3::parseStatistics(unsigned int frame, [[maybe_unused]] int64_t frameTimestamp, const ipu3_uapi_stats_3a *stats) { + double lineDuration = context_.configuration.sensor.lineDuration.get(); ControlList ctrls(controls::controls); for (auto const &algo : algorithms_) @@ -628,14 +630,14 @@ void IPAIPU3::parseStatistics(unsigned int frame, setControls(frame); /* \todo Use VBlank value calculated from each frame exposure. */ - int64_t frameDuration = (defVBlank_ + sensorInfo_.outputSize.height) * lineDuration_.get(); + int64_t frameDuration = (defVBlank_ + sensorInfo_.outputSize.height) * lineDuration; ctrls.set(controls::FrameDuration, frameDuration); ctrls.set(controls::AnalogueGain, context_.frameContext.sensor.gain); ctrls.set(controls::ColourTemperature, context_.frameContext.awb.temperatureK); - ctrls.set(controls::ExposureTime, context_.frameContext.sensor.exposure * lineDuration_.get()); + ctrls.set(controls::ExposureTime, context_.frameContext.sensor.exposure * lineDuration); /* * \todo The Metadata provides a path to getting extended data From patchwork Thu Feb 24 15:11:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 15388 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 0275EC3262 for ; Thu, 24 Feb 2022 15:11:25 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8DA9561179; Thu, 24 Feb 2022 16:11:23 +0100 (CET) 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="eVVKGZ4Z"; 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 7B0F361154 for ; Thu, 24 Feb 2022 16:11:19 +0100 (CET) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce74:6df2:4b76:b230]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3B899484; Thu, 24 Feb 2022 16:11:19 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1645715479; bh=pVNrn3LsHd9D01TInDIdRr6NOWngi+kM+wrAXqd7XOY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eVVKGZ4ZDupWfxvYIZnpZ3iSC//0lJeDSoBBK55IX9shVBpTdE1A0+ZCgEVzKmVam Z4gyLRn6eoNs99HrhrtyFJKWoGORTPyzAChF/i/9odd7/MXu2mV77bwaIiO3hatFLp EIxMSZS/AofkgSwcgh4QkSmp+UlVTQywY9p35p7g= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Thu, 24 Feb 2022 16:11:13 +0100 Message-Id: <20220224151113.109858-5-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220224151113.109858-1-jeanmichel.hautbois@ideasonboard.com> References: <20220224151113.109858-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 4/4] ipa: ipu3: awb: Clamp gain 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" The gain values are coded as u3.13 fixed point values, ie they can not be more than 8. Clampt the values in order to avoid any off limits value which could make the IPU3 behave weirdly. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham --- src/ipa/ipu3/algorithms/awb.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp index 1dc27fc9..dc25be81 100644 --- a/src/ipa/ipu3/algorithms/awb.cpp +++ b/src/ipa/ipu3/algorithms/awb.cpp @@ -353,6 +353,14 @@ void Awb::awbGreyWorld() /* Color temperature is not relevant in Grey world but still useful to estimate it :-) */ asyncResults_.temperatureK = estimateCCT(sumRed.R, sumRed.G, sumBlue.B); + + /* + * Gain values are unsigned integer value, range 0 to 8 with 13 bit + * fractional part. + */ + redGain = std::clamp(redGain, 0.0, 65535.0 / 8192); + blueGain = std::clamp(blueGain, 0.0, 65535.0 / 8192); + asyncResults_.redGain = redGain; /* Hardcode the green gain to 1.0. */ asyncResults_.greenGain = 1.0;