libcamera: ipa_manager: implement class for managing IPA modules
IPAManager is a class that will search in given directories for IPA modules, and will load them into a list. It also provides an interface for pipeline handlers to acquire an IPA. A meson build file for the IPAs is added, which also specifies a hard-coded path for where to load the IPAs from in the installation directory. More paths can be specified with the environment variable LIBCAMERA_IPA_MODULE_PATH, with the same syntax as the regular PATH environment variable. Make the test framework set this environment variable. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
42c9b4bad4
commit
7fa98a4cdd
6 changed files with 200 additions and 0 deletions
2
src/ipa/meson.build
Normal file
2
src/ipa/meson.build
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
config_h.set('IPA_MODULE_DIR',
|
||||||
|
'"' + join_paths(get_option('prefix'), get_option('libdir'), 'libcamera') + '"')
|
40
src/libcamera/include/ipa_manager.h
Normal file
40
src/libcamera/include/ipa_manager.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019, Google Inc.
|
||||||
|
*
|
||||||
|
* ipa_manager.h - Image Processing Algorithm module manager
|
||||||
|
*/
|
||||||
|
#ifndef __LIBCAMERA_IPA_MANAGER_H__
|
||||||
|
#define __LIBCAMERA_IPA_MANAGER_H__
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <libcamera/ipa/ipa_interface.h>
|
||||||
|
#include <libcamera/ipa/ipa_module_info.h>
|
||||||
|
|
||||||
|
#include "ipa_module.h"
|
||||||
|
#include "pipeline_handler.h"
|
||||||
|
|
||||||
|
namespace libcamera {
|
||||||
|
|
||||||
|
class IPAManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static IPAManager *instance();
|
||||||
|
|
||||||
|
std::unique_ptr<IPAInterface> createIPA(PipelineHandler *pipe,
|
||||||
|
uint32_t maxVersion,
|
||||||
|
uint32_t minVersion);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<IPAModule *> modules_;
|
||||||
|
|
||||||
|
IPAManager();
|
||||||
|
~IPAManager();
|
||||||
|
|
||||||
|
int addDir(const char *libDir);
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace libcamera */
|
||||||
|
|
||||||
|
#endif /* __LIBCAMERA_IPA_MANAGER_H__ */
|
149
src/libcamera/ipa_manager.cpp
Normal file
149
src/libcamera/ipa_manager.cpp
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019, Google Inc.
|
||||||
|
*
|
||||||
|
* ipa_manager.cpp - Image Processing Algorithm module manager
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ipa_manager.h"
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "ipa_module.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "pipeline_handler.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file ipa_manager.h
|
||||||
|
* \brief Image Processing Algorithm module manager
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace libcamera {
|
||||||
|
|
||||||
|
LOG_DEFINE_CATEGORY(IPAManager)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class IPAManager
|
||||||
|
* \brief Manager for IPA modules
|
||||||
|
*/
|
||||||
|
|
||||||
|
IPAManager::IPAManager()
|
||||||
|
{
|
||||||
|
addDir(IPA_MODULE_DIR);
|
||||||
|
|
||||||
|
std::string modulePaths = utils::secure_getenv("LIBCAMERA_IPA_MODULE_PATH");
|
||||||
|
if (modulePaths.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (size_t pos = 0, delim = 0; delim != std::string::npos;
|
||||||
|
pos = delim + 1) {
|
||||||
|
delim = modulePaths.find(':', pos);
|
||||||
|
size_t count = delim == std::string::npos ? delim : delim - pos;
|
||||||
|
std::string path = modulePaths.substr(pos, count);
|
||||||
|
if (path.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
addDir(path.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IPAManager::~IPAManager()
|
||||||
|
{
|
||||||
|
for (IPAModule *module : modules_)
|
||||||
|
delete module;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieve the IPA manager instance
|
||||||
|
*
|
||||||
|
* The IPAManager is a singleton and can't be constructed manually. This
|
||||||
|
* function shall instead be used to retrieve the single global instance of the
|
||||||
|
* manager.
|
||||||
|
*
|
||||||
|
* \return The IPA manager instance
|
||||||
|
*/
|
||||||
|
IPAManager *IPAManager::instance()
|
||||||
|
{
|
||||||
|
static IPAManager ipaManager;
|
||||||
|
return &ipaManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Load IPA modules from a directory
|
||||||
|
* \param[in] libDir directory to search for IPA modules
|
||||||
|
*
|
||||||
|
* This method tries to create an IPAModule instance for every shared object
|
||||||
|
* found in \a libDir, and skips invalid IPA modules.
|
||||||
|
*
|
||||||
|
* \return Number of modules loaded by this call, or a negative error code
|
||||||
|
* otherwise
|
||||||
|
*/
|
||||||
|
int IPAManager::addDir(const char *libDir)
|
||||||
|
{
|
||||||
|
struct dirent *ent;
|
||||||
|
DIR *dir;
|
||||||
|
|
||||||
|
dir = opendir(libDir);
|
||||||
|
if (!dir) {
|
||||||
|
int ret = -errno;
|
||||||
|
LOG(IPAManager, Error)
|
||||||
|
<< "Invalid path " << libDir << " for IPA modules: "
|
||||||
|
<< strerror(-ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int count = 0;
|
||||||
|
while ((ent = readdir(dir)) != nullptr) {
|
||||||
|
int offset = strlen(ent->d_name) - 3;
|
||||||
|
if (offset < 0)
|
||||||
|
continue;
|
||||||
|
if (strcmp(&ent->d_name[offset], ".so"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
IPAModule *ipaModule = new IPAModule(std::string(libDir) +
|
||||||
|
"/" + ent->d_name);
|
||||||
|
if (!ipaModule->isValid()) {
|
||||||
|
delete ipaModule;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
modules_.push_back(ipaModule);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Create an IPA interface that matches a given pipeline handler
|
||||||
|
* \param[in] pipe The pipeline handler that wants a matching IPA interface
|
||||||
|
* \param[in] minVersion Minimum acceptable version of IPA module
|
||||||
|
* \param[in] maxVersion Maximum acceptable version of IPA module
|
||||||
|
*
|
||||||
|
* \return A newly created IPA interface, or nullptr if no matching
|
||||||
|
* IPA module is found
|
||||||
|
*/
|
||||||
|
std::unique_ptr<IPAInterface> IPAManager::createIPA(PipelineHandler *pipe,
|
||||||
|
uint32_t maxVersion,
|
||||||
|
uint32_t minVersion)
|
||||||
|
{
|
||||||
|
IPAModule *m = nullptr;
|
||||||
|
|
||||||
|
for (IPAModule *module : modules_) {
|
||||||
|
if (module->match(pipe, minVersion, maxVersion)) {
|
||||||
|
m = module;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m || !m->load())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return m->createInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace libcamera */
|
|
@ -11,6 +11,7 @@ libcamera_sources = files([
|
||||||
'formats.cpp',
|
'formats.cpp',
|
||||||
'geometry.cpp',
|
'geometry.cpp',
|
||||||
'ipa_interface.cpp',
|
'ipa_interface.cpp',
|
||||||
|
'ipa_manager.cpp',
|
||||||
'ipa_module.cpp',
|
'ipa_module.cpp',
|
||||||
'log.cpp',
|
'log.cpp',
|
||||||
'media_device.cpp',
|
'media_device.cpp',
|
||||||
|
@ -33,6 +34,7 @@ libcamera_headers = files([
|
||||||
'include/device_enumerator_udev.h',
|
'include/device_enumerator_udev.h',
|
||||||
'include/event_dispatcher_poll.h',
|
'include/event_dispatcher_poll.h',
|
||||||
'include/formats.h',
|
'include/formats.h',
|
||||||
|
'include/ipa_manager.h',
|
||||||
'include/ipa_module.h',
|
'include/ipa_module.h',
|
||||||
'include/log.h',
|
'include/log.h',
|
||||||
'include/media_device.h',
|
'include/media_device.h',
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
subdir('libcamera')
|
subdir('libcamera')
|
||||||
|
subdir('ipa')
|
||||||
subdir('cam')
|
subdir('cam')
|
||||||
subdir('qcam')
|
subdir('qcam')
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
* test.cpp - libcamera test base class
|
* test.cpp - libcamera test base class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
Test::Test()
|
Test::Test()
|
||||||
|
@ -19,6 +21,10 @@ int Test::execute()
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
ret = setenv("LIBCAMERA_IPA_MODULE_PATH", "src/ipa", 1);
|
||||||
|
if (ret)
|
||||||
|
return errno;
|
||||||
|
|
||||||
ret = init();
|
ret = init();
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue