[libcamera-devel,v4,07/10] ipa: rkisp1: af: Add "Windows" Metering mode
diff mbox series

Message ID 20230314144834.85193-8-dse@thaumatec.com
State Superseded
Headers show
Series
  • ipa: rkisp1: Add autofocus algorithm
Related show

Commit Message

Daniel Semkowicz March 14, 2023, 2:48 p.m. UTC
Add platform related code for configuring auto focus window on the
rkisp1. Connect to the windowUpdateRequested() signal exposed by the
AfHillClimbing and configure the window on each signal emission.
This enables support of AfMetering and AfWindows controls on the rkisp1
platform.

Currently, only one window is enabled, but ISP allows up to three
of them.

Signed-off-by: Daniel Semkowicz <dse@thaumatec.com>
---
 src/ipa/rkisp1/algorithms/af.cpp | 63 +++++++++++++++++++++++++++++++-
 src/ipa/rkisp1/algorithms/af.h   | 11 ++++++
 2 files changed, 73 insertions(+), 1 deletion(-)

Patch
diff mbox series

diff --git a/src/ipa/rkisp1/algorithms/af.cpp b/src/ipa/rkisp1/algorithms/af.cpp
index abf5d91f..794fa59e 100644
--- a/src/ipa/rkisp1/algorithms/af.cpp
+++ b/src/ipa/rkisp1/algorithms/af.cpp
@@ -31,18 +31,48 @@  namespace libcamera::ipa::rkisp1::algorithms {
  *   amount of time on each movement. This parameter should be set according
  *   to the worst case  - the number of frames it takes to move lens between
  *   limit positions.
+ * - **isp-threshold:** Threshold used for minimizing the influence of noise.
+ *   This affects the ISP sharpness calculation.
+ * - **isp-var-shift:** The number of bits for the shift operation at the end
+ *   of the calculation chain. This affects the ISP sharpness calculation.
+ *
+ * \sa libcamera::ipa::common::algorithms::AfHillClimbing for additional tuning
+ * parameters.
  */
 
 LOG_DEFINE_CATEGORY(RkISP1Af)
 
+namespace {
+
+constexpr rkisp1_cif_isp_window rectangleToIspWindow(const Rectangle &rectangle)
+{
+	return rkisp1_cif_isp_window{
+		.h_offs = static_cast<uint16_t>(rectangle.x),
+		.v_offs = static_cast<uint16_t>(rectangle.y),
+		.h_size = static_cast<uint16_t>(rectangle.width),
+		.v_size = static_cast<uint16_t>(rectangle.height)
+	};
+}
+
+} /* namespace */
+
+Af::Af()
+{
+	af.windowUpdateRequested.connect(this, &Af::updateCurrentWindow);
+}
+
 /**
  * \copydoc libcamera::ipa::Algorithm::init
  */
 int Af::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData)
 {
 	waitFramesLens_ = tuningData["wait-frames-lens"].get<uint32_t>(1);
+	ispThreshold_ = tuningData["isp-threshold"].get<uint32_t>(128);
+	ispVarShift_ = tuningData["isp-var-shift"].get<uint32_t>(4);
 
-	LOG(RkISP1Af, Debug) << "waitFramesLens_: " << waitFramesLens_;
+	LOG(RkISP1Af, Debug) << "waitFramesLens_: " << waitFramesLens_
+			     << ", ispThreshold_: " << ispThreshold_
+			     << ", ispVarShift_: " << ispVarShift_;
 
 	return af.init(tuningData);
 }
@@ -77,6 +107,32 @@  void Af::queueRequest([[maybe_unused]] IPAContext &context,
 	af.queueRequest(controls);
 }
 
+/**
+ * \copydoc libcamera::ipa::Algorithm::prepare
+ */
+void Af::prepare([[maybe_unused]] IPAContext &context,
+		 [[maybe_unused]] const uint32_t frame,
+		 [[maybe_unused]] IPAFrameContext &frameContext,
+		 rkisp1_params_cfg *params)
+{
+	if (updateWindow_) {
+		params->meas.afc_config.num_afm_win = 1;
+		params->meas.afc_config.thres = ispThreshold_;
+		params->meas.afc_config.var_shift = ispVarShift_;
+		params->meas.afc_config.afm_win[0] =
+			rectangleToIspWindow(*updateWindow_);
+
+		params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_AFC;
+		params->module_ens |= RKISP1_CIF_ISP_MODULE_AFC;
+		params->module_en_update |= RKISP1_CIF_ISP_MODULE_AFC;
+
+		updateWindow_.reset();
+
+		/* Wait one frame for the ISP to apply changes */
+		af.setFramesToSkip(1);
+	}
+}
+
 /**
  * \copydoc libcamera::ipa::Algorithm::process
  */
@@ -102,6 +158,11 @@  void Af::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
 	}
 }
 
+void Af::updateCurrentWindow(const Rectangle &window)
+{
+	updateWindow_ = window;
+}
+
 REGISTER_IPA_ALGORITHM(Af, "Af")
 
 } /* namespace libcamera::ipa::rkisp1::algorithms */
diff --git a/src/ipa/rkisp1/algorithms/af.h b/src/ipa/rkisp1/algorithms/af.h
index 85de0a64..df2ca31a 100644
--- a/src/ipa/rkisp1/algorithms/af.h
+++ b/src/ipa/rkisp1/algorithms/af.h
@@ -18,20 +18,31 @@  namespace libcamera::ipa::rkisp1::algorithms {
 class Af : public Algorithm
 {
 public:
+	Af();
+
 	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,
+		     rkisp1_params_cfg *params) override;
 	void process(IPAContext &context, const uint32_t frame,
 		     IPAFrameContext &frameContext,
 		     const rkisp1_stat_buffer *stats,
 		     ControlList &metadata) override;
 
 private:
+	void updateCurrentWindow(const Rectangle &window);
+
 	ipa::common::algorithms::AfHillClimbing af;
 
+	std::optional<Rectangle> updateWindow_;
+	uint32_t ispThreshold_;
+	uint32_t ispVarShift_;
+
 	/* Wait number of frames after changing lens position */
 	uint32_t waitFramesLens_;
 };