[libcamera-devel] [PATCH v4 05/12] ipa: libipa: module: Add support for instantiation from YAML
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Mon Jun 20 03:42:58 CEST 2022
Add a Module::createAlgorithms() function to instantiate algorithms from
a YamlObject. The instantiated algorithms are stored in a private member
variable list, exposed through the Module::algorithms() function.
Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
src/ipa/libipa/module.cpp | 42 ++++++++++++++++------
src/ipa/libipa/module.h | 73 +++++++++++++++++++++++++++++++++++----
2 files changed, 99 insertions(+), 16 deletions(-)
diff --git a/src/ipa/libipa/module.cpp b/src/ipa/libipa/module.cpp
index 451614fd04da..7735210444b6 100644
--- a/src/ipa/libipa/module.cpp
+++ b/src/ipa/libipa/module.cpp
@@ -14,6 +14,8 @@
namespace libcamera {
+LOG_DEFINE_CATEGORY(IPAModuleAlgo)
+
/**
* \brief The IPA namespace
*
@@ -76,7 +78,36 @@ namespace ipa {
*/
/**
- * \fn Module::createAlgorithm()
+ * \fn Module::algorithms()
+ * \brief Retrieve the list of instantiated algorithms
+ * \return The list of instantiated algorithms
+ */
+
+/**
+ * \fn Module::createAlgorithms()
+ * \brief Create algorithms from YAML configuration data
+ * \param[in] context The IPA context
+ * \param[in] algorithms Algorithms configuration data as a parsed YamlObject
+ *
+ * This function iterates over the list of \a algorithms parsed from the YAML
+ * configuration file, and instantiates and initializes the corresponding
+ * algorithms. The configuration data is expected to be correct, any error
+ * causes the function to fail and return immediately.
+ *
+ * \return 0 on success, or a negative error code on failure
+ */
+
+/**
+ * \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.
+ */
+
+/**
+ * \fn Module::createAlgorithm(const std::string &name)
* \brief Create an instance of an Algorithm by name
* \param[in] name The algorithm name
*
@@ -90,15 +121,6 @@ namespace ipa {
* \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 f30fc33711bb..00d5785e1aa0 100644
--- a/src/ipa/libipa/module.h
+++ b/src/ipa/libipa/module.h
@@ -7,14 +7,22 @@
#pragma once
+#include <list>
#include <memory>
#include <string>
#include <vector>
+#include <libcamera/base/log.h>
+#include <libcamera/base/utils.h>
+
+#include "libcamera/internal/yaml_parser.h"
+
#include "algorithm.h"
namespace libcamera {
+LOG_DECLARE_CATEGORY(IPAModuleAlgo)
+
namespace ipa {
template<typename _Context, typename _FrameContext, typename _Config,
@@ -30,6 +38,63 @@ public:
virtual ~Module() {}
+ const std::list<std::unique_ptr<Algorithm<Module>>> &algorithms() const
+ {
+ return algorithms_;
+ }
+
+ int createAlgorithms(Context &context, const YamlObject &algorithms)
+ {
+ const auto &list = algorithms.asList();
+
+ for (const auto &[i, algo] : utils::enumerate(list)) {
+ if (!algo.isDictionary()) {
+ LOG(IPAModuleAlgo, Error)
+ << "Invalid YAML syntax for algorithm " << i;
+ algorithms_.clear();
+ return -EINVAL;
+ }
+
+ int ret = createAlgorithm(context, algo);
+ if (ret) {
+ algorithms_.clear();
+ return ret;
+ }
+ }
+
+ return 0;
+ }
+
+ static void registerAlgorithm(AlgorithmFactory<Module> *factory)
+ {
+ factories().push_back(factory);
+ }
+
+private:
+ int createAlgorithm(Context &context, const YamlObject &data)
+ {
+ const auto &[name, algoData] = *data.asDict().begin();
+ std::unique_ptr<Algorithm<Module>> algo = createAlgorithm(name);
+ if (!algo) {
+ LOG(IPAModuleAlgo, Error)
+ << "Algorithm '" << name << "' not found";
+ return -EINVAL;
+ }
+
+ int ret = algo->init(context, algoData);
+ if (ret) {
+ LOG(IPAModuleAlgo, Error)
+ << "Algorithm '" << name << "' failed to initialize";
+ return ret;
+ }
+
+ LOG(IPAModuleAlgo, Debug)
+ << "Instantiated algorithm '" << name << "'";
+
+ algorithms_.push_back(std::move(algo));
+ return 0;
+ }
+
static std::unique_ptr<Algorithm<Module>> createAlgorithm(const std::string &name)
{
for (const AlgorithmFactory<Module> *factory : factories()) {
@@ -40,12 +105,6 @@ public:
return nullptr;
}
- static void registerAlgorithm(AlgorithmFactory<Module> *factory)
- {
- factories().push_back(factory);
- }
-
-private:
static std::vector<AlgorithmFactory<Module> *> &factories()
{
/*
@@ -56,6 +115,8 @@ private:
static std::vector<AlgorithmFactory<Module> *> factories;
return factories;
}
+
+ std::list<std::unique_ptr<Algorithm<Module>>> algorithms_;
};
} /* namespace ipa */
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list