@@ -71,12 +71,6 @@ for improved debugging: [optional]
information, and libunwind is not needed if both libdw and the glibc
backtrace() function are available.
-for the Raspberry Pi IPA: [optional]
- libboost-dev
-
- Support for Raspberry Pi can be disabled through the meson
- 'pipelines' option to avoid this dependency.
-
for device hotplug enumeration: [optional]
libudev-dev
@@ -9,7 +9,7 @@
using namespace RPiController;
-void Algorithm::Read([[maybe_unused]] boost::property_tree::ptree const ¶ms)
+void Algorithm::Read([[maybe_unused]] const libcamera::YamlObject ¶ms)
{
}
@@ -13,10 +13,10 @@
#include <memory>
#include <map>
+#include "libcamera/internal/yaml_parser.h"
+
#include "controller.hpp"
-#include <boost/property_tree/ptree.hpp>
-
namespace RPiController {
// This defines the basic interface for all control algorithms.
@@ -33,7 +33,7 @@ public:
virtual bool IsPaused() const { return paused_; }
virtual void Pause() { paused_ = true; }
virtual void Resume() { paused_ = false; }
- virtual void Read(boost::property_tree::ptree const ¶ms);
+ virtual void Read(const libcamera::YamlObject ¶ms);
virtual void Initialise();
virtual void SwitchMode(CameraMode const &camera_mode, Metadata *metadata);
virtual void Prepare(Metadata *image_metadata);
@@ -5,14 +5,16 @@
* 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.hpp"
#include "controller.hpp"
-#include <boost/property_tree/json_parser.hpp>
-#include <boost/property_tree/ptree.hpp>
-
using namespace RPiController;
using namespace libcamera;
@@ -32,16 +34,23 @@ Controller::~Controller() {}
void Controller::Read(char const *filename)
{
- boost::property_tree::ptree root;
- boost::property_tree::read_json(filename, root);
- for (auto const &key_and_value : root) {
- Algorithm *algo = CreateAlgorithm(key_and_value.first.c_str());
+ File file(filename);
+ if (!file.open(File::OpenModeFlag::ReadOnly)) {
+ LOG(RPiController, Warning)
+ << "Failed to open tuning file '" << filename << "'";
+ return;
+ }
+
+ std::unique_ptr<YamlObject> root = YamlParser::parse(file);
+
+ for (auto const &[key, value] : root->asDict()) {
+ Algorithm *algo = CreateAlgorithm(key.c_str());
if (algo) {
- algo->Read(key_and_value.second);
+ algo->Read(value);
algorithms_.push_back(AlgorithmPtr(algo));
} else
LOG(RPiController, Warning)
- << "No algorithm found for \"" << key_and_value.first << "\"";
+ << "No algorithm found for \"" << key << "\"";
}
}
@@ -12,13 +12,15 @@
using namespace RPiController;
-void Pwl::Read(boost::property_tree::ptree const ¶ms)
+void Pwl::Read(const libcamera::YamlObject ¶ms)
{
- for (auto it = params.begin(); it != params.end(); it++) {
- double x = it->second.get_value<double>();
- assert(it == params.begin() || x > points_.back().x);
+ const auto &list = params.asList();
+
+ for (auto it = list.begin(); it != list.end(); it++) {
+ double x = it->get<double>(0.0);
+ assert(it == list.begin() || x > points_.back().x);
it++;
- double y = it->second.get_value<double>();
+ double y = it->get<double>(0.0);
points_.push_back(Point(x, y));
}
assert(points_.size() >= 2);
@@ -6,10 +6,11 @@
*/
#pragma once
+#include <functional>
#include <math.h>
#include <vector>
-#include <boost/property_tree/ptree.hpp>
+#include "libcamera/internal/yaml_parser.h"
namespace RPiController {
@@ -55,7 +56,7 @@ public:
};
Pwl() {}
Pwl(std::vector<Point> const &points) : points_(points) {}
- void Read(boost::property_tree::ptree const ¶ms);
+ void Read(const libcamera::YamlObject ¶ms);
void Append(double x, double y, const double eps = 1e-6);
void Prepend(double x, double y, const double eps = 1e-6);
Interval Domain() const;
@@ -30,13 +30,13 @@ LOG_DEFINE_CATEGORY(RPiAgc)
#define PIPELINE_BITS 13 // seems to be a 13-bit pipeline
-void AgcMeteringMode::Read(boost::property_tree::ptree const ¶ms)
+void AgcMeteringMode::Read(const libcamera::YamlObject ¶ms)
{
int num = 0;
- for (auto &p : params.get_child("weights")) {
+ for (const auto &p : params["weights"].asList()) {
if (num == AGC_STATS_SIZE)
throw std::runtime_error("AgcConfig: too many weights");
- weights[num++] = p.second.get_value<double>();
+ weights[num++] = p.get<double>(0.0);
}
if (num != AGC_STATS_SIZE)
throw std::runtime_error("AgcConfig: insufficient weights");
@@ -44,39 +44,39 @@ void AgcMeteringMode::Read(boost::property_tree::ptree const ¶ms)
static std::string
read_metering_modes(std::map<std::string, AgcMeteringMode> &metering_modes,
- boost::property_tree::ptree const ¶ms)
+ const libcamera::YamlObject ¶ms)
{
std::string first;
- for (auto &p : params) {
+ for (const auto &[key, value] : params.asDict()) {
AgcMeteringMode metering_mode;
- metering_mode.Read(p.second);
- metering_modes[p.first] = std::move(metering_mode);
+ metering_mode.Read(value);
+ metering_modes[key] = std::move(metering_mode);
if (first.empty())
- first = p.first;
+ first = key;
}
return first;
}
static int read_list(std::vector<double> &list,
- boost::property_tree::ptree const ¶ms)
+ const libcamera::YamlObject ¶ms)
{
- for (auto &p : params)
- list.push_back(p.second.get_value<double>());
+ for (const auto &p : params.asList())
+ list.push_back(p.get<double>(0.0));
return list.size();
}
static int read_list(std::vector<Duration> &list,
- boost::property_tree::ptree const ¶ms)
+ const libcamera::YamlObject ¶ms)
{
- for (auto &p : params)
- list.push_back(p.second.get_value<double>() * 1us);
+ for (const auto &p : params.asList())
+ list.push_back(p.get<double>(0.0) * 1us);
return list.size();
}
-void AgcExposureMode::Read(boost::property_tree::ptree const ¶ms)
+void AgcExposureMode::Read(const libcamera::YamlObject ¶ms)
{
- int num_shutters = read_list(shutter, params.get_child("shutter"));
- int num_ags = read_list(gain, params.get_child("gain"));
+ int num_shutters = read_list(shutter, params["shutter"]);
+ int num_ags = read_list(gain, params["gain"]);
if (num_shutters < 2 || num_ags < 2)
throw std::runtime_error(
"AgcConfig: must have at least two entries in exposure profile");
@@ -87,40 +87,40 @@ void AgcExposureMode::Read(boost::property_tree::ptree const ¶ms)
static std::string
read_exposure_modes(std::map<std::string, AgcExposureMode> &exposure_modes,
- boost::property_tree::ptree const ¶ms)
+ const libcamera::YamlObject ¶ms)
{
std::string first;
- for (auto &p : params) {
+ for (const auto &[key, value] : params.asDict()) {
AgcExposureMode exposure_mode;
- exposure_mode.Read(p.second);
- exposure_modes[p.first] = std::move(exposure_mode);
+ exposure_mode.Read(value);
+ exposure_modes[key] = std::move(exposure_mode);
if (first.empty())
- first = p.first;
+ first = key;
}
return first;
}
-void AgcConstraint::Read(boost::property_tree::ptree const ¶ms)
+void AgcConstraint::Read(const libcamera::YamlObject ¶ms)
{
- std::string bound_string = params.get<std::string>("bound", "");
+ std::string bound_string = params["bound"].get<std::string>("");
transform(bound_string.begin(), bound_string.end(),
bound_string.begin(), ::toupper);
if (bound_string != "UPPER" && bound_string != "LOWER")
throw std::runtime_error(
"AGC constraint type should be UPPER or LOWER");
bound = bound_string == "UPPER" ? Bound::UPPER : Bound::LOWER;
- q_lo = params.get<double>("q_lo");
- q_hi = params.get<double>("q_hi");
- Y_target.Read(params.get_child("y_target"));
+ q_lo = params["q_lo"].get<double>(0.0);
+ q_hi = params["q_hi"].get<double>(0.0);
+ Y_target.Read(params["y_target"]);
}
static AgcConstraintMode
-read_constraint_mode(boost::property_tree::ptree const ¶ms)
+read_constraint_mode(const libcamera::YamlObject ¶ms)
{
AgcConstraintMode mode;
- for (auto &p : params) {
+ for (const auto &p : params.asList()) {
AgcConstraint constraint;
- constraint.Read(p.second);
+ constraint.Read(p);
mode.push_back(std::move(constraint));
}
return mode;
@@ -128,36 +128,36 @@ read_constraint_mode(boost::property_tree::ptree const ¶ms)
static std::string read_constraint_modes(
std::map<std::string, AgcConstraintMode> &constraint_modes,
- boost::property_tree::ptree const ¶ms)
+ const libcamera::YamlObject ¶ms)
{
std::string first;
- for (auto &p : params) {
- constraint_modes[p.first] = read_constraint_mode(p.second);
+ for (const auto &[key, value] : params.asDict()) {
+ constraint_modes[key] = read_constraint_mode(value);
if (first.empty())
- first = p.first;
+ first = key;
}
return first;
}
-void AgcConfig::Read(boost::property_tree::ptree const ¶ms)
+void AgcConfig::Read(const libcamera::YamlObject ¶ms)
{
LOG(RPiAgc, Debug) << "AgcConfig";
default_metering_mode = read_metering_modes(
- metering_modes, params.get_child("metering_modes"));
+ metering_modes, params["metering_modes"]);
default_exposure_mode = read_exposure_modes(
- exposure_modes, params.get_child("exposure_modes"));
+ exposure_modes, params["exposure_modes"]);
default_constraint_mode = read_constraint_modes(
- constraint_modes, params.get_child("constraint_modes"));
- Y_target.Read(params.get_child("y_target"));
- speed = params.get<double>("speed", 0.2);
- startup_frames = params.get<uint16_t>("startup_frames", 10);
- convergence_frames = params.get<unsigned int>("convergence_frames", 6);
+ constraint_modes, params["constraint_modes"]);
+ Y_target.Read(params["y_target"]);
+ speed = params["speed"].get<double>(0.2);
+ startup_frames = params["startup_frames"].get<uint16_t>(10);
+ convergence_frames = params["convergence_frames"].get<unsigned int>(6);
fast_reduce_threshold =
- params.get<double>("fast_reduce_threshold", 0.4);
- base_ev = params.get<double>("base_ev", 1.0);
+ params["fast_reduce_threshold"].get<double>(0.4);
+ base_ev = params["base_ev"].get<double>(1.0);
// Start with quite a low value as ramping up is easier than ramping down.
- default_exposure_time = params.get<double>("default_exposure_time", 1000) * 1us;
- default_analogue_gain = params.get<double>("default_analogue_gain", 1.0);
+ default_exposure_time = params["default_exposure_time"].get<double>(1000) * 1us;
+ default_analogue_gain = params["default_analogue_gain"].get<double>(1.0);
}
Agc::ExposureValues::ExposureValues()
@@ -186,7 +186,7 @@ char const *Agc::Name() const
return NAME;
}
-void Agc::Read(boost::property_tree::ptree const ¶ms)
+void Agc::Read(const libcamera::YamlObject ¶ms)
{
LOG(RPiAgc, Debug) << "Agc";
config_.Read(params);
@@ -26,13 +26,13 @@ namespace RPiController {
struct AgcMeteringMode {
double weights[AGC_STATS_SIZE];
- void Read(boost::property_tree::ptree const ¶ms);
+ void Read(const libcamera::YamlObject ¶ms);
};
struct AgcExposureMode {
std::vector<libcamera::utils::Duration> shutter;
std::vector<double> gain;
- void Read(boost::property_tree::ptree const ¶ms);
+ void Read(const libcamera::YamlObject ¶ms);
};
struct AgcConstraint {
@@ -41,13 +41,13 @@ struct AgcConstraint {
double q_lo;
double q_hi;
Pwl Y_target;
- void Read(boost::property_tree::ptree const ¶ms);
+ void Read(const libcamera::YamlObject ¶ms);
};
typedef std::vector<AgcConstraint> AgcConstraintMode;
struct AgcConfig {
- void Read(boost::property_tree::ptree const ¶ms);
+ void Read(const libcamera::YamlObject ¶ms);
std::map<std::string, AgcMeteringMode> metering_modes;
std::map<std::string, AgcExposureMode> exposure_modes;
std::map<std::string, AgcConstraintMode> constraint_modes;
@@ -72,7 +72,7 @@ class Agc : public AgcAlgorithm
public:
Agc(Controller *controller);
char const *Name() const override;
- void Read(boost::property_tree::ptree const ¶ms) override;
+ void Read(const libcamera::YamlObject ¶ms) override;
// AGC handles "pausing" for itself.
bool IsPaused() const override;
void Pause() override;
@@ -5,6 +5,7 @@
* alsc.cpp - ALSC (auto lens shading correction) control algorithm
*/
+#include <functional>
#include <math.h>
#include <numeric>
@@ -50,12 +51,12 @@ char const *Alsc::Name() const
return NAME;
}
-static void generate_lut(double *lut, boost::property_tree::ptree const ¶ms)
+static void generate_lut(double *lut, const libcamera::YamlObject ¶ms)
{
- double cstrength = params.get<double>("corner_strength", 2.0);
+ double cstrength = params["corner_strength"].get<double>(2.0);
if (cstrength <= 1.0)
throw std::runtime_error("Alsc: corner_strength must be > 1.0");
- double asymmetry = params.get<double>("asymmetry", 1.0);
+ double asymmetry = params["asymmetry"].get<double>(1.0);
if (asymmetry < 0)
throw std::runtime_error("Alsc: asymmetry must be >= 0");
double f1 = cstrength - 1, f2 = 1 + sqrt(cstrength);
@@ -73,50 +74,43 @@ static void generate_lut(double *lut, boost::property_tree::ptree const ¶ms)
}
}
-static void read_lut(double *lut, boost::property_tree::ptree const ¶ms)
+static void read_lut(double *lut, const libcamera::YamlObject ¶ms)
{
+ if (params.size() != XY)
+ throw std::runtime_error(
+ "Alsc: invalid number of entries in LSC table");
+
int num = 0;
- const int max_num = XY;
- for (auto &p : params) {
- if (num == max_num)
- throw std::runtime_error(
- "Alsc: too many entries in LSC table");
- lut[num++] = p.second.get_value<double>();
- }
- if (num < max_num)
- throw std::runtime_error("Alsc: too few entries in LSC table");
+ for (const auto &p : params.asList())
+ lut[num++] = p.get<double>(0.0);
}
static void read_calibrations(std::vector<AlscCalibration> &calibrations,
- boost::property_tree::ptree const ¶ms,
+ const libcamera::YamlObject ¶ms,
std::string const &name)
{
- if (params.get_child_optional(name)) {
+ if (params.contains(name)) {
double last_ct = 0;
- for (auto &p : params.get_child(name)) {
- double ct = p.second.get<double>("ct");
+ for (const auto &p : params[name].asList()) {
+ double ct = p["ct"].get<double>(0.0);
if (ct <= last_ct)
throw std::runtime_error(
"Alsc: entries in " + name +
" must be in increasing ct order");
AlscCalibration calibration;
calibration.ct = last_ct = ct;
- boost::property_tree::ptree const &table =
- p.second.get_child("table");
+
+ const libcamera::YamlObject &table = p["table"];
+ if (table.size() != XY)
+ throw std::runtime_error(
+ "Alsc: incorrect number of values for ct " +
+ std::to_string(ct) + " in " +
+ name);
+
int num = 0;
- for (auto it = table.begin(); it != table.end(); it++) {
- if (num == XY)
- throw std::runtime_error(
- "Alsc: too many values for ct " +
- std::to_string(ct) + " in " +
- name);
- calibration.table[num++] =
- it->second.get_value<double>();
- }
- if (num != XY)
- throw std::runtime_error(
- "Alsc: too few values for ct " +
- std::to_string(ct) + " in " + name);
+ for (const auto &value : table.asList())
+ calibration.table[num++] = value.get<double>(0.0);
+
calibrations.push_back(calibration);
LOG(RPiAlsc, Debug)
<< "Read " << name << " calibration for ct " << ct;
@@ -124,35 +118,35 @@ static void read_calibrations(std::vector<AlscCalibration> &calibrations,
}
}
-void Alsc::Read(boost::property_tree::ptree const ¶ms)
+void Alsc::Read(const libcamera::YamlObject ¶ms)
{
- config_.frame_period = params.get<uint16_t>("frame_period", 12);
- config_.startup_frames = params.get<uint16_t>("startup_frames", 10);
- config_.speed = params.get<double>("speed", 0.05);
- double sigma = params.get<double>("sigma", 0.01);
- config_.sigma_Cr = params.get<double>("sigma_Cr", sigma);
- config_.sigma_Cb = params.get<double>("sigma_Cb", sigma);
- config_.min_count = params.get<double>("min_count", 10.0);
- config_.min_G = params.get<uint16_t>("min_G", 50);
- config_.omega = params.get<double>("omega", 1.3);
- config_.n_iter = params.get<uint32_t>("n_iter", X + Y);
+ config_.frame_period = params["frame_period"].get<uint16_t>(12);
+ config_.startup_frames = params["startup_frames"].get<uint16_t>(10);
+ config_.speed = params["speed"].get<double>(0.05);
+ double sigma = params["sigma"].get<double>(0.01);
+ config_.sigma_Cr = params["sigma_Cr"].get<double>(sigma);
+ config_.sigma_Cb = params["sigma_Cb"].get<double>(sigma);
+ config_.min_count = params["min_count"].get<double>(10.0);
+ config_.min_G = params["min_G"].get<uint16_t>(50);
+ config_.omega = params["omega"].get<double>(1.3);
+ config_.n_iter = params["n_iter"].get<uint32_t>(X + Y);
config_.luminance_strength =
- params.get<double>("luminance_strength", 1.0);
+ params["luminance_strength"].get<double>(1.0);
for (int i = 0; i < XY; i++)
config_.luminance_lut[i] = 1.0;
- if (params.get_child_optional("corner_strength"))
+ if (params.contains("corner_strength"))
generate_lut(config_.luminance_lut, params);
- else if (params.get_child_optional("luminance_lut"))
+ else if (params.contains("luminance_lut"))
read_lut(config_.luminance_lut,
- params.get_child("luminance_lut"));
+ params["luminance_lut"]);
else
LOG(RPiAlsc, Warning)
<< "no luminance table - assume unity everywhere";
read_calibrations(config_.calibrations_Cr, params, "calibrations_Cr");
read_calibrations(config_.calibrations_Cb, params, "calibrations_Cb");
- config_.default_ct = params.get<double>("default_ct", 4500.0);
- config_.threshold = params.get<double>("threshold", 1e-3);
- config_.lambda_bound = params.get<double>("lambda_bound", 0.05);
+ config_.default_ct = params["default_ct"].get<double>(4500.0);
+ config_.threshold = params["threshold"].get<double>(1e-3);
+ config_.lambda_bound = params["lambda_bound"].get<double>(0.05);
}
static double get_ct(Metadata *metadata, double default_ct);
@@ -52,7 +52,7 @@ public:
char const *Name() const override;
void Initialise() override;
void SwitchMode(CameraMode const &camera_mode, Metadata *metadata) override;
- void Read(boost::property_tree::ptree const ¶ms) override;
+ void Read(const libcamera::YamlObject ¶ms) override;
void Prepare(Metadata *image_metadata) override;
void Process(StatisticsPtr &stats, Metadata *image_metadata) override;
@@ -5,6 +5,8 @@
* awb.cpp - AWB control algorithm
*/
+#include <assert.h>
+
#include <libcamera/base/log.h>
#include "../lux_status.h"
@@ -24,33 +26,35 @@ LOG_DEFINE_CATEGORY(RPiAwb)
// todo - the locking in this algorithm needs some tidying up as has been done
// elsewhere (ALSC and AGC).
-void AwbMode::Read(boost::property_tree::ptree const ¶ms)
+void AwbMode::Read(const libcamera::YamlObject ¶ms)
{
- ct_lo = params.get<double>("lo");
- ct_hi = params.get<double>("hi");
+ ct_lo = params["lo"].get<double>(0.0);
+ ct_hi = params["hi"].get<double>(0.0);
}
-void AwbPrior::Read(boost::property_tree::ptree const ¶ms)
+void AwbPrior::Read(const libcamera::YamlObject ¶ms)
{
- lux = params.get<double>("lux");
- prior.Read(params.get_child("prior"));
+ lux = params["lux"].get<double>(0.0);
+ prior.Read(params["prior"]);
}
static void read_ct_curve(Pwl &ct_r, Pwl &ct_b,
- boost::property_tree::ptree const ¶ms)
+ const libcamera::YamlObject ¶ms)
{
+ const auto &list = params.asList();
int num = 0;
- for (auto it = params.begin(); it != params.end(); it++) {
- double ct = it->second.get_value<double>();
- assert(it == params.begin() || ct != ct_r.Domain().end);
- if (++it == params.end())
+
+ for (auto it = list.begin(); it != list.end(); it++) {
+ double ct = it->get<double>(0.0);
+ assert(it == list.begin() || ct != ct_r.Domain().end);
+ if (++it == list.end())
throw std::runtime_error(
"AwbConfig: incomplete CT curve entry");
- ct_r.Append(ct, it->second.get_value<double>());
- if (++it == params.end())
+ ct_r.Append(ct, it->get<double>(0.0));
+ if (++it == list.end())
throw std::runtime_error(
"AwbConfig: incomplete CT curve entry");
- ct_b.Append(ct, it->second.get_value<double>());
+ ct_b.Append(ct, it->get<double>(0.0));
num++;
}
if (num < 2)
@@ -58,19 +62,19 @@ static void read_ct_curve(Pwl &ct_r, Pwl &ct_b,
"AwbConfig: insufficient points in CT curve");
}
-void AwbConfig::Read(boost::property_tree::ptree const ¶ms)
+void AwbConfig::Read(const libcamera::YamlObject ¶ms)
{
- bayes = params.get<int>("bayes", 1);
- frame_period = params.get<uint16_t>("frame_period", 10);
- startup_frames = params.get<uint16_t>("startup_frames", 10);
- convergence_frames = params.get<unsigned int>("convergence_frames", 3);
- speed = params.get<double>("speed", 0.05);
- if (params.get_child_optional("ct_curve"))
- read_ct_curve(ct_r, ct_b, params.get_child("ct_curve"));
- if (params.get_child_optional("priors")) {
- for (auto &p : params.get_child("priors")) {
+ bayes = params["bayes"].get<int>(1);
+ frame_period = params["frame_period"].get<uint16_t>(10);
+ startup_frames = params["startup_frames"].get<uint16_t>(10);
+ convergence_frames = params["convergence_frames"].get<unsigned int>(3);
+ speed = params["speed"].get<double>(0.05);
+ if (params.contains("ct_curve"))
+ read_ct_curve(ct_r, ct_b, params["ct_curve"]);
+ if (params.contains("priors")) {
+ for (const auto &p : params["priors"].asList()) {
AwbPrior prior;
- prior.Read(p.second);
+ prior.Read(p);
if (!priors.empty() && prior.lux <= priors.back().lux)
throw std::runtime_error(
"AwbConfig: Prior must be ordered in increasing lux value");
@@ -80,28 +84,28 @@ void AwbConfig::Read(boost::property_tree::ptree const ¶ms)
throw std::runtime_error(
"AwbConfig: no AWB priors configured");
}
- if (params.get_child_optional("modes")) {
- for (auto &p : params.get_child("modes")) {
- modes[p.first].Read(p.second);
+ if (params.contains("modes")) {
+ for (const auto &[key, value] : params["modes"].asDict()) {
+ modes[key].Read(value);
if (default_mode == nullptr)
- default_mode = &modes[p.first];
+ default_mode = &modes[key];
}
if (default_mode == nullptr)
throw std::runtime_error(
"AwbConfig: no AWB modes configured");
}
- min_pixels = params.get<double>("min_pixels", 16.0);
- min_G = params.get<uint16_t>("min_G", 32);
- min_regions = params.get<uint32_t>("min_regions", 10);
- delta_limit = params.get<double>("delta_limit", 0.2);
- coarse_step = params.get<double>("coarse_step", 0.2);
- transverse_pos = params.get<double>("transverse_pos", 0.01);
- transverse_neg = params.get<double>("transverse_neg", 0.01);
+ min_pixels = params["min_pixels"].get<double>(16.0);
+ min_G = params["min_G"].get<uint16_t>(32);
+ min_regions = params["min_regions"].get<uint32_t>(10);
+ delta_limit = params["delta_limit"].get<double>(0.2);
+ coarse_step = params["coarse_step"].get<double>(0.2);
+ transverse_pos = params["transverse_pos"].get<double>(0.01);
+ transverse_neg = params["transverse_neg"].get<double>(0.01);
if (transverse_pos <= 0 || transverse_neg <= 0)
throw std::runtime_error(
"AwbConfig: transverse_pos/neg must be > 0");
- sensitivity_r = params.get<double>("sensitivity_r", 1.0);
- sensitivity_b = params.get<double>("sensitivity_b", 1.0);
+ sensitivity_r = params["sensitivity_r"].get<double>(1.0);
+ sensitivity_b = params["sensitivity_b"].get<double>(1.0);
if (bayes) {
if (ct_r.Empty() || ct_b.Empty() || priors.empty() ||
default_mode == nullptr) {
@@ -110,10 +114,9 @@ void AwbConfig::Read(boost::property_tree::ptree const ¶ms)
bayes = false;
}
}
- fast = params.get<int>(
- "fast", bayes); // default to fast for Bayesian, otherwise slow
- whitepoint_r = params.get<double>("whitepoint_r", 0.0);
- whitepoint_b = params.get<double>("whitepoint_b", 0.0);
+ fast = params[fast].get<int>(bayes); // default to fast for Bayesian, otherwise slow
+ whitepoint_r = params["whitepoint_r"].get<double>(0.0);
+ whitepoint_b = params["whitepoint_b"].get<double>(0.0);
if (bayes == false)
sensitivity_r = sensitivity_b =
1.0; // nor do sensitivities make any sense
@@ -144,7 +147,7 @@ char const *Awb::Name() const
return NAME;
}
-void Awb::Read(boost::property_tree::ptree const ¶ms)
+void Awb::Read(const libcamera::YamlObject ¶ms)
{
config_.Read(params);
}
@@ -19,20 +19,20 @@ namespace RPiController {
// Control algorithm to perform AWB calculations.
struct AwbMode {
- void Read(boost::property_tree::ptree const ¶ms);
+ void Read(const libcamera::YamlObject ¶ms);
double ct_lo; // low CT value for search
double ct_hi; // high CT value for search
};
struct AwbPrior {
- void Read(boost::property_tree::ptree const ¶ms);
+ void Read(const libcamera::YamlObject ¶ms);
double lux; // lux level
Pwl prior; // maps CT to prior log likelihood for this lux level
};
struct AwbConfig {
AwbConfig() : default_mode(nullptr) {}
- void Read(boost::property_tree::ptree const ¶ms);
+ void Read(const libcamera::YamlObject ¶ms);
// Only repeat the AWB calculation every "this many" frames
uint16_t frame_period;
// number of initial frames for which speed taken as 1.0 (maximum)
@@ -82,7 +82,7 @@ public:
~Awb();
char const *Name() const override;
void Initialise() override;
- void Read(boost::property_tree::ptree const ¶ms) override;
+ void Read(const libcamera::YamlObject ¶ms) override;
// AWB handles "pausing" for itself.
bool IsPaused() const override;
void Pause() override;
@@ -31,13 +31,13 @@ char const *BlackLevel::Name() const
return NAME;
}
-void BlackLevel::Read(boost::property_tree::ptree const ¶ms)
+void BlackLevel::Read(const libcamera::YamlObject ¶ms)
{
- uint16_t black_level = params.get<uint16_t>(
- "black_level", 4096); // 64 in 10 bits scaled to 16 bits
- black_level_r_ = params.get<uint16_t>("black_level_r", black_level);
- black_level_g_ = params.get<uint16_t>("black_level_g", black_level);
- black_level_b_ = params.get<uint16_t>("black_level_b", black_level);
+ // 64 in 10 bits scaled to 16 bits
+ uint16_t black_level = params["black_level"].get<uint16_t>(4096);
+ black_level_r_ = params["black_level_r"].get<uint16_t>(black_level);
+ black_level_g_ = params["black_level_g"].get<uint16_t>(black_level);
+ black_level_b_ = params["black_level_b"].get<uint16_t>(black_level);
LOG(RPiBlackLevel, Debug)
<< " Read black levels red " << black_level_r_
<< " green " << black_level_g_
@@ -18,7 +18,7 @@ class BlackLevel : public Algorithm
public:
BlackLevel(Controller *controller);
char const *Name() const override;
- void Read(boost::property_tree::ptree const ¶ms) override;
+ void Read(const libcamera::YamlObject ¶ms) override;
void Prepare(Metadata *image_metadata) override;
private:
@@ -37,17 +37,15 @@ Matrix::Matrix(double m0, double m1, double m2, double m3, double m4, double m5,
m[0][0] = m0, m[0][1] = m1, m[0][2] = m2, m[1][0] = m3, m[1][1] = m4,
m[1][2] = m5, m[2][0] = m6, m[2][1] = m7, m[2][2] = m8;
}
-void Matrix::Read(boost::property_tree::ptree const ¶ms)
+void Matrix::Read(const libcamera::YamlObject ¶ms)
{
double *ptr = (double *)m;
- int n = 0;
- for (auto it = params.begin(); it != params.end(); it++) {
- if (n++ == 9)
- throw std::runtime_error("Ccm: too many values in CCM");
- *ptr++ = it->second.get_value<double>();
- }
- if (n < 9)
- throw std::runtime_error("Ccm: too few values in CCM");
+
+ if (params.size() != 9)
+ throw std::runtime_error("Ccm: wrong number of values in CCM");
+
+ for (const auto ¶m : params.asList())
+ *ptr++ = param.get<double>(0.0);
}
Ccm::Ccm(Controller *controller)
@@ -58,14 +56,14 @@ char const *Ccm::Name() const
return NAME;
}
-void Ccm::Read(boost::property_tree::ptree const ¶ms)
+void Ccm::Read(const libcamera::YamlObject ¶ms)
{
- if (params.get_child_optional("saturation"))
- config_.saturation.Read(params.get_child("saturation"));
- for (auto &p : params.get_child("ccms")) {
+ if (params.contains("saturation"))
+ config_.saturation.Read(params["saturation"]);
+ for (auto &p : params["ccms"].asList()) {
CtCcm ct_ccm;
- ct_ccm.ct = p.second.get<double>("ct");
- ct_ccm.ccm.Read(p.second.get_child("ccm"));
+ ct_ccm.ct = p["ct"].get<double>(0.0);
+ ct_ccm.ccm.Read(p["ccm"]);
if (!config_.ccms.empty() &&
ct_ccm.ct <= config_.ccms.back().ct)
throw std::runtime_error(
@@ -20,7 +20,7 @@ struct Matrix {
double m6, double m7, double m8);
Matrix();
double m[3][3];
- void Read(boost::property_tree::ptree const ¶ms);
+ void Read(const libcamera::YamlObject ¶ms);
};
static inline Matrix operator*(double d, Matrix const &m)
{
@@ -62,7 +62,7 @@ class Ccm : public CcmAlgorithm
public:
Ccm(Controller *controller = NULL);
char const *Name() const override;
- void Read(boost::property_tree::ptree const ¶ms) override;
+ void Read(const libcamera::YamlObject ¶ms) override;
void SetSaturation(double saturation) override;
void Initialise() override;
void Prepare(Metadata *image_metadata) override;
@@ -36,21 +36,21 @@ char const *Contrast::Name() const
return NAME;
}
-void Contrast::Read(boost::property_tree::ptree const ¶ms)
+void Contrast::Read(const libcamera::YamlObject ¶ms)
{
// enable adaptive enhancement by default
- config_.ce_enable = params.get<int>("ce_enable", 1);
+ config_.ce_enable = params["ce_enable"].get<int>(1);
// the point near the bottom of the histogram to move
- config_.lo_histogram = params.get<double>("lo_histogram", 0.01);
+ config_.lo_histogram = params["lo_histogram"].get<double>(0.01);
// where in the range to try and move it to
- config_.lo_level = params.get<double>("lo_level", 0.015);
+ config_.lo_level = params["lo_level"].get<double>(0.015);
// but don't move by more than this
- config_.lo_max = params.get<double>("lo_max", 500);
+ config_.lo_max = params["lo_max"].get<double>(500);
// equivalent values for the top of the histogram...
- config_.hi_histogram = params.get<double>("hi_histogram", 0.95);
- config_.hi_level = params.get<double>("hi_level", 0.95);
- config_.hi_max = params.get<double>("hi_max", 2000);
- config_.gamma_curve.Read(params.get_child("gamma_curve"));
+ config_.hi_histogram = params["hi_histogram"].get<double>(0.95);
+ config_.hi_level = params["hi_level"].get<double>(0.95);
+ config_.hi_max = params["hi_max"].get<double>(2000);
+ config_.gamma_curve.Read(params["gamma_curve"]);
}
void Contrast::SetBrightness(double brightness)
@@ -32,7 +32,7 @@ class Contrast : public ContrastAlgorithm
public:
Contrast(Controller *controller = NULL);
char const *Name() const override;
- void Read(boost::property_tree::ptree const ¶ms) override;
+ void Read(const libcamera::YamlObject ¶ms) override;
void SetBrightness(double brightness) override;
void SetContrast(double contrast) override;
void Initialise() override;
@@ -29,9 +29,9 @@ char const *Dpc::Name() const
return NAME;
}
-void Dpc::Read(boost::property_tree::ptree const ¶ms)
+void Dpc::Read(const libcamera::YamlObject ¶ms)
{
- config_.strength = params.get<int>("strength", 1);
+ config_.strength = params["strength"].get<int>(1);
if (config_.strength < 0 || config_.strength > 2)
throw std::runtime_error("Dpc: bad strength value");
}
@@ -22,7 +22,7 @@ class Dpc : public Algorithm
public:
Dpc(Controller *controller);
char const *Name() const override;
- void Read(boost::property_tree::ptree const ¶ms) override;
+ void Read(const libcamera::YamlObject ¶ms) override;
void Prepare(Metadata *image_metadata) override;
private:
@@ -33,14 +33,14 @@ char const *Geq::Name() const
return NAME;
}
-void Geq::Read(boost::property_tree::ptree const ¶ms)
+void Geq::Read(const libcamera::YamlObject ¶ms)
{
- config_.offset = params.get<uint16_t>("offset", 0);
- config_.slope = params.get<double>("slope", 0.0);
+ config_.offset = params["offset"].get<uint16_t>(0);
+ config_.slope = params["slope"].get<double>(0.0);
if (config_.slope < 0.0 || config_.slope >= 1.0)
throw std::runtime_error("Geq: bad slope value");
- if (params.get_child_optional("strength"))
- config_.strength.Read(params.get_child("strength"));
+ if (params.contains("strength"))
+ config_.strength.Read(params["strength"]);
}
void Geq::Prepare(Metadata *image_metadata)
@@ -24,7 +24,7 @@ class Geq : public Algorithm
public:
Geq(Controller *controller);
char const *Name() const override;
- void Read(boost::property_tree::ptree const ¶ms) override;
+ void Read(const libcamera::YamlObject ¶ms) override;
void Prepare(Metadata *image_metadata) override;
private:
@@ -36,14 +36,14 @@ char const *Lux::Name() const
return NAME;
}
-void Lux::Read(boost::property_tree::ptree const ¶ms)
+void Lux::Read(const libcamera::YamlObject ¶ms)
{
reference_shutter_speed_ =
- params.get<double>("reference_shutter_speed") * 1.0us;
- reference_gain_ = params.get<double>("reference_gain");
- reference_aperture_ = params.get<double>("reference_aperture", 1.0);
- reference_Y_ = params.get<double>("reference_Y");
- reference_lux_ = params.get<double>("reference_lux");
+ params["reference_shutter_speed"].get<double>(0.0) * 1.0us;
+ reference_gain_ = params["reference_gain"].get<double>(0.0);
+ reference_aperture_ = params["reference_aperture"].get<double>(1.0);
+ reference_Y_ = params["reference_Y"].get<double>(0.0);
+ reference_lux_ = params["reference_lux"].get<double>(0.0);
current_aperture_ = reference_aperture_;
}
@@ -22,7 +22,7 @@ class Lux : public Algorithm
public:
Lux(Controller *controller);
char const *Name() const override;
- void Read(boost::property_tree::ptree const ¶ms) override;
+ void Read(const libcamera::YamlObject ¶ms) override;
void Prepare(Metadata *image_metadata) override;
void Process(StatisticsPtr &stats, Metadata *image_metadata) override;
void SetCurrentAperture(double aperture);
@@ -39,10 +39,10 @@ void Noise::SwitchMode(CameraMode const &camera_mode,
mode_factor_ = std::max(1.0, camera_mode.noise_factor);
}
-void Noise::Read(boost::property_tree::ptree const ¶ms)
+void Noise::Read(const libcamera::YamlObject ¶ms)
{
- reference_constant_ = params.get<double>("reference_constant");
- reference_slope_ = params.get<double>("reference_slope");
+ reference_constant_ = params["reference_constant"].get<double>(0.0);
+ reference_slope_ = params["reference_slope"].get<double>(0.0);
}
void Noise::Prepare(Metadata *image_metadata)
@@ -19,7 +19,7 @@ public:
Noise(Controller *controller);
char const *Name() const override;
void SwitchMode(CameraMode const &camera_mode, Metadata *metadata) override;
- void Read(boost::property_tree::ptree const ¶ms) override;
+ void Read(const libcamera::YamlObject ¶ms) override;
void Prepare(Metadata *image_metadata) override;
private:
@@ -32,10 +32,10 @@ char const *Sdn::Name() const
return NAME;
}
-void Sdn::Read(boost::property_tree::ptree const ¶ms)
+void Sdn::Read(const libcamera::YamlObject ¶ms)
{
- deviation_ = params.get<double>("deviation", 3.2);
- strength_ = params.get<double>("strength", 0.75);
+ deviation_ = params["deviation"].get<double>(3.2);
+ strength_ = params["strength"].get<double>(0.75);
}
void Sdn::Initialise() {}
@@ -18,7 +18,7 @@ class Sdn : public DenoiseAlgorithm
public:
Sdn(Controller *controller = NULL);
char const *Name() const override;
- void Read(boost::property_tree::ptree const ¶ms) override;
+ void Read(const libcamera::YamlObject ¶ms) override;
void Initialise() override;
void Prepare(Metadata *image_metadata) override;
void SetMode(DenoiseMode mode) override;
@@ -37,11 +37,11 @@ void Sharpen::SwitchMode(CameraMode const &camera_mode,
mode_factor_ = std::max(1.0, camera_mode.noise_factor);
}
-void Sharpen::Read(boost::property_tree::ptree const ¶ms)
+void Sharpen::Read(const libcamera::YamlObject ¶ms)
{
- threshold_ = params.get<double>("threshold", 1.0);
- strength_ = params.get<double>("strength", 1.0);
- limit_ = params.get<double>("limit", 1.0);
+ threshold_ = params["threshold"].get<double>(1.0);
+ strength_ = params["strength"].get<double>(1.0);
+ limit_ = params["limit"].get<double>(1.0);
LOG(RPiSharpen, Debug)
<< "Read threshold " << threshold_
<< " strength " << strength_
@@ -19,7 +19,7 @@ public:
Sharpen(Controller *controller);
char const *Name() const override;
void SwitchMode(CameraMode const &camera_mode, Metadata *metadata) override;
- void Read(boost::property_tree::ptree const ¶ms) override;
+ void Read(const libcamera::YamlObject ¶ms) override;
void SetStrength(double strength) override;
void Prepare(Metadata *image_metadata) override;
@@ -4,7 +4,6 @@ ipa_name = 'ipa_rpi'
rpi_ipa_deps = [
libcamera_private,
- dependency('boost'),
libatomic,
]
@@ -7,6 +7,7 @@
#include <algorithm>
#include <array>
+#include <cstring>
#include <fcntl.h>
#include <math.h>
#include <stdint.h>
The Raspberry Pi IPA module depends on boost only to parse the JSON tuning data files. As libcamera depends on libyaml, use the YamlParser class to parse those files and drop the dependency on boost. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> --- README.rst | 6 -- src/ipa/raspberrypi/controller/algorithm.cpp | 2 +- src/ipa/raspberrypi/controller/algorithm.hpp | 6 +- src/ipa/raspberrypi/controller/controller.cpp | 27 ++++-- src/ipa/raspberrypi/controller/pwl.cpp | 12 ++- src/ipa/raspberrypi/controller/pwl.hpp | 5 +- src/ipa/raspberrypi/controller/rpi/agc.cpp | 94 +++++++++---------- src/ipa/raspberrypi/controller/rpi/agc.hpp | 10 +- src/ipa/raspberrypi/controller/rpi/alsc.cpp | 94 +++++++++---------- src/ipa/raspberrypi/controller/rpi/alsc.hpp | 2 +- src/ipa/raspberrypi/controller/rpi/awb.cpp | 89 +++++++++--------- src/ipa/raspberrypi/controller/rpi/awb.hpp | 8 +- .../controller/rpi/black_level.cpp | 12 +-- .../controller/rpi/black_level.hpp | 2 +- src/ipa/raspberrypi/controller/rpi/ccm.cpp | 28 +++--- src/ipa/raspberrypi/controller/rpi/ccm.hpp | 4 +- .../raspberrypi/controller/rpi/contrast.cpp | 18 ++-- .../raspberrypi/controller/rpi/contrast.hpp | 2 +- src/ipa/raspberrypi/controller/rpi/dpc.cpp | 4 +- src/ipa/raspberrypi/controller/rpi/dpc.hpp | 2 +- src/ipa/raspberrypi/controller/rpi/geq.cpp | 10 +- src/ipa/raspberrypi/controller/rpi/geq.hpp | 2 +- src/ipa/raspberrypi/controller/rpi/lux.cpp | 12 +-- src/ipa/raspberrypi/controller/rpi/lux.hpp | 2 +- src/ipa/raspberrypi/controller/rpi/noise.cpp | 6 +- src/ipa/raspberrypi/controller/rpi/noise.hpp | 2 +- src/ipa/raspberrypi/controller/rpi/sdn.cpp | 6 +- src/ipa/raspberrypi/controller/rpi/sdn.hpp | 2 +- .../raspberrypi/controller/rpi/sharpen.cpp | 8 +- .../raspberrypi/controller/rpi/sharpen.hpp | 2 +- src/ipa/raspberrypi/meson.build | 1 - src/ipa/raspberrypi/raspberrypi.cpp | 1 + 32 files changed, 241 insertions(+), 240 deletions(-)