From 7a5e23585fc1f292da7c127d9c5eb323b28b7f99 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 20 Jun 2022 03:36:23 +0300 Subject: ipa: libipa: module: Add support for instantiation from YAML 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 Reviewed-by: Paul Elder --- src/ipa/libipa/module.cpp | 42 +++++++++++++++++++++------- src/ipa/libipa/module.h | 71 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 98 insertions(+), 15 deletions(-) diff --git a/src/ipa/libipa/module.cpp b/src/ipa/libipa/module.cpp index 451614fd..77352104 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,18 +78,23 @@ namespace ipa { */ /** - * \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. + * \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 * - * To make an algorithm available to the IPA module, it shall be registered with - * the REGISTER_IPA_ALGORITHM() macro. + * 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 A new instance of the Algorithm subclass corresponding to the \a name + * \return 0 on success, or a negative error code on failure */ /** @@ -99,6 +106,21 @@ namespace ipa { * 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 + * + * 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 + */ + } /* namespace ipa */ } /* namespace libcamera */ diff --git a/src/ipa/libipa/module.h b/src/ipa/libipa/module.h index 05f39801..addae067 100644 --- a/src/ipa/libipa/module.h +++ b/src/ipa/libipa/module.h @@ -7,14 +7,22 @@ #pragma once +#include #include #include #include +#include +#include + +#include "libcamera/internal/yaml_parser.h" + #include "algorithm.h" namespace libcamera { +LOG_DECLARE_CATEGORY(IPAModuleAlgo) + namespace ipa { template> createAlgorithm(const std::string &name) + const std::list>> &algorithms() const { - for (const AlgorithmFactoryBase *factory : factories()) { - if (factory->name() == name) - return factory->create(); + 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 nullptr; + return 0; } static void registerAlgorithm(AlgorithmFactoryBase *factory) @@ -46,6 +71,40 @@ public: } private: + int createAlgorithm(Context &context, const YamlObject &data) + { + const auto &[name, algoData] = *data.asDict().begin(); + std::unique_ptr> 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> createAlgorithm(const std::string &name) + { + for (const AlgorithmFactoryBase *factory : factories()) { + if (factory->name() == name) + return factory->create(); + } + + return nullptr; + } + static std::vector *> &factories() { /* @@ -56,6 +115,8 @@ private: static std::vector *> factories; return factories; } + + std::list>> algorithms_; }; } /* namespace ipa */ -- cgit v1.2.1