From 0c249cbd2b3711e9372219b655e10bc5f5560a90 Mon Sep 17 00:00:00 2001 From: Daniel Semkowicz via libcamera-devel Date: Wed, 13 Jul 2022 10:43:14 +0200 Subject: ipa: rkisp1: Add "Windows" Metering mode to auto focus algorithm 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 --- src/ipa/rkisp1/algorithms/af.cpp | 74 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 6 deletions(-) (limited to 'src/ipa/rkisp1/algorithms/af.cpp') diff --git a/src/ipa/rkisp1/algorithms/af.cpp b/src/ipa/rkisp1/algorithms/af.cpp index 6e047804..cd4f0e08 100644 --- a/src/ipa/rkisp1/algorithms/af.cpp +++ b/src/ipa/rkisp1/algorithms/af.cpp @@ -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 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 windows) +void Af::updateCurrentWindow(const Rectangle &window) { - LOG(RkISP1Af, Error) << __FUNCTION__ << " not implemented!"; + currentWindow_ = window; + updateAfwindow_ = true; } REGISTER_IPA_ALGORITHM(Af, "Af") -- cgit v1.2.1