[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