From patchwork Fri Nov 14 00:54:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 25048 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 75126C3241 for ; Fri, 14 Nov 2025 00:55:11 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 28B4760AAD; Fri, 14 Nov 2025 01:55:11 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="XOvCWz02"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 47E9C6069A for ; Fri, 14 Nov 2025 01:54:54 +0100 (CET) Received: from charm.hippo-penny.ts.net (cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id BC94420A4; Fri, 14 Nov 2025 01:52:53 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1763081573; bh=58vba508uZ769PzpojQWpViY+uYaqEr0rRQ22PkPNSA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XOvCWz02E5t5BDWWeXGI0tAdc+Q0wJrEVSkj0BNwRotHiSxdN/Wkt7RuiRISRonDd XiNM92ru55tQEhbxDT5SUiELiGu/OKE3kz2FJM7q0gVA+EQmtoqsReA1JouXANts6/ 3PWr/048xedSFnqSq2YNM394/rQ25oX+fpYemmV8= From: Kieran Bingham To: libcamera devel Cc: Kieran Bingham Subject: [PATCH v4 18/21] ipa: mali-c55: agc: Quantise the ISP Digital Gain Date: Fri, 14 Nov 2025 00:54:22 +0000 Message-ID: <20251114005428.90024-19-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251114005428.90024-1-kieran.bingham@ideasonboard.com> References: <20251114005428.90024-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 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 Mali-C55 ISP has a digital gain block which allows setting gain in Q5.8 format, a range of 0.0 to (very nearly) 32.0. Convert usage to the new UQ5_8 FixedPoint Quantised type which will support the conversion, clamping and quantisation so that the metadata and debug prints can now report the effective gain applied instead of the potentially inaccurate float. As the UQ5_8 type already clamps values, remove the explicit clamping. This removes the clamping to a minimum of 1.0 gain, so we rely on calculateNewEv to provide a valid gain. Signed-off-by: Kieran Bingham --- src/ipa/mali-c55/algorithms/agc.cpp | 20 ++++++++++---------- src/ipa/mali-c55/ipa_context.h | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ipa/mali-c55/algorithms/agc.cpp b/src/ipa/mali-c55/algorithms/agc.cpp index f60fddac3f04..3f10b237f581 100644 --- a/src/ipa/mali-c55/algorithms/agc.cpp +++ b/src/ipa/mali-c55/algorithms/agc.cpp @@ -38,8 +38,8 @@ static constexpr unsigned int kNumHistogramBins = 256; * format, a range of 0.0 to (very nearly) 32.0. We clamp from 1.0 to the actual * max value which is 8191 * 2^-8. */ -static constexpr double kMinDigitalGain = 1.0; -static constexpr double kMaxDigitalGain = 31.99609375; +static constexpr float kMinDigitalGain = 1.0; +static constexpr float kMaxDigitalGain = UQ5_8::TraitsType::max; uint32_t AgcStatistics::decodeBinValue(uint16_t binVal) { @@ -236,7 +236,7 @@ void Agc::queueRequest(IPAContext &context, const uint32_t frame, agc.manual.ispGain = *digitalGain; LOG(MaliC55Agc, Debug) - << "Digital gain set to " << agc.manual.ispGain + << "Digital gain set to " << agc.manual.ispGain.value() << " on request sequence " << frame; } } @@ -245,7 +245,7 @@ size_t Agc::fillGainParamBlock(IPAContext &context, IPAFrameContext &frameContex mali_c55_params_block block) { IPAActiveState &activeState = context.activeState; - double gain; + UQ5_8 gain; if (activeState.agc.autoEnabled) gain = activeState.agc.automatic.ispGain; @@ -256,7 +256,7 @@ size_t Agc::fillGainParamBlock(IPAContext &context, IPAFrameContext &frameContex block.header->flags = MALI_C55_PARAM_BLOCK_FL_NONE; block.header->size = sizeof(struct mali_c55_params_digital_gain); - block.digital_gain->gain = floatingToFixedPoint<5, 8, uint16_t, double>(gain); + block.digital_gain->gain = gain.quantized(); frameContext.agc.ispGain = gain; return block.header->size; @@ -376,7 +376,7 @@ void Agc::process(IPAContext &context, */ uint32_t exposure = frameContext.agc.exposure; double analogueGain = frameContext.agc.sensorGain; - double digitalGain = frameContext.agc.ispGain; + double digitalGain = frameContext.agc.ispGain.value(); double totalGain = analogueGain * digitalGain; utils::Duration currentShutter = exposure * configuration.sensor.lineDuration; utils::Duration effectiveExposureValue = currentShutter * totalGain; @@ -388,19 +388,19 @@ void Agc::process(IPAContext &context, activeState.agc.exposureMode, statistics_.yHist, effectiveExposureValue); - dGain = std::clamp(dGain, kMinDigitalGain, kMaxDigitalGain); + UQ5_8 dGainQ = static_cast(dGain); LOG(MaliC55Agc, Debug) << "Divided up shutter, analogue gain and digital gain are " - << shutterTime << ", " << aGain << " and " << dGain; + << shutterTime << ", " << aGain << " and " << dGainQ.value(); activeState.agc.automatic.exposure = shutterTime / configuration.sensor.lineDuration; activeState.agc.automatic.sensorGain = aGain; - activeState.agc.automatic.ispGain = dGain; + activeState.agc.automatic.ispGain = dGainQ; metadata.set(controls::ExposureTime, currentShutter.get()); metadata.set(controls::AnalogueGain, frameContext.agc.sensorGain); - metadata.set(controls::DigitalGain, frameContext.agc.ispGain); + metadata.set(controls::DigitalGain, frameContext.agc.ispGain.value()); metadata.set(controls::ColourTemperature, context.activeState.agc.temperatureK); } diff --git a/src/ipa/mali-c55/ipa_context.h b/src/ipa/mali-c55/ipa_context.h index 86d060a731cb..2db3fdf9e5cf 100644 --- a/src/ipa/mali-c55/ipa_context.h +++ b/src/ipa/mali-c55/ipa_context.h @@ -41,12 +41,12 @@ struct IPAActiveState { struct { uint32_t exposure; double sensorGain; - double ispGain; + UQ5_8 ispGain; } automatic; struct { uint32_t exposure; double sensorGain; - double ispGain; + UQ5_8 ispGain; } manual; bool autoEnabled; uint32_t constraintMode; @@ -64,7 +64,7 @@ struct IPAFrameContext : public FrameContext { struct { uint32_t exposure; double sensorGain; - double ispGain; + UQ5_8 ispGain; } agc; struct {