summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ipa/meson.build6
-rw-r--r--src/libcamera/include/ipa_proxy.h11
-rw-r--r--src/libcamera/ipa_proxy.cpp92
-rw-r--r--src/libcamera/proxy/ipa_proxy_linux.cpp2
-rw-r--r--src/libcamera/proxy/ipa_proxy_thread.cpp2
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;