mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-13 07:19:45 +03:00
libcamera: pipeline_handler: Implement factories through class templates
The REGISTER_PIPELINE_HANDLER() macro defines a class type that inherits from the PipelineHandlerFactory class, and implements a constructor and a createInstance() function. Replace the code generation through macro with the C++ equivalent, a class template, as done in libipa with the Algorithm and CameraSensorHelper factories. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Xavier Roumegue <xavier.roumegue@oss.nxp.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
This commit is contained in:
parent
ba3a1adc13
commit
0bc9286eb9
4 changed files with 71 additions and 50 deletions
|
@ -95,23 +95,23 @@ private:
|
||||||
Mutex lock_;
|
Mutex lock_;
|
||||||
unsigned int useCount_ LIBCAMERA_TSA_GUARDED_BY(lock_);
|
unsigned int useCount_ LIBCAMERA_TSA_GUARDED_BY(lock_);
|
||||||
|
|
||||||
friend class PipelineHandlerFactory;
|
friend class PipelineHandlerFactoryBase;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PipelineHandlerFactory
|
class PipelineHandlerFactoryBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PipelineHandlerFactory(const char *name);
|
PipelineHandlerFactoryBase(const char *name);
|
||||||
virtual ~PipelineHandlerFactory() = default;
|
virtual ~PipelineHandlerFactoryBase() = default;
|
||||||
|
|
||||||
std::shared_ptr<PipelineHandler> create(CameraManager *manager) const;
|
std::shared_ptr<PipelineHandler> create(CameraManager *manager) const;
|
||||||
|
|
||||||
const std::string &name() const { return name_; }
|
const std::string &name() const { return name_; }
|
||||||
|
|
||||||
static std::vector<PipelineHandlerFactory *> &factories();
|
static std::vector<PipelineHandlerFactoryBase *> &factories();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void registerType(PipelineHandlerFactory *factory);
|
static void registerType(PipelineHandlerFactoryBase *factory);
|
||||||
|
|
||||||
virtual std::unique_ptr<PipelineHandler>
|
virtual std::unique_ptr<PipelineHandler>
|
||||||
createInstance(CameraManager *manager) const = 0;
|
createInstance(CameraManager *manager) const = 0;
|
||||||
|
@ -119,19 +119,23 @@ private:
|
||||||
std::string name_;
|
std::string name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define REGISTER_PIPELINE_HANDLER(handler) \
|
template<typename _PipelineHandler>
|
||||||
class handler##Factory final : public PipelineHandlerFactory \
|
class PipelineHandlerFactory final : public PipelineHandlerFactoryBase
|
||||||
{ \
|
{
|
||||||
public: \
|
public:
|
||||||
handler##Factory() : PipelineHandlerFactory(#handler) {} \
|
PipelineHandlerFactory(const char *name)
|
||||||
\
|
: PipelineHandlerFactoryBase(name)
|
||||||
private: \
|
{
|
||||||
std::unique_ptr<PipelineHandler> \
|
}
|
||||||
createInstance(CameraManager *manager) const \
|
|
||||||
{ \
|
std::unique_ptr<PipelineHandler>
|
||||||
return std::make_unique<handler>(manager); \
|
createInstance(CameraManager *manager) const override
|
||||||
} \
|
{
|
||||||
}; \
|
return std::make_unique<_PipelineHandler>(manager);
|
||||||
static handler##Factory global_##handler##Factory;
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define REGISTER_PIPELINE_HANDLER(handler) \
|
||||||
|
static PipelineHandlerFactory<handler> global_##handler##Factory(#handler);
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
||||||
|
|
|
@ -142,10 +142,10 @@ void CameraManager::Private::createPipelineHandlers()
|
||||||
* file and only fallback on all handlers if there is no
|
* file and only fallback on all handlers if there is no
|
||||||
* configuration file.
|
* configuration file.
|
||||||
*/
|
*/
|
||||||
const std::vector<PipelineHandlerFactory *> &factories =
|
const std::vector<PipelineHandlerFactoryBase *> &factories =
|
||||||
PipelineHandlerFactory::factories();
|
PipelineHandlerFactoryBase::factories();
|
||||||
|
|
||||||
for (const PipelineHandlerFactory *factory : factories) {
|
for (const PipelineHandlerFactoryBase *factory : factories) {
|
||||||
LOG(Camera, Debug)
|
LOG(Camera, Debug)
|
||||||
<< "Found registered pipeline handler '"
|
<< "Found registered pipeline handler '"
|
||||||
<< factory->name() << "'";
|
<< factory->name() << "'";
|
||||||
|
|
|
@ -64,8 +64,7 @@ LOG_DEFINE_CATEGORY(Pipeline)
|
||||||
*
|
*
|
||||||
* In order to honour the std::enable_shared_from_this<> contract,
|
* In order to honour the std::enable_shared_from_this<> contract,
|
||||||
* PipelineHandler instances shall never be constructed manually, but always
|
* PipelineHandler instances shall never be constructed manually, but always
|
||||||
* through the PipelineHandlerFactory::create() function implemented by the
|
* through the PipelineHandlerFactoryBase::create() function.
|
||||||
* respective factories.
|
|
||||||
*/
|
*/
|
||||||
PipelineHandler::PipelineHandler(CameraManager *manager)
|
PipelineHandler::PipelineHandler(CameraManager *manager)
|
||||||
: manager_(manager), useCount_(0)
|
: manager_(manager), useCount_(0)
|
||||||
|
@ -643,27 +642,25 @@ void PipelineHandler::disconnect()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \class PipelineHandlerFactory
|
* \class PipelineHandlerFactoryBase
|
||||||
* \brief Registration of PipelineHandler classes and creation of instances
|
* \brief Base class for pipeline handler factories
|
||||||
*
|
*
|
||||||
* To facilitate discovery and instantiation of PipelineHandler classes, the
|
* The PipelineHandlerFactoryBase class is the base of all specializations of
|
||||||
* PipelineHandlerFactory class maintains a registry of pipeline handler
|
* the PipelineHandlerFactory class template. It implements the factory
|
||||||
* classes. Each PipelineHandler subclass shall register itself using the
|
* registration, maintains a registry of factories, and provides access to the
|
||||||
* REGISTER_PIPELINE_HANDLER() macro, which will create a corresponding
|
* registered factories.
|
||||||
* instance of a PipelineHandlerFactory subclass and register it with the
|
|
||||||
* static list of factories.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Construct a pipeline handler factory
|
* \brief Construct a pipeline handler factory base
|
||||||
* \param[in] name Name of the pipeline handler class
|
* \param[in] name Name of the pipeline handler class
|
||||||
*
|
*
|
||||||
* Creating an instance of the factory registers is with the global list of
|
* Creating an instance of the factory base registers it with the global list of
|
||||||
* factories, accessible through the factories() function.
|
* factories, accessible through the factories() function.
|
||||||
*
|
*
|
||||||
* The factory \a name is used for debug purpose and shall be unique.
|
* The factory \a name is used for debug purpose and shall be unique.
|
||||||
*/
|
*/
|
||||||
PipelineHandlerFactory::PipelineHandlerFactory(const char *name)
|
PipelineHandlerFactoryBase::PipelineHandlerFactoryBase(const char *name)
|
||||||
: name_(name)
|
: name_(name)
|
||||||
{
|
{
|
||||||
registerType(this);
|
registerType(this);
|
||||||
|
@ -676,7 +673,7 @@ PipelineHandlerFactory::PipelineHandlerFactory(const char *name)
|
||||||
* \return A shared pointer to a new instance of the PipelineHandler subclass
|
* \return A shared pointer to a new instance of the PipelineHandler subclass
|
||||||
* corresponding to the factory
|
* corresponding to the factory
|
||||||
*/
|
*/
|
||||||
std::shared_ptr<PipelineHandler> PipelineHandlerFactory::create(CameraManager *manager) const
|
std::shared_ptr<PipelineHandler> PipelineHandlerFactoryBase::create(CameraManager *manager) const
|
||||||
{
|
{
|
||||||
std::unique_ptr<PipelineHandler> handler = createInstance(manager);
|
std::unique_ptr<PipelineHandler> handler = createInstance(manager);
|
||||||
handler->name_ = name_.c_str();
|
handler->name_ = name_.c_str();
|
||||||
|
@ -684,7 +681,7 @@ std::shared_ptr<PipelineHandler> PipelineHandlerFactory::create(CameraManager *m
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \fn PipelineHandlerFactory::name()
|
* \fn PipelineHandlerFactoryBase::name()
|
||||||
* \brief Retrieve the factory name
|
* \brief Retrieve the factory name
|
||||||
* \return The factory name
|
* \return The factory name
|
||||||
*/
|
*/
|
||||||
|
@ -696,9 +693,10 @@ std::shared_ptr<PipelineHandler> PipelineHandlerFactory::create(CameraManager *m
|
||||||
* The caller is responsible to guarantee the uniqueness of the pipeline handler
|
* The caller is responsible to guarantee the uniqueness of the pipeline handler
|
||||||
* name.
|
* name.
|
||||||
*/
|
*/
|
||||||
void PipelineHandlerFactory::registerType(PipelineHandlerFactory *factory)
|
void PipelineHandlerFactoryBase::registerType(PipelineHandlerFactoryBase *factory)
|
||||||
{
|
{
|
||||||
std::vector<PipelineHandlerFactory *> &factories = PipelineHandlerFactory::factories();
|
std::vector<PipelineHandlerFactoryBase *> &factories =
|
||||||
|
PipelineHandlerFactoryBase::factories();
|
||||||
|
|
||||||
factories.push_back(factory);
|
factories.push_back(factory);
|
||||||
}
|
}
|
||||||
|
@ -707,26 +705,45 @@ void PipelineHandlerFactory::registerType(PipelineHandlerFactory *factory)
|
||||||
* \brief Retrieve the list of all pipeline handler factories
|
* \brief Retrieve the list of all pipeline handler factories
|
||||||
* \return the list of pipeline handler factories
|
* \return the list of pipeline handler factories
|
||||||
*/
|
*/
|
||||||
std::vector<PipelineHandlerFactory *> &PipelineHandlerFactory::factories()
|
std::vector<PipelineHandlerFactoryBase *> &PipelineHandlerFactoryBase::factories()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The static factories map is defined inside the function to ensure
|
* The static factories map is defined inside the function to ensure
|
||||||
* it gets initialized on first use, without any dependency on
|
* it gets initialized on first use, without any dependency on
|
||||||
* link order.
|
* link order.
|
||||||
*/
|
*/
|
||||||
static std::vector<PipelineHandlerFactory *> factories;
|
static std::vector<PipelineHandlerFactoryBase *> factories;
|
||||||
return factories;
|
return factories;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class PipelineHandlerFactory
|
||||||
|
* \brief Registration of PipelineHandler classes and creation of instances
|
||||||
|
* \tparam _PipelineHandler The pipeline handler class type for this factory
|
||||||
|
*
|
||||||
|
* To facilitate discovery and instantiation of PipelineHandler classes, the
|
||||||
|
* PipelineHandlerFactory class implements auto-registration of pipeline
|
||||||
|
* handlers. Each PipelineHandler subclass shall register itself using the
|
||||||
|
* REGISTER_PIPELINE_HANDLER() macro, which will create a corresponding
|
||||||
|
* instance of a PipelineHandlerFactory and register it with the static list of
|
||||||
|
* factories.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fn PipelineHandlerFactory::PipelineHandlerFactory(const char *name)
|
||||||
|
* \brief Construct a pipeline handler factory
|
||||||
|
* \param[in] name Name of the pipeline handler class
|
||||||
|
*
|
||||||
|
* Creating an instance of the factory registers it with the global list of
|
||||||
|
* factories, accessible through the factories() function.
|
||||||
|
*
|
||||||
|
* The factory \a name is used for debug purpose and shall be unique.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \fn PipelineHandlerFactory::createInstance() const
|
* \fn PipelineHandlerFactory::createInstance() const
|
||||||
* \brief Create an instance of the PipelineHandler corresponding to the factory
|
* \brief Create an instance of the PipelineHandler corresponding to the factory
|
||||||
* \param[in] manager The camera manager
|
* \param[in] manager The camera manager
|
||||||
*
|
|
||||||
* This virtual function is implemented by the REGISTER_PIPELINE_HANDLER()
|
|
||||||
* macro. It creates a pipeline handler instance associated with the camera
|
|
||||||
* \a manager.
|
|
||||||
*
|
|
||||||
* \return A unique pointer to a newly constructed instance of the
|
* \return A unique pointer to a newly constructed instance of the
|
||||||
* PipelineHandler subclass corresponding to the factory
|
* PipelineHandler subclass corresponding to the factory
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -52,9 +52,9 @@ protected:
|
||||||
ipaManager_ = make_unique<IPAManager>();
|
ipaManager_ = make_unique<IPAManager>();
|
||||||
|
|
||||||
/* Create a pipeline handler for vimc. */
|
/* Create a pipeline handler for vimc. */
|
||||||
const std::vector<PipelineHandlerFactory *> &factories =
|
const std::vector<PipelineHandlerFactoryBase *> &factories =
|
||||||
PipelineHandlerFactory::factories();
|
PipelineHandlerFactoryBase::factories();
|
||||||
for (const PipelineHandlerFactory *factory : factories) {
|
for (const PipelineHandlerFactoryBase *factory : factories) {
|
||||||
if (factory->name() == "PipelineHandlerVimc") {
|
if (factory->name() == "PipelineHandlerVimc") {
|
||||||
pipe_ = factory->create(nullptr);
|
pipe_ = factory->create(nullptr);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue