[libcamera-devel] [PATCH 5/8] libcamera: ipa_manager: implement class for managing IPA modules
Paul Elder
paul.elder at ideasonboard.com
Tue May 28 00:35:37 CEST 2019
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 aquire an IPA.
Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
---
src/libcamera/include/ipa_manager.h | 40 +++++++++
src/libcamera/ipa_manager.cpp | 129 ++++++++++++++++++++++++++++
src/libcamera/meson.build | 2 +
3 files changed, 171 insertions(+)
create mode 100644 src/libcamera/include/ipa_manager.h
create mode 100644 src/libcamera/ipa_manager.cpp
diff --git a/src/libcamera/include/ipa_manager.h b/src/libcamera/include/ipa_manager.h
new file mode 100644
index 0000000..fafafad
--- /dev/null
+++ b/src/libcamera/include/ipa_manager.h
@@ -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 <libcamera/ipa/ipa_interface.h>
+#include <libcamera/ipa/ipa_module_info.h>
+#include <list>
+#include <string>
+
+#include "ipa_module.h"
+#include "pipeline_handler.h"
+
+namespace libcamera {
+
+class IPAManager
+{
+public:
+ static IPAManager *instance();
+
+ int addDir(const std::string &libDir);
+
+ std::unique_ptr<IPAInterface> createIPA(PipelineHandler *pipe) const;
+
+private:
+ std::list<IPAModule *> modules_;
+
+ IPAManager();
+ ~IPAManager();
+
+ bool match(const IPAModule *ipam, PipelineHandler *pipe) const;
+};
+
+} /* namespace libcamera */
+
+#endif /* __LIBCAMERA_IPA_MANAGER_H__ */
diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp
new file mode 100644
index 0000000..3b3c1a6
--- /dev/null
+++ b/src/libcamera/ipa_manager.cpp
@@ -0,0 +1,129 @@
+/* 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 "ipa_module.h"
+#include "pipeline_handler.h"
+#include "utils.h"
+
+#include <dlfcn.h>
+#include <dirent.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "log.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()
+{
+}
+
+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
+ *
+ * Goes through \a libDir and tries to create an IPAModule instance for every
+ * found shared object. Skips invalid IPA modules.
+ *
+ * \return total number of modules loaded (including modules loaded in
+ * previous calls of this function), or negative error code
+ */
+int IPAManager::addDir(const std::string &libDir)
+{
+ struct dirent *ent;
+ DIR *dir;
+
+ dir = opendir(libDir.c_str());
+ if (!dir) {
+ int ret = -errno;
+ LOG(IPAManager, Error) << "Invalid path for IPA modules: "
+ << strerror(ret);
+ return ret;
+ }
+
+ while ((ent = readdir(dir)) != nullptr) {
+ int offset = strlen(ent->d_name) - 3;
+ if (strncmp(&ent->d_name[offset], ".so", 3))
+ continue;
+
+ IPAModule *ipaModule = new IPAModule(libDir + "/" + ent->d_name);
+ if (ipaModule->isValid())
+ modules_.push_back(ipaModule);
+ }
+
+ closedir(dir);
+ return modules_.size();
+}
+
+/**
+ * \brief Create an IPA interface that matches a given pipeline handler
+ * \param[in] pipe the pipeline handler that wants a matching IPA interface
+ *
+ * \return IPA interface, or nullptr if no matching IPA module is found
+ */
+std::unique_ptr<IPAInterface> IPAManager::createIPA(PipelineHandler *pipe) const
+{
+ IPAModule *m = nullptr;
+
+ for (IPAModule *module : modules_) {
+ if (match(module, pipe)) {
+ m = module;
+ break;
+ }
+ }
+
+ if (!m || !m->load())
+ return nullptr;
+
+ return m->createInstance();
+}
+
+bool IPAManager::match(const IPAModule *ipam, PipelineHandler *pipe) const
+{
+ const struct IPAModuleInfo *info = &ipam->info();
+
+ return !strcmp(info->pipelineName, pipe->name()) &&
+ info->pipelineVersionMajor == pipe->majorVersion() &&
+ info->pipelineVersionMinor >= pipe->minorVersion() &&
+ info->moduleAPIVersion == IPA_MODULE_API_VERSION;
+}
+
+} /* namespace libcamera */
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index 32f7da4..0889b0d 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -11,6 +11,7 @@ libcamera_sources = files([
'formats.cpp',
'geometry.cpp',
'ipa_interface.cpp',
+ 'ipa_manager.cpp',
'ipa_module.cpp',
'log.cpp',
'media_device.cpp',
@@ -33,6 +34,7 @@ libcamera_headers = files([
'include/device_enumerator_udev.h',
'include/event_dispatcher_poll.h',
'include/formats.h',
+ 'include/ipa_manager.h',
'include/ipa_module.h',
'include/log.h',
'include/media_device.h',
--
2.20.1
More information about the libcamera-devel
mailing list