diff options
-rw-r--r-- | src/ipa/meson.build | 6 | ||||
-rw-r--r-- | src/libcamera/include/ipa_proxy.h | 11 | ||||
-rw-r--r-- | src/libcamera/ipa_proxy.cpp | 92 | ||||
-rw-r--r-- | src/libcamera/proxy/ipa_proxy_linux.cpp | 2 | ||||
-rw-r--r-- | src/libcamera/proxy/ipa_proxy_thread.cpp | 2 |
5 files changed, 106 insertions, 7 deletions
diff --git a/src/ipa/meson.build b/src/ipa/meson.build index cb4e3ab3..145bf810 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 e696551a..1111065b 100644 --- a/src/libcamera/include/ipa_proxy.h +++ b/src/libcamera/include/ipa_proxy.h @@ -13,22 +13,27 @@ #include <ipa/ipa_interface.h> -#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 43ac9afc..401ac52d 100644 --- a/src/libcamera/ipa_proxy.cpp +++ b/src/libcamera/ipa_proxy.cpp @@ -8,8 +8,11 @@ #include "ipa_proxy.h" #include <string.h> +#include <sys/stat.h> +#include <sys/types.h> #include <unistd.h> +#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) { } @@ -58,6 +62,90 @@ IPAProxy::~IPAProxy() */ /** + * \brief Retrieve the absolute path to an IPA configuration file + * \param[in] name The configuration file 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; + } + } + + 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; + } + } + + LOG(IPAProxy, Error) + << "Configuration file '" << name + << "' not found for IPA module '" << ipaName << "'"; + + 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 2aa80b94..89f5cb54 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 368ccca1..1ebb9b6a 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; |