From patchwork Thu Feb 27 19:58:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22895 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 492CABE080 for ; Thu, 27 Feb 2025 19:58:33 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 07F3A6875A; Thu, 27 Feb 2025 20:58:33 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="vwUG5N9q"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B175D60322 for ; Thu, 27 Feb 2025 20:58:30 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:a3f5:6799:2ce9:5b66]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0711511D8; Thu, 27 Feb 2025 20:57:01 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1740686222; bh=mAiZ4bkUh/Fvif1YkbafGywPZeG8xdmKUVhWSezepGk=; h=From:To:Cc:Subject:Date:From; b=vwUG5N9q9sPBiEDLX/JgP1iUOOIfMcf7wSH9yz67XOJgaDjkJngZWJBAtG0SaP50K ekmTInuOa21YYq3KjnQOvfiIf/qPkT9sWX5FYFJ1JCMZ8PTsSYKem67ULfkLHxvVVu n+EAsmVxUZKeC4deIAuaCsY8qmdBYwrWcq18/Bh4= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH] ipa: libipa: Fix bug in ExposureModeHelper that leads to oscillations in AEGC Date: Thu, 27 Feb 2025 20:58:10 +0100 Message-ID: <20250227195821.3172905-1-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 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 ExposureModeHelper::splitExposures() runs through the configured stages to find the best gain/exposure time pair. It first raises the exposure time until it reaches the limit of the current stage. Then it raises the gain until that also reaches the limit of the current stage. After that it continues with the next stage until a match is found. Due to a slight mistake in the initial code, the second step doesn't work as expected because the exposure time gets divided by the gain of the current stage, effectively leading to a jump of the gain value from the maximum gain of the last stage to the maximum gain of the current stage instead of gradually increasing the gain value. Depending on the tuning file this leads to very visible oscillations and jumps in the brightness. Fix by clamping the exposure time in the second step to the maximum exposure time of the current stage. While at it, add two comments for easier understanding. Fixes: 34c9ab62827b ("ipa: libipa: Add ExposureModeHelper") Signed-off-by: Stefan Klug Reviewed-by: Daniel Scally Reviewed-by: Paul Elder --- src/ipa/libipa/exposure_mode_helper.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ipa/libipa/exposure_mode_helper.cpp b/src/ipa/libipa/exposure_mode_helper.cpp index f235316d3539..0c1e99e31a47 100644 --- a/src/ipa/libipa/exposure_mode_helper.cpp +++ b/src/ipa/libipa/exposure_mode_helper.cpp @@ -182,6 +182,7 @@ ExposureModeHelper::splitExposure(utils::Duration exposure) const * the stage limits are initialised. */ + /* Clamp the gain to lastStageGain and regulate exposureTime. */ if (stageExposureTime * lastStageGain >= exposure) { exposureTime = clampExposureTime(exposure / clampGain(lastStageGain)); gain = clampGain(exposure / exposureTime); @@ -189,8 +190,9 @@ ExposureModeHelper::splitExposure(utils::Duration exposure) const return { exposureTime, gain, exposure / (exposureTime * gain) }; } + /* Clamp the exposureTime to stageExposureTime and regulate gain. */ if (stageExposureTime * stageGain >= exposure) { - exposureTime = clampExposureTime(exposure / clampGain(stageGain)); + exposureTime = clampExposureTime(stageExposureTime); gain = clampGain(exposure / exposureTime); return { exposureTime, gain, exposure / (exposureTime * gain) };