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

Message ID 20260108-sklug-lsc-resampling-v2-dev-v2-15-e682ec4b9893@ideasonboard.com
State New
Headers show
Series
  • Add resampling support for polynomial LSC data
Related show

Commit Message

Stefan Klug Jan. 8, 2026, 4:05 p.m. UTC
Implement the LensShadingCorrectionEnable control for rkisp1.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>

---

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 | 48 ++++++++++++++++++++++++++++++++++-----
 src/ipa/rkisp1/algorithms/lsc.h   |  3 +++
 src/ipa/rkisp1/ipa_context.h      | 13 +++++++----
 4 files changed, 55 insertions(+), 11 deletions(-)

Comments

Barnabás Pőcze Jan. 9, 2026, 12:30 p.m. UTC | #1
2026. 01. 08. 17:05 keltezéssel, Stefan Klug írta:
> Implement the LensShadingCorrectionEnable control for rkisp1.
> 
> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
> 
> ---

A cursory test with camshark works ok (no dpf).

Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>


> 
> 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 | 48 ++++++++++++++++++++++++++++++++++-----
>   src/ipa/rkisp1/algorithms/lsc.h   |  3 +++
>   src/ipa/rkisp1/ipa_context.h      | 13 +++++++----
>   4 files changed, 55 insertions(+), 11 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 698f07b85bfa5d3de0c454087bf8e0874d85add7..cb3f8550457eb2e67959ce034d037ac60328d267 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)
> +			<< (*lscEnable ? "Enabling" : "Disabling") << " Lsc";
> +
> +		frameContext.lsc.update = true;
> +	}
> +
> +	frameContext.lsc.enabled = lsc.enabled;
> +}
> +
>   /**
>    * \copydoc libcamera::ipa::Algorithm::prepare
>    */
> @@ -493,14 +518,25 @@ void LensShadingCorrection::prepare([[maybe_unused]] IPAContext &context,
>   	unsigned int quantizedCt = quantize(ct, kColourTemperatureChangeThreshhold);
>   	int ctDiff = static_cast<int>(ct) - static_cast<int>(lastAppliedCt_);
>   
> -	if (quantizedCt == lastAppliedQuantizedCt_)
> -		return;
>   
> -	if (std::abs(ctDiff) < kColourTemperatureChangeThreshhold)
> -		return;
> +	/* Check if we can skip the update. */
> +	if (!frameContext.lsc.update) {
> +		if (!frameContext.lsc.enabled)
> +			return;
> +
> +		if (quantizedCt == lastAppliedQuantizedCt_)
> +			return;
> +
> +		if (std::abs(ctDiff) < kColourTemperatureChangeThreshhold)
> +			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);
> diff --git a/src/ipa/rkisp1/algorithms/lsc.h b/src/ipa/rkisp1/algorithms/lsc.h
> index 3097740a6cb2ce9063a4ba087856987a489b0ab6..ff4e8d91fe87d99b6dae8d611afc23846081bcd5 100644
> --- a/src/ipa/rkisp1/algorithms/lsc.h
> +++ b/src/ipa/rkisp1/algorithms/lsc.h
> @@ -29,6 +29,9 @@ public:
>   	void prepare(IPAContext &context, const uint32_t frame,
>   		     IPAFrameContext &frameContext,
>   		     RkISP1Params *params) override;
> +	void queueRequest(IPAContext &context, const uint32_t frame,
> +			  IPAFrameContext &frameContext,
> +			  const ControlList &controls) 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 {
>
Barnabás Pőcze Jan. 9, 2026, 12:32 p.m. UTC | #2
2026. 01. 08. 17:05 keltezéssel, Stefan Klug írta:
> Implement the LensShadingCorrectionEnable control for rkisp1.
> 
> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
> 
> ---

I see that `LensShadingCorrectionEnable` is an inout control.
Is the addition to metadata intentionally omitted here?


> 
> 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 | 48 ++++++++++++++++++++++++++++++++++-----
>   src/ipa/rkisp1/algorithms/lsc.h   |  3 +++
>   src/ipa/rkisp1/ipa_context.h      | 13 +++++++----
>   4 files changed, 55 insertions(+), 11 deletions(-)
> 
> [...]

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 698f07b85bfa5d3de0c454087bf8e0874d85add7..cb3f8550457eb2e67959ce034d037ac60328d267 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)
+			<< (*lscEnable ? "Enabling" : "Disabling") << " Lsc";
+
+		frameContext.lsc.update = true;
+	}
+
+	frameContext.lsc.enabled = lsc.enabled;
+}
+
 /**
  * \copydoc libcamera::ipa::Algorithm::prepare
  */
@@ -493,14 +518,25 @@  void LensShadingCorrection::prepare([[maybe_unused]] IPAContext &context,
 	unsigned int quantizedCt = quantize(ct, kColourTemperatureChangeThreshhold);
 	int ctDiff = static_cast<int>(ct) - static_cast<int>(lastAppliedCt_);
 
-	if (quantizedCt == lastAppliedQuantizedCt_)
-		return;
 
-	if (std::abs(ctDiff) < kColourTemperatureChangeThreshhold)
-		return;
+	/* Check if we can skip the update. */
+	if (!frameContext.lsc.update) {
+		if (!frameContext.lsc.enabled)
+			return;
+
+		if (quantizedCt == lastAppliedQuantizedCt_)
+			return;
+
+		if (std::abs(ctDiff) < kColourTemperatureChangeThreshhold)
+			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);
diff --git a/src/ipa/rkisp1/algorithms/lsc.h b/src/ipa/rkisp1/algorithms/lsc.h
index 3097740a6cb2ce9063a4ba087856987a489b0ab6..ff4e8d91fe87d99b6dae8d611afc23846081bcd5 100644
--- a/src/ipa/rkisp1/algorithms/lsc.h
+++ b/src/ipa/rkisp1/algorithms/lsc.h
@@ -29,6 +29,9 @@  public:
 	void prepare(IPAContext &context, const uint32_t frame,
 		     IPAFrameContext &frameContext,
 		     RkISP1Params *params) override;
+	void queueRequest(IPAContext &context, const uint32_t frame,
+			  IPAFrameContext &frameContext,
+			  const ControlList &controls) 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 {