[libcamera-devel] [PATCH v4 03/12] ipa: libipa: algorithm: Add an algorithm registration mechanism

paul.elder at ideasonboard.com paul.elder at ideasonboard.com
Thu Jun 23 09:00:56 CEST 2022


Hi Laurent,

On Mon, Jun 20, 2022 at 04:42:56AM +0300, Laurent Pinchart wrote:
> In order to allow dynamic instantiation of algorithms based on tuning
> data files, add a mechanism to register algorithms with the IPA module.
> The implementation relies on an AlgorithmFactory class and a
> registration macro, similar to the pipeline handler registration
> mechanism. The main difference is that the algorithm registration and
> instantiation are implemented in the Module class instead of the
> AlgorithmFactory class, making the factory an internal implementation
> detail.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

Reviewed-by: Paul Elder <paul.elder at ideasonboard.com>

> ---
>  src/ipa/libipa/algorithm.cpp | 54 ++++++++++++++++++++++++++++++++++++
>  src/ipa/libipa/algorithm.h   | 41 ++++++++++++++++++++++++++-
>  src/ipa/libipa/module.cpp    | 24 ++++++++++++++++
>  src/ipa/libipa/module.h      | 33 ++++++++++++++++++++++
>  4 files changed, 151 insertions(+), 1 deletion(-)
> 
> diff --git a/src/ipa/libipa/algorithm.cpp b/src/ipa/libipa/algorithm.cpp
> index 2df91e5d8fed..6e0bba56ecb2 100644
> --- a/src/ipa/libipa/algorithm.cpp
> +++ b/src/ipa/libipa/algorithm.cpp
> @@ -32,6 +32,11 @@ namespace ipa {
>   * argument.
>   */
>  
> +/**
> + * \typedef Algorithm::Module
> + * \brief The IPA module type for this class of algorithms
> + */
> +
>  /**
>   * \fn Algorithm::configure()
>   * \brief Configure the Algorithm given an IPAConfigInfo
> @@ -94,6 +99,55 @@ namespace ipa {
>   * such that the algorithms use up to date state as required.
>   */
>  
> +/**
> + * \class AlgorithmFactory
> + * \brief Registration of Algorithm classes and creation of instances
> + *
> + * 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
> + * subclass 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::name()
> + * \brief Retrieve the factory name
> + * \return The factory name
> + */
> +
> +/**
> + * \fn AlgorithmFactory::create()
> + * \brief Create an instance of the Algorithm corresponding to the factory
> + *
> + * This virtual function is implemented by the REGISTER_IPA_ALGORITHM()
> + * macro. It creates an algorithm instance.
> + *
> + * \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
> + *
> + * Register an Algorithm subclass with the IPA module to make it available for
> + * instantiation through Module::createAlgorithm().
> + */
> +
>  } /* namespace ipa */
>  
>  } /* namespace libcamera */
> diff --git a/src/ipa/libipa/algorithm.h b/src/ipa/libipa/algorithm.h
> index fd2ffcfbc900..356c094976d4 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,40 @@ public:
>  	}
>  };
>  
> +template<typename Module>
> +class AlgorithmFactory
> +{
> +public:
> +	AlgorithmFactory(const char *name)
> +		: name_(name)
> +	{
> +		Module::registerAlgorithm(this);
> +	}
> +
> +	virtual ~AlgorithmFactory() = default;
> +
> +	const std::string &name() const { return name_; }
> +
> +	virtual std::unique_ptr<Algorithm<Module>> create() const = 0;
> +
> +private:
> +	std::string name_;
> +};
> +
> +#define REGISTER_IPA_ALGORITHM(algorithm)					\
> +class algorithm##Factory final : public AlgorithmFactory<algorithm::Module>	\
> +{										\
> +public:										\
> +	algorithm##Factory() : AlgorithmFactory(#algorithm) {}			\
> +										\
> +	std::unique_ptr<ipa::Algorithm<algorithm::Module>> create() const	\
> +	{									\
> +		return std::make_unique<algorithm>();				\
> +	}									\
> +};										\
> +										\
> +static algorithm##Factory global_##algorithm##Factory;
> +
>  } /* namespace ipa */
>  
>  } /* namespace libcamera */
> diff --git a/src/ipa/libipa/module.cpp b/src/ipa/libipa/module.cpp
> index d03cc8ef03ed..451614fd04da 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 c4d778120408..f30fc33711bb 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 AlgorithmFactory<Module> *factory : factories()) {
> +			if (factory->name() == name)
> +				return factory->create();
> +		}
> +
> +		return nullptr;
> +	}
> +
> +	static void registerAlgorithm(AlgorithmFactory<Module> *factory)
> +	{
> +		factories().push_back(factory);
> +	}
> +
> +private:
> +	static std::vector<AlgorithmFactory<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<AlgorithmFactory<Module> *> factories;
> +		return factories;
> +	}
>  };
>  
>  } /* namespace ipa */
> -- 
> Regards,
> 
> Laurent Pinchart
> 


More information about the libcamera-devel mailing list