[libcamera-devel] [PATCH 06/10] ipa: raspberrypi: Add AfMode control

Jean-Michel Hautbois jeanmichel.hautbois at ideasonboard.com
Mon Jun 13 16:28:49 CEST 2022


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 at 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(-)

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()
-- 
2.34.1



More information about the libcamera-devel mailing list