[libcamera-devel,v3,03/17] ipa: libipa: Provide a common base for FrameContexts
diff mbox series

Message ID 20220818094410.1671-4-jacopo@jmondi.org
State New
Headers show
Series
  • libcamera: Align IPU3 and RKISP1 interfaces
Related show

Commit Message

Jacopo Mondi Aug. 18, 2022, 9:43 a.m. UTC
From: Kieran Bingham via libcamera-devel <libcamera-devel@lists.libcamera.org>

Provide a common IPAFrameContext as a base for IPA modules to inherit
from.

This will allow having a common set of parameters for every FrameContext
required by the FCQueue implementation.

Make both the RKISP1 and the IPU3 define IPA specific FrameContext
structures which inherit from the IPAFrameContext.

While adjusting interface to Algorithm::process() the FrameContext is
converted from a pointer to a reference.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
---
 src/ipa/ipu3/algorithms/af.cpp           |  3 ++-
 src/ipa/ipu3/algorithms/af.h             |  2 +-
 src/ipa/ipu3/algorithms/agc.cpp          |  9 ++++----
 src/ipa/ipu3/algorithms/agc.h            |  4 ++--
 src/ipa/ipu3/algorithms/awb.cpp          |  3 ++-
 src/ipa/ipu3/algorithms/awb.h            |  2 +-
 src/ipa/ipu3/algorithms/tone_mapping.cpp |  3 ++-
 src/ipa/ipu3/algorithms/tone_mapping.h   |  2 +-
 src/ipa/ipu3/ipa_context.cpp             | 26 +++++-------------------
 src/ipa/ipu3/ipa_context.h               |  5 ++---
 src/ipa/ipu3/ipu3.cpp                    |  6 +++---
 src/ipa/ipu3/module.h                    |  2 +-
 src/ipa/libipa/algorithm.h               |  2 +-
 src/ipa/libipa/fc_queue.cpp              | 18 ++++++++++++++++
 src/ipa/libipa/fc_queue.h                |  4 ++++
 src/ipa/rkisp1/algorithms/agc.cpp        |  2 +-
 src/ipa/rkisp1/algorithms/agc.h          |  2 +-
 src/ipa/rkisp1/algorithms/awb.cpp        |  2 +-
 src/ipa/rkisp1/algorithms/awb.h          |  2 +-
 src/ipa/rkisp1/ipa_context.h             |  4 +++-
 src/ipa/rkisp1/module.h                  |  2 +-
 src/ipa/rkisp1/rkisp1.cpp                |  5 ++++-
 22 files changed, 62 insertions(+), 48 deletions(-)

Patch
diff mbox series

diff --git a/src/ipa/ipu3/algorithms/af.cpp b/src/ipa/ipu3/algorithms/af.cpp
index 4835a0345931..e7ed37003217 100644
--- a/src/ipa/ipu3/algorithms/af.cpp
+++ b/src/ipa/ipu3/algorithms/af.cpp
@@ -420,7 +420,8 @@  bool Af::afIsOutOfFocus(IPAContext context)
  *
  * [1] Hill Climbing Algorithm, https://en.wikipedia.org/wiki/Hill_climbing
  */
-void Af::process(IPAContext &context, [[maybe_unused]] IPAFrameContext *frameContext,
+void Af::process(IPAContext &context,
+		 [[maybe_unused]] IPU3FrameContext &frameContext,
 		 const ipu3_uapi_stats_3a *stats)
 {
 	/* Evaluate the AF buffer length */
diff --git a/src/ipa/ipu3/algorithms/af.h b/src/ipa/ipu3/algorithms/af.h
index ccf015f3f8f5..7a5aeb1b6bf4 100644
--- a/src/ipa/ipu3/algorithms/af.h
+++ b/src/ipa/ipu3/algorithms/af.h
@@ -32,7 +32,7 @@  public:
 
 	void prepare(IPAContext &context, ipu3_uapi_params *params) override;
 	int configure(IPAContext &context, const IPAConfigInfo &configInfo) override;
-	void process(IPAContext &context, IPAFrameContext *frameContext,
+	void process(IPAContext &context, IPU3FrameContext &frameContext,
 		     const ipu3_uapi_stats_3a *stats) override;
 
 private:
diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp
index ed4809d98007..57bd8a38d22d 100644
--- a/src/ipa/ipu3/algorithms/agc.cpp
+++ b/src/ipa/ipu3/algorithms/agc.cpp
@@ -183,13 +183,13 @@  utils::Duration Agc::filterExposure(utils::Duration exposureValue)
  * \param[in] yGain The gain calculated based on the relative luminance target
  * \param[in] iqMeanGain The gain calculated based on the relative luminance target
  */
-void Agc::computeExposure(IPAContext &context, IPAFrameContext *frameContext,
+void Agc::computeExposure(IPAContext &context, IPU3FrameContext &frameContext,
 			  double yGain, double iqMeanGain)
 {
 	const IPASessionConfiguration &configuration = context.configuration;
 	/* Get the effective exposure and gain applied on the sensor. */
-	uint32_t exposure = frameContext->sensor.exposure;
-	double analogueGain = frameContext->sensor.gain;
+	uint32_t exposure = frameContext.sensor.exposure;
+	double analogueGain = frameContext.sensor.gain;
 
 	/* Use the highest of the two gain estimates. */
 	double evGain = std::max(yGain, iqMeanGain);
@@ -323,7 +323,8 @@  double Agc::estimateLuminance(IPAActiveState &activeState,
  * Identify the current image brightness, and use that to estimate the optimal
  * new exposure and gain for the scene.
  */
-void Agc::process(IPAContext &context, [[maybe_unused]] IPAFrameContext *frameContext,
+void Agc::process(IPAContext &context,
+		  IPU3FrameContext &frameContext,
 		  const ipu3_uapi_stats_3a *stats)
 {
 	/*
diff --git a/src/ipa/ipu3/algorithms/agc.h b/src/ipa/ipu3/algorithms/agc.h
index 105ae0f2aac6..96585f48933f 100644
--- a/src/ipa/ipu3/algorithms/agc.h
+++ b/src/ipa/ipu3/algorithms/agc.h
@@ -28,14 +28,14 @@  public:
 	~Agc() = default;
 
 	int configure(IPAContext &context, const IPAConfigInfo &configInfo) override;
-	void process(IPAContext &context, IPAFrameContext *frameContext,
+	void process(IPAContext &context, IPU3FrameContext &frameContext,
 		     const ipu3_uapi_stats_3a *stats) override;
 
 private:
 	double measureBrightness(const ipu3_uapi_stats_3a *stats,
 				 const ipu3_uapi_grid_config &grid) const;
 	utils::Duration filterExposure(utils::Duration currentExposure);
-	void computeExposure(IPAContext &context, IPAFrameContext *frameContext,
+	void computeExposure(IPAContext &context, IPU3FrameContext &frameContext,
 			     double yGain, double iqMeanGain);
 	double estimateLuminance(IPAActiveState &activeState,
 				 const ipu3_uapi_grid_config &grid,
diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp
index b658ee546b87..35eafd5ec50e 100644
--- a/src/ipa/ipu3/algorithms/awb.cpp
+++ b/src/ipa/ipu3/algorithms/awb.cpp
@@ -387,7 +387,8 @@  void Awb::calculateWBGains(const ipu3_uapi_stats_3a *stats)
 /**
  * \copydoc libcamera::ipa::Algorithm::process
  */
-void Awb::process(IPAContext &context, [[maybe_unused]] IPAFrameContext *frameContext,
+void Awb::process(IPAContext &context,
+		  [[maybe_unused]] IPU3FrameContext &frameContext,
 		  const ipu3_uapi_stats_3a *stats)
 {
 	calculateWBGains(stats);
diff --git a/src/ipa/ipu3/algorithms/awb.h b/src/ipa/ipu3/algorithms/awb.h
index 0acd21480845..28e39620fd59 100644
--- a/src/ipa/ipu3/algorithms/awb.h
+++ b/src/ipa/ipu3/algorithms/awb.h
@@ -40,7 +40,7 @@  public:
 
 	int configure(IPAContext &context, const IPAConfigInfo &configInfo) override;
 	void prepare(IPAContext &context, ipu3_uapi_params *params) override;
-	void process(IPAContext &context, IPAFrameContext *frameContext,
+	void process(IPAContext &context, IPU3FrameContext &frameContext,
 		     const ipu3_uapi_stats_3a *stats) override;
 
 private:
diff --git a/src/ipa/ipu3/algorithms/tone_mapping.cpp b/src/ipa/ipu3/algorithms/tone_mapping.cpp
index 49a5558b6faa..72627ea1e658 100644
--- a/src/ipa/ipu3/algorithms/tone_mapping.cpp
+++ b/src/ipa/ipu3/algorithms/tone_mapping.cpp
@@ -78,7 +78,8 @@  void ToneMapping::prepare([[maybe_unused]] IPAContext &context,
  * The tone mapping look up table is generated as an inverse power curve from
  * our gamma setting.
  */
-void ToneMapping::process(IPAContext &context, [[maybe_unused]] IPAFrameContext *frameContext,
+void ToneMapping::process(IPAContext &context,
+			  [[maybe_unused]] IPU3FrameContext &frameContext,
 			  [[maybe_unused]] const ipu3_uapi_stats_3a *stats)
 {
 	/*
diff --git a/src/ipa/ipu3/algorithms/tone_mapping.h b/src/ipa/ipu3/algorithms/tone_mapping.h
index d7d4800628f2..8cce38c742a6 100644
--- a/src/ipa/ipu3/algorithms/tone_mapping.h
+++ b/src/ipa/ipu3/algorithms/tone_mapping.h
@@ -20,7 +20,7 @@  public:
 
 	int configure(IPAContext &context, const IPAConfigInfo &configInfo) override;
 	void prepare(IPAContext &context, ipu3_uapi_params *params) override;
-	void process(IPAContext &context, IPAFrameContext *frameContext,
+	void process(IPAContext &context, IPU3FrameContext &frameContext,
 		     const ipu3_uapi_stats_3a *stats) override;
 
 private:
diff --git a/src/ipa/ipu3/ipa_context.cpp b/src/ipa/ipu3/ipa_context.cpp
index dd139cb4c868..536d76ecd63b 100644
--- a/src/ipa/ipu3/ipa_context.cpp
+++ b/src/ipa/ipu3/ipa_context.cpp
@@ -35,22 +35,6 @@  namespace libcamera::ipa::ipu3 {
  * most recently computed by the IPA algorithms.
  */
 
-/**
- * \struct IPAFrameContext
- * \brief Context for a frame
- *
- * The frame context stores data specific to a single frame processed by the
- * IPA. Each frame processed by the IPA has a context associated with it,
- * accessible through the IPAContext structure.
- *
- * Fields in the frame context should reflect values and controls
- * associated with the specific frame as requested by the application, and
- * as configured by the hardware. Fields can be read by algorithms to
- * determine if they should update any specific action for this frame, and
- * finally to update the metadata control lists when the frame is fully
- * completed.
- */
-
 /**
  * \struct IPAContext
  * \brief Global IPA context data shared between all algorithms
@@ -181,16 +165,16 @@  namespace libcamera::ipa::ipu3 {
  */
 
 /**
- * \var IPAFrameContext::frame
- * \brief The frame number
+ * \struct IPU3FrameContext
+ * \copybrief libcamera::ipa::IPAFrameContext
  *
- * \var IPAFrameContext::sensor
+ * \var IPU3FrameContext::sensor
  * \brief Effective sensor values that were applied for the frame
  *
- * \var IPAFrameContext::sensor.exposure
+ * \var IPU3FrameContext::sensor.exposure
  * \brief Exposure time expressed as a number of lines
  *
- * \var IPAFrameContext::sensor.gain
+ * \var IPU3FrameContext::sensor.gain
  * \brief Analogue gain multiplier
  */
 
diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h
index 193fc44a821a..c4aa4c3f4f6a 100644
--- a/src/ipa/ipu3/ipa_context.h
+++ b/src/ipa/ipu3/ipa_context.h
@@ -73,8 +73,7 @@  struct IPAActiveState {
 	} toneMapping;
 };
 
-struct IPAFrameContext {
-	uint32_t frame;
+struct IPU3FrameContext : public IPAFrameContext {
 
 	struct {
 		uint32_t exposure;
@@ -86,7 +85,7 @@  struct IPAContext {
 	IPASessionConfiguration configuration;
 	IPAActiveState activeState;
 
-	FCQueue<IPAFrameContext> frameContexts;
+	FCQueue<IPU3FrameContext> frameContexts;
 };
 
 } /* namespace ipa::ipu3 */
diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
index 5396b0704950..13d7c878a242 100644
--- a/src/ipa/ipu3/ipu3.cpp
+++ b/src/ipa/ipu3/ipu3.cpp
@@ -605,7 +605,7 @@  void IPAIPU3::processStatsBuffer(const uint32_t frame,
 	const ipu3_uapi_stats_3a *stats =
 		reinterpret_cast<ipu3_uapi_stats_3a *>(mem.data());
 
-	IPAFrameContext &frameContext = context_.frameContexts.get(frame);
+	IPU3FrameContext &frameContext = context_.frameContexts.get(frame);
 
 	if (frameContext.frame != frame)
 		LOG(IPAIPU3, Warning) << "Frame " << frame << " does not match its frame context";
@@ -618,7 +618,7 @@  void IPAIPU3::processStatsBuffer(const uint32_t frame,
 	ControlList ctrls(controls::controls);
 
 	for (auto const &algo : algorithms())
-		algo->process(context_, &frameContext, stats);
+		algo->process(context_, frameContext, stats);
 
 	setControls(frame);
 
@@ -654,7 +654,7 @@  void IPAIPU3::processStatsBuffer(const uint32_t frame,
 void IPAIPU3::queueRequest(const uint32_t frame, const ControlList &controls)
 {
 	/* \todo Start processing for 'frame' based on 'controls'. */
-	IPAFrameContext &frameContext = context_.frameContexts.initialise(frame);
+	IPU3FrameContext &frameContext = context_.frameContexts.initialise(frame);
 
 	/* \todo Implement queueRequest to each algorithm. */
 	(void)frameContext;
diff --git a/src/ipa/ipu3/module.h b/src/ipa/ipu3/module.h
index d94fc4594871..6d0d50f615d8 100644
--- a/src/ipa/ipu3/module.h
+++ b/src/ipa/ipu3/module.h
@@ -19,7 +19,7 @@  namespace libcamera {
 
 namespace ipa::ipu3 {
 
-using Module = ipa::Module<IPAContext, IPAFrameContext, IPAConfigInfo,
+using Module = ipa::Module<IPAContext, IPU3FrameContext, IPAConfigInfo,
 			   ipu3_uapi_params, ipu3_uapi_stats_3a>;
 
 } /* namespace ipa::ipu3 */
diff --git a/src/ipa/libipa/algorithm.h b/src/ipa/libipa/algorithm.h
index ccc659a63e3b..0fe3d772963a 100644
--- a/src/ipa/libipa/algorithm.h
+++ b/src/ipa/libipa/algorithm.h
@@ -49,7 +49,7 @@  public:
 	}
 
 	virtual void process([[maybe_unused]] typename Module::Context &context,
-			     [[maybe_unused]] typename Module::FrameContext *frameContext,
+			     [[maybe_unused]] typename Module::FrameContext &frameContext,
 			     [[maybe_unused]] const typename Module::Stats *stats)
 	{
 	}
diff --git a/src/ipa/libipa/fc_queue.cpp b/src/ipa/libipa/fc_queue.cpp
index a69579290043..ed058f1cc648 100644
--- a/src/ipa/libipa/fc_queue.cpp
+++ b/src/ipa/libipa/fc_queue.cpp
@@ -66,6 +66,24 @@  namespace ipa {
  * \todo Set an error flag for per-frame control errors.
  */
 
+/**
+ * \struct IPAFrameContext
+ * \brief Context for a frame
+ *
+ * The frame context stores data specific to a single frame processed by the
+ * IPA. Each frame processed by the IPA has a context associated with it,
+ * accessible through the Frame Context Queue.
+ *
+ * Fields in the frame context should reflect values and controls associated
+ * with the specific frame as requested by the application, and as configured by
+ * the hardware. Fields can be read by algorithms to determine if they should
+ * update any specific action for this frame, and finally to update the metadata
+ * control lists when the frame is fully completed.
+ *
+ * \var IPAFrameContext::frame
+ * \brief The frame number
+ */
+
 /**
  * \fn FCQueue::clear()
  * \brief Clear the context queue
diff --git a/src/ipa/libipa/fc_queue.h b/src/ipa/libipa/fc_queue.h
index 5966817ce673..7f0a1f74938d 100644
--- a/src/ipa/libipa/fc_queue.h
+++ b/src/ipa/libipa/fc_queue.h
@@ -24,6 +24,10 @@  namespace ipa {
  */
 static constexpr uint32_t kMaxFrameContexts = 16;
 
+struct IPAFrameContext {
+	unsigned int frame;
+};
+
 template<typename FrameContext>
 class FCQueue : private std::array<FrameContext, kMaxFrameContexts>
 {
diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp
index 483e941fe427..40d27963ef68 100644
--- a/src/ipa/rkisp1/algorithms/agc.cpp
+++ b/src/ipa/rkisp1/algorithms/agc.cpp
@@ -281,7 +281,7 @@  double Agc::measureBrightness(const rkisp1_cif_isp_hist_stat *hist) const
  * new exposure and gain for the scene.
  */
 void Agc::process(IPAContext &context,
-		  [[maybe_unused]] IPAFrameContext *frameContext,
+		  [[maybe_unused]] RKISP1FrameContext &frameContext,
 		  const rkisp1_stat_buffer *stats)
 {
 	const rkisp1_cif_isp_stat *params = &stats->params;
diff --git a/src/ipa/rkisp1/algorithms/agc.h b/src/ipa/rkisp1/algorithms/agc.h
index 1c9818b7db2a..af7fe2740908 100644
--- a/src/ipa/rkisp1/algorithms/agc.h
+++ b/src/ipa/rkisp1/algorithms/agc.h
@@ -27,7 +27,7 @@  public:
 
 	int configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override;
 	void prepare(IPAContext &context, rkisp1_params_cfg *params) override;
-	void process(IPAContext &context, IPAFrameContext *frameContext,
+	void process(IPAContext &context, RKISP1FrameContext &frameContext,
 		     const rkisp1_stat_buffer *stats) override;
 
 private:
diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp
index 427aaeb1e955..3beafb73ca33 100644
--- a/src/ipa/rkisp1/algorithms/awb.cpp
+++ b/src/ipa/rkisp1/algorithms/awb.cpp
@@ -120,7 +120,7 @@  void Awb::prepare(IPAContext &context, rkisp1_params_cfg *params)
  * \copydoc libcamera::ipa::Algorithm::process
  */
 void Awb::process([[maybe_unused]] IPAContext &context,
-		  [[maybe_unused]] IPAFrameContext *frameCtx,
+		  [[maybe_unused]] RKISP1FrameContext &frameCtx,
 		  const rkisp1_stat_buffer *stats)
 {
 	const rkisp1_cif_isp_stat *params = &stats->params;
diff --git a/src/ipa/rkisp1/algorithms/awb.h b/src/ipa/rkisp1/algorithms/awb.h
index 667a8beb7689..5954034b8142 100644
--- a/src/ipa/rkisp1/algorithms/awb.h
+++ b/src/ipa/rkisp1/algorithms/awb.h
@@ -21,7 +21,7 @@  public:
 
 	int configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override;
 	void prepare(IPAContext &context, rkisp1_params_cfg *params) override;
-	void process(IPAContext &context, IPAFrameContext *frameCtx,
+	void process(IPAContext &context, RKISP1FrameContext &frameCtx,
 		     const rkisp1_stat_buffer *stats) override;
 
 private:
diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h
index a8daeca487ae..c42bcd73b314 100644
--- a/src/ipa/rkisp1/ipa_context.h
+++ b/src/ipa/rkisp1/ipa_context.h
@@ -14,6 +14,8 @@ 
 
 #include <libcamera/geometry.h>
 
+#include <libipa/fc_queue.h>
+
 namespace libcamera {
 
 namespace ipa::rkisp1 {
@@ -78,7 +80,7 @@  struct IPAActiveState {
 	unsigned int frameCount;
 };
 
-struct IPAFrameContext {
+struct RKISP1FrameContext : public IPAFrameContext {
 };
 
 struct IPAContext {
diff --git a/src/ipa/rkisp1/module.h b/src/ipa/rkisp1/module.h
index 89f83208a75c..2568c624df0f 100644
--- a/src/ipa/rkisp1/module.h
+++ b/src/ipa/rkisp1/module.h
@@ -19,7 +19,7 @@  namespace libcamera {
 
 namespace ipa::rkisp1 {
 
-using Module = ipa::Module<IPAContext, IPAFrameContext, IPACameraSensorInfo,
+using Module = ipa::Module<IPAContext, RKISP1FrameContext, IPACameraSensorInfo,
 			   rkisp1_params_cfg, rkisp1_stat_buffer>;
 
 } /* namespace ipa::rkisp1 */
diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
index 88e6a2b23eed..c3aa49329693 100644
--- a/src/ipa/rkisp1/rkisp1.cpp
+++ b/src/ipa/rkisp1/rkisp1.cpp
@@ -323,8 +323,11 @@  void IPARkISP1::processStatsBuffer(const uint32_t frame, const uint32_t bufferId
 
 	unsigned int aeState = 0;
 
+	/* \todo Obtain the frame context to pass to process from the FCQueue */
+	RKISP1FrameContext frameContext;
+
 	for (auto const &algo : algorithms())
-		algo->process(context_, nullptr, stats);
+		algo->process(context_, frameContext, stats);
 
 	setControls(frame);