[RFC,v1] ipa: rkisp1: Allow algorithms to update `ControlInfoMap`
diff mbox series

Message ID 20251215115348.626656-1-barnabas.pocze@ideasonboard.com
State New
Headers show
Series
  • [RFC,v1] ipa: rkisp1: Allow algorithms to update `ControlInfoMap`
Related show

Commit Message

Barnabás Pőcze Dec. 15, 2025, 11:53 a.m. UTC
In `IPARkISP1::init()`, the `ControlInfoMap` that will be returned
to the pipeline handler is updated after creating the algorithms;
naturally, since otherwise no algorithm could register its own controls.

However, in `IPARkISP1::configure()`, the update is done before the
algorithms are configured. This is not ideal because this prevents
algorithms from correctly updating e.g. the `ControlInfo`s of their
controls.

While no algorithm is affected today, during development, it is useful
for various debug related controls, whose ranges depend on the exact
configuration.

However, `updateControls()` cannot simply be moved to be after the loop
because it updates the limits of `FrameDurationLimits`, which `Agc::configure()`
needs to access. Moving it after the loop would lead to stale data
being used.

So move the updating of `ipaControls` out of `updateControls()`.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
---
 src/ipa/rkisp1/rkisp1.cpp | 29 +++++++++++++++++------------
 1 file changed, 17 insertions(+), 12 deletions(-)

Comments

Jacopo Mondi Dec. 15, 2025, 4:21 p.m. UTC | #1
Hi Barnabás

On Mon, Dec 15, 2025 at 12:53:48PM +0100, Barnabás Pőcze wrote:
> In `IPARkISP1::init()`, the `ControlInfoMap` that will be returned
> to the pipeline handler is updated after creating the algorithms;
> naturally, since otherwise no algorithm could register its own controls.
>
> However, in `IPARkISP1::configure()`, the update is done before the
> algorithms are configured. This is not ideal because this prevents
> algorithms from correctly updating e.g. the `ControlInfo`s of their
> controls.
>
> While no algorithm is affected today, during development, it is useful
> for various debug related controls, whose ranges depend on the exact
> configuration.
>
> However, `updateControls()` cannot simply be moved to be after the loop
> because it updates the limits of `FrameDurationLimits`, which `Agc::configure()`
> needs to access. Moving it after the loop would lead to stale data
> being used.

While I think the patch has merits of its own, this last issue is a
consequence of the fact we are abusing the context ctrlMap to
communicate the control limits from IPA to the algorithms.

What do you think of
https://patchwork.libcamera.org/patch/25055/ ?

>
> So move the updating of `ipaControls` out of `updateControls()`.
>
> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
> ---
>  src/ipa/rkisp1/rkisp1.cpp | 29 +++++++++++++++++------------
>  1 file changed, 17 insertions(+), 12 deletions(-)
>
> diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
> index 61d3d1f6f..6c9ff306d 100644
> --- a/src/ipa/rkisp1/rkisp1.cpp
> +++ b/src/ipa/rkisp1/rkisp1.cpp
> @@ -76,7 +76,7 @@ protected:
>  private:
>  	void updateControls(const IPACameraSensorInfo &sensorInfo,
>  			    const ControlInfoMap &sensorControls,
> -			    ControlInfoMap *ipaControls);
> +			    ControlInfoMap::Map &ctrlMap);
>  	void setControls(unsigned int frame);
>
>  	std::map<unsigned int, FrameBuffer> buffers_;
> @@ -202,12 +202,17 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
>  		return -EINVAL;
>  	}
>
> +	ControlInfoMap::Map ctrlMap = rkisp1Controls;
> +
> +	/* Initialize controls. */
> +	updateControls(sensorInfo, sensorControls, ctrlMap);
> +
>  	int ret = createAlgorithms(context_, (*data)["algorithms"]);
>  	if (ret)
>  		return ret;
>
> -	/* Initialize controls. */
> -	updateControls(sensorInfo, sensorControls, ipaControls);
> +	ctrlMap.insert(context_.ctrlMap.begin(), context_.ctrlMap.end());
> +	*ipaControls = ControlInfoMap(std::move(ctrlMap), controls::controls);
>
>  	return 0;
>  }
> @@ -254,9 +259,6 @@ int IPARkISP1::configure(const IPAConfigInfo &ipaConfig,
>  	context_.configuration.sensor.size = info.outputSize;
>  	context_.configuration.sensor.lineDuration = info.minLineLength * 1.0s / info.pixelRate;
>
> -	/* Update the camera controls using the new sensor settings. */
> -	updateControls(info, sensorControls_, ipaControls);
> -
>  	/*
>  	 * When the AGC computes the new exposure values for a frame, it needs
>  	 * to know the limits for exposure time and analogue gain. As it depends
> @@ -280,6 +282,11 @@ int IPARkISP1::configure(const IPAConfigInfo &ipaConfig,
>  			return format.colourEncoding == PixelFormatInfo::ColourEncodingRAW;
>  		});
>
> +	ControlInfoMap::Map ctrlMap = rkisp1Controls;
> +
> +	/* Update the camera controls using the new sensor settings. */
> +	updateControls(info, sensorControls_, ctrlMap);
> +

I wonder if we shouldn't actually register all controls in
algorithms..

>  	for (auto const &a : algorithms()) {
>  		Algorithm *algo = static_cast<Algorithm *>(a.get());
>
> @@ -293,6 +300,9 @@ int IPARkISP1::configure(const IPAConfigInfo &ipaConfig,
>  			return ret;
>  	}
>
> +	ctrlMap.insert(context_.ctrlMap.begin(), context_.ctrlMap.end());
> +	*ipaControls = ControlInfoMap(std::move(ctrlMap), controls::controls);
> +
>  	return 0;
>  }
>
> @@ -388,10 +398,8 @@ void IPARkISP1::processStats(const uint32_t frame, const uint32_t bufferId,
>
>  void IPARkISP1::updateControls(const IPACameraSensorInfo &sensorInfo,
>  			       const ControlInfoMap &sensorControls,
> -			       ControlInfoMap *ipaControls)
> +			       ControlInfoMap::Map &ctrlMap)

nit: why use a reference if the argument is modifiable ?

I think the patch is however good, and as far as I can see doesn't
impact the AGC frame duration limits rework I have in progress:

Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>

Thanks
  j

>  {
> -	ControlInfoMap::Map ctrlMap = rkisp1Controls;
> -
>  	/*
>  	 * Compute exposure time limits from the V4L2_CID_EXPOSURE control
>  	 * limits and the line duration.
> @@ -441,9 +449,6 @@ void IPARkISP1::updateControls(const IPACameraSensorInfo &sensorInfo,
>  	context_.ctrlMap[&controls::FrameDurationLimits] =
>  		ControlInfo(frameDurations[0], frameDurations[1],
>  			    ControlValue(Span<const int64_t, 2>{ { frameDurations[2], frameDurations[2] } }));
> -
> -	ctrlMap.insert(context_.ctrlMap.begin(), context_.ctrlMap.end());
> -	*ipaControls = ControlInfoMap(std::move(ctrlMap), controls::controls);
>  }
>
>  void IPARkISP1::setControls(unsigned int frame)
> --
> 2.52.0
>

Patch
diff mbox series

diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
index 61d3d1f6f..6c9ff306d 100644
--- a/src/ipa/rkisp1/rkisp1.cpp
+++ b/src/ipa/rkisp1/rkisp1.cpp
@@ -76,7 +76,7 @@  protected:
 private:
 	void updateControls(const IPACameraSensorInfo &sensorInfo,
 			    const ControlInfoMap &sensorControls,
-			    ControlInfoMap *ipaControls);
+			    ControlInfoMap::Map &ctrlMap);
 	void setControls(unsigned int frame);
 
 	std::map<unsigned int, FrameBuffer> buffers_;
@@ -202,12 +202,17 @@  int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
 		return -EINVAL;
 	}
 
+	ControlInfoMap::Map ctrlMap = rkisp1Controls;
+
+	/* Initialize controls. */
+	updateControls(sensorInfo, sensorControls, ctrlMap);
+
 	int ret = createAlgorithms(context_, (*data)["algorithms"]);
 	if (ret)
 		return ret;
 
-	/* Initialize controls. */
-	updateControls(sensorInfo, sensorControls, ipaControls);
+	ctrlMap.insert(context_.ctrlMap.begin(), context_.ctrlMap.end());
+	*ipaControls = ControlInfoMap(std::move(ctrlMap), controls::controls);
 
 	return 0;
 }
@@ -254,9 +259,6 @@  int IPARkISP1::configure(const IPAConfigInfo &ipaConfig,
 	context_.configuration.sensor.size = info.outputSize;
 	context_.configuration.sensor.lineDuration = info.minLineLength * 1.0s / info.pixelRate;
 
-	/* Update the camera controls using the new sensor settings. */
-	updateControls(info, sensorControls_, ipaControls);
-
 	/*
 	 * When the AGC computes the new exposure values for a frame, it needs
 	 * to know the limits for exposure time and analogue gain. As it depends
@@ -280,6 +282,11 @@  int IPARkISP1::configure(const IPAConfigInfo &ipaConfig,
 			return format.colourEncoding == PixelFormatInfo::ColourEncodingRAW;
 		});
 
+	ControlInfoMap::Map ctrlMap = rkisp1Controls;
+
+	/* Update the camera controls using the new sensor settings. */
+	updateControls(info, sensorControls_, ctrlMap);
+
 	for (auto const &a : algorithms()) {
 		Algorithm *algo = static_cast<Algorithm *>(a.get());
 
@@ -293,6 +300,9 @@  int IPARkISP1::configure(const IPAConfigInfo &ipaConfig,
 			return ret;
 	}
 
+	ctrlMap.insert(context_.ctrlMap.begin(), context_.ctrlMap.end());
+	*ipaControls = ControlInfoMap(std::move(ctrlMap), controls::controls);
+
 	return 0;
 }
 
@@ -388,10 +398,8 @@  void IPARkISP1::processStats(const uint32_t frame, const uint32_t bufferId,
 
 void IPARkISP1::updateControls(const IPACameraSensorInfo &sensorInfo,
 			       const ControlInfoMap &sensorControls,
-			       ControlInfoMap *ipaControls)
+			       ControlInfoMap::Map &ctrlMap)
 {
-	ControlInfoMap::Map ctrlMap = rkisp1Controls;
-
 	/*
 	 * Compute exposure time limits from the V4L2_CID_EXPOSURE control
 	 * limits and the line duration.
@@ -441,9 +449,6 @@  void IPARkISP1::updateControls(const IPACameraSensorInfo &sensorInfo,
 	context_.ctrlMap[&controls::FrameDurationLimits] =
 		ControlInfo(frameDurations[0], frameDurations[1],
 			    ControlValue(Span<const int64_t, 2>{ { frameDurations[2], frameDurations[2] } }));
-
-	ctrlMap.insert(context_.ctrlMap.begin(), context_.ctrlMap.end());
-	*ipaControls = ControlInfoMap(std::move(ctrlMap), controls::controls);
 }
 
 void IPARkISP1::setControls(unsigned int frame)