[libcamera-devel] [PATCH v2 09/12] ipa: ipu3: awb: Use the line stride for the stats

Jean-Michel Hautbois jeanmichel.hautbois at ideasonboard.com
Thu Sep 30 11:37:12 CEST 2021


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 now no more 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 at ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
---
 src/ipa/ipu3/algorithms/awb.cpp | 13 ++++++-------
 src/ipa/ipu3/algorithms/awb.h   |  7 +++----
 src/ipa/ipu3/ipa_context.h      |  1 +
 src/ipa/ipu3/ipu3.cpp           |  3 +++
 4 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp
index c1ff9450..fcd1469f 100644
--- a/src/ipa/ipu3/algorithms/awb.cpp
+++ b/src/ipa/ipu3/algorithms/awb.cpp
@@ -172,6 +172,7 @@ int Awb::configure(IPAContext &context,
 		   [[maybe_unused]] const IPAConfigInfo &configInfo)
 {
 	const ipu3_uapi_grid_config &grid = context.configuration.grid.bdsGrid;
+	stride_ = context.configuration.grid.stride;
 
 	cellsPerZoneX_ = std::round(grid.width / static_cast<double>(kAwbStatsSizeX));
 	cellsPerZoneY_ = std::round(grid.height / static_cast<double>(kAwbStatsSizeY));
@@ -234,8 +235,7 @@ void Awb::generateZones(std::vector<RGB> &zones)
 }
 
 /* Translate the IPU3 statistics into the default statistics zone array */
-void Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats,
-			   const ipu3_uapi_grid_config &grid)
+void Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats)
 {
 	/*
 	 * Generate a (kAwbStatsSizeX x kAwbStatsSizeY) array from the IPU3 grid which is
@@ -243,7 +243,7 @@ void Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats,
 	 */
 	for (unsigned int cellY = 0; cellY < kAwbStatsSizeY * cellsPerZoneY_; cellY++) {
 		for (unsigned int cellX = 0; cellX < kAwbStatsSizeX * cellsPerZoneX_; cellX++) {
-			uint32_t cellPosition = (cellY * grid.width + cellX)
+			uint32_t cellPosition = (cellY * stride_ + cellX)
 					      * sizeof(Ipu3AwbCell);
 			uint32_t zoneX = cellX / cellsPerZoneX_;
 			uint32_t zoneY = cellY / cellsPerZoneY_;
@@ -318,13 +318,12 @@ void Awb::awbGreyWorld()
 	asyncResults_.blueGain = blueGain;
 }
 
-void Awb::calculateWBGains(const ipu3_uapi_stats_3a *stats,
-			   const ipu3_uapi_grid_config &grid)
+void Awb::calculateWBGains(const ipu3_uapi_stats_3a *stats)
 {
 	ASSERT(stats->stats_3a_status.awb_en);
 	zones_.clear();
 	clearAwbStats();
-	generateAwbStats(stats, grid);
+	generateAwbStats(stats);
 	generateZones(zones_);
 	LOG(IPU3Awb, Debug) << "Valid zones: " << zones_.size();
 	if (zones_.size() > 10) {
@@ -336,7 +335,7 @@ void Awb::calculateWBGains(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.
diff --git a/src/ipa/ipu3/algorithms/awb.h b/src/ipa/ipu3/algorithms/awb.h
index 681d8c2b..b3e0ad82 100644
--- a/src/ipa/ipu3/algorithms/awb.h
+++ b/src/ipa/ipu3/algorithms/awb.h
@@ -74,11 +74,9 @@ public:
 	};
 
 private:
-	void calculateWBGains(const ipu3_uapi_stats_3a *stats,
-			      const ipu3_uapi_grid_config &grid);
+	void calculateWBGains(const ipu3_uapi_stats_3a *stats);
 	void generateZones(std::vector<RGB> &zones);
-	void generateAwbStats(const ipu3_uapi_stats_3a *stats,
-			      const ipu3_uapi_grid_config &grid);
+	void generateAwbStats(const ipu3_uapi_stats_3a *stats);
 	void clearAwbStats();
 	void awbGreyWorld();
 	uint32_t estimateCCT(double red, double green, double blue);
@@ -87,6 +85,7 @@ private:
 	Accumulator awbStats_[kAwbStatsSizeX * kAwbStatsSizeY];
 	AwbStatus asyncResults_;
 
+	uint32_t stride_;
 	uint32_t cellsPerZoneX_;
 	uint32_t cellsPerZoneY_;
 	uint32_t cellsPerZoneThreshold_;
diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h
index 9d9444dc..5bab684c 100644
--- a/src/ipa/ipu3/ipa_context.h
+++ b/src/ipa/ipu3/ipa_context.h
@@ -20,6 +20,7 @@ struct IPASessionConfiguration {
 	struct {
 		ipu3_uapi_grid_config bdsGrid;
 		Size bdsOutputSize;
+		uint32_t stride;
 	} grid;
 };
 
diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
index 757a5d50..b33e8c77 100644
--- a/src/ipa/ipu3/ipu3.cpp
+++ b/src/ipa/ipu3/ipu3.cpp
@@ -352,6 +352,9 @@ void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize)
 	bdsGrid.height = best.height >> bestLog2.height;
 	bdsGrid.block_height_log2 = bestLog2.height;
 
+	/* The grid width is aligned to the next multiple of 4 */
+	context_.configuration.grid.stride = utils::alignUp(bdsGrid.width, 4);
+
 	LOG(IPAIPU3, Debug) << "Best grid found is: ("
 			    << (int)bdsGrid.width << " << " << (int)bdsGrid.block_width_log2 << ") x ("
 			    << (int)bdsGrid.height << " << " << (int)bdsGrid.block_height_log2 << ")";
-- 
2.30.2



More information about the libcamera-devel mailing list