From patchwork Fri Mar 24 14:29:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Semkowicz X-Patchwork-Id: 18448 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 BB0A9C329D for ; Fri, 24 Mar 2023 14:29:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 31B5062726; Fri, 24 Mar 2023 15:29:35 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1679668175; bh=FODGdPtQZZhgvjqOGU8oExhjvYtsMWjVyG+lNSK7Frw=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=oaiAphdeaAjvyR74lVHlx7wSN5427GdNS7Ms57sq3n7NC3MAXSdn4dSNBnDT2QUvP MqZBN0id2P78meW4HMVM9OyoMUZ7HnkPN0eguSpsBR0wU/6sJotOXg4wYMKQRU7L4F ExN24RrfWCr25JYAL6gIpKHz20dgt3GjQn35AgxV6rijPkW3jYRtOu3TD85xwqiVCn LUSVLHpHMjEVHu0DmvPIhvXS5iG/RaEBUInm7IAa5DB1s6iTHBNJE6BAZRjPUKyLAz Szrt1vkAHZjk8G2gEOUiDtqPbhNwYeeXiQlawNWzgHuWPrx3us3YQJR/OgZIBr9sCE r2vGUmlgVcR/A== Received: from mail-lj1-x22c.google.com (mail-lj1-x22c.google.com [IPv6:2a00:1450:4864:20::22c]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 87EB662717 for ; Fri, 24 Mar 2023 15:29:27 +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="Zexbqc7T"; dkim-atps=neutral Received: by mail-lj1-x22c.google.com with SMTP id g18so1918554ljl.3 for ; Fri, 24 Mar 2023 07:29:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=thaumatec-com.20210112.gappssmtp.com; s=20210112; t=1679668167; 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=7EsqPwgI0oXnlJ+z0E4iqsZzdQVGBOc459CaOA0zDf4=; b=Zexbqc7TM6Bg4nj9ugXqxAkFuuZa3IOWo1BAiBUOa4SEoG8cZ2ntUkr2gsjmRBJM3z bDGjpCAd62BBQStHst4JCAKR/OCGBeglqloNqTWlvbIiwfDq2h55Ccfrx9XrMz+ehY1R sxobdUGdZO0tg7thVEKbjGwhtZ0GPfxTbWKHW25Jk/1rIPd1CQBds2r/MpDP7rY8t3xs 7VagMc7ew6Eai1O11reB4OleN/YEbYoOZf3p+YLpqqAnI5M+OZGh/CTd+bpnk/pzKDfv h4xcyEMa5nz/PpbB1drAQfCL4Ca2cCnblXxtWX43dHdr/JussGD6cgz55u8BOLu0ZNtv ZFiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679668167; 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=7EsqPwgI0oXnlJ+z0E4iqsZzdQVGBOc459CaOA0zDf4=; b=Y7wF5cMWFufK0tbtuT3GwW+KJfW5owcsN09iS8G3OwU6ltBAf6nFwj6Ed1Nvq4pwAM u1riUPA2Zy8HnTsaFOjwKdwUUZBalcYzm6lKvZdgeMlHeLTSRCdUUXVeNa6VBnE78wMM CHjy1Wc/MTbnKdKupwoplGddoBzErWtEy0WNkjJihsFogC5Rgfg845Wtg0a3M7c1IL52 jWQtPbh/Ztwgx3Ei5NEWaqFa232yqUzct+0EPEQA+ElrWrz0RUfEKbkEKFTiuJoLIt7l zIJo1oLSY85tGqW9FDPdQsVtmJTXxUxl+xlXmVQqH/FBOCtzQ+Apgu4aLMPYIjpSDuJ8 I5+w== X-Gm-Message-State: AAQBX9eZqN9qUFHkwjWTdx15ysfXmfpcQU/EsNBFd8NRK9DcB1g7NZA4 PHdXtL/awDKUQDOWywwyBRtiOwn/7UXRcwHv5Sw= X-Google-Smtp-Source: AKy350ZkYs4cwLki5ju7CEaCrAoJPCSV0feza1p4BBF1ZExiO/F8IohswAqvqPfRi1rNSvLYWyv5nQ== X-Received: by 2002:a2e:b016:0:b0:29b:4f87:c7cf with SMTP id y22-20020a2eb016000000b0029b4f87c7cfmr937292ljk.26.1679668166860; Fri, 24 Mar 2023 07:29:26 -0700 (PDT) Received: from localhost.localdomain ([91.90.166.178]) by smtp.gmail.com with ESMTPSA id j21-20020a2e8515000000b002a10b2ea089sm981714lji.16.2023.03.24.07.29.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Mar 2023 07:29:26 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Fri, 24 Mar 2023 15:29:03 +0100 Message-Id: <20230324142908.64224-6-dse@thaumatec.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230324142908.64224-1-dse@thaumatec.com> References: <20230324142908.64224-1-dse@thaumatec.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 05/10] ipa: af_hill_climbing: Add "Windows" metering mode 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 Cc: jacopo.mondi@ideasonboard.com Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add support for setting user defined auto focus window in the AfHillClimbing. This enables usage of AfMetering and AfWindows controls. Each time, there is a need for changing the window configuration in the ISP, the signal is emitted. Platform layer that wants to use the "Windows" metering mode, needs to connect to this signal and configure the ISP on each emission. Currently only one window is supported. Signed-off-by: Daniel Semkowicz --- .../libipa/algorithms/af_hill_climbing.cpp | 53 ++++++++++++++++--- src/ipa/libipa/algorithms/af_hill_climbing.h | 12 ++++- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/ipa/libipa/algorithms/af_hill_climbing.cpp b/src/ipa/libipa/algorithms/af_hill_climbing.cpp index 6ee090eb..636a8674 100644 --- a/src/ipa/libipa/algorithms/af_hill_climbing.cpp +++ b/src/ipa/libipa/algorithms/af_hill_climbing.cpp @@ -63,9 +63,8 @@ LOG_DEFINE_CATEGORY(Af) * movement range rather than coarse search result. * \todo Implement setRange. * \todo Implement setSpeed. - * \todo Implement setMeteringMode. - * \todo Implement setWindows. * \todo Implement the AfPauseDeferred mode. + * \todo Implement support for multiple AF windows. */ /** @@ -97,15 +96,28 @@ int AfHillClimbing::init(const YamlObject &tuningData) * \brief Configure the AfHillClimbing with sensor and lens information * \param[in] minFocusPosition Minimum position supported by camera lens * \param[in] maxFocusPosition Maximum position supported by camera lens + * \param[in] outputSize Camera sensor output size * * This method should be called in the libcamera::ipa::Algorithm::configure() * method of the platform layer. */ void AfHillClimbing::configure(int32_t minFocusPosition, - int32_t maxFocusPosition) + int32_t maxFocusPosition, + const Size &outputSize) { minLensPosition_ = minFocusPosition; maxLensPosition_ = maxFocusPosition; + + /* + * Default AF window of 3/4 size of the camera sensor output, + * placed at the center + */ + defaultWindow_ = Rectangle(static_cast(outputSize.width / 8), + static_cast(outputSize.height / 8), + 3 * outputSize.width / 4, + 3 * outputSize.height / 4); + + windowUpdateRequested.emit(defaultWindow_); } /** @@ -194,6 +206,14 @@ void AfHillClimbing::setFramesToSkip(uint32_t n) framesToSkip_ = n; } +/** + * \var AfHillClimbing::windowUpdateRequested + * \brief Signal emitted when change in AF window was requested + * + * Platform layer supporting AF windows should connect to this signal + * and configure the ISP with new window on each emition. + */ + void AfHillClimbing::setMode(controls::AfModeEnum mode) { if (mode == mode_) @@ -219,14 +239,33 @@ void AfHillClimbing::setSpeed([[maybe_unused]] controls::AfSpeedEnum speed) LOG(Af, Error) << __FUNCTION__ << " not implemented!"; } -void AfHillClimbing::setMeteringMode([[maybe_unused]] controls::AfMeteringEnum metering) +void AfHillClimbing::setMeteringMode(controls::AfMeteringEnum metering) { - LOG(Af, Error) << __FUNCTION__ << " not implemented!"; + if (metering == meteringMode_) + return; + + if (metering == controls::AfMeteringWindows) { + windowUpdateRequested.emit(userWindow_); + } else { + windowUpdateRequested.emit(defaultWindow_); + } + + meteringMode_ = metering; } -void AfHillClimbing::setWindows([[maybe_unused]] Span windows) +void AfHillClimbing::setWindows(Span windows) { - LOG(Af, Error) << __FUNCTION__ << " not implemented!"; + if (windows.size() != 1) { + LOG(Af, Error) << "Only one AF window is supported"; + return; + } + + LOG(Af, Debug) << "setWindows: " << windows[0]; + + userWindow_ = windows[0]; + + if (meteringMode_ == controls::AfMeteringWindows) + windowUpdateRequested.emit(userWindow_); } void AfHillClimbing::setTrigger(controls::AfTriggerEnum trigger) diff --git a/src/ipa/libipa/algorithms/af_hill_climbing.h b/src/ipa/libipa/algorithms/af_hill_climbing.h index 47d2bbec..dee91f23 100644 --- a/src/ipa/libipa/algorithms/af_hill_climbing.h +++ b/src/ipa/libipa/algorithms/af_hill_climbing.h @@ -10,6 +10,7 @@ #pragma once #include +#include #include "af.h" @@ -25,13 +26,16 @@ class AfHillClimbing : public Af { public: int init(const YamlObject &tuningData); - void configure(int32_t minFocusPosition, int32_t maxFocusPosition); + void configure(int32_t minFocusPosition, int32_t maxFocusPosition, + const Size &outputSize); int32_t process(double currentContrast); void setFramesToSkip(uint32_t n); controls::AfStateEnum state() final { return state_; } controls::AfPauseStateEnum pauseState() final { return pauseState_; } + Signal windowUpdateRequested; + private: void setMode(controls::AfModeEnum mode) final; void setRange(controls::AfRangeEnum range) final; @@ -54,6 +58,7 @@ private: controls::AfModeEnum mode_ = controls::AfModeManual; controls::AfStateEnum state_ = controls::AfStateIdle; controls::AfPauseStateEnum pauseState_ = controls::AfPauseStateRunning; + controls::AfMeteringEnum meteringMode_ = controls::AfMeteringAuto; /* Current focus lens position. */ int32_t lensPosition_ = 0; @@ -84,6 +89,11 @@ private: /* Max ratio of variance change, 0.0 < maxChange_ < 1.0. */ double maxChange_; + + /* Default AF window. */ + Rectangle defaultWindow_; + /* AF window set by user using AF_WINDOWS control. */ + Rectangle userWindow_; }; } /* namespace ipa::algorithms */