[v5,15/15] ipa: rkisp1: Implement LensShadingCorrectionEnable control
diff mbox series

Message ID 20260120-sklug-lsc-resampling-v2-dev-v5-15-ef5cec7b299f@ideasonboard.com
State Superseded
Headers show
Series
  • Add resampling support for polynomial LSC data
Related show

Commit Message

Stefan Klug Jan. 20, 2026, 12:26 p.m. UTC
Implement the LensShadingCorrectionEnable control for rkisp1.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

---

Changes in v5:
- Split patch 14 into two again, to have a separate patch for
  control_ids_core.yaml

Changes in v4:
- Squahed patch 14 (addition od the LSC control) and 15 (implementation)
  into one.
- Collected tag

Changes in v3:
- Include LensShadingCorrectionEnable in metadata
- Add the queueRequest function in the header in logical order instead
  of alphabetical order

Changes in v2:
- Add the control only if LSC is properly configured in the tuning file
- Introduce enable flag in frame context for per frame control
---
 src/ipa/rkisp1/algorithms/dpf.cpp |  2 +-
 src/ipa/rkisp1/algorithms/lsc.cpp | 67 +++++++++++++++++++++++++++++++++------
 src/ipa/rkisp1/algorithms/lsc.h   |  7 ++++
 src/ipa/rkisp1/ipa_context.h      | 13 +++++---
 4 files changed, 74 insertions(+), 15 deletions(-)

Comments

Laurent Pinchart Jan. 28, 2026, 11:27 a.m. UTC | #1
On Tue, Jan 20, 2026 at 01:26:20PM +0100, Stefan Klug wrote:
> Implement the LensShadingCorrectionEnable control for rkisp1.
> 
> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
> Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> 
> ---
> 
> Changes in v5:
> - Split patch 14 into two again, to have a separate patch for
>   control_ids_core.yaml
> 
> Changes in v4:
> - Squahed patch 14 (addition od the LSC control) and 15 (implementation)
>   into one.
> - Collected tag
> 
> Changes in v3:
> - Include LensShadingCorrectionEnable in metadata
> - Add the queueRequest function in the header in logical order instead
>   of alphabetical order
> 
> Changes in v2:
> - Add the control only if LSC is properly configured in the tuning file
> - Introduce enable flag in frame context for per frame control
> ---
>  src/ipa/rkisp1/algorithms/dpf.cpp |  2 +-
>  src/ipa/rkisp1/algorithms/lsc.cpp | 67 +++++++++++++++++++++++++++++++++------
>  src/ipa/rkisp1/algorithms/lsc.h   |  7 ++++
>  src/ipa/rkisp1/ipa_context.h      | 13 +++++---
>  4 files changed, 74 insertions(+), 15 deletions(-)
> 
> diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp
> index 39f3e461f313dfbf35cb5d6a0daca0540bdf7b6b..83c1e4b7b355041295cbe0498a8dd70877ea6636 100644
> --- a/src/ipa/rkisp1/algorithms/dpf.cpp
> +++ b/src/ipa/rkisp1/algorithms/dpf.cpp
> @@ -233,7 +233,7 @@ void Dpf::prepare(IPAContext &context, const uint32_t frame,
>  		*strengthConfig = strengthConfig_;
>  
>  		const auto &awb = context.configuration.awb;
> -		const auto &lsc = context.configuration.lsc;
> +		const auto &lsc = context.activeState.lsc;
>  
>  		auto &mode = config->gain.mode;
>  
> diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp
> index 8589243ea04f5a712fb2ddd95677a197566f390f..8e3878d7e738d4b6212ca09671ed4e66b2dc5102 100644
> --- a/src/ipa/rkisp1/algorithms/lsc.cpp
> +++ b/src/ipa/rkisp1/algorithms/lsc.cpp
> @@ -416,6 +416,8 @@ int LensShadingCorrection::init([[maybe_unused]] IPAContext &context,
>  	if (ret)
>  		return ret;
>  
> +	context.ctrlMap[&controls::LensShadingCorrectionEnable] = ControlInfo(false, true, true);

Line wrap.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> +
>  	shadingDescriptors_ = std::move(lscData);
>  
>  	return 0;
> @@ -460,7 +462,7 @@ int LensShadingCorrection::configure(IPAContext &context,
>  
>  	sets_.setData(std::move(shadingData));
>  
> -	context.configuration.lsc.enabled = true;
> +	context.activeState.lsc.enabled = true;
>  	return 0;
>  }
>  
> @@ -481,6 +483,29 @@ void LensShadingCorrection::copyTable(rkisp1_cif_isp_lsc_config &config,
>  	std::copy(set.b.begin(), set.b.end(), &config.b_data_tbl[0][0]);
>  }
>  
> +/**
> + * \copydoc libcamera::ipa::Algorithm::queueRequest
> + */
> +void LensShadingCorrection::queueRequest(IPAContext &context,
> +					 [[maybe_unused]] const uint32_t frame,
> +					 IPAFrameContext &frameContext,
> +					 const ControlList &controls)
> +{
> +	auto &lsc = context.activeState.lsc;
> +
> +	const auto &lscEnable = controls.get(controls::LensShadingCorrectionEnable);
> +	if (lscEnable && *lscEnable != lsc.enabled) {
> +		lsc.enabled = *lscEnable;
> +
> +		LOG(RkISP1Lsc, Debug)
> +			<< (lsc.enabled ? "Enabling" : "Disabling") << " Lsc";
> +
> +		frameContext.lsc.update = true;
> +	}
> +
> +	frameContext.lsc.enabled = lsc.enabled;
> +}
> +
>  /**
>   * \copydoc libcamera::ipa::Algorithm::prepare
>   */
> @@ -492,18 +517,28 @@ void LensShadingCorrection::prepare([[maybe_unused]] IPAContext &context,
>  	uint32_t ct = frameContext.awb.temperatureK;
>  	unsigned int quantizedCt = quantize(ct, kColourTemperatureQuantization);
>  
> -	/*
> -	 * Add a threshold so that oscillations around a quantization step don't
> -	 * lead to constant changes.
> -	 */
> -	if (utils::abs_diff(ct, lastAppliedCt_) < kColourTemperatureQuantization / 2)
> -		return;
> +	/* Check if we can skip the update. */
> +	if (!frameContext.lsc.update) {
> +		if (!frameContext.lsc.enabled)
> +			return;
>  
> -	if (quantizedCt == lastAppliedQuantizedCt_)
> -		return;
> +		/*
> +		 * Add a threshold so that oscillations around a quantization
> +		 * step don't lead to constant changes.
> +		 */
> +		if (utils::abs_diff(ct, lastAppliedCt_) < kColourTemperatureQuantization / 2)
> +			return;
> +
> +		if (quantizedCt == lastAppliedQuantizedCt_)
> +			return;
> +	}
>  
>  	auto config = params->block<BlockType::Lsc>();
> -	config.setEnabled(true);
> +	config.setEnabled(frameContext.lsc.enabled);
> +
> +	if (!frameContext.lsc.enabled)
> +		return;
> +
>  	setParameters(*config);
>  
>  	const Components &set = sets_.getInterpolated(quantizedCt);
> @@ -517,6 +552,18 @@ void LensShadingCorrection::prepare([[maybe_unused]] IPAContext &context,
>  		<< quantizedCt;
>  }
>  
> +/**
> + * \copydoc libcamera::ipa::Algorithm::process
> + */
> +void LensShadingCorrection::process([[maybe_unused]] IPAContext &context,
> +				    [[maybe_unused]] const uint32_t frame,
> +				    IPAFrameContext &frameContext,
> +				    [[maybe_unused]] const rkisp1_stat_buffer *stats,
> +				    ControlList &metadata)
> +{
> +	metadata.set(controls::LensShadingCorrectionEnable, frameContext.lsc.enabled);
> +}
> +
>  REGISTER_IPA_ALGORITHM(LensShadingCorrection, "LensShadingCorrection")
>  
>  } /* namespace ipa::rkisp1::algorithms */
> diff --git a/src/ipa/rkisp1/algorithms/lsc.h b/src/ipa/rkisp1/algorithms/lsc.h
> index 3097740a6cb2ce9063a4ba087856987a489b0ab6..fb9dcc1a52af4a88a52808346b5da99e3f2b1c87 100644
> --- a/src/ipa/rkisp1/algorithms/lsc.h
> +++ b/src/ipa/rkisp1/algorithms/lsc.h
> @@ -26,9 +26,16 @@ public:
>  
>  	int init(IPAContext &context, const YamlObject &tuningData) override;
>  	int configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override;
> +	void queueRequest(IPAContext &context, const uint32_t frame,
> +			  IPAFrameContext &frameContext,
> +			  const ControlList &controls) override;
>  	void prepare(IPAContext &context, const uint32_t frame,
>  		     IPAFrameContext &frameContext,
>  		     RkISP1Params *params) override;
> +	void process(IPAContext &context, const uint32_t frame,
> +		     IPAFrameContext &frameContext,
> +		     const rkisp1_stat_buffer *stats,
> +		     ControlList &metadata) override;
>  
>  	struct Components {
>  		std::vector<uint16_t> r;
> diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h
> index b257cee55379ad932b42e613f94eccbe69a939e3..fa748811be743b43ce6ee289408c054c6f9a7046 100644
> --- a/src/ipa/rkisp1/ipa_context.h
> +++ b/src/ipa/rkisp1/ipa_context.h
> @@ -55,10 +55,6 @@ struct IPASessionConfiguration {
>  		bool supported;
>  	} compress;
>  
> -	struct {
> -		bool enabled;
> -	} lsc;
> -
>  	struct {
>  		utils::Duration minExposureTime;
>  		utils::Duration maxExposureTime;
> @@ -143,6 +139,10 @@ struct IPAActiveState {
>  		double gain;
>  		double strength;
>  	} wdr;
> +
> +	struct {
> +		bool enabled;
> +	} lsc;
>  };
>  
>  struct IPAFrameContext : public FrameContext {
> @@ -218,6 +218,11 @@ struct IPAFrameContext : public FrameContext {
>  		double strength;
>  		double gain;
>  	} wdr;
> +
> +	struct {
> +		bool enabled;
> +		bool update;
> +	} lsc;
>  };
>  
>  struct IPAContext {

Patch
diff mbox series

diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp
index 39f3e461f313dfbf35cb5d6a0daca0540bdf7b6b..83c1e4b7b355041295cbe0498a8dd70877ea6636 100644
--- a/src/ipa/rkisp1/algorithms/dpf.cpp
+++ b/src/ipa/rkisp1/algorithms/dpf.cpp
@@ -233,7 +233,7 @@  void Dpf::prepare(IPAContext &context, const uint32_t frame,
 		*strengthConfig = strengthConfig_;
 
 		const auto &awb = context.configuration.awb;
-		const auto &lsc = context.configuration.lsc;
+		const auto &lsc = context.activeState.lsc;
 
 		auto &mode = config->gain.mode;
 
diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp
index 8589243ea04f5a712fb2ddd95677a197566f390f..8e3878d7e738d4b6212ca09671ed4e66b2dc5102 100644
--- a/src/ipa/rkisp1/algorithms/lsc.cpp
+++ b/src/ipa/rkisp1/algorithms/lsc.cpp
@@ -416,6 +416,8 @@  int LensShadingCorrection::init([[maybe_unused]] IPAContext &context,
 	if (ret)
 		return ret;
 
+	context.ctrlMap[&controls::LensShadingCorrectionEnable] = ControlInfo(false, true, true);
+
 	shadingDescriptors_ = std::move(lscData);
 
 	return 0;
@@ -460,7 +462,7 @@  int LensShadingCorrection::configure(IPAContext &context,
 
 	sets_.setData(std::move(shadingData));
 
-	context.configuration.lsc.enabled = true;
+	context.activeState.lsc.enabled = true;
 	return 0;
 }
 
@@ -481,6 +483,29 @@  void LensShadingCorrection::copyTable(rkisp1_cif_isp_lsc_config &config,
 	std::copy(set.b.begin(), set.b.end(), &config.b_data_tbl[0][0]);
 }
 
+/**
+ * \copydoc libcamera::ipa::Algorithm::queueRequest
+ */
+void LensShadingCorrection::queueRequest(IPAContext &context,
+					 [[maybe_unused]] const uint32_t frame,
+					 IPAFrameContext &frameContext,
+					 const ControlList &controls)
+{
+	auto &lsc = context.activeState.lsc;
+
+	const auto &lscEnable = controls.get(controls::LensShadingCorrectionEnable);
+	if (lscEnable && *lscEnable != lsc.enabled) {
+		lsc.enabled = *lscEnable;
+
+		LOG(RkISP1Lsc, Debug)
+			<< (lsc.enabled ? "Enabling" : "Disabling") << " Lsc";
+
+		frameContext.lsc.update = true;
+	}
+
+	frameContext.lsc.enabled = lsc.enabled;
+}
+
 /**
  * \copydoc libcamera::ipa::Algorithm::prepare
  */
@@ -492,18 +517,28 @@  void LensShadingCorrection::prepare([[maybe_unused]] IPAContext &context,
 	uint32_t ct = frameContext.awb.temperatureK;
 	unsigned int quantizedCt = quantize(ct, kColourTemperatureQuantization);
 
-	/*
-	 * Add a threshold so that oscillations around a quantization step don't
-	 * lead to constant changes.
-	 */
-	if (utils::abs_diff(ct, lastAppliedCt_) < kColourTemperatureQuantization / 2)
-		return;
+	/* Check if we can skip the update. */
+	if (!frameContext.lsc.update) {
+		if (!frameContext.lsc.enabled)
+			return;
 
-	if (quantizedCt == lastAppliedQuantizedCt_)
-		return;
+		/*
+		 * Add a threshold so that oscillations around a quantization
+		 * step don't lead to constant changes.
+		 */
+		if (utils::abs_diff(ct, lastAppliedCt_) < kColourTemperatureQuantization / 2)
+			return;
+
+		if (quantizedCt == lastAppliedQuantizedCt_)
+			return;
+	}
 
 	auto config = params->block<BlockType::Lsc>();
-	config.setEnabled(true);
+	config.setEnabled(frameContext.lsc.enabled);
+
+	if (!frameContext.lsc.enabled)
+		return;
+
 	setParameters(*config);
 
 	const Components &set = sets_.getInterpolated(quantizedCt);
@@ -517,6 +552,18 @@  void LensShadingCorrection::prepare([[maybe_unused]] IPAContext &context,
 		<< quantizedCt;
 }
 
+/**
+ * \copydoc libcamera::ipa::Algorithm::process
+ */
+void LensShadingCorrection::process([[maybe_unused]] IPAContext &context,
+				    [[maybe_unused]] const uint32_t frame,
+				    IPAFrameContext &frameContext,
+				    [[maybe_unused]] const rkisp1_stat_buffer *stats,
+				    ControlList &metadata)
+{
+	metadata.set(controls::LensShadingCorrectionEnable, frameContext.lsc.enabled);
+}
+
 REGISTER_IPA_ALGORITHM(LensShadingCorrection, "LensShadingCorrection")
 
 } /* namespace ipa::rkisp1::algorithms */
diff --git a/src/ipa/rkisp1/algorithms/lsc.h b/src/ipa/rkisp1/algorithms/lsc.h
index 3097740a6cb2ce9063a4ba087856987a489b0ab6..fb9dcc1a52af4a88a52808346b5da99e3f2b1c87 100644
--- a/src/ipa/rkisp1/algorithms/lsc.h
+++ b/src/ipa/rkisp1/algorithms/lsc.h
@@ -26,9 +26,16 @@  public:
 
 	int init(IPAContext &context, const YamlObject &tuningData) override;
 	int configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override;
+	void queueRequest(IPAContext &context, const uint32_t frame,
+			  IPAFrameContext &frameContext,
+			  const ControlList &controls) override;
 	void prepare(IPAContext &context, const uint32_t frame,
 		     IPAFrameContext &frameContext,
 		     RkISP1Params *params) override;
+	void process(IPAContext &context, const uint32_t frame,
+		     IPAFrameContext &frameContext,
+		     const rkisp1_stat_buffer *stats,
+		     ControlList &metadata) override;
 
 	struct Components {
 		std::vector<uint16_t> r;
diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h
index b257cee55379ad932b42e613f94eccbe69a939e3..fa748811be743b43ce6ee289408c054c6f9a7046 100644
--- a/src/ipa/rkisp1/ipa_context.h
+++ b/src/ipa/rkisp1/ipa_context.h
@@ -55,10 +55,6 @@  struct IPASessionConfiguration {
 		bool supported;
 	} compress;
 
-	struct {
-		bool enabled;
-	} lsc;
-
 	struct {
 		utils::Duration minExposureTime;
 		utils::Duration maxExposureTime;
@@ -143,6 +139,10 @@  struct IPAActiveState {
 		double gain;
 		double strength;
 	} wdr;
+
+	struct {
+		bool enabled;
+	} lsc;
 };
 
 struct IPAFrameContext : public FrameContext {
@@ -218,6 +218,11 @@  struct IPAFrameContext : public FrameContext {
 		double strength;
 		double gain;
 	} wdr;
+
+	struct {
+		bool enabled;
+		bool update;
+	} lsc;
 };
 
 struct IPAContext {