From patchwork Mon Apr 27 03:17:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 3557 Return-Path: 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 B8DBB601B8 for ; Mon, 27 Apr 2020 05:17:34 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="oczknb41"; dkim-atps=neutral Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 5B1F272C for ; Mon, 27 Apr 2020 05:17:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1587957454; bh=+bCKeeRKlKKGlXKTgM0sj3xdHdjbiWTrb31gXoU4oec=; h=From:To:Subject:Date:In-Reply-To:References:From; b=oczknb41AkpwEg+nYadkrL+8nR7N7oTlQmK0Ar+9t8suIf9vI6GoyXWI/HTjf2Ahk rB1rKDovBaY4xNA1R+SSMFw3mIpqJrQ8GUwbjOlzq3jN3jU48zcnafgr6bzTzUoZEf fcCkYoQb2ye7eVkeuyCVkbRYoI5xG6zB5NIdqzAM= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Apr 2020 06:17:07 +0300 Message-Id: <20200427031713.14013-6-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.25.3 In-Reply-To: <20200427031713.14013-1-laurent.pinchart@ideasonboard.com> References: <20200427031713.14013-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 05/11] libcamera: ipa_proxy: Provide suport for IPA configuration files 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: , X-List-Received-Date: Mon, 27 Apr 2020 03:17:34 -0000 IPA modules may require configuration files, which may be stored in different locations in the file system. To standardize file locations between all IPAs and pipeline handlers, provide a helper function to locate a configuration file by searching in the following directories: - All directories specified in the LIBCAMERA_IPA_CONFIG_PATH environment variable ; or - In the build tree if libcamera is not installed ; otherwise - In standard system locations (etc and share directories). More locations, or extensions to the mechanism, may be implemented later. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- src/ipa/meson.build | 6 ++ src/libcamera/include/ipa_proxy.h | 11 ++- src/libcamera/ipa_proxy.cpp | 91 +++++++++++++++++++++++- src/libcamera/proxy/ipa_proxy_linux.cpp | 2 +- src/libcamera/proxy/ipa_proxy_thread.cpp | 2 +- 5 files changed, 105 insertions(+), 7 deletions(-) diff --git a/src/ipa/meson.build b/src/ipa/meson.build index cb4e3ab3388f..145bf8105af7 100644 --- a/src/ipa/meson.build +++ b/src/ipa/meson.build @@ -1,10 +1,16 @@ ipa_install_dir = join_paths(get_option('libdir'), 'libcamera') +ipa_data_dir = join_paths(get_option('datadir'), 'libcamera', 'ipa') +ipa_sysconf_dir = join_paths(get_option('sysconfdir'), 'libcamera', 'ipa') ipa_includes = [ libcamera_includes, libcamera_internal_includes, ] +config_h.set('IPA_CONFIG_DIR', + '"' + join_paths(get_option('prefix'), ipa_sysconf_dir) + + ':' + join_paths(get_option('prefix'), ipa_data_dir) + '"') + config_h.set('IPA_MODULE_DIR', '"' + join_paths(get_option('prefix'), ipa_install_dir) + '"') diff --git a/src/libcamera/include/ipa_proxy.h b/src/libcamera/include/ipa_proxy.h index e696551af39f..1111065b36a7 100644 --- a/src/libcamera/include/ipa_proxy.h +++ b/src/libcamera/include/ipa_proxy.h @@ -13,22 +13,27 @@ #include -#include "ipa_module.h" - namespace libcamera { +class IPAModule; + class IPAProxy : public IPAInterface { public: - IPAProxy(); + IPAProxy(IPAModule *ipam); ~IPAProxy(); bool isValid() const { return valid_; } + std::string configurationFile(const std::string &file) const; + protected: std::string resolvePath(const std::string &file) const; bool valid_; + +private: + IPAModule *ipam_; }; class IPAProxyFactory diff --git a/src/libcamera/ipa_proxy.cpp b/src/libcamera/ipa_proxy.cpp index 43ac9afc25cb..ea69e63d6bb8 100644 --- a/src/libcamera/ipa_proxy.cpp +++ b/src/libcamera/ipa_proxy.cpp @@ -8,8 +8,11 @@ #include "ipa_proxy.h" #include +#include +#include #include +#include "ipa_module.h" #include "log.h" #include "utils.h" @@ -34,12 +37,13 @@ LOG_DEFINE_CATEGORY(IPAProxy) /** * \brief Construct an IPAProxy instance + * \param[in] ipam The IPA module * * IPAProxy instances shall be constructed through the IPAProxyFactory::create() * method implemented by the respective factories. */ -IPAProxy::IPAProxy() - : valid_(false) +IPAProxy::IPAProxy(IPAModule *ipam) + : valid_(false), ipam_(ipam) { } @@ -57,6 +61,89 @@ IPAProxy::~IPAProxy() * \return True if the IPAProxy is valid, false otherwise */ +/** + * \brief Retrieve the absolute path to an IPA configuration file + * \param[in] name The configuration name + * + * This function locates the configuration file for an IPA and returns its + * absolute path. It searches the following directories, in order: + * + * - All directories specified in the colon-separated LIBCAMERA_IPA_CONFIG_PATH + * environment variable ; or + * - If libcamera is not installed, the src/ipa/ directory within the source + * tree ; otherwise + * - The system sysconf (etc/libcamera/ipa) and the data (share/libcamera/ipa/) + * directories. + * + * The system directories are not searched if libcamera is not installed. + * + * Within each of those directories, the function looks for a subdirectory + * named after the IPA module name, as reported in IPAModuleInfo::name, and for + * a file named \a name within that directory. The \a name is IPA-specific. + * + * \return The full path to the IPA configuration file, or an empty string if + * no configuration file can be found + */ +std::string IPAProxy::configurationFile(const std::string &name) const +{ + struct stat statbuf; + int ret; + + /* + * The IPA module name can be used as-is to build directory names as it + * has been validated when loading the module. + */ + std::string ipaName = ipam_->info().name; + + /* Check the environment variable first. */ + 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; + } + } + + /* + * 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 root = utils::libcameraSourcePath(); + if (!root.empty()) { + 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; + + return std::string(); + } + + /* Else look in the system locations. */ + for (const auto &dir : utils::split(IPA_CONFIG_DIR, ":")) { + 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; + } + + return std::string(); +} + /** * \brief Find a valid full path for a proxy worker for a given executable name * \param[in] file File name of proxy worker executable diff --git a/src/libcamera/proxy/ipa_proxy_linux.cpp b/src/libcamera/proxy/ipa_proxy_linux.cpp index 2aa80b946704..89f5cb54687b 100644 --- a/src/libcamera/proxy/ipa_proxy_linux.cpp +++ b/src/libcamera/proxy/ipa_proxy_linux.cpp @@ -44,7 +44,7 @@ private: }; IPAProxyLinux::IPAProxyLinux(IPAModule *ipam) - : proc_(nullptr), socket_(nullptr) + : IPAProxy(ipam), proc_(nullptr), socket_(nullptr) { LOG(IPAProxy, Debug) << "initializing dummy proxy: loading IPA from " diff --git a/src/libcamera/proxy/ipa_proxy_thread.cpp b/src/libcamera/proxy/ipa_proxy_thread.cpp index 368ccca1cf60..1ebb9b6a6c9d 100644 --- a/src/libcamera/proxy/ipa_proxy_thread.cpp +++ b/src/libcamera/proxy/ipa_proxy_thread.cpp @@ -73,7 +73,7 @@ private: }; IPAProxyThread::IPAProxyThread(IPAModule *ipam) - : running_(false) + : IPAProxy(ipam), running_(false) { if (!ipam->load()) return;