[libcamera-devel] [PATCH v4 9/9] ipa: ipu3: Move IPU3 agc into algorithms

Jean-Michel Hautbois jeanmichel.hautbois at ideasonboard.com
Thu Aug 19 16:57:59 CEST 2021


Now that the interface is properly used by the AGC class, move it into
ipa::ipu3::algorithms and let the loops do the calls.
As we need to exchange the exposure_ and gain_ by passing them through the
FrameContext, use the calculated values in setControls() function to
ease the reading.

Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 .../ipu3/{ipu3_agc.cpp => algorithms/agc.cpp} | 18 ++++++++---------
 src/ipa/ipu3/{ipu3_agc.h => algorithms/agc.h} | 20 +++++++++----------
 src/ipa/ipu3/algorithms/meson.build           |  1 +
 src/ipa/ipu3/ipu3.cpp                         | 20 ++++++++-----------
 src/ipa/ipu3/meson.build                      |  1 -
 5 files changed, 28 insertions(+), 32 deletions(-)
 rename src/ipa/ipu3/{ipu3_agc.cpp => algorithms/agc.cpp} (94%)
 rename src/ipa/ipu3/{ipu3_agc.h => algorithms/agc.h} (73%)

diff --git a/src/ipa/ipu3/ipu3_agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp
similarity index 94%
rename from src/ipa/ipu3/ipu3_agc.cpp
rename to src/ipa/ipu3/algorithms/agc.cpp
index 30888e10..db333509 100644
--- a/src/ipa/ipu3/ipu3_agc.cpp
+++ b/src/ipa/ipu3/algorithms/agc.cpp
@@ -5,7 +5,7 @@
  * ipu3_agc.cpp - AGC/AEC control algorithm
  */
 
-#include "ipu3_agc.h"
+#include "agc.h"
 
 #include <algorithm>
 #include <chrono>
@@ -21,7 +21,7 @@ namespace libcamera {
 
 using namespace std::literals::chrono_literals;
 
-namespace ipa::ipu3 {
+namespace ipa::ipu3::algorithms {
 
 LOG_DEFINE_CATEGORY(IPU3Agc)
 
@@ -50,14 +50,14 @@ static constexpr double kEvGainTarget = 0.5;
 /* A cell is 8 bytes and contains averages for RGB values and saturation ratio */
 static constexpr uint8_t kCellSize = 8;
 
-IPU3Agc::IPU3Agc()
+Agc::Agc()
 	: frameCount_(0), lastFrame_(0), iqMean_(0.0), lineDuration_(0s),
 	  maxExposureTime_(0s), prevExposure_(0s), prevExposureNoDg_(0s),
 	  currentExposure_(0s), currentExposureNoDg_(0s)
 {
 }
 
-int IPU3Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo)
+int Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo)
 {
 	aeGrid_ = context.configuration.grid.bdsGrid;
 
@@ -68,7 +68,7 @@ int IPU3Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo)
 	return 0;
 }
 
-void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats)
+void Agc::processBrightness(const ipu3_uapi_stats_3a *stats)
 {
 	const struct ipu3_uapi_grid_config statsAeGrid = stats->stats_4a_config.awb_config.grid;
 	Rectangle aeRegion = { statsAeGrid.x_start,
@@ -109,7 +109,7 @@ void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats)
 	iqMean_ = Histogram(Span<uint32_t>(hist)).interQuantileMean(0.98, 1.0);
 }
 
-void IPU3Agc::filterExposure()
+void Agc::filterExposure()
 {
 	double speed = 0.2;
 	if (prevExposure_ == 0s) {
@@ -143,7 +143,7 @@ void IPU3Agc::filterExposure()
 	LOG(IPU3Agc, Debug) << "After filtering, total_exposure " << prevExposure_;
 }
 
-void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain)
+void Agc::lockExposureGain(uint32_t &exposure, double &gain)
 {
 	/* Algorithm initialization should wait for first valid frames */
 	/* \todo - have a number of frames given by DelayedControls ?
@@ -186,7 +186,7 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain)
 	lastFrame_ = frameCount_;
 }
 
-void IPU3Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *&stats)
+void Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *&stats)
 {
 	uint32_t &exposure = context.frameContext.agc.exposure;
 	double &gain = context.frameContext.agc.gain;
@@ -195,6 +195,6 @@ void IPU3Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *&stats)
 	frameCount_++;
 }
 
-} /* namespace ipa::ipu3 */
+} /* namespace ipa::ipu3::algorithms */
 
 } /* namespace libcamera */
diff --git a/src/ipa/ipu3/ipu3_agc.h b/src/ipa/ipu3/algorithms/agc.h
similarity index 73%
rename from src/ipa/ipu3/ipu3_agc.h
rename to src/ipa/ipu3/algorithms/agc.h
index 0bd70021..80ce5fa5 100644
--- a/src/ipa/ipu3/ipu3_agc.h
+++ b/src/ipa/ipu3/algorithms/agc.h
@@ -2,10 +2,10 @@
 /*
  * Copyright (C) 2021, Ideas On Board
  *
- * ipu3_agc.h - IPU3 AGC/AEC control algorithm
+ * agc.h - IPU3 AGC/AEC control algorithm
  */
-#ifndef __LIBCAMERA_IPU3_AGC_H__
-#define __LIBCAMERA_IPU3_AGC_H__
+#ifndef __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__
+#define __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__
 
 #include <linux/intel-ipu3.h>
 
@@ -13,21 +13,21 @@
 
 #include <libcamera/geometry.h>
 
-#include "algorithms/algorithm.h"
+#include "algorithm.h"
 
 namespace libcamera {
 
 struct IPACameraSensorInfo;
 
-namespace ipa::ipu3 {
+namespace ipa::ipu3::algorithms {
 
 using utils::Duration;
 
-class IPU3Agc : public Algorithm
+class Agc : public Algorithm
 {
 public:
-	IPU3Agc();
-	~IPU3Agc() = default;
+	Agc();
+	~Agc() = default;
 
 	int configure(IPAContext &context, const IPAConfigInfo &configInfo) override;
 	void process(IPAContext &context, const ipu3_uapi_stats_3a *&stats) override;
@@ -53,8 +53,8 @@ private:
 	Duration currentExposureNoDg_;
 };
 
-} /* namespace ipa::ipu3 */
+} /* namespace ipa::ipu3::algorithms */
 
 } /* namespace libcamera */
 
-#endif /* __LIBCAMERA_IPU3_AGC_H__ */
+#endif /* __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__ */
diff --git a/src/ipa/ipu3/algorithms/meson.build b/src/ipa/ipu3/algorithms/meson.build
index fa004df4..deae225b 100644
--- a/src/ipa/ipu3/algorithms/meson.build
+++ b/src/ipa/ipu3/algorithms/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: CC0-1.0
 
 ipu3_ipa_algorithms = files([
+    'agc.cpp',
     'algorithm.cpp',
     'awb.cpp',
     'tone_mapping.cpp',
diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
index c124ce31..822959fe 100644
--- a/src/ipa/ipu3/ipu3.cpp
+++ b/src/ipa/ipu3/ipu3.cpp
@@ -29,10 +29,10 @@
 
 #include "libcamera/internal/mapped_framebuffer.h"
 
+#include "algorithms/agc.h"
 #include "algorithms/algorithm.h"
 #include "algorithms/awb.h"
 #include "algorithms/tone_mapping.h"
-#include "ipu3_agc.h"
 #include "libipa/camera_sensor_helper.h"
 
 static constexpr uint32_t kMaxCellWidthPerSet = 160;
@@ -187,8 +187,6 @@ private:
 	uint32_t minGain_;
 	uint32_t maxGain_;
 
-	/* Interface to the AEC/AGC algorithm */
-	std::unique_ptr<IPU3Agc> agcAlgo_;
 	/* Interface to the Camera Helper */
 	std::unique_ptr<CameraSensorHelper> camHelper_;
 
@@ -269,6 +267,7 @@ int IPAIPU3::init(const IPASettings &settings,
 	*ipaControls = ControlInfoMap(std::move(controls), controls::controls);
 
 	/* Construct our Algorithms */
+	algorithms_.push_back(std::make_unique<algorithms::Agc>());
 	algorithms_.push_back(std::make_unique<algorithms::Awb>());
 	algorithms_.push_back(std::make_unique<algorithms::ToneMapping>());
 
@@ -388,9 +387,6 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo)
 			return ret;
 	}
 
-	agcAlgo_ = std::make_unique<IPU3Agc>();
-	agcAlgo_->configure(context_, configInfo);
-
 	return 0;
 }
 
@@ -480,15 +476,12 @@ void IPAIPU3::parseStatistics(unsigned int frame,
 {
 	ControlList ctrls(controls::controls);
 
-	for (auto const &algo : algorithms_)
-		algo->process(context_, stats);
-
 	/* \todo These fields should not be written by the IPAIPU3 layer */
 	context_.frameContext.agc.gain = camHelper_->gain(gain_);
 	context_.frameContext.agc.exposure = exposure_;
-	agcAlgo_->process(context_, stats);
-	exposure_ = context_.frameContext.agc.exposure;
-	gain_ = camHelper_->gainCode(context_.frameContext.agc.gain);
+
+	for (auto const &algo : algorithms_)
+		algo->process(context_, stats);
 
 	setControls(frame);
 
@@ -509,6 +502,9 @@ void IPAIPU3::setControls(unsigned int frame)
 	IPU3Action op;
 	op.op = ActionSetSensorControls;
 
+	exposure_ = context_.frameContext.agc.exposure;
+	gain_ = camHelper_->gainCode(context_.frameContext.agc.gain);
+
 	ControlList ctrls(ctrls_);
 	ctrls.set(V4L2_CID_EXPOSURE, static_cast<int32_t>(exposure_));
 	ctrls.set(V4L2_CID_ANALOGUE_GAIN, static_cast<int32_t>(gain_));
diff --git a/src/ipa/ipu3/meson.build b/src/ipa/ipu3/meson.build
index d1126947..39320980 100644
--- a/src/ipa/ipu3/meson.build
+++ b/src/ipa/ipu3/meson.build
@@ -6,7 +6,6 @@ ipa_name = 'ipa_ipu3'
 
 ipu3_ipa_sources = files([
     'ipu3.cpp',
-    'ipu3_agc.cpp',
 ])
 
 ipu3_ipa_sources += ipu3_ipa_algorithms
-- 
2.30.2



More information about the libcamera-devel mailing list