ipa: raspberrypi: Add hardware configuration to the controller

Add a new Controller::HardwareConfig structure that captures the
hardware statistics grid/histogram sizes and pipeline widths. This
ensures there is a single centralised places for these parameters.

Add a getHardwareConfig() helper function to retrieve these values for a
given hardware target.

Update the statistics populating routine in the IPA to use the values
from this structure instead of the hardcoded numbers.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Naushir Patuck 2023-03-27 13:20:22 +01:00 committed by Kieran Bingham
parent cf6df17958
commit f6cc78b446
4 changed files with 54 additions and 13 deletions

View file

@ -45,6 +45,10 @@ public:
{ {
return controller_->getTarget(); return controller_->getTarget();
} }
const Controller::HardwareConfig &getHardwareConfig() const
{
return controller_->getHardwareConfig();
}
private: private:
Controller *controller_; Controller *controller_;

View file

@ -20,6 +20,25 @@ using namespace libcamera;
LOG_DEFINE_CATEGORY(RPiController) LOG_DEFINE_CATEGORY(RPiController)
static const std::map<std::string, Controller::HardwareConfig> HardwareConfigMap = {
{
"bcm2835",
{
/*
* There are only ever 15 AGC regions computed by the firmware
* due to zoning, but the HW defines AGC_REGIONS == 16!
*/
.agcRegions = { 15 , 1 },
.agcZoneWeights = { 15 , 1 },
.awbRegions = { 16, 12 },
.focusRegions = { 4, 3 },
.numHistogramBins = 128,
.numGammaPoints = 33,
.pipelineWidth = 13
}
},
};
Controller::Controller() Controller::Controller()
: switchModeCalled_(false) : switchModeCalled_(false)
{ {
@ -148,3 +167,15 @@ const std::string &Controller::getTarget() const
{ {
return target_; return target_;
} }
const Controller::HardwareConfig &Controller::getHardwareConfig() const
{
auto cfg = HardwareConfigMap.find(getTarget());
/*
* This really should not happen, the IPA ought to validate the target
* on initialisation.
*/
ASSERT(cfg != HardwareConfigMap.end());
return cfg->second;
}

View file

@ -37,6 +37,16 @@ typedef std::unique_ptr<Algorithm> AlgorithmPtr;
class Controller class Controller
{ {
public: public:
struct HardwareConfig {
libcamera::Size agcRegions;
libcamera::Size agcZoneWeights;
libcamera::Size awbRegions;
libcamera::Size focusRegions;
unsigned int numHistogramBins;
unsigned int numGammaPoints;
unsigned int pipelineWidth;
};
Controller(); Controller();
~Controller(); ~Controller();
int read(char const *filename); int read(char const *filename);
@ -47,6 +57,7 @@ public:
Metadata &getGlobalMetadata(); Metadata &getGlobalMetadata();
Algorithm *getAlgorithm(std::string const &name) const; Algorithm *getAlgorithm(std::string const &name) const;
const std::string &getTarget() const; const std::string &getTarget() const;
const HardwareConfig &getHardwareConfig() const;
protected: protected:
int createAlgorithm(const std::string &name, const libcamera::YamlObject &params); int createAlgorithm(const std::string &name, const libcamera::YamlObject &params);

View file

@ -1394,20 +1394,19 @@ RPiController::StatisticsPtr IPARPi::fillStatistics(bcm2835_isp_stats *stats) co
{ {
using namespace RPiController; using namespace RPiController;
const Controller::HardwareConfig &hw = controller_.getHardwareConfig();
unsigned int i; unsigned int i;
StatisticsPtr statistics = StatisticsPtr statistics =
std::make_unique<Statistics>(Statistics::AgcStatsPos::PreWb, Statistics::ColourStatsPos::PostLsc); std::make_unique<Statistics>(Statistics::AgcStatsPos::PreWb, Statistics::ColourStatsPos::PostLsc);
/* RGB histograms are not used, so do not populate them. */ /* RGB histograms are not used, so do not populate them. */
statistics->yHist = RPiController::Histogram(stats->hist[0].g_hist, NUM_HISTOGRAM_BINS); statistics->yHist = RPiController::Histogram(stats->hist[0].g_hist,
hw.numHistogramBins);
/* /* All region sums are based on a 16-bit normalised pipeline bit-depth. */
* All region sums are based on a 13-bit pipeline bit-depth. Normalise unsigned int scale = Statistics::NormalisationFactorPow2 - hw.pipelineWidth;
* this to 16-bits for the AGC/AWB/ALSC algorithms.
*/
constexpr unsigned int scale = Statistics::NormalisationFactorPow2 - 13;
statistics->awbRegions.init({ DEFAULT_AWB_REGIONS_X, DEFAULT_AWB_REGIONS_Y }); statistics->awbRegions.init(hw.awbRegions);
for (i = 0; i < statistics->awbRegions.numRegions(); i++) for (i = 0; i < statistics->awbRegions.numRegions(); i++)
statistics->awbRegions.set(i, { { stats->awb_stats[i].r_sum << scale, statistics->awbRegions.set(i, { { stats->awb_stats[i].r_sum << scale,
stats->awb_stats[i].g_sum << scale, stats->awb_stats[i].g_sum << scale,
@ -1415,11 +1414,7 @@ RPiController::StatisticsPtr IPARPi::fillStatistics(bcm2835_isp_stats *stats) co
stats->awb_stats[i].counted, stats->awb_stats[i].counted,
stats->awb_stats[i].notcounted }); stats->awb_stats[i].notcounted });
/* statistics->agcRegions.init(hw.agcRegions);
* There are only ever 15 regions computed by the firmware due to zoning,
* but the HW defines AGC_REGIONS == 16!
*/
statistics->agcRegions.init(15);
for (i = 0; i < statistics->agcRegions.numRegions(); i++) for (i = 0; i < statistics->agcRegions.numRegions(); i++)
statistics->agcRegions.set(i, { { stats->agc_stats[i].r_sum << scale, statistics->agcRegions.set(i, { { stats->agc_stats[i].r_sum << scale,
stats->agc_stats[i].g_sum << scale, stats->agc_stats[i].g_sum << scale,
@ -1427,7 +1422,7 @@ RPiController::StatisticsPtr IPARPi::fillStatistics(bcm2835_isp_stats *stats) co
stats->agc_stats[i].counted, stats->agc_stats[i].counted,
stats->awb_stats[i].notcounted }); stats->awb_stats[i].notcounted });
statistics->focusRegions.init({ 4, 3 }); statistics->focusRegions.init(hw.focusRegions);
for (i = 0; i < statistics->focusRegions.numRegions(); i++) for (i = 0; i < statistics->focusRegions.numRegions(); i++)
statistics->focusRegions.set(i, { stats->focus_stats[i].contrast_val[1][1] / 1000, statistics->focusRegions.set(i, { stats->focus_stats[i].contrast_val[1][1] / 1000,
stats->focus_stats[i].contrast_val_num[1][1], stats->focus_stats[i].contrast_val_num[1][1],