[libcamera-devel,06/10] ipa: raspberrypi: Add AfMode control
diff mbox series

Message ID 20220613142853.98484-7-jeanmichel.hautbois@ideasonboard.com
State New
Headers show
Series
  • ipa: raspberrypi: Introduce an autofocus algorithm
Related show

Commit Message

Jean-Michel Hautbois June 13, 2022, 2:28 p.m. UTC
Implement the AfMode control to allow the user to switch between manual,
auto or continuous mode. As the mode changes, the AfState value is
updated and lets the user follow the algorithm state.

Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
---
 include/libcamera/ipa/raspberrypi.h       |  3 ++-
 src/ipa/raspberrypi/controller/iob/af.cpp | 24 ++++++++++++++++-------
 src/ipa/raspberrypi/raspberrypi.cpp       | 15 ++++++++++++++
 3 files changed, 34 insertions(+), 8 deletions(-)

Patch
diff mbox series

diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h
index 519f7160..5bc14f4e 100644
--- a/include/libcamera/ipa/raspberrypi.h
+++ b/include/libcamera/ipa/raspberrypi.h
@@ -46,7 +46,8 @@  static const ControlInfoMap Controls({
 		{ &controls::ScalerCrop, ControlInfo(Rectangle{}, Rectangle(65535, 65535, 65535, 65535), Rectangle{}) },
 		{ &controls::FrameDurationLimits, ControlInfo(INT64_C(1000), INT64_C(1000000000)) },
 		{ &controls::draft::NoiseReductionMode, ControlInfo(controls::draft::NoiseReductionModeValues) },
-		{ &controls::AfState, ControlInfo(controls::AfStateValues) }
+		{ &controls::AfMode, ControlInfo(controls::AfModeValues) },
+		{ &controls::AfState, ControlInfo(controls::AfStateValues) },
 	}, controls::controls);
 
 } /* namespace RPi */
diff --git a/src/ipa/raspberrypi/controller/iob/af.cpp b/src/ipa/raspberrypi/controller/iob/af.cpp
index b03e52c5..e09514c4 100644
--- a/src/ipa/raspberrypi/controller/iob/af.cpp
+++ b/src/ipa/raspberrypi/controller/iob/af.cpp
@@ -40,7 +40,7 @@  Af::Af(Controller *controller)
 	: AfAlgorithm(controller), focus_(0), bestFocus_(0),
 	  currentContrast_(0.0), previousContrast_(0.0), maxContrast_(0.0),
 	  maxStep_(0), coarseCompleted_(false), fineCompleted_(false),
-	  mode_(0)
+	  mode_(libcamera::controls::AfModeManual)
 {
 }
 
@@ -49,9 +49,13 @@  char const *Af::Name() const
 	return NAME;
 }
 
-void Af::SetMode([[maybe_unused]] const uint32_t &mode)
+void Af::SetMode(const uint32_t &mode)
 {
-	mode_ = mode;
+	if (mode != mode_) {
+		LOG(IoBAf, Debug) << "Switched AF mode from " << mode_
+				  << " to " << mode;
+		mode_ = mode;
+	}
 }
 
 void Af::Trigger()
@@ -78,7 +82,7 @@  void Af::Initialise()
 {
 	status_.lensPosition = 0.0;
 	maxContrast_ = 0.0;
-	status_.state = libcamera::controls::AfStateScanning;
+	status_.state = libcamera::controls::AfStateIdle;
 }
 
 void Af::Prepare(Metadata *image_metadata)
@@ -162,7 +166,7 @@  void Af::afReset()
 	LOG(IoBAf, Debug) << "Reset AF parameters";
 	status_.lensPosition = 0;
 	focus_ = 0;
-	status_.state = libcamera::controls::AfStateIdle;
+	status_.state = libcamera::controls::AfStateScanning;
 	previousContrast_ = 0.0;
 	coarseCompleted_ = false;
 	fineCompleted_ = false;
@@ -195,12 +199,18 @@  void Af::Process(StatisticsPtr &stats, [[maybe_unused]] Metadata *image_metadata
 		currentContrast_ += stats->focus_stats[i].contrast_val[1][1]
 				  / stats->focus_stats[i].contrast_val_num[1][1];
 
+	/* Depending on the mode, we may or may not process the stats */
+	if (status_.state == libcamera::controls::AfStateIdle)
+	    return;
+
 	if (status_.state != libcamera::controls::AfStateFocused) {
 		afCoarseScan();
 		afFineScan();
 	} else {
-		if (afIsOutOfFocus())
-			afReset();
+		/* We can re-start the scan at any moment in AfModeContinuous */
+		if (mode_ == libcamera::controls::AfModeContinuous)
+			if (afIsOutOfFocus())
+				afReset();
 	}
 }
 
diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp
index a4e1c834..226388a7 100644
--- a/src/ipa/raspberrypi/raspberrypi.cpp
+++ b/src/ipa/raspberrypi/raspberrypi.cpp
@@ -30,6 +30,7 @@ 
 
 #include "libcamera/internal/mapped_framebuffer.h"
 
+#include "af_algorithm.hpp"
 #include "af_status.h"
 #include "agc_algorithm.hpp"
 #include "agc_status.h"
@@ -956,6 +957,20 @@  void IPARPi::queueRequest(const ControlList &controls)
 			break;
 		}
 
+		case controls::AF_MODE: {
+			RPiController::AfAlgorithm *af = dynamic_cast<RPiController::AfAlgorithm *>(
+				controller_.GetAlgorithm("iob.af"));
+			if (!af) {
+				LOG(IPARPI, Warning)
+					<< "Could not set AF_MODE - no AF algorithm";
+				break;
+			}
+
+			int32_t idx = ctrl.second.get<int32_t>();
+			af->SetMode(idx);
+			break;
+		}
+
 		default:
 			LOG(IPARPI, Warning)
 				<< "Ctrl " << controls::controls.at(ctrl.first)->name()