The target string may be used by algorithms to determine the running hardware target. Store the target string provided by the camera tuning files in the controller state. Add a getTarget() member function to retrieve this string. Validate the correct hardware target ("bcm2835") during the IPA initialisation phase. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
150 lines
3.4 KiB
C++
150 lines
3.4 KiB
C++
/* SPDX-License-Identifier: BSD-2-Clause */
|
|
/*
|
|
* Copyright (C) 2019, Raspberry Pi Ltd
|
|
*
|
|
* controller.cpp - ISP controller
|
|
*/
|
|
|
|
#include <assert.h>
|
|
|
|
#include <libcamera/base/file.h>
|
|
#include <libcamera/base/log.h>
|
|
|
|
#include "libcamera/internal/yaml_parser.h"
|
|
|
|
#include "algorithm.h"
|
|
#include "controller.h"
|
|
|
|
using namespace RPiController;
|
|
using namespace libcamera;
|
|
|
|
LOG_DEFINE_CATEGORY(RPiController)
|
|
|
|
Controller::Controller()
|
|
: switchModeCalled_(false)
|
|
{
|
|
}
|
|
|
|
Controller::~Controller() {}
|
|
|
|
int Controller::read(char const *filename)
|
|
{
|
|
File file(filename);
|
|
if (!file.open(File::OpenModeFlag::ReadOnly)) {
|
|
LOG(RPiController, Warning)
|
|
<< "Failed to open tuning file '" << filename << "'";
|
|
return -EINVAL;
|
|
}
|
|
|
|
std::unique_ptr<YamlObject> root = YamlParser::parse(file);
|
|
double version = (*root)["version"].get<double>(1.0);
|
|
target_ = (*root)["target"].get<std::string>("bcm2835");
|
|
|
|
if (version < 2.0) {
|
|
LOG(RPiController, Warning)
|
|
<< "This format of the tuning file will be deprecated soon!"
|
|
<< " Please use the convert_tuning.py utility to update to version 2.0.";
|
|
|
|
for (auto const &[key, value] : root->asDict()) {
|
|
int ret = createAlgorithm(key, value);
|
|
if (ret)
|
|
return ret;
|
|
}
|
|
} else if (version < 3.0) {
|
|
if (!root->contains("algorithms")) {
|
|
LOG(RPiController, Error)
|
|
<< "Tuning file " << filename
|
|
<< " does not have an \"algorithms\" list!";
|
|
return -EINVAL;
|
|
}
|
|
|
|
for (auto const &rootAlgo : (*root)["algorithms"].asList())
|
|
for (auto const &[key, value] : rootAlgo.asDict()) {
|
|
int ret = createAlgorithm(key, value);
|
|
if (ret)
|
|
return ret;
|
|
}
|
|
} else {
|
|
LOG(RPiController, Error)
|
|
<< "Unrecognised version " << version
|
|
<< " for the tuning file " << filename;
|
|
return -EINVAL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int Controller::createAlgorithm(const std::string &name, const YamlObject ¶ms)
|
|
{
|
|
auto it = getAlgorithms().find(name);
|
|
if (it == getAlgorithms().end()) {
|
|
LOG(RPiController, Warning)
|
|
<< "No algorithm found for \"" << name << "\"";
|
|
return 0;
|
|
}
|
|
|
|
Algorithm *algo = (*it->second)(this);
|
|
int ret = algo->read(params);
|
|
if (ret)
|
|
return ret;
|
|
|
|
algorithms_.push_back(AlgorithmPtr(algo));
|
|
return 0;
|
|
}
|
|
|
|
void Controller::initialise()
|
|
{
|
|
for (auto &algo : algorithms_)
|
|
algo->initialise();
|
|
}
|
|
|
|
void Controller::switchMode(CameraMode const &cameraMode, Metadata *metadata)
|
|
{
|
|
for (auto &algo : algorithms_)
|
|
algo->switchMode(cameraMode, metadata);
|
|
switchModeCalled_ = true;
|
|
}
|
|
|
|
void Controller::prepare(Metadata *imageMetadata)
|
|
{
|
|
assert(switchModeCalled_);
|
|
for (auto &algo : algorithms_)
|
|
algo->prepare(imageMetadata);
|
|
}
|
|
|
|
void Controller::process(StatisticsPtr stats, Metadata *imageMetadata)
|
|
{
|
|
assert(switchModeCalled_);
|
|
for (auto &algo : algorithms_)
|
|
algo->process(stats, imageMetadata);
|
|
}
|
|
|
|
Metadata &Controller::getGlobalMetadata()
|
|
{
|
|
return globalMetadata_;
|
|
}
|
|
|
|
Algorithm *Controller::getAlgorithm(std::string const &name) const
|
|
{
|
|
/*
|
|
* The passed name must be the entire algorithm name, or must match the
|
|
* last part of it with a period (.) just before.
|
|
*/
|
|
size_t nameLen = name.length();
|
|
for (auto &algo : algorithms_) {
|
|
char const *algoName = algo->name();
|
|
size_t algoNameLen = strlen(algoName);
|
|
if (algoNameLen >= nameLen &&
|
|
strcasecmp(name.c_str(),
|
|
algoName + algoNameLen - nameLen) == 0 &&
|
|
(nameLen == algoNameLen ||
|
|
algoName[algoNameLen - nameLen - 1] == '.'))
|
|
return algo.get();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
const std::string &Controller::getTarget() const
|
|
{
|
|
return target_;
|
|
}
|