[libcamera-devel] [PATCH 05/11] libcamera: ipa_proxy: Provide suport for IPA configuration files
Kieran Bingham
kieran.bingham at ideasonboard.com
Mon Apr 27 14:27:42 CEST 2020
Hi,
On 27/04/2020 13:23, Laurent Pinchart wrote:
> Hi Kieran,
>
> On Mon, Apr 27, 2020 at 01:08:31PM +0100, Kieran Bingham wrote:
>> On 27/04/2020 04:17, Laurent Pinchart wrote:
>>> 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 <laurent.pinchart at ideasonboard.com>
>>> ---
>>> 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 <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 43ac9afc25cb..ea69e63d6bb8 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)
>>> {
>>> }
>>>
>>> @@ -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.
>>
>> Hrm ... this seems to be hidden in the implementation.
>>
>> Perhaps worth describing that configuration files are stored in 'data'
>> in the source tree as part of the commit log at least, and we'll need
>> this documenting in the 'ipa-writers-guide' at least, but as that
>> doesn't exist yet - I'll let you off for not adding it there. ;-)
>
> I'll add this to the commit message.
>
> When stored in the source tree, configuration files shall be located in
> a 'data' subdirectory of their respective IPA directory.
Great, that will at least improve the git-documentation ;-)
--
Kieran
>> Other than that,
>>
>> Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
>>
>>> + */
>>> + 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;
>>>
>
--
Regards
--
Kieran
More information about the libcamera-devel
mailing list