From patchwork Mon Oct 19 18:45:15 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: 28515 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 3EB70C324C for ; Mon, 19 Oct 2026 18:45:56 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2239868ED9; Mon, 19 Oct 2026 20:45:45 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="FILmEFY0"; 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 18B8968ED1 for ; Mon, 19 Oct 2026 20:45:33 +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 EE482593 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=1792435407; bh=VhSZ1BTG+jnNFy1ZfcxjAhfB9165TOgaHioiMRxEou4=; h=From:To:Subject:Date:In-Reply-To:References:From; b=FILmEFY0OSJfSBzBK1VxRvwtB8yWC03edvYAKKKrB76nErhogzIflf039lw3qPiY+ HFJ6DCpemCScDn8jzVDP5f189712rbKb3s7WaFG6a5sTQn6Tqm1LJQNYecRe7CPtXC vrQWdKpjkptKAKfm3xBA5/vJs9RibZ52hdP5VYig= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v3 08/19] libcamera: controls: Add two new exposure modes Date: Mon, 19 Oct 2026 20:45:15 +0200 Message-ID: <20261019184526.252977-9-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" Add two new `AeExposureMode` enumerators: "Minimize" and "Maximize". The already existing exposure modes depend on specific configuration in tuning files. These two new modes implement very simple exposure splitting behaviour: either minimize / maximize the used exposure time. The "staged" exposure modes limit the maximum exposure / gain to those of the last stage. This means that e.g. the exposure time will not be raised even if the application would allow it by explicitly changing `FrameDurationLimits`. Short of manual AGC it is not really possible to work around that on the application side. And having to modify tuning files is inconvenient. The new "Maximize" mode is a better fit to represent how `AgcMSV` operates, so adjust the reported exposure mode if that algorithm used. And lastly, change `AgcMeanLuminance::parseTuningData()` so that it always creates exposure mode helper instances for the two new modes as they require no configuration. Signed-off-by: Barnabás Pőcze --- src/ipa/libipa/agc.cpp | 2 +- src/ipa/libipa/agc_mean_luminance.cpp | 25 ++++++++++++++++--------- src/libcamera/control_ids_core.yaml | 6 ++++++ 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/ipa/libipa/agc.cpp b/src/ipa/libipa/agc.cpp index 51b05e3c2a..e793de832b 100644 --- a/src/ipa/libipa/agc.cpp +++ b/src/ipa/libipa/agc.cpp @@ -489,7 +489,7 @@ int AgcAlgorithm::configure(agc::Session &session, agc::ActiveState &state, [&](AgcMSV &) { /* No constraint/exposure mode support. */ state.constraintMode = controls::AeConstraintModeEnum::ConstraintNormal; - state.exposureMode = controls::AeExposureModeEnum::ExposureNormal; + state.exposureMode = controls::AeExposureModeEnum::ExposureMaximize; state.automatic.yTarget = 0; /* Not supported. */ diff --git a/src/ipa/libipa/agc_mean_luminance.cpp b/src/ipa/libipa/agc_mean_luminance.cpp index f0e47cc06d..3ecdebd3cf 100644 --- a/src/ipa/libipa/agc_mean_luminance.cpp +++ b/src/ipa/libipa/agc_mean_luminance.cpp @@ -281,11 +281,20 @@ int AgcMeanLuminance::parseConstraintModes(const ValueNode &tuningData) int AgcMeanLuminance::parseExposureModes(const ValueNode &tuningData) { + static const std::pair modes[] = { + { "ExposureNormal", controls::ExposureNormal }, + { "ExposureShort", controls::ExposureShort }, + { "ExposureLong", controls::ExposureLong }, + { "ExposureCustom", controls::ExposureCustom }, + }; + const ValueNode &exposureModes = tuningData[controls::AeExposureMode.name()]; if (exposureModes.isDictionary()) { for (const auto &[modeName, modeValues] : exposureModes.asDict()) { - auto it = AeExposureModeNameValueMap.find(modeName); - if (it == AeExposureModeNameValueMap.end()) { + auto it = std::find_if(std::begin(modes), std::end(modes), [&name = modeName](const auto &m) { + return m.first == name; + }); + if (it == std::end(modes)) { LOG(AgcMeanLuminance, Warning) << "Skipping unknown exposure mode '" << modeName << "'"; continue; @@ -326,13 +335,11 @@ int AgcMeanLuminance::parseExposureModes(const ValueNode &tuningData) } } - /* - * If we don't have any exposure modes in the tuning data we create an - * ExposureModeHelper in "maximize" mode. - */ - if (exposureModeHelpers_.empty()) - exposureModeHelpers_.try_emplace(controls::ExposureNormal, - ExposureModeHelper::Maximize{}); + /* These need no configuration, so they are always available. */ + exposureModeHelpers_.try_emplace(controls::ExposureMaximize, + ExposureModeHelper::Maximize{}); + exposureModeHelpers_.try_emplace(controls::ExposureMinimize, + ExposureModeHelper::Minimize{}); return 0; } diff --git a/src/libcamera/control_ids_core.yaml b/src/libcamera/control_ids_core.yaml index 89991d03d7..c29d9fb1d3 100644 --- a/src/libcamera/control_ids_core.yaml +++ b/src/libcamera/control_ids_core.yaml @@ -188,6 +188,12 @@ controls: - name: ExposureCustom value: 3 description: Custom exposure mode. + - name: ExposureMaximize + value: 4 + description: Maximize exposure time. + - name: ExposureMinimize + value: 5 + description: Minimize exposure time. - ExposureValue: type: float