To help attribute messages logged by the Module class to a particular IPA module, make the class loggable. The logPrefix() function must be implemented by the IPA module-specific derived class. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
125 lines
2.6 KiB
C++
125 lines
2.6 KiB
C++
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
/*
|
|
* Copyright (C) 2022, Ideas On Board
|
|
*
|
|
* module.h - IPA module
|
|
*/
|
|
|
|
#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,
|
|
typename _Params, typename _Stats>
|
|
class Module : public Loggable
|
|
{
|
|
public:
|
|
using Context = _Context;
|
|
using FrameContext = _FrameContext;
|
|
using Config = _Config;
|
|
using Params = _Params;
|
|
using Stats = _Stats;
|
|
|
|
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(AlgorithmFactoryBase<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 AlgorithmFactoryBase<Module> *factory : factories()) {
|
|
if (factory->name() == name)
|
|
return factory->create();
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
std::list<std::unique_ptr<Algorithm<Module>>> algorithms_;
|
|
};
|
|
|
|
} /* namespace ipa */
|
|
|
|
} /* namespace libcamera */
|