mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-15 16:35:06 +03:00
libcamera: ipa_module: allow instantiation of IPAInterface
Add functions for loading the IPAInterface factory function from an IPA module shared object, and for creating an instance of an IPAInterface. These functions will be used by IPAManager, from which a PipelineHandler will request an IPAInterface. Also update meson to add the "-ldl" linker argument, to allow loading of the factory function from a shared object. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
9b4eb44581
commit
7faa67889f
3 changed files with 94 additions and 4 deletions
|
@ -7,8 +7,10 @@
|
||||||
#ifndef __LIBCAMERA_IPA_MODULE_H__
|
#ifndef __LIBCAMERA_IPA_MODULE_H__
|
||||||
#define __LIBCAMERA_IPA_MODULE_H__
|
#define __LIBCAMERA_IPA_MODULE_H__
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <libcamera/ipa/ipa_interface.h>
|
||||||
#include <libcamera/ipa/ipa_module_info.h>
|
#include <libcamera/ipa/ipa_module_info.h>
|
||||||
|
|
||||||
namespace libcamera {
|
namespace libcamera {
|
||||||
|
@ -17,16 +19,26 @@ class IPAModule
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit IPAModule(const std::string &libPath);
|
explicit IPAModule(const std::string &libPath);
|
||||||
|
~IPAModule();
|
||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
|
||||||
const struct IPAModuleInfo &info() const;
|
const struct IPAModuleInfo &info() const;
|
||||||
|
|
||||||
|
bool load();
|
||||||
|
|
||||||
|
std::unique_ptr<IPAInterface> createInstance();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct IPAModuleInfo info_;
|
struct IPAModuleInfo info_;
|
||||||
|
|
||||||
std::string libPath_;
|
std::string libPath_;
|
||||||
bool valid_;
|
bool valid_;
|
||||||
|
bool loaded_;
|
||||||
|
|
||||||
|
void *dlHandle_;
|
||||||
|
typedef IPAInterface *(*IPAIntfFactory)(void);
|
||||||
|
IPAIntfFactory ipaCreate_;
|
||||||
|
|
||||||
int loadIPAModuleInfo();
|
int loadIPAModuleInfo();
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "ipa_module.h"
|
#include "ipa_module.h"
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
#include <elf.h>
|
#include <elf.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.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
|
* The IPA module shared object file must be of the same endianness and
|
||||||
* bitness as libcamera.
|
* bitness as libcamera.
|
||||||
*
|
*
|
||||||
* \todo load funtions from the IPA to be used by pipelines
|
|
||||||
*
|
|
||||||
* The caller shall call the isValid() method after constructing an
|
* The caller shall call the isValid() method after constructing an
|
||||||
* IPAModule instance to verify the validity of the IPAModule.
|
* IPAModule instance to verify the validity of the IPAModule.
|
||||||
*/
|
*/
|
||||||
IPAModule::IPAModule(const std::string &libPath)
|
IPAModule::IPAModule(const std::string &libPath)
|
||||||
: libPath_(libPath), valid_(false)
|
: libPath_(libPath), valid_(false), loaded_(false),
|
||||||
|
dlHandle_(nullptr), ipaCreate_(nullptr)
|
||||||
{
|
{
|
||||||
if (loadIPAModuleInfo() < 0)
|
if (loadIPAModuleInfo() < 0)
|
||||||
return;
|
return;
|
||||||
|
@ -240,6 +240,12 @@ IPAModule::IPAModule(const std::string &libPath)
|
||||||
valid_ = true;
|
valid_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IPAModule::~IPAModule()
|
||||||
|
{
|
||||||
|
if (dlHandle_)
|
||||||
|
dlclose(dlHandle_);
|
||||||
|
}
|
||||||
|
|
||||||
int IPAModule::loadIPAModuleInfo()
|
int IPAModule::loadIPAModuleInfo()
|
||||||
{
|
{
|
||||||
int fd = open(libPath_.c_str(), O_RDONLY);
|
int fd = open(libPath_.c_str(), O_RDONLY);
|
||||||
|
@ -314,4 +320,75 @@ const struct IPAModuleInfo &IPAModule::info() const
|
||||||
return info_;
|
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 */
|
} /* namespace libcamera */
|
||||||
|
|
|
@ -65,7 +65,8 @@ libcamera = shared_library('camera',
|
||||||
libcamera_sources,
|
libcamera_sources,
|
||||||
install : true,
|
install : true,
|
||||||
include_directories : includes,
|
include_directories : includes,
|
||||||
dependencies : libudev)
|
dependencies : libudev,
|
||||||
|
link_args : '-ldl')
|
||||||
|
|
||||||
libcamera_dep = declare_dependency(sources : [libcamera_api, libcamera_h],
|
libcamera_dep = declare_dependency(sources : [libcamera_api, libcamera_h],
|
||||||
include_directories : libcamera_includes,
|
include_directories : libcamera_includes,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue