From patchwork Mon Oct 19 18:45:07 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: 28507 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 5BBF4C324C for ; Mon, 19 Oct 2026 18:45:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0731D68ED0; Mon, 19 Oct 2026 20:45:33 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="cQJRS6CI"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E23E868E44 for ; Mon, 19 Oct 2026 20:45:30 +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 ABDCE593 for ; Mon, 19 Oct 2026 20:43:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1792435404; bh=lXwdsCQRtZcVJALBmtPd+QiexGrB5g5RiKeB6MEJkqw=; h=From:To:Subject:Date:From; b=cQJRS6CItrlavUMq3YT88d6oa4fuGwn07tAAUJk+vw4B6gOtrDBWiRSxqcCI1FknL K0mZtm9HgMq9kL8yQsloiln+RuRAd7LNj2Gta3tveXCR5EUaEn4DXbm6w6VcAaDl7d w0QQCVitOomUwJ8oeHlx3p9aqW1EkpoM332KtOFE= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v3 00/19] ipa: libipa: agc: Take exposure margin into account Date: Mon, 19 Oct 2026 20:45:07 +0200 Message-ID: <20261019184526.252977-1-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.56.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 maximum available exposure depends on the frame duration, but this is not considered by the current agc implementation, it fixes the maximum exposure time based on whatever configuration was used to configure the algorithm. This means that in certain situations the full exposure range might not be used, even in dark scenes. This a third attempt at adapting https://patchwork.libcamera.org/project/libcamera/list/?series=5590 on the current master branch. But now that the agc handling is largely unified, fewer changes are needed to make this work on every platform. So effectively only patch 7 is taken directly, but only the exposure margin introduction part of it. This was mainly tested on rkisp1+imx219, softisp+ov2740, rppx1+imx708. Unfortunately, back to RFC this time, mainly due to https://gitlab.freedesktop.org/camera/libcamera/-/work_items/362 It turns out to be a bit problematic. So this version adds significant changes: * last exposure stage constitutes a hard-limit for both exposure time and gain, this matches the behaviour of the raspberry pi ipa (see AgcChannel::computeTargetExposure() ) ( https://gitlab.freedesktop.org/camera/libcamera/-/work_items/362 ) * empty stage list is no longer supported, instead two new exposure modes are introduced: minimize and maximize, which implement the very simple behaviour of either minimizing or maximizing the exposure time, respectively; these modes are always available, even without any specific tuning, and this effectively preserves the current behaviour * the default max frame duration is now determined based on the largest exposure time among all stages (if any), otherwise it is capped to the arbitrary limit of 100ms ~ 10fps changes in v2: * report `FrameDurationLimits` in metadata * add exposure margin to more sensor helpers v2: https://patchwork.libcamera.org/cover/28367/ v1: https://patchwork.libcamera.org/cover/28111/ Barnabás Pőcze (18): ipa: libipa: exposure_mode_helper: Remove defaulted destructor ipa: libipa: exposure_mode_helper: Keep stage params together ipa: libipa: exposure_mode_helper: Remove limit getters ipa: libipa: exposure_mode_helper: Move `stageGain` variable ipa: libipa: exposure_mode_helper: Handle no stages ipa: libipa: exposure_mode_helper: Consider last stage as hard-limit ipa: libipa: exposure_mode_helper: Add separate maximize/minimize modes libcamera: controls: Add two new exposure modes ipa: libipa: agc: Keep frame duration limits ordered ipa: libipa: agc: Retrieve `FrameDurationLimits` earlier ipa: libipa: agc: Report `FrameDurationLimits` ipa: libipa: agc: Calculate vblank and frame duration sooner ipa: libipa: agc: Take parameters from active state for calculation libcamera: pipeline: Set vblank on more platforms ipa: libipa: agc: Rework frame duration limit calculation ipa: libipa: agc: Move control info map setup ipa: libipa: exposure_mode_helper: Add getter for max exp time ipa: libipa: agc: Take exposure margin into account Jacopo Mondi (1): ipa: camera_sensor_helper: Introduce exposure margin src/ipa/ipu3/algorithms/agc.cpp | 2 +- src/ipa/ipu3/ipu3.cpp | 3 +- src/ipa/libipa/agc.cpp | 311 +++++++++++-------- src/ipa/libipa/agc.h | 18 +- src/ipa/libipa/agc_mean_luminance.cpp | 37 ++- src/ipa/libipa/camera_sensor_helper.cpp | 68 ++++ src/ipa/libipa/camera_sensor_helper.h | 2 + src/ipa/libipa/exposure_mode_helper.cpp | 231 +++++++++----- src/ipa/libipa/exposure_mode_helper.h | 50 ++- src/ipa/mali-c55/algorithms/agc.cpp | 2 +- src/ipa/mali-c55/mali-c55.cpp | 3 +- src/ipa/rkisp1/algorithms/agc.cpp | 2 +- src/ipa/rkisp1/rkisp1.cpp | 4 +- src/ipa/softisp/algorithms/agc.cpp | 2 +- src/ipa/softisp/softisp.cpp | 3 +- src/libcamera/control_ids_core.yaml | 6 + src/libcamera/pipeline/ipu3/ipu3.cpp | 1 + src/libcamera/pipeline/mali-c55/mali-c55.cpp | 1 + src/libcamera/pipeline/simple/simple.cpp | 1 + 19 files changed, 500 insertions(+), 247 deletions(-) --- 2.56.0