diff options
-rw-r--r-- | Documentation/Doxyfile.in | 1 | ||||
-rw-r--r-- | src/ipa/libipa/algorithm.cpp | 48 | ||||
-rw-r--r-- | src/ipa/libipa/algorithm.h | 47 | ||||
-rw-r--r-- | src/ipa/libipa/module.cpp | 24 | ||||
-rw-r--r-- | src/ipa/libipa/module.h | 33 |
5 files changed, 152 insertions, 1 deletions
diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in index 3d20e3ca..4bb83d50 100644 --- a/Documentation/Doxyfile.in +++ b/Documentation/Doxyfile.in @@ -886,6 +886,7 @@ EXCLUDE_SYMBOLS = libcamera::BoundMethodArgs \ libcamera::BoundMethodStatic \ libcamera::CameraManager::Private \ libcamera::SignalBase \ + libcamera::ipa::AlgorithmFactoryBase \ *::details \ std::* diff --git a/src/ipa/libipa/algorithm.cpp b/src/ipa/libipa/algorithm.cpp index 2df91e5d..1d099808 100644 --- a/src/ipa/libipa/algorithm.cpp +++ b/src/ipa/libipa/algorithm.cpp @@ -33,6 +33,11 @@ namespace ipa { */ /** + * \typedef Algorithm::Module + * \brief The IPA module type for this class of algorithms + */ + +/** * \fn Algorithm::configure() * \brief Configure the Algorithm given an IPAConfigInfo * \param[in] context The shared IPA context @@ -94,6 +99,49 @@ namespace ipa { * such that the algorithms use up to date state as required. */ +/** + * \class AlgorithmFactory + * \brief Registration of Algorithm classes and creation of instances + * \tparam _Algorithm The algorithm class type for this factory + * + * To facilitate instantiation of Algorithm classes, the AlgorithmFactory class + * implements auto-registration of algorithms with the IPA Module class. Each + * Algorithm subclass shall register itself using the REGISTER_IPA_ALGORITHM() + * macro, which will create a corresponding instance of an AlgorithmFactory and + * register it with the IPA Module. + */ + +/** + * \fn AlgorithmFactory::AlgorithmFactory() + * \brief Construct an algorithm factory + * \param[in] name Name of the algorithm class + * + * Creating an instance of the factory automatically registers is with the IPA + * Module class, enabling creation of algorithm instances through + * Module::createAlgorithm(). + * + * The factory \a name identifies the algorithm and shall be unique. + */ + +/** + * \fn AlgorithmFactory::create() + * \brief Create an instance of the Algorithm corresponding to the factory + * \return A pointer to a newly constructed instance of the Algorithm subclass + * corresponding to the factory + */ + +/** + * \def REGISTER_IPA_ALGORITHM + * \brief Register an algorithm with the IPA module + * \param[in] algorithm Class name of Algorithm derived class to register + * \param[in] name Name of the algorithm + * + * Register an Algorithm subclass with the IPA module to make it available for + * instantiation through Module::createAlgorithm(). The \a name identifies the + * algorithm and must be unique across all algorithms registered for the IPA + * module. + */ + } /* namespace ipa */ } /* namespace libcamera */ diff --git a/src/ipa/libipa/algorithm.h b/src/ipa/libipa/algorithm.h index fd2ffcfb..cfbe4ed8 100644 --- a/src/ipa/libipa/algorithm.h +++ b/src/ipa/libipa/algorithm.h @@ -6,14 +6,19 @@ */ #pragma once +#include <memory> +#include <string> + namespace libcamera { namespace ipa { -template<typename Module> +template<typename _Module> class Algorithm { public: + using Module = _Module; + virtual ~Algorithm() {} virtual int configure([[maybe_unused]] typename Module::Context &context, @@ -34,6 +39,46 @@ public: } }; +template<typename _Module> +class AlgorithmFactoryBase +{ +public: + AlgorithmFactoryBase(const char *name) + : name_(name) + { + _Module::registerAlgorithm(this); + } + + virtual ~AlgorithmFactoryBase() = default; + + const std::string &name() const { return name_; } + + virtual std::unique_ptr<Algorithm<_Module>> create() const = 0; + +private: + std::string name_; +}; + +template<typename _Algorithm> +class AlgorithmFactory : public AlgorithmFactoryBase<typename _Algorithm::Module> +{ +public: + AlgorithmFactory(const char *name) + : AlgorithmFactoryBase<typename _Algorithm::Module>(name) + { + } + + ~AlgorithmFactory() = default; + + std::unique_ptr<Algorithm<typename _Algorithm::Module>> create() const override + { + return std::make_unique<_Algorithm>(); + } +}; + +#define REGISTER_IPA_ALGORITHM(algorithm, name) \ +static AlgorithmFactory<algorithm> global_##algorithm##Factory(name); + } /* namespace ipa */ } /* namespace libcamera */ diff --git a/src/ipa/libipa/module.cpp b/src/ipa/libipa/module.cpp index d03cc8ef..451614fd 100644 --- a/src/ipa/libipa/module.cpp +++ b/src/ipa/libipa/module.cpp @@ -75,6 +75,30 @@ namespace ipa { * \brief The type of the IPA statistics and ISP results */ +/** + * \fn Module::createAlgorithm() + * \brief Create an instance of an Algorithm by name + * \param[in] name The algorithm name + * + * This function is the entry point to algorithm instantiation for the IPA + * module. It creates and returns an instance of an algorithm identified by its + * \a name. If no such algorithm exists, the function returns nullptr. + * + * To make an algorithm available to the IPA module, it shall be registered with + * the REGISTER_IPA_ALGORITHM() macro. + * + * \return A new instance of the Algorithm subclass corresponding to the \a name + */ + +/** + * \fn Module::registerAlgorithm() + * \brief Add an algorithm factory class to the list of available algorithms + * \param[in] factory Factory to use to construct the algorithm + * + * This function registers an algorithm factory. It is meant to be called by the + * AlgorithmFactory constructor only. + */ + } /* namespace ipa */ } /* namespace libcamera */ diff --git a/src/ipa/libipa/module.h b/src/ipa/libipa/module.h index c4d77812..05f39801 100644 --- a/src/ipa/libipa/module.h +++ b/src/ipa/libipa/module.h @@ -7,6 +7,12 @@ #pragma once +#include <memory> +#include <string> +#include <vector> + +#include "algorithm.h" + namespace libcamera { namespace ipa { @@ -23,6 +29,33 @@ public: using Stats = _Stats; virtual ~Module() {} + + static std::unique_ptr<Algorithm<Module>> createAlgorithm(const std::string &name) + { + for (const AlgorithmFactoryBase<Module> *factory : factories()) { + if (factory->name() == name) + return factory->create(); + } + + return nullptr; + } + + static void registerAlgorithm(AlgorithmFactoryBase<Module> *factory) + { + factories().push_back(factory); + } + +private: + static std::vector<AlgorithmFactoryBase<Module> *> &factories() + { + /* + * The static factories map is defined inside the function to ensure + * it gets initialized on first use, without any dependency on + * link order. + */ + static std::vector<AlgorithmFactoryBase<Module> *> factories; + return factories; + } }; } /* namespace ipa */ |