From patchwork Mon Oct 19 18:45:13 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 28513 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 77437C324C for ; Mon, 19 Oct 2026 18:45:53 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BC4E568EEE; Mon, 19 Oct 2026 20:45:41 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="JU18JZ6j"; 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 9BB9168EC1 for ; Mon, 19 Oct 2026 20:45:32 +0200 (CEST) Received: from pb-laptop.local (185.221.141.235.nat.pool.zt.hu [185.221.141.235]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7CB89593 for ; Mon, 19 Oct 2026 20:43:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1792435406; bh=9RSMKK+Z6+1uddptWGCuJE2yemrS5ZhvR1CkMoH6Pgg=; h=From:To:Subject:Date:In-Reply-To:References:From; b=JU18JZ6j5+Kzz58ZQnyYoc/jRZpUcdrq1vvfo5bfD7c6hzldLvDJ5jivoablYMWuF ppUA8g2Q3v2ktp8h3Cii1l0aDHHzIZhnyQw8rz0h8x7mmTLAEHB0g9xA68b92Gm80v eLgrYCJblZG82Xay2UY8jwWEGOPnimzmVmM59W6s= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v3 06/19] ipa: libipa: exposure_mode_helper: Consider last stage as hard-limit Date: Mon, 19 Oct 2026 20:45:13 +0200 Message-ID: <20261019184526.252977-7-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261019184526.252977-1-barnabas.pocze@ideasonboard.com> References: <20261019184526.252977-1-barnabas.pocze@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" Currently `splitExposure()` will raise the exposure and analogue gain above what is specified in the last stage, if the desired exposure could not be reached. This behaviour is different from that of the raspberry pi ipa, and also could be surprising to the user. So make sure that the exposure time and analogue gain is limited by the last stage, in addition to the runtime controlled upper bound. Closes: https://gitlab.freedesktop.org/camera/libcamera/-/work_items/362 Signed-off-by: Barnabás Pőcze --- src/ipa/libipa/exposure_mode_helper.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ipa/libipa/exposure_mode_helper.cpp b/src/ipa/libipa/exposure_mode_helper.cpp index 7a810a3673..cadd1903d8 100644 --- a/src/ipa/libipa/exposure_mode_helper.cpp +++ b/src/ipa/libipa/exposure_mode_helper.cpp @@ -203,8 +203,9 @@ double ExposureModeHelper::clampGain(double gain, double *quantizationGain) cons * value. * * If no combination of exposure time and gain limits is found that meets the - * required exposure, the helper falls-back to simply maximising the exposure - * time first, followed by analogue gain, followed by digital gain. + * required exposure, then the exposure and gain of the last stage will be used, + * unless there are no stages, in which case first the exposure, then the + * analogue gain, then the digital gain will be maximized as necessary. * * During the calculations the gain missed due to quantization is recorded and * returned as quantization gain. The quantization gain is not included in the @@ -295,12 +296,11 @@ ExposureModeHelper::splitExposure(utils::Duration exposure) const } /* - * From here on all we can do is max out the exposure time, followed by - * the analogue gain. If we still haven't achieved the target we send - * the rest of the exposure time to digital gain. + * If no stages could satisfy the desired exposure, then use the last + * stage's exposure time and gain. */ - exposureTime = clampExposureTime(exposure / lastStageGain, &quantGain); - gain = clampGain(exposure / exposureTime, &quantGain2); + exposureTime = clampExposureTime(stages_.back().exposureTime, &quantGain); + gain = clampGain(stages_.back().gain, &quantGain2); quantGain *= quantGain2; return { exposureTime, gain, quantGain,