ipa: ipu3: awb: Use the line stride for the stats

The statistics buffer 'ipu3_uapi_awb_raw_buffer' stores the ImgU
calculation results in a buffer aligned horizontally to a multiple of 4
cells. The AWB loop should take care of it to add the proper offset
between lines and avoid any staircase effect.

It is no longer required to pass the grid configuration context to the
private functions called from process() which simplifies the code flow.

Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
Jean-Michel Hautbois 2021-09-22 17:44:01 +02:00
parent 03132d0ff9
commit 380b08754f
4 changed files with 16 additions and 11 deletions

View file

@ -176,6 +176,7 @@ int Awb::configure(IPAContext &context,
[[maybe_unused]] const IPAConfigInfo &configInfo) [[maybe_unused]] const IPAConfigInfo &configInfo)
{ {
const ipu3_uapi_grid_config &grid = context.configuration.grid.bdsGrid; const ipu3_uapi_grid_config &grid = context.configuration.grid.bdsGrid;
stride_ = context.configuration.grid.stride;
cellsPerZoneX_ = std::round(grid.width / static_cast<double>(kAwbStatsSizeX)); cellsPerZoneX_ = std::round(grid.width / static_cast<double>(kAwbStatsSizeX));
cellsPerZoneY_ = std::round(grid.height / static_cast<double>(kAwbStatsSizeY)); cellsPerZoneY_ = std::round(grid.height / static_cast<double>(kAwbStatsSizeY));
@ -238,8 +239,7 @@ void Awb::generateZones(std::vector<RGB> &zones)
} }
/* Translate the IPU3 statistics into the default statistics zone array */ /* Translate the IPU3 statistics into the default statistics zone array */
void Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats, void Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats)
const ipu3_uapi_grid_config &grid)
{ {
/* /*
* Generate a (kAwbStatsSizeX x kAwbStatsSizeY) array from the IPU3 grid which is * Generate a (kAwbStatsSizeX x kAwbStatsSizeY) array from the IPU3 grid which is
@ -247,7 +247,7 @@ void Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats,
*/ */
for (unsigned int cellY = 0; cellY < kAwbStatsSizeY * cellsPerZoneY_; cellY++) { for (unsigned int cellY = 0; cellY < kAwbStatsSizeY * cellsPerZoneY_; cellY++) {
for (unsigned int cellX = 0; cellX < kAwbStatsSizeX * cellsPerZoneX_; cellX++) { for (unsigned int cellX = 0; cellX < kAwbStatsSizeX * cellsPerZoneX_; cellX++) {
uint32_t cellPosition = (cellY * grid.width + cellX) uint32_t cellPosition = (cellY * stride_ + cellX)
* sizeof(Ipu3AwbCell); * sizeof(Ipu3AwbCell);
uint32_t zoneX = cellX / cellsPerZoneX_; uint32_t zoneX = cellX / cellsPerZoneX_;
uint32_t zoneY = cellY / cellsPerZoneY_; uint32_t zoneY = cellY / cellsPerZoneY_;
@ -322,13 +322,12 @@ void Awb::awbGreyWorld()
asyncResults_.blueGain = blueGain; asyncResults_.blueGain = blueGain;
} }
void Awb::calculateWBGains(const ipu3_uapi_stats_3a *stats, void Awb::calculateWBGains(const ipu3_uapi_stats_3a *stats)
const ipu3_uapi_grid_config &grid)
{ {
ASSERT(stats->stats_3a_status.awb_en); ASSERT(stats->stats_3a_status.awb_en);
zones_.clear(); zones_.clear();
clearAwbStats(); clearAwbStats();
generateAwbStats(stats, grid); generateAwbStats(stats);
generateZones(zones_); generateZones(zones_);
LOG(IPU3Awb, Debug) << "Valid zones: " << zones_.size(); LOG(IPU3Awb, Debug) << "Valid zones: " << zones_.size();
if (zones_.size() > 10) { if (zones_.size() > 10) {
@ -340,7 +339,7 @@ void Awb::calculateWBGains(const ipu3_uapi_stats_3a *stats,
void Awb::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) void Awb::process(IPAContext &context, const ipu3_uapi_stats_3a *stats)
{ {
calculateWBGains(stats, context.configuration.grid.bdsGrid); calculateWBGains(stats);
/* /*
* Gains are only recalculated if enough zones were detected. * Gains are only recalculated if enough zones were detected.

View file

@ -74,11 +74,9 @@ public:
}; };
private: private:
void calculateWBGains(const ipu3_uapi_stats_3a *stats, void calculateWBGains(const ipu3_uapi_stats_3a *stats);
const ipu3_uapi_grid_config &grid);
void generateZones(std::vector<RGB> &zones); void generateZones(std::vector<RGB> &zones);
void generateAwbStats(const ipu3_uapi_stats_3a *stats, void generateAwbStats(const ipu3_uapi_stats_3a *stats);
const ipu3_uapi_grid_config &grid);
void clearAwbStats(); void clearAwbStats();
void awbGreyWorld(); void awbGreyWorld();
uint32_t estimateCCT(double red, double green, double blue); uint32_t estimateCCT(double red, double green, double blue);
@ -87,6 +85,7 @@ private:
Accumulator awbStats_[kAwbStatsSizeX * kAwbStatsSizeY]; Accumulator awbStats_[kAwbStatsSizeX * kAwbStatsSizeY];
AwbStatus asyncResults_; AwbStatus asyncResults_;
uint32_t stride_;
uint32_t cellsPerZoneX_; uint32_t cellsPerZoneX_;
uint32_t cellsPerZoneY_; uint32_t cellsPerZoneY_;
uint32_t cellsPerZoneThreshold_; uint32_t cellsPerZoneThreshold_;

View file

@ -20,6 +20,7 @@ struct IPASessionConfiguration {
struct { struct {
ipu3_uapi_grid_config bdsGrid; ipu3_uapi_grid_config bdsGrid;
Size bdsOutputSize; Size bdsOutputSize;
uint32_t stride;
} grid; } grid;
}; };

View file

@ -91,6 +91,9 @@
* *
* \var IPASessionConfiguration::grid::bdsOutputSize * \var IPASessionConfiguration::grid::bdsOutputSize
* \brief BDS output size configured by the pipeline handler * \brief BDS output size configured by the pipeline handler
*
* \var IPASessionConfiguration::grid::stride
* \brief Number of cells on one line including the ImgU padding
*/ */
/** /**
@ -352,6 +355,9 @@ void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize)
bdsGrid.height = best.height >> bestLog2.height; bdsGrid.height = best.height >> bestLog2.height;
bdsGrid.block_height_log2 = bestLog2.height; bdsGrid.block_height_log2 = bestLog2.height;
/* The ImgU pads the lines to a multiple of 4 cells. */
context_.configuration.grid.stride = utils::alignUp(bdsGrid.width, 4);
LOG(IPAIPU3, Debug) << "Best grid found is: (" LOG(IPAIPU3, Debug) << "Best grid found is: ("
<< (int)bdsGrid.width << " << " << (int)bdsGrid.block_width_log2 << ") x (" << (int)bdsGrid.width << " << " << (int)bdsGrid.block_width_log2 << ") x ("
<< (int)bdsGrid.height << " << " << (int)bdsGrid.block_height_log2 << ")"; << (int)bdsGrid.height << " << " << (int)bdsGrid.block_height_log2 << ")";