[libcamera-devel,07/10] ipa: raspberrypi: Introduce AfPause and AfPauseState
diff mbox series

Message ID 20220613142853.98484-8-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
In the continuous mode, the algorithm can be paused and resumed by the
user using the AfPause control. Introduce the state machine associated
with this call, and populate a specific pause state which will populate
the AfPauseState control.

Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
---
 include/libcamera/ipa/raspberrypi.h             |  2 ++
 src/ipa/raspberrypi/controller/af_algorithm.hpp |  2 ++
 src/ipa/raspberrypi/controller/af_status.h      |  1 +
 src/ipa/raspberrypi/controller/iob/af.cpp       | 14 +++++++++++++-
 src/ipa/raspberrypi/controller/iob/af.h         |  1 +
 src/ipa/raspberrypi/raspberrypi.cpp             | 15 +++++++++++++++
 6 files changed, 34 insertions(+), 1 deletion(-)

Patch
diff mbox series

diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h
index 5bc14f4e..a7a15904 100644
--- a/include/libcamera/ipa/raspberrypi.h
+++ b/include/libcamera/ipa/raspberrypi.h
@@ -48,6 +48,8 @@  static const ControlInfoMap Controls({
 		{ &controls::draft::NoiseReductionMode, ControlInfo(controls::draft::NoiseReductionModeValues) },
 		{ &controls::AfMode, ControlInfo(controls::AfModeValues) },
 		{ &controls::AfState, ControlInfo(controls::AfStateValues) },
+		{ &controls::AfPause, ControlInfo(controls::AfPauseValues) },
+		{ &controls::AfPauseState, ControlInfo(controls::AfPauseStateValues) },
 	}, controls::controls);
 
 } /* namespace RPi */
diff --git a/src/ipa/raspberrypi/controller/af_algorithm.hpp b/src/ipa/raspberrypi/controller/af_algorithm.hpp
index 1e7aaa45..ac34e3b6 100644
--- a/src/ipa/raspberrypi/controller/af_algorithm.hpp
+++ b/src/ipa/raspberrypi/controller/af_algorithm.hpp
@@ -22,6 +22,8 @@  public:
 	virtual void Trigger() = 0;
 	// cancel a cycle (in auto mode)
 	virtual void Cancel() = 0;
+	// pause the continuous mode
+	virtual void Pause(const uint32_t &pause) = 0;
 	// set AF windows
 	virtual void SetWindows(const libcamera::Rectangle &afWindows) = 0;
 	// set AF range
diff --git a/src/ipa/raspberrypi/controller/af_status.h b/src/ipa/raspberrypi/controller/af_status.h
index 3428d032..aa412ef6 100644
--- a/src/ipa/raspberrypi/controller/af_status.h
+++ b/src/ipa/raspberrypi/controller/af_status.h
@@ -18,5 +18,6 @@ 
 struct AfStatus {
 	uint32_t lensPosition;
 	libcamera::controls::AfStateEnum state;
+	libcamera::controls::AfPauseStateEnum pauseState;
 	libcamera::Rectangle windows;
 };
diff --git a/src/ipa/raspberrypi/controller/iob/af.cpp b/src/ipa/raspberrypi/controller/iob/af.cpp
index e09514c4..2efc12f5 100644
--- a/src/ipa/raspberrypi/controller/iob/af.cpp
+++ b/src/ipa/raspberrypi/controller/iob/af.cpp
@@ -54,6 +54,7 @@  void Af::SetMode(const uint32_t &mode)
 	if (mode != mode_) {
 		LOG(IoBAf, Debug) << "Switched AF mode from " << mode_
 				  << " to " << mode;
+		status_.pauseState = libcamera::controls::AfPauseStateRunning;
 		mode_ = mode;
 	}
 }
@@ -62,8 +63,15 @@  void Af::Trigger()
 {
 }
 
-void Af::Cancel()
+void Af::Pause(const uint32_t &pause)
 {
+	/* \todo: add the AfPauseDeferred mode */
+	if (mode_ == libcamera::controls::AfModeContinuous) {
+		if (pause == libcamera::controls::AfPauseImmediate)
+			status_.pauseState = libcamera::controls::AfPauseStatePaused;
+		else if (pause == libcamera::controls::AfPauseResume)
+			status_.pauseState = libcamera::controls::AfPauseStateRunning;
+	}
 }
 
 void Af::SetWindows([[maybe_unused]] const libcamera::Rectangle &afWindows)
@@ -199,6 +207,10 @@  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];
 
+	/* If we are in a paused state, we won't process the stats */
+	if (status_.pauseState == libcamera::controls::AfPauseStatePaused)
+		return;
+
 	/* Depending on the mode, we may or may not process the stats */
 	if (status_.state == libcamera::controls::AfStateIdle)
 	    return;
diff --git a/src/ipa/raspberrypi/controller/iob/af.h b/src/ipa/raspberrypi/controller/iob/af.h
index 4ed50cfb..c4ab3574 100644
--- a/src/ipa/raspberrypi/controller/iob/af.h
+++ b/src/ipa/raspberrypi/controller/iob/af.h
@@ -26,6 +26,7 @@  public:
 	void SetMode(const uint32_t &mode) override;
 	void Trigger() override;
 	void Cancel() override;
+	void Pause(const uint32_t &pause) override;
 	void SetWindows(const libcamera::Rectangle &afWindows) override;
 	void SetRange(const uint32_t &range) override;
 	void setSpeed(const uint32_t &speed) override;
diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp
index 226388a7..8c6f213f 100644
--- a/src/ipa/raspberrypi/raspberrypi.cpp
+++ b/src/ipa/raspberrypi/raspberrypi.cpp
@@ -552,6 +552,7 @@  void IPARPi::reportMetadata()
 	AfStatus *afStatus = rpiMetadata_.GetLocked<AfStatus>("af.status");
 	if (afStatus) {
 		libcameraMetadata_.set(controls::AfState, afStatus->state);
+		libcameraMetadata_.set(controls::AfPauseState, afStatus->pauseState);
 	}
 }
 
@@ -971,6 +972,20 @@  void IPARPi::queueRequest(const ControlList &controls)
 			break;
 		}
 
+		case controls::AF_PAUSE: {
+			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;
+			}
+
+			af->Pause(ctrl.second.get<int32_t>());
+
+			break;
+		}
+
 		default:
 			LOG(IPARPI, Warning)
 				<< "Ctrl " << controls::controls.at(ctrl.first)->name()