summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/Doxyfile.in1
-rw-r--r--src/ipa/libipa/algorithm.cpp48
-rw-r--r--src/ipa/libipa/algorithm.h47
-rw-r--r--src/ipa/libipa/module.cpp24
-rw-r--r--src/ipa/libipa/module.h33
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 */