@@ -182,25 +182,6 @@ public:
return get<T>().value_or(std::forward<U>(defaultValue));
}
-#ifndef __DOXYGEN__
- template<typename T,
- std::enable_if_t<
- std::is_same_v<bool, T> ||
- std::is_same_v<float, T> ||
- std::is_same_v<double, T> ||
- std::is_same_v<int8_t, T> ||
- std::is_same_v<uint8_t, T> ||
- std::is_same_v<int16_t, T> ||
- std::is_same_v<uint16_t, T> ||
- std::is_same_v<int32_t, T> ||
- std::is_same_v<uint32_t, T> ||
- std::is_same_v<std::string, T> ||
- std::is_same_v<Size, T>> * = nullptr>
-#else
- template<typename T>
-#endif
- std::optional<std::vector<T>> getList() const;
-
DictAdapter asDict() const { return DictAdapter{ list_ }; }
ListAdapter asList() const { return ListAdapter{ list_ }; }
@@ -288,9 +288,9 @@ int AgcMeanLuminance::parseExposureModes(const YamlObject &tuningData)
}
std::vector<uint32_t> exposureTimes =
- modeValues["exposureTime"].getList<uint32_t>().value_or(std::vector<uint32_t>{});
+ modeValues["exposureTime"].get<std::vector<uint32_t>>().value_or(std::vector<uint32_t>{});
std::vector<double> gains =
- modeValues["gain"].getList<double>().value_or(std::vector<double>{});
+ modeValues["gain"].get<std::vector<double>>().value_or(std::vector<double>{});
if (exposureTimes.size() != gains.size()) {
LOG(AgcMeanLuminance, Error)
@@ -211,9 +211,9 @@ int AwbBayes::readPriors(const YamlObject &tuningData)
}
std::vector<uint32_t> temperatures =
- p["ct"].getList<uint32_t>().value_or(std::vector<uint32_t>{});
+ p["ct"].get<std::vector<uint32_t>>().value_or(std::vector<uint32_t>{});
std::vector<double> probabilities =
- p["probability"].getList<double>().value_or(std::vector<double>{});
+ p["probability"].get<std::vector<double>>().value_or(std::vector<double>{});
if (temperatures.size() != probabilities.size()) {
LOG(Awb, Error)
@@ -48,11 +48,11 @@ int Lsc::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData
}
std::vector<uint8_t> rTable =
- yamlSet["r"].getList<uint8_t>().value_or(std::vector<uint8_t>{});
+ yamlSet["r"].get<std::vector<uint8_t>>().value_or(std::vector<uint8_t>{});
std::vector<uint8_t> gTable =
- yamlSet["g"].getList<uint8_t>().value_or(std::vector<uint8_t>{});
+ yamlSet["g"].get<std::vector<uint8_t>>().value_or(std::vector<uint8_t>{});
std::vector<uint8_t> bTable =
- yamlSet["b"].getList<uint8_t>().value_or(std::vector<uint8_t>{});
+ yamlSet["b"].get<std::vector<uint8_t>>().value_or(std::vector<uint8_t>{});
/*
* Some validation to do; only 16x16 and 32x32 tables of
@@ -55,7 +55,7 @@ int Agc::parseMeteringModes(IPAContext &context, const YamlObject &tuningData)
}
std::vector<uint8_t> weights =
- value.getList<uint8_t>().value_or(std::vector<uint8_t>{});
+ value.get<std::vector<uint8_t>>().value_or(std::vector<uint8_t>{});
if (weights.size() != context.hw.numHistogramWeights) {
LOG(RkISP1Agc, Warning)
<< "Failed to read metering mode'" << key << "'";
@@ -72,7 +72,7 @@ int Dpf::init([[maybe_unused]] IPAContext &context,
* +---------|--------> X
* -4....-1 0 1 2 3 4
*/
- values = dFObject["g"].getList<uint8_t>().value_or(std::vector<uint8_t>{});
+ values = dFObject["g"].get<std::vector<uint8_t>>().value_or(std::vector<uint8_t>{});
if (values.size() != RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS) {
LOG(RkISP1Dpf, Error)
<< "Invalid 'DomainFilter:g': expected "
@@ -108,7 +108,7 @@ int Dpf::init([[maybe_unused]] IPAContext &context,
* For a 9x9 kernel, columns -6 and 6 are dropped, so coefficient
* number 6 is not used.
*/
- values = dFObject["rb"].getList<uint8_t>().value_or(std::vector<uint8_t>{});
+ values = dFObject["rb"].get<std::vector<uint8_t>>().value_or(std::vector<uint8_t>{});
if (values.size() != RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS &&
values.size() != RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS - 1) {
LOG(RkISP1Dpf, Error)
@@ -137,7 +137,7 @@ int Dpf::init([[maybe_unused]] IPAContext &context,
const YamlObject &rFObject = tuningData["NoiseLevelFunction"];
std::vector<uint16_t> nllValues;
- nllValues = rFObject["coeff"].getList<uint16_t>().value_or(std::vector<uint16_t>{});
+ nllValues = rFObject["coeff"].get<std::vector<uint16_t>>().value_or(std::vector<uint16_t>{});
if (nllValues.size() != RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS) {
LOG(RkISP1Dpf, Error)
<< "Invalid 'RangeFilter:coeff': expected "
@@ -59,7 +59,7 @@ int GammaSensorLinearization::init([[maybe_unused]] IPAContext &context,
const YamlObject &tuningData)
{
std::vector<uint16_t> xIntervals =
- tuningData["x-intervals"].getList<uint16_t>().value_or(std::vector<uint16_t>{});
+ tuningData["x-intervals"].get<std::vector<uint16_t>>().value_or(std::vector<uint16_t>{});
if (xIntervals.size() != kDegammaXIntervals) {
LOG(RkISP1Gsl, Error)
<< "Invalid 'x' coordinates: expected "
@@ -83,7 +83,7 @@ int GammaSensorLinearization::init([[maybe_unused]] IPAContext &context,
return -EINVAL;
}
- curveYr_ = yObject["red"].getList<uint16_t>().value_or(std::vector<uint16_t>{});
+ curveYr_ = yObject["red"].get<std::vector<uint16_t>>().value_or(std::vector<uint16_t>{});
if (curveYr_.size() != RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE) {
LOG(RkISP1Gsl, Error)
<< "Invalid 'y:red' coordinates: expected "
@@ -92,7 +92,7 @@ int GammaSensorLinearization::init([[maybe_unused]] IPAContext &context,
return -EINVAL;
}
- curveYg_ = yObject["green"].getList<uint16_t>().value_or(std::vector<uint16_t>{});
+ curveYg_ = yObject["green"].get<std::vector<uint16_t>>().value_or(std::vector<uint16_t>{});
if (curveYg_.size() != RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE) {
LOG(RkISP1Gsl, Error)
<< "Invalid 'y:green' coordinates: expected "
@@ -101,7 +101,7 @@ int GammaSensorLinearization::init([[maybe_unused]] IPAContext &context,
return -EINVAL;
}
- curveYb_ = yObject["blue"].getList<uint16_t>().value_or(std::vector<uint16_t>{});
+ curveYb_ = yObject["blue"].get<std::vector<uint16_t>>().value_or(std::vector<uint16_t>{});
if (curveYb_.size() != RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE) {
LOG(RkISP1Gsl, Error)
<< "Invalid 'y:blue' coordinates: expected "
@@ -252,7 +252,7 @@ private:
RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX;
std::vector<uint16_t> table =
- tuningData[prop].getList<uint16_t>().value_or(std::vector<uint16_t>{});
+ tuningData[prop].get<std::vector<uint16_t>>().value_or(std::vector<uint16_t>{});
if (table.size() != kLscNumSamples) {
LOG(RkISP1Lsc, Error)
<< "Invalid '" << prop << "' values: expected "
@@ -269,7 +269,7 @@ static std::vector<double> parseSizes(const YamlObject &tuningData,
const char *prop)
{
std::vector<double> sizes =
- tuningData[prop].getList<double>().value_or(std::vector<double>{});
+ tuningData[prop].get<std::vector<double>>().value_or(std::vector<double>{});
if (sizes.size() != RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE) {
LOG(RkISP1Lsc, Error)
<< "Invalid '" << prop << "' values: expected "
@@ -66,13 +66,13 @@ readMeteringModes(std::map<std::string, AgcMeteringMode> &metering_modes,
int AgcExposureMode::read(const libcamera::YamlObject ¶ms)
{
- auto value = params["shutter"].getList<double>();
+ auto value = params["shutter"].get<std::vector<double>>();
if (!value)
return -EINVAL;
std::transform(value->begin(), value->end(), std::back_inserter(exposureTime),
[](double v) { return v * 1us; });
- value = params["gain"].getList<double>();
+ value = params["gain"].get<std::vector<double>>();
if (!value)
return -EINVAL;
gain = std::move(*value);
@@ -29,7 +29,7 @@ void HdrConfig::read(const libcamera::YamlObject ¶ms, const std::string &mod
if (!params.contains("cadence"))
LOG(RPiHdr, Fatal) << "No cadence for HDR mode " << name;
- cadence = params["cadence"].getList<unsigned int>().value();
+ cadence = params["cadence"].get<std::vector<unsigned int>>().value();
if (cadence.empty())
LOG(RPiHdr, Fatal) << "Empty cadence in HDR mode " << name;
@@ -69,14 +69,14 @@ void HdrConfig::read(const libcamera::YamlObject ¶ms, const std::string &mod
tonemap = params["tonemap"].get<ipa::Pwl>(ipa::Pwl{});
speed = params["speed"].get<double>(1.0);
if (params.contains("hi_quantile_targets")) {
- hiQuantileTargets = params["hi_quantile_targets"].getList<double>().value();
+ hiQuantileTargets = params["hi_quantile_targets"].get<std::vector<double>>().value();
if (hiQuantileTargets.empty() || hiQuantileTargets.size() % 2)
LOG(RPiHdr, Fatal) << "hi_quantile_targets much be even and non-empty";
} else
hiQuantileTargets = { 0.95, 0.65, 0.5, 0.28, 0.3, 0.25 };
hiQuantileMaxGain = params["hi_quantile_max_gain"].get<double>(1.6);
if (params.contains("quantile_targets")) {
- quantileTargets = params["quantile_targets"].getList<double>().value();
+ quantileTargets = params["quantile_targets"].get<std::vector<double>>().value();
if (quantileTargets.empty() || quantileTargets.size() % 2)
LOG(RPiHdr, Fatal) << "quantile_targets much be even and non-empty";
} else
@@ -84,7 +84,7 @@ void HdrConfig::read(const libcamera::YamlObject ¶ms, const std::string &mod
powerMin = params["power_min"].get<double>(0.65);
powerMax = params["power_max"].get<double>(1.0);
if (params.contains("contrast_adjustments")) {
- contrastAdjustments = params["contrast_adjustments"].getList<double>().value();
+ contrastAdjustments = params["contrast_adjustments"].get<std::vector<double>>().value();
} else
contrastAdjustments = { 0.5, 0.75 };
@@ -126,7 +126,7 @@ int ConverterDW100Module::init(const YamlObject ¶ms)
return -EINVAL;
}
- const auto coeffs = coefficients.getList<double>();
+ const auto coeffs = coefficients.get<std::vector<double>>();
if (!coeffs) {
LOG(Converter, Error) << "Dewarp parameters 'coefficients' value is not a list";
return -EINVAL;
@@ -152,7 +152,7 @@ std::optional<std::vector<std::string>> GlobalConfiguration::listOption(
if (!*c)
return {};
}
- return c->getList<std::string>();
+ return c->get<std::vector<std::string>>();
}
/**
@@ -115,7 +115,7 @@ int ConfigParser::parseSupportedFormats(const YamlObject &cameraConfigData,
std::vector<int64_t> frameRates;
if (supportedResolution.contains("frame_rates")) {
auto frameRatesList =
- supportedResolution["frame_rates"].getList<int>();
+ supportedResolution["frame_rates"].get<std::vector<int>>();
if (!frameRatesList || (frameRatesList->size() != 1 &&
frameRatesList->size() != 2)) {
LOG(Virtual, Error) << "Invalid frame_rates: either one or two values";
@@ -109,12 +109,16 @@ std::size_t YamlObject::size() const
/**
* \fn template<typename T> YamlObject::get<T>() const
+ * \tparam T Type of the value
* \brief Parse the YamlObject as a \a T value
*
* This function parses the value of the YamlObject as a \a T object, and
* returns the value. If parsing fails (usually because the YamlObject doesn't
* store a \a T value), std::nullopt is returned.
*
+ * If the type \a T is an std::vector, the YamlObject will be parsed as a list
+ * of values.
+ *
* \return The YamlObject value, or std::nullopt if parsing failed
*/
@@ -127,6 +131,9 @@ std::size_t YamlObject::size() const
* returns the value. If parsing fails (usually because the YamlObject doesn't
* store a \a T value), the \a defaultValue is returned.
*
+ * Unlike the get() function, this overload does not support std::vector for the
+ * type \a T.
+ *
* \return The YamlObject value, or \a defaultValue if parsing failed
*/
@@ -239,65 +246,50 @@ YamlObject::Accessor<Size>::get(const YamlObject &obj) const
return Size(*width, *height);
}
-#endif /* __DOXYGEN__ */
-
-/**
- * \fn template<typename T> YamlObject::getList<T>() const
- * \brief Parse the YamlObject as a list of \a T
- *
- * This function parses the value of the YamlObject as a list of \a T objects,
- * and returns the value as a \a std::vector<T>. If parsing fails, std::nullopt
- * is returned.
- *
- * \return The YamlObject value as a std::vector<T>, or std::nullopt if parsing
- * failed
- */
-
-#ifndef __DOXYGEN__
-
-template<typename T,
- std::enable_if_t<
- std::is_same_v<bool, T> ||
- std::is_same_v<float, T> ||
- std::is_same_v<double, T> ||
- std::is_same_v<int8_t, T> ||
- std::is_same_v<uint8_t, T> ||
- std::is_same_v<int16_t, T> ||
- std::is_same_v<uint16_t, T> ||
- std::is_same_v<int32_t, T> ||
- std::is_same_v<uint32_t, T> ||
- std::is_same_v<std::string, T> ||
- std::is_same_v<Size, T>> *>
-std::optional<std::vector<T>> YamlObject::getList() const
+template<typename T>
+struct YamlObject::Accessor<std::vector<T>, std::enable_if_t<
+ std::is_same_v<bool, T> ||
+ std::is_same_v<float, T> ||
+ std::is_same_v<double, T> ||
+ std::is_same_v<int8_t, T> ||
+ std::is_same_v<uint8_t, T> ||
+ std::is_same_v<int16_t, T> ||
+ std::is_same_v<uint16_t, T> ||
+ std::is_same_v<int32_t, T> ||
+ std::is_same_v<uint32_t, T> ||
+ std::is_same_v<std::string, T> ||
+ std::is_same_v<Size, T>>>
{
- if (type_ != Type::List)
- return std::nullopt;
-
- std::vector<T> values;
- values.reserve(list_.size());
-
- for (const YamlObject &entry : asList()) {
- const auto value = entry.get<T>();
- if (!value)
+ std::optional<std::vector<T>> get(const YamlObject &obj) const
+ {
+ if (obj.type_ != Type::List)
return std::nullopt;
- values.emplace_back(*value);
+
+ std::vector<T> values;
+ values.reserve(obj.list_.size());
+
+ for (const YamlObject &entry : obj.asList()) {
+ const auto value = entry.get<T>();
+ if (!value)
+ return std::nullopt;
+ values.emplace_back(*value);
+ }
+
+ return values;
}
+};
- return values;
-}
-
-template std::optional<std::vector<bool>> YamlObject::getList<bool>() const;
-template std::optional<std::vector<float>> YamlObject::getList<float>() const;
-template std::optional<std::vector<double>> YamlObject::getList<double>() const;
-template std::optional<std::vector<int8_t>> YamlObject::getList<int8_t>() const;
-template std::optional<std::vector<uint8_t>> YamlObject::getList<uint8_t>() const;
-template std::optional<std::vector<int16_t>> YamlObject::getList<int16_t>() const;
-template std::optional<std::vector<uint16_t>> YamlObject::getList<uint16_t>() const;
-template std::optional<std::vector<int32_t>> YamlObject::getList<int32_t>() const;
-template std::optional<std::vector<uint32_t>> YamlObject::getList<uint32_t>() const;
-template std::optional<std::vector<std::string>> YamlObject::getList<std::string>() const;
-template std::optional<std::vector<Size>> YamlObject::getList<Size>() const;
-
+template struct YamlObject::Accessor<std::vector<bool>>;
+template struct YamlObject::Accessor<std::vector<float>>;
+template struct YamlObject::Accessor<std::vector<double>>;
+template struct YamlObject::Accessor<std::vector<int8_t>>;
+template struct YamlObject::Accessor<std::vector<uint8_t>>;
+template struct YamlObject::Accessor<std::vector<int16_t>>;
+template struct YamlObject::Accessor<std::vector<uint16_t>>;
+template struct YamlObject::Accessor<std::vector<int32_t>>;
+template struct YamlObject::Accessor<std::vector<uint32_t>>;
+template struct YamlObject::Accessor<std::vector<std::string>>;
+template struct YamlObject::Accessor<std::vector<Size>>;
#endif /* __DOXYGEN__ */
/**
@@ -587,9 +587,9 @@ protected:
return TestFail;
}
- const auto &values = firstElement.getList<uint16_t>();
+ const auto &values = firstElement.get<std::vector<uint16_t>>();
if (!values || values->size() != 2 || (*values)[0] != 1 || (*values)[1] != 2) {
- cerr << "getList() failed to return correct vector" << std::endl;
+ cerr << "get() failed to return correct vector" << std::endl;
return TestFail;
}
The YamlObject class has two member function templates to get values: the get() function gets a scalar value, while the getList() function gets a vector of scalar values. As get() is a function template, we can provide specializations for vector types. This makes the code more systematic, and therefore more readable. Replace all getList() occurrences, and drop the getList() function. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> --- include/libcamera/internal/yaml_parser.h | 19 ---- src/ipa/libipa/agc_mean_luminance.cpp | 4 +- src/ipa/libipa/awb_bayes.cpp | 4 +- src/ipa/mali-c55/algorithms/lsc.cpp | 6 +- src/ipa/rkisp1/algorithms/agc.cpp | 2 +- src/ipa/rkisp1/algorithms/dpf.cpp | 6 +- src/ipa/rkisp1/algorithms/gsl.cpp | 8 +- src/ipa/rkisp1/algorithms/lsc.cpp | 4 +- src/ipa/rpi/controller/rpi/agc_channel.cpp | 4 +- src/ipa/rpi/controller/rpi/hdr.cpp | 8 +- src/libcamera/converter/converter_dw100.cpp | 2 +- src/libcamera/global_configuration.cpp | 2 +- .../pipeline/virtual/config_parser.cpp | 2 +- src/libcamera/yaml_parser.cpp | 102 ++++++++---------- test/yaml-parser.cpp | 4 +- 15 files changed, 75 insertions(+), 102 deletions(-)