summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libcamera/include/ipa_module.h12
-rw-r--r--src/libcamera/ipa_module.cpp83
-rw-r--r--src/libcamera/meson.build3
3 files changed, 94 insertions, 4 deletions
diff --git a/src/libcamera/include/ipa_module.h b/src/libcamera/include/ipa_module.h
index a4c6dbdf..7ac5cad5 100644
--- a/src/libcamera/include/ipa_module.h
+++ b/src/libcamera/include/ipa_module.h
@@ -7,8 +7,10 @@
#ifndef __LIBCAMERA_IPA_MODULE_H__
#define __LIBCAMERA_IPA_MODULE_H__
+#include <memory>
#include <string>
+#include <libcamera/ipa/ipa_interface.h>
#include <libcamera/ipa/ipa_module_info.h>
namespace libcamera {
@@ -17,16 +19,26 @@ class IPAModule
{
public:
explicit IPAModule(const std::string &libPath);
+ ~IPAModule();
bool isValid() const;
const struct IPAModuleInfo &info() const;
+ bool load();
+
+ std::unique_ptr<IPAInterface> createInstance();
+
private:
struct IPAModuleInfo info_;
std::string libPath_;
bool valid_;
+ bool loaded_;
+
+ void *dlHandle_;
+ typedef IPAInterface *(*IPAIntfFactory)(void);
+ IPAIntfFactory ipaCreate_;
int loadIPAModuleInfo();
};
diff --git a/src/libcamera/ipa_module.cpp b/src/libcamera/ipa_module.cpp
index ac166402..5490f9b6 100644
--- a/src/libcamera/ipa_module.cpp
+++ b/src/libcamera/ipa_module.cpp
@@ -7,6 +7,7 @@
#include "ipa_module.h"
+#include <dlfcn.h>
#include <elf.h>
#include <errno.h>
#include <fcntl.h>
@@ -226,13 +227,12 @@ int elfLoadSymbol(void *dst, size_t size, void *map, size_t soSize,
* The IPA module shared object file must be of the same endianness and
* bitness as libcamera.
*
- * \todo load funtions from the IPA to be used by pipelines
- *
* The caller shall call the isValid() method after constructing an
* IPAModule instance to verify the validity of the IPAModule.
*/
IPAModule::IPAModule(const std::string &libPath)
- : libPath_(libPath), valid_(false)
+ : libPath_(libPath), valid_(false), loaded_(false),
+ dlHandle_(nullptr), ipaCreate_(nullptr)
{
if (loadIPAModuleInfo() < 0)
return;
@@ -240,6 +240,12 @@ IPAModule::IPAModule(const std::string &libPath)
valid_ = true;
}
+IPAModule::~IPAModule()
+{
+ if (dlHandle_)
+ dlclose(dlHandle_);
+}
+
int IPAModule::loadIPAModuleInfo()
{
int fd = open(libPath_.c_str(), O_RDONLY);
@@ -314,4 +320,75 @@ const struct IPAModuleInfo &IPAModule::info() const
return info_;
}
+/**
+ * \brief Load the IPA implementation factory from the shared object
+ *
+ * The IPA module shared object implements an IPAInterface class to be used
+ * by pipeline handlers. This method loads the factory function from the
+ * shared object. Later, createInstance() can be called to instantiate the
+ * IPAInterface.
+ *
+ * This method only needs to be called successfully once, after which
+ * createInstance() can be called as many times as IPAInterface instances are
+ * needed.
+ *
+ * Calling this function on an invalid module (as returned by isValid()) is
+ * an error.
+ *
+ * \return True if load was successful, or already loaded, and false otherwise
+ */
+bool IPAModule::load()
+{
+ if (!valid_)
+ return false;
+
+ if (loaded_)
+ return true;
+
+ dlHandle_ = dlopen(libPath_.c_str(), RTLD_LAZY);
+ if (!dlHandle_) {
+ LOG(IPAModule, Error)
+ << "Failed to open IPA module shared object: "
+ << dlerror();
+ return false;
+ }
+
+ void *symbol = dlsym(dlHandle_, "ipaCreate");
+ if (!symbol) {
+ LOG(IPAModule, Error)
+ << "Failed to load ipaCreate() from IPA module shared object: "
+ << dlerror();
+ dlclose(dlHandle_);
+ dlHandle_ = nullptr;
+ return false;
+ }
+
+ ipaCreate_ = reinterpret_cast<IPAIntfFactory>(symbol);
+
+ loaded_ = true;
+
+ return true;
+}
+
+/**
+ * \brief Instantiate an IPAInterface
+ *
+ * After loading the IPA module with load(), this method creates an
+ * instance of the IPA module interface.
+ *
+ * Calling this function on a module that has not yet been loaded, or an
+ * invalid module (as returned by load() and isValid(), respectively) is
+ * an error.
+ *
+ * \return The IPA implementation as a new IPAInterface instance on success,
+ * or nullptr on error
+ */
+std::unique_ptr<IPAInterface> IPAModule::createInstance()
+{
+ if (!valid_ || !loaded_)
+ return nullptr;
+
+ return std::unique_ptr<IPAInterface>(ipaCreate_());
+}
+
} /* namespace libcamera */
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index 07335e53..32f7da4d 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -65,7 +65,8 @@ libcamera = shared_library('camera',
libcamera_sources,
install : true,
include_directories : includes,
- dependencies : libudev)
+ dependencies : libudev,
+ link_args : '-ldl')
libcamera_dep = declare_dependency(sources : [libcamera_api, libcamera_h],
include_directories : libcamera_includes,