Message ID | 20230327122030.11756-9-naush@raspberrypi.com |
---|---|
State | Superseded |
Headers | show |
Series |
|
Related | show |
Quoting Naushir Patuck via libcamera-devel (2023-03-27 13:20:28) > Remove any hard-coded assumptions about the target hardware platform > from the AGC algorithm. Instead, use the "target" string provided by > the camera tuning config and generalised statistics structures to > determing parameters such as grid and region sizes. > > This change replaces all hard-coded arrays with equivalent std::vector > types. > > Signed-off-by: Naushir Patuck <naush@raspberrypi.com> > Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > --- > src/ipa/raspberrypi/controller/rpi/agc.cpp | 20 +++++++++++++------- > src/ipa/raspberrypi/controller/rpi/agc.h | 9 +-------- > 2 files changed, 14 insertions(+), 15 deletions(-) > > diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp b/src/ipa/raspberrypi/controller/rpi/agc.cpp > index 4ea0dd41e66c..fb96bb556e84 100644 > --- a/src/ipa/raspberrypi/controller/rpi/agc.cpp > +++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp > @@ -31,17 +31,12 @@ LOG_DEFINE_CATEGORY(RPiAgc) > int AgcMeteringMode::read(const libcamera::YamlObject ¶ms) > { > const YamlObject &yamlWeights = params["weights"]; > - if (yamlWeights.size() != AgcStatsSize) { > - LOG(RPiAgc, Error) << "AgcMeteringMode: Incorrect number of weights"; > - return -EINVAL; > - } > > - unsigned int num = 0; > for (const auto &p : yamlWeights.asList()) { > auto value = p.get<double>(); > if (!value) > return -EINVAL; > - weights[num++] = *value; > + weights.push_back(*value); > } > > return 0; > @@ -249,6 +244,14 @@ int Agc::read(const libcamera::YamlObject ¶ms) > if (ret) > return ret; > > + const Size &size = getHardwareConfig().agcZoneWeights; > + for (auto const &modes : config_.meteringModes) { > + if (modes.second.weights.size() != size.width * size.height) { > + LOG(RPiAgc, Error) << "AgcMeteringMode: Incorrect number of weights"; > + return -EINVAL; > + } > + } > + > /* > * Set the config's defaults (which are the first ones it read) as our > * current modes, until someone changes them. (they're all known to > @@ -582,9 +585,12 @@ void Agc::fetchAwbStatus(Metadata *imageMetadata) > } > > static double computeInitialY(StatisticsPtr &stats, AwbStatus const &awb, > - double weights[], double gain) > + std::vector<double> &weights, double gain) > { > constexpr uint64_t maxVal = 1 << Statistics::NormalisationFactorPow2; > + > + ASSERT(weights.size() == stats->agcRegions.numRegions()); > + > /* > * Note how the calculation below means that equal weights give you > * "average" metering (i.e. all pixels equally important). > diff --git a/src/ipa/raspberrypi/controller/rpi/agc.h b/src/ipa/raspberrypi/controller/rpi/agc.h > index f04896ca25ad..d11a49c9cd85 100644 > --- a/src/ipa/raspberrypi/controller/rpi/agc.h > +++ b/src/ipa/raspberrypi/controller/rpi/agc.h > @@ -17,17 +17,10 @@ > > /* This is our implementation of AGC. */ > > -/* > - * This is the number actually set up by the firmware, not the maximum possible > - * number (which is 16). > - */ > - > -constexpr unsigned int AgcStatsSize = 15; > - > namespace RPiController { > > struct AgcMeteringMode { > - double weights[AgcStatsSize]; > + std::vector<double> weights; > int read(const libcamera::YamlObject ¶ms); > }; > > -- > 2.34.1 >
diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp b/src/ipa/raspberrypi/controller/rpi/agc.cpp index 4ea0dd41e66c..fb96bb556e84 100644 --- a/src/ipa/raspberrypi/controller/rpi/agc.cpp +++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp @@ -31,17 +31,12 @@ LOG_DEFINE_CATEGORY(RPiAgc) int AgcMeteringMode::read(const libcamera::YamlObject ¶ms) { const YamlObject &yamlWeights = params["weights"]; - if (yamlWeights.size() != AgcStatsSize) { - LOG(RPiAgc, Error) << "AgcMeteringMode: Incorrect number of weights"; - return -EINVAL; - } - unsigned int num = 0; for (const auto &p : yamlWeights.asList()) { auto value = p.get<double>(); if (!value) return -EINVAL; - weights[num++] = *value; + weights.push_back(*value); } return 0; @@ -249,6 +244,14 @@ int Agc::read(const libcamera::YamlObject ¶ms) if (ret) return ret; + const Size &size = getHardwareConfig().agcZoneWeights; + for (auto const &modes : config_.meteringModes) { + if (modes.second.weights.size() != size.width * size.height) { + LOG(RPiAgc, Error) << "AgcMeteringMode: Incorrect number of weights"; + return -EINVAL; + } + } + /* * Set the config's defaults (which are the first ones it read) as our * current modes, until someone changes them. (they're all known to @@ -582,9 +585,12 @@ void Agc::fetchAwbStatus(Metadata *imageMetadata) } static double computeInitialY(StatisticsPtr &stats, AwbStatus const &awb, - double weights[], double gain) + std::vector<double> &weights, double gain) { constexpr uint64_t maxVal = 1 << Statistics::NormalisationFactorPow2; + + ASSERT(weights.size() == stats->agcRegions.numRegions()); + /* * Note how the calculation below means that equal weights give you * "average" metering (i.e. all pixels equally important). diff --git a/src/ipa/raspberrypi/controller/rpi/agc.h b/src/ipa/raspberrypi/controller/rpi/agc.h index f04896ca25ad..d11a49c9cd85 100644 --- a/src/ipa/raspberrypi/controller/rpi/agc.h +++ b/src/ipa/raspberrypi/controller/rpi/agc.h @@ -17,17 +17,10 @@ /* This is our implementation of AGC. */ -/* - * This is the number actually set up by the firmware, not the maximum possible - * number (which is 16). - */ - -constexpr unsigned int AgcStatsSize = 15; - namespace RPiController { struct AgcMeteringMode { - double weights[AgcStatsSize]; + std::vector<double> weights; int read(const libcamera::YamlObject ¶ms); };