From patchwork Thu Jan 19 08:41:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Semkowicz X-Patchwork-Id: 18146 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 150DAC3240 for ; Thu, 19 Jan 2023 08:42:25 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CC530625EB; Thu, 19 Jan 2023 09:42:24 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1674117744; bh=/sWMrM0yDvzVCpeO45m6mMKX2012/YfF5BROtCocLs8=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=q+qP9boHawxIJW6aJJDT4Rpd24h6HbKn/w2R2eXN/0QRwRNj8S8W0FgPzZ5RJGlKf qBtIraDBBk/UrqUo+aDGVWgD4kJXKbLrK480zSP+xIiL3Wxi3WrNfXsaFgtVM120dn k9w71SNef2BAMg/vt263O+pTfOGiutUCI4bYxU55H3QZ99dYaTQ2NANI5Sd4ecDEWv 4q9zAB9SAGsydTRhBGFr5GgfeFyJB55A+DW5H406u+QHs1YTUTaP3Yczuqk76eqaj8 WIMRFh35tzhzUogxt1sOnfJBmOx0JV/0jM0sgxEwNtrD5Mo1Hc542R98hMmCqB7Z39 t6LkH82pvm5Eg== Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com [IPv6:2a00:1450:4864:20::32c]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9939F625F6 for ; Thu, 19 Jan 2023 09:42:13 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=thaumatec-com.20210112.gappssmtp.com header.i=@thaumatec-com.20210112.gappssmtp.com header.b="dRdmPQa/"; dkim-atps=neutral Received: by mail-wm1-x32c.google.com with SMTP id c4-20020a1c3504000000b003d9e2f72093so3044568wma.1 for ; Thu, 19 Jan 2023 00:42:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=thaumatec-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZdYpCqlVgBVjIXhtQANwxiepcG4LDSc5L3JxbSsR2KI=; b=dRdmPQa/2FfkiDhcclksM8LF+gn1x1tG7Fk9lwvzWmEDGiX0cAV3QMgO90SN9g25Dh bn10FV2R9aO72fFlISTdF/8FaV3njHioORxWF7O4H9JKJxhEzB6Qfhg/ksB5vNYPnQfN y5Xa7PN3SbmWIQWdNvjQJdkTewS1Ins3+U9Zf/2nm8S1+0J4gA2JdCzAuwoD9sX8wYsO kubQo/PkzP8Q353ICf43YCGbbVN7G4VWZ66JEoCpoX8oyoT+UxfdQ6OP8+mAUMycs+kj bbxy/Cc1hY5OpP2pnP7G40HAJPabfDq9umcfwfP80LksLJO0umreXjsBygJSL6f84Pe7 kMyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZdYpCqlVgBVjIXhtQANwxiepcG4LDSc5L3JxbSsR2KI=; b=K5gTNUpo3pZ1r8t514kJzZccsULFF39T4EZoBCsxgLevfxXUtL7U2Pv8JMEhYWk3c1 uKQc4HGMqTw92hIDiG9w+pAmUi2/FAXPWqoxTv0wGb8V6G24Lk1wgkjQMk1FTVnZCrG3 XXRVpqwZIxZZWh4SuXWuScG/qoNerko2e78Et2/vPRceDJ47EbWyB+GaM4ySQkbN4cfe DXuiU7k4DZjWnKFSs3YfkTZkQUPUpkYCZ0+DMxrfkz2nf5m0lAqsOWbUr1P9sRDn8CrH xnDLKHTaeDz5M42lc6UUBnNLaoZDth6TMTqHjE0KDunHKr8d066/q+E2DuY7flTEfzJG FvzQ== X-Gm-Message-State: AFqh2kpgWQbXbhgdXM1xIEg5yNSxLcE7t3DV0iAHrGSoCumXbIf07tqT C5HRfWbM9yrTCq2NKyAKw68Aar/62thm3S+RIJ4= X-Google-Smtp-Source: AMrXdXvd+oyp7qnUJ5BSw0OuEe7OaPrIKGJokgLkgwY/HnieD5B/pWyLQgeqIneK68tQRa3pig64Fw== X-Received: by 2002:a05:600c:3495:b0:3db:a3a:4594 with SMTP id a21-20020a05600c349500b003db0a3a4594mr8239090wmq.28.1674117733262; Thu, 19 Jan 2023 00:42:13 -0800 (PST) Received: from localhost.localdomain (ip092042140082.rev.nessus.at. [92.42.140.82]) by smtp.gmail.com with ESMTPSA id j10-20020a05600c074a00b003db0ee277b2sm3935754wmn.5.2023.01.19.00.42.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Jan 2023 00:42:12 -0800 (PST) To: libcamera-devel@lists.libcamera.org Date: Thu, 19 Jan 2023 09:41:11 +0100 Message-Id: <20230119084112.20564-8-dse@thaumatec.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230119084112.20564-1-dse@thaumatec.com> References: <20230119084112.20564-1-dse@thaumatec.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 7/8] ipa: rkisp1: Add "Windows" Metering mode to auto focus algorithm X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Daniel Semkowicz via libcamera-devel From: Daniel Semkowicz Reply-To: Daniel Semkowicz Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" 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(-) 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 bc2508a2..c300c3b0 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) },