From 8e56eb6d087fd4e712a24e1e3c47dbc990867eec Mon Sep 17 00:00:00 2001 From: Daniel Semkowicz Date: Thu, 19 Jan 2023 09:41:11 +0100 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 | 93 +++++++++++++++++++++++++++++++++++++--- src/ipa/rkisp1/algorithms/af.h | 9 ++++ src/ipa/rkisp1/rkisp1.cpp | 2 + 3 files changed, 98 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/ipa/rkisp1/algorithms/af.cpp b/src/ipa/rkisp1/algorithms/af.cpp index c2a321cd..65768fc4 100644 --- a/src/ipa/rkisp1/algorithms/af.cpp +++ b/src/ipa/rkisp1/algorithms/af.cpp @@ -20,14 +20,32 @@ namespace libcamera::ipa::rkisp1::algorithms { LOG_DEFINE_CATEGORY(RkISP1Af) +namespace { + +constexpr rkisp1_cif_isp_window rectangleToIspWindow(const Rectangle &rectangle) +{ + return rkisp1_cif_isp_window{ + .h_offs = static_cast(rectangle.x), + .v_offs = static_cast(rectangle.y), + .h_size = static_cast(rectangle.width), + .v_size = static_cast(rectangle.height) + }; +} + +} /* namespace */ + /** * \copydoc libcamera::ipa::Algorithm::init */ int Af::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData) { waitFramesLens_ = tuningData["wait-frames-lens"].get(1); + ispThreshold_ = tuningData["isp-threshold"].get(128); + ispVarShift_ = tuningData["isp-var-shift"].get(4); - LOG(RkISP1Af, Debug) << "waitFramesLens_: " << waitFramesLens_; + LOG(RkISP1Af, Debug) << "waitFramesLens_: " << waitFramesLens_ + << ", ispThreshold_: " << ispThreshold_ + << ", ispVarShift_: " << ispVarShift_; return initBase(tuningData); } @@ -36,8 +54,15 @@ int Af::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData) * \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; } @@ -50,6 +75,21 @@ void Af::queueRequest([[maybe_unused]] IPAContext &context, const ControlList &controls) { queueRequestBase(frame, controls); + + for (auto const &[id, value] : controls) { + switch (id) { + case controls::AF_METERING: { + setMeteringMode(static_cast(value.get())); + break; + } + case controls::AF_WINDOWS: { + setWindows(value.get>()); + break; + } + default: + break; + } + } } /** @@ -58,8 +98,23 @@ void Af::queueRequest([[maybe_unused]] IPAContext &context, void Af::prepare([[maybe_unused]] IPAContext &context, [[maybe_unused]] const uint32_t frame, [[maybe_unused]] IPAFrameContext &frameContext, - [[maybe_unused]] rkisp1_params_cfg *params) + rkisp1_params_cfg *params) { + if (updateWindow_) { + params->meas.afc_config.num_afm_win = 1; + params->meas.afc_config.thres = ispThreshold_; + params->meas.afc_config.var_shift = ispVarShift_; + params->meas.afc_config.afm_win[0] = rectangleToIspWindow(*updateWindow_); + + 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; + + updateWindow_.reset(); + + /* Wait one frame for the ISP to apply changes */ + setFramesToSkip(1); + } } /** @@ -88,12 +143,38 @@ void Af::process(IPAContext &context, [[maybe_unused]] const uint32_t frame, void Af::setMeteringMode([[maybe_unused]] 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!"; + updateWindow_ = window; } REGISTER_IPA_ALGORITHM(Af, "Af") diff --git a/src/ipa/rkisp1/algorithms/af.h b/src/ipa/rkisp1/algorithms/af.h index 882be952..72cc7932 100644 --- a/src/ipa/rkisp1/algorithms/af.h +++ b/src/ipa/rkisp1/algorithms/af.h @@ -35,6 +35,15 @@ private: void setMeteringMode(controls::AfMeteringEnum metering) final; void setWindows(Span windows) final; + void updateCurrentWindow(const Rectangle &window); + + controls::AfMeteringEnum meteringMode_ = controls::AfMeteringAuto; + Rectangle defaultWindow_; + Rectangle userWindow_; + std::optional updateWindow_; + uint32_t ispThreshold_; + uint32_t ispVarShift_; + /* Wait number of frames after changing lens position */ uint32_t waitFramesLens_; }; diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index 2ad711d5..32839360 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -101,9 +101,11 @@ namespace { /* List of controls handled by the RkISP1 IPA */ const ControlInfoMap::Map rkisp1Controls{ { &controls::AeEnable, ControlInfo(false, true) }, + { &controls::AfMetering, ControlInfo(controls::AfMeteringValues) }, { &controls::AfMode, ControlInfo(controls::AfModeValues) }, { &controls::AfPause, ControlInfo(controls::AfPauseValues) }, { &controls::AfTrigger, ControlInfo(controls::AfTriggerValues) }, + { &controls::AfWindows, ControlInfo(Rectangle{}, Rectangle(65535, 65535, 65535, 65535), Rectangle{}) }, { &controls::AwbEnable, ControlInfo(false, true) }, { &controls::ColourGains, ControlInfo(0.0f, 3.996f, 1.0f) }, { &controls::Brightness, ControlInfo(-1.0f, 0.993f, 0.0f) }, -- cgit v1.2.1