From patchwork Thu Oct 29 17:43:29 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: 28719 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 A0E2FC3261 for ; Thu, 29 Oct 2026 17:43:34 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A776E690EE; Thu, 29 Oct 2026 18:43:33 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="nXbKfDU4"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8342F690A0 for ; Thu, 29 Oct 2026 18:43:32 +0100 (CET) Received: from pb-laptop.local (185.221.143.99.nat.pool.zt.hu [185.221.143.99]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D56094DC for ; Thu, 29 Oct 2026 18:41:18 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1793295678; bh=fGo87iRysNNRmY9VqednzmF2xt9d0FqkIOiSrrlv0B0=; h=From:To:Subject:Date:From; b=nXbKfDU4B3231IBdLiPWDqm1n2yUVie1xCZ0XqZZfTVu9ascBEQHiuGRInuUVp4DV 988/jWddAJPuPXUz6vRtW3+JLMG8Xx0zM1P+TQoAhVaQjFph69ZOdCiNiA9MzVIz/o wz9BJwnZy7tslDOzXlHG9/CPpisE2x76tlZJV9XI= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1] ipa: libipa: Support old enum names Date: Thu, 29 Oct 2026 18:43:29 +0100 Message-ID: <20261029174329.246241-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" It is somewhat unfortunate that the parsing logic uses the enum names directly, and does not have separate key -> value mapping like the rpi ipa has. Commit 974102049a41 ("libcamera: controls: Remove common enum prefix") has changed some enum names, crucially some of those have been used in tuning files. To make the the transition, add support for using the old names and warn about the new names. Signed-off-by: Barnabás Pőcze --- Another approach in addition to https://patchwork.libcamera.org/project/libcamera/list/?series=6318, this is more code, but keeps the old files working. (Apart from the virtual pipeline handler config file.) Similarly, only compile tested. --- src/ipa/libipa/agc_mean_luminance.cpp | 54 ++++++++++++++++++++++++++- src/ipa/libipa/awb.cpp | 40 ++++++++++++++++---- 2 files changed, 85 insertions(+), 9 deletions(-) -- 2.56.0 diff --git a/src/ipa/libipa/agc_mean_luminance.cpp b/src/ipa/libipa/agc_mean_luminance.cpp index 486c09c076..a39ea5e504 100644 --- a/src/ipa/libipa/agc_mean_luminance.cpp +++ b/src/ipa/libipa/agc_mean_luminance.cpp @@ -237,11 +237,36 @@ int AgcMeanLuminance::parseConstraint(const ValueNode &modeDict, int32_t id) int AgcMeanLuminance::parseConstraintModes(const ValueNode &tuningData) { + static constexpr std::tuple compat[] = { + { "ConstraintNormal", "Normal", controls::AeConstraintModeNormal }, + { "ConstraintHighlight", "Highlight", controls::AeConstraintModeHighlight }, + { "ConstraintShadows", "Shadows", controls::AeConstraintModeShadows }, + { "ConstraintCustom", "Custom", controls::AeConstraintModeCustom }, + }; + const ValueNode &constraintModes = tuningData[controls::AeConstraintMode.name()]; if (constraintModes.isDictionary()) { for (const auto &[modeName, modeDict] : constraintModes.asDict()) { + std::optional modeValue; + auto it = AeConstraintModeNameValueMap.find(modeName); if (it == AeConstraintModeNameValueMap.end()) { + for (const auto &[oldName, newName, v] : compat) { + if (modeName != oldName) + continue; + + modeValue = v; + + LOG(AgcMeanLuminance, Warning) + << "Constraint mode '" << oldName << "' has been renamed to '" + << newName << "', please fix the tuning file"; + break; + } + } else { + modeValue = static_cast(it->second); + } + + if (!modeValue) { LOG(AgcMeanLuminance, Warning) << "Skipping unknown constraint mode '" << modeName << "'"; continue; @@ -253,7 +278,7 @@ int AgcMeanLuminance::parseConstraintModes(const ValueNode &tuningData) return -EINVAL; } - int ret = parseConstraint(modeDict, it->second); + int ret = parseConstraint(modeDict, *modeValue); if (ret) return ret; } @@ -281,11 +306,36 @@ int AgcMeanLuminance::parseConstraintModes(const ValueNode &tuningData) int AgcMeanLuminance::parseExposureModes(const ValueNode &tuningData) { + static constexpr std::tuple compat[] = { + { "ExposureNormal", "Normal", controls::AeExposureModeNormal }, + { "ExposureShort", "Short", controls::AeExposureModeShort }, + { "ExposureLong", "Long", controls::AeExposureModeLong }, + { "ExposureCustom", "Custom", controls::AeExposureModeCustom }, + }; + const ValueNode &exposureModes = tuningData[controls::AeExposureMode.name()]; if (exposureModes.isDictionary()) { for (const auto &[modeName, modeValues] : exposureModes.asDict()) { + std::optional modeValue; + auto it = AeExposureModeNameValueMap.find(modeName); if (it == AeExposureModeNameValueMap.end()) { + for (const auto &[oldName, newName, v] : compat) { + if (modeName != oldName) + continue; + + modeValue = v; + + LOG(AgcMeanLuminance, Warning) + << "Exposure mode '" << oldName << "' has been renamed to '" + << newName << "', please fix the tuning file"; + break; + } + } else { + modeValue = static_cast(it->second); + } + + if (!modeValue) { LOG(AgcMeanLuminance, Warning) << "Skipping unknown exposure mode '" << modeName << "'"; continue; @@ -322,7 +372,7 @@ int AgcMeanLuminance::parseExposureModes(const ValueNode &tuningData) }); } - exposureModeHelpers_.try_emplace(it->second, stages); + exposureModeHelpers_.try_emplace(*modeValue, stages); } } diff --git a/src/ipa/libipa/awb.cpp b/src/ipa/libipa/awb.cpp index cad2b5777f..3b95fecee8 100644 --- a/src/ipa/libipa/awb.cpp +++ b/src/ipa/libipa/awb.cpp @@ -451,9 +451,38 @@ int AwbAlgorithmBase::parseModeConfigs(const ValueNode &tuningData, return -EINVAL; } + static constexpr std::tuple compat[] = { + { "AwbAuto", "Auto", controls::AwbModeAuto }, + { "AwbIncandescent", "Incandescent", controls::AwbModeIncandescent }, + { "AwbTungsten", "Tungsten", controls::AwbModeTungsten }, + { "AwbFluorescent", "Fluorescent", controls::AwbModeFluorescent }, + { "AwbIndoor", "Indoor", controls::AwbModeIndoor }, + { "AwbDaylight", "Daylight", controls::AwbModeDaylight }, + { "AwbCloudy", "Cloudy", controls::AwbModeCloudy }, + { "AwbCustom", "Custom", controls::AwbModeCustom }, + }; + for (const auto &[modeName, modeDict] : modes.asDict()) { - if (controls::AwbModeNameValueMap.find(modeName) == - controls::AwbModeNameValueMap.end()) { + std::optional modeValue; + + auto it = controls::AwbModeNameValueMap.find(modeName); + if (it == controls::AwbModeNameValueMap.end()) { + for (const auto &[oldName, newName, v] : compat) { + if (modeName != oldName) + continue; + + modeValue = v; + + LOG(Awb, Warning) + << "AWB mode '" << oldName << " has been renamed to '" + << newName << "', please fix the tuning file"; + break; + } + } else { + modeValue = static_cast(it->second); + } + + if (!modeValue) { LOG(Awb, Warning) << "Skipping unknown AWB mode '" << modeName << "'"; @@ -466,10 +495,7 @@ int AwbAlgorithmBase::parseModeConfigs(const ValueNode &tuningData, return -EINVAL; } - const auto &modeValue = static_cast( - controls::AwbModeNameValueMap.at(modeName)); - - ModeConfig &config = modes_[modeValue]; + ModeConfig &config = modes_[*modeValue]; auto hi = modeDict["hi"].get(); if (!hi) { @@ -487,7 +513,7 @@ int AwbAlgorithmBase::parseModeConfigs(const ValueNode &tuningData, } config.ctLo = *lo; - availableModes.push_back(modeValue); + availableModes.push_back(*modeValue); } if (modes_.empty()) {