@@ -20,20 +20,54 @@ namespace libcamera::ipa::rkisp1::algorithms {
LOG_DEFINE_CATEGORY(RkISP1Af)
+
+static rkisp1_cif_isp_window rectangleToIspWindow(const Rectangle &rectangle)
+{
+ rkisp1_cif_isp_window ispwindow;
+
+ ispwindow.h_offs = rectangle.x;
+ ispwindow.v_offs = rectangle.y;
+ ispwindow.h_size = rectangle.width;
+ ispwindow.v_size = rectangle.height;
+
+ return ispwindow;
+}
+
/**
* \copydoc libcamera::ipa::Algorithm::configure
*/
int Af::configure([[maybe_unused]] IPAContext &context,
- [[maybe_unused]] const IPACameraSensorInfo &configInfo)
+ const IPACameraSensorInfo &configInfo)
{
+ /* Default AF window of 3/4 size of the screen placed at the center */
+ defaultWindow_ = Rectangle(configInfo.outputSize.width / 8,
+ configInfo.outputSize.height / 8,
+ 3 * configInfo.outputSize.width / 4,
+ 3 * configInfo.outputSize.height / 4);
+ updateCurrentWindow(defaultWindow_);
+
return 0;
}
/**
* \copydoc libcamera::ipa::Algorithm::prepare
*/
-void Af::prepare([[maybe_unused]] IPAContext &context, [[maybe_unused]] rkisp1_params_cfg *params)
+void Af::prepare([[maybe_unused]] IPAContext &context, rkisp1_params_cfg *params)
{
+ if (updateAfwindow_) {
+ params->meas.afc_config.num_afm_win = 1;
+ params->meas.afc_config.thres = 128;
+ params->meas.afc_config.var_shift = 4;
+ /* \todo Allow setting thres and var_shift in tuning file */
+
+ params->meas.afc_config.afm_win[0] = rectangleToIspWindow(currentWindow_);
+
+ 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;
+
+ updateAfwindow_ = false;
+ }
}
/**
@@ -55,14 +89,42 @@ void Af::process(IPAContext &context,
context.frameContext.af.focus = lensPosition;
}
-void Af::setMetering([[maybe_unused]] controls::AfMeteringEnum metering)
+void Af::setMetering(controls::AfMeteringEnum metering)
{
- LOG(RkISP1Af, Error) << __FUNCTION__ << " not implemented!";
+ if (metering == meteringMode_)
+ return;
+
+ if (metering == controls::AfMeteringWindows) {
+ updateCurrentWindow(userWindow_);
+ } else {
+ updateCurrentWindow(defaultWindow_);
+ }
+
+ meteringMode_ = metering;
+}
+
+void Af::setWindows(Span<const Rectangle> windows)
+{
+ if (windows.size() != 1) {
+ LOG(RkISP1Af, Error) << "Only one AF window is supported";
+ return;
+ }
+
+ /* \todo Check if window size is valid for ISP */
+
+ LOG(RkISP1Af, Debug) << "setWindows: " << userWindow_;
+
+ userWindow_ = windows[0];
+
+ if (meteringMode_ == controls::AfMeteringWindows) {
+ updateCurrentWindow(userWindow_);
+ }
}
-void Af::setWindows([[maybe_unused]] Span<const Rectangle> windows)
+void Af::updateCurrentWindow(const Rectangle &window)
{
- LOG(RkISP1Af, Error) << __FUNCTION__ << " not implemented!";
+ currentWindow_ = window;
+ updateAfwindow_ = true;
}
REGISTER_IPA_ALGORITHM(Af, "Af")
@@ -27,6 +27,15 @@ public:
void setMetering(controls::AfMeteringEnum metering) override;
void setWindows(Span<const Rectangle> windows) override;
+
+private:
+ void updateCurrentWindow(const Rectangle &window);
+
+ controls::AfMeteringEnum meteringMode_ = controls::AfMeteringAuto;
+ Rectangle currentWindow_;
+ Rectangle defaultWindow_;
+ Rectangle userWindow_;
+ bool updateAfwindow_ = false;
};
} /* namespace libcamera::ipa::rkisp1::algorithms */
@@ -319,6 +319,26 @@ void IPARkISP1::queueRequest([[maybe_unused]] const uint32_t frame,
af->setMode(static_cast<controls::AfModeEnum>(ctrlValue.get<int32_t>()));
break;
}
+ case controls::AF_METERING: {
+ Af *af = getAlgorithm<Af>();
+ if (!af) {
+ LOG(IPARkISP1, Warning) << "Could not set AF_WINDOWS - no AF algorithm";
+ break;
+ }
+
+ af->setMetering(static_cast<controls::AfMeteringEnum>(ctrlValue.get<int32_t>()));
+ break;
+ }
+ case controls::AF_WINDOWS: {
+ Af *af = getAlgorithm<Af>();
+ if (!af) {
+ LOG(IPARkISP1, Warning) << "Could not set AF_WINDOWS - no AF algorithm";
+ break;
+ }
+
+ af->setWindows(ctrlValue.get<Span<const Rectangle>>());
+ break;
+ }
case controls::AF_TRIGGER: {
Af *af = getAlgorithm<Af>();
if (!af) {
@@ -961,6 +961,8 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
ControlInfoMap::Map ctrls({
{ &controls::AeEnable, ControlInfo(false, true) },
{ &controls::AfMode, ControlInfo(controls::AfModeValues) },
+ { &controls::AfMetering, ControlInfo(controls::AfMeteringValues) },
+ { &controls::AfWindows, ControlInfo(Rectangle{}, Rectangle(65535, 65535, 65535, 65535), Rectangle{}) },
{ &controls::AfTrigger, ControlInfo(controls::AfTriggerValues) },
{ &controls::AfPause, ControlInfo(controls::AfPauseValues) }
});
Allow manually setting auto focus window. 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 | 74 ++++++++++++++++++++++-- src/ipa/rkisp1/algorithms/af.h | 9 +++ src/ipa/rkisp1/rkisp1.cpp | 20 +++++++ src/libcamera/pipeline/rkisp1/rkisp1.cpp | 2 + 4 files changed, 99 insertions(+), 6 deletions(-)