From patchwork Tue Aug 12 14:38:04 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 24094 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 9712BBEFBE for ; Tue, 12 Aug 2025 14:38:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5582E69249; Tue, 12 Aug 2025 16:38:21 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="eQB/PARS"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3FA286921A for ; Tue, 12 Aug 2025 16:38:19 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:7c24:e2bc:68da:c990]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 5273C3DA; Tue, 12 Aug 2025 16:37:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1755009446; bh=lXOibL5+UYk2LGZhzCDKnQrSGRkVKO/MlBTDk+mqsfw=; h=From:To:Cc:Subject:Date:From; b=eQB/PARSXj6YCtqld6OEjQidPWKylxM16RC8F9cVvBAbHAnw+X5UrRo6jrj3fex8j eiXk/x7zKXH1Cj3UVoBMnZhJwQwkaCo9ho38H8Rzpqhf5WnOCWjMJegwkC76vxcd15 1le/jeVXVedxJ3hK0lWjA8o/WUJUAcXPlVB5FDZU= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH] libcamera: ipa_proxy: Log configuration file path Date: Tue, 12 Aug 2025 16:38:04 +0200 Message-ID: <20250812143814.120975-1-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.48.1 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 often helpful to know which tuning file is used. Add a log statement with INFO level for that. As the core logic has multiple return paths, adding the log statement is not straight forward. Extract finder logic into a ipaConfigurationFile() function and call that with the name and optionally the fallbackName from the configurationFile() function. Signed-off-by: Stefan Klug Reviewed-by: Kieran Bingham Reviewed-by: Barnabás Pőcze --- Hi all, I posted a similar patch a while ago here: https://lists.libcamera.org/pipermail/libcamera-devel/2025-January/048324.html We didn't merge it back then because it should be central in ipa_proxy. Adding it there is a bit ugly because there are a few return paths. I tried to use a scope_exit but that doesn't work as the exit function is called after confPath is moved out to the caller. So I settled for refactoring which imho makes the configurationFile() function also easier to read. Best regards, Stefan --- src/libcamera/ipa_proxy.cpp | 143 ++++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 64 deletions(-) diff --git a/src/libcamera/ipa_proxy.cpp b/src/libcamera/ipa_proxy.cpp index 9907b9615ec7..b5c13a30f1d4 100644 --- a/src/libcamera/ipa_proxy.cpp +++ b/src/libcamera/ipa_proxy.cpp @@ -25,6 +25,78 @@ namespace libcamera { LOG_DEFINE_CATEGORY(IPAProxy) +namespace { + +std::string ipaConfigurationFile(const std::string &ipaName, const std::string &name) +{ + /* + * Start with any user override through the module-specific environment + * variable. Use the name of the IPA module up to the first '/' to + * construct the variable name. + */ + std::string ipaEnvName = ipaName.substr(0, ipaName.find('/')); + std::transform(ipaEnvName.begin(), ipaEnvName.end(), ipaEnvName.begin(), + [](unsigned char c) { return std::toupper(c); }); + ipaEnvName = "LIBCAMERA_" + ipaEnvName + "_TUNING_FILE"; + + char const *configFromEnv = utils::secure_getenv(ipaEnvName.c_str()); + if (configFromEnv && *configFromEnv != '\0') + return { configFromEnv }; + + struct stat statbuf; + int ret; + + /* + * Check the directory pointed to by the IPA config path environment + * variable next. + */ + const char *confPaths = utils::secure_getenv("LIBCAMERA_IPA_CONFIG_PATH"); + if (confPaths) { + for (const auto &dir : utils::split(confPaths, ":")) { + if (dir.empty()) + continue; + + std::string confPath = dir + "/" + ipaName + "/" + name; + ret = stat(confPath.c_str(), &statbuf); + if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG) + return confPath; + } + } + + std::string root = utils::libcameraSourcePath(); + if (!root.empty()) { + /* + * When libcamera is used before it is installed, load + * configuration files from the source directory. The + * configuration files are then located in the 'data' + * subdirectory of the corresponding IPA module. + */ + std::string ipaConfDir = root + "src/ipa/" + ipaName + "/data"; + + LOG(IPAProxy, Info) + << "libcamera is not installed. Loading IPA configuration from '" + << ipaConfDir << "'"; + + std::string confPath = ipaConfDir + "/" + name; + ret = stat(confPath.c_str(), &statbuf); + if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG) + return confPath; + + } else { + /* Else look in the system locations. */ + for (const auto &dir : utils::split(IPA_CONFIG_DIR, ":")) { + std::string confPath = dir + "/" + ipaName + "/" + name; + ret = stat(confPath.c_str(), &statbuf); + if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG) + return confPath; + } + } + + return {}; +} + +} /* namespace */ + /** * \class IPAProxy * \brief IPA Proxy @@ -103,68 +175,10 @@ std::string IPAProxy::configurationFile(const std::string &name, * has been validated when loading the module. */ const std::string ipaName = ipam_->info().name; - - /* - * Start with any user override through the module-specific environment - * variable. Use the name of the IPA module up to the first '/' to - * construct the variable name. - */ - std::string ipaEnvName = ipaName.substr(0, ipaName.find('/')); - std::transform(ipaEnvName.begin(), ipaEnvName.end(), ipaEnvName.begin(), - [](unsigned char c) { return std::toupper(c); }); - ipaEnvName = "LIBCAMERA_" + ipaEnvName + "_TUNING_FILE"; - - char const *configFromEnv = utils::secure_getenv(ipaEnvName.c_str()); - if (configFromEnv && *configFromEnv != '\0') - return { configFromEnv }; - - struct stat statbuf; - int ret; - - /* - * Check the directory pointed to by the IPA config path environment - * variable next. - */ - const char *confPaths = utils::secure_getenv("LIBCAMERA_IPA_CONFIG_PATH"); - if (confPaths) { - for (const auto &dir : utils::split(confPaths, ":")) { - if (dir.empty()) - continue; - - std::string confPath = dir + "/" + ipaName + "/" + name; - ret = stat(confPath.c_str(), &statbuf); - if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG) - return confPath; - } - } - - std::string root = utils::libcameraSourcePath(); - if (!root.empty()) { - /* - * When libcamera is used before it is installed, load - * configuration files from the source directory. The - * configuration files are then located in the 'data' - * subdirectory of the corresponding IPA module. - */ - std::string ipaConfDir = root + "src/ipa/" + ipaName + "/data"; - - LOG(IPAProxy, Info) - << "libcamera is not installed. Loading IPA configuration from '" - << ipaConfDir << "'"; - - std::string confPath = ipaConfDir + "/" + name; - ret = stat(confPath.c_str(), &statbuf); - if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG) - return confPath; - - } else { - /* Else look in the system locations. */ - for (const auto &dir : utils::split(IPA_CONFIG_DIR, ":")) { - std::string confPath = dir + "/" + ipaName + "/" + name; - ret = stat(confPath.c_str(), &statbuf); - if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG) - return confPath; - } + std::string confPath = ipaConfigurationFile(ipaName, name); + if (!confPath.empty()) { + LOG(IPAProxy, Info) << "Using tuning file " << confPath; + return confPath; } if (fallbackName.empty()) { @@ -174,11 +188,12 @@ std::string IPAProxy::configurationFile(const std::string &name, return std::string(); } + confPath = ipaConfigurationFile(ipaName, fallbackName); LOG(IPAProxy, Warning) << "Configuration file '" << name << "' not found for IPA module '" << ipaName - << "', falling back to '" << fallbackName << "'"; - return configurationFile(fallbackName); + << "', falling back to '" << confPath << "'"; + return confPath; } /**