@@ -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 */
@@ -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
@@ -18,5 +18,6 @@
struct AfStatus {
uint32_t lensPosition;
libcamera::controls::AfStateEnum state;
+ libcamera::controls::AfPauseStateEnum pauseState;
libcamera::Rectangle windows;
};
@@ -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;
@@ -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;
@@ -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()
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(-)