From patchwork Mon Jun 13 14:28:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 16210 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 B96F7C3273 for ; Mon, 13 Jun 2022 14:29:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3C83065646; Mon, 13 Jun 2022 16:29:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1655130542; bh=pCUBdvfmR8EpviWT+F/VZq32WxVsPa1B4jht1VZ92xA=; 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=iV7M2VX4TddV3XEUJw4NjopPaxyTxIJZuuCuq/i2CI3sSEdF2srLuz4DkbLNc9VvE nzc1Jvai+e9JJJQqHoZQMu5f6+uwxD0+itxvocXly+fDIzxVRmCbDyiD6GMXZ/g1J1 5yIoLM+1ENr3GImH5LTg1shnMkLoWmh9OpR2LwMi8YEN2mmzyP4NJWwRcNRexT3pD3 mG9bBt+pX8fdCxRQz7AcG9/VmtzK5tZQJyGxuIkIdd9afJk8wfXGnL+5Bh9lefQPKJ MNw+GpV5lPEw2gC9J9cr2vgWJKxVgIwnhlY21ClZEbjA47OYq1CCLzc695VLnzHGNZ xs+3BsVPwoPAQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 32D8665631 for ; Mon, 13 Jun 2022 16:29:00 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="f1hm0Gwq"; dkim-atps=neutral Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:a1c7:c28c:7720:9b30]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C7606440; Mon, 13 Jun 2022 16:28:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1655130539; bh=pCUBdvfmR8EpviWT+F/VZq32WxVsPa1B4jht1VZ92xA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=f1hm0GwqlXfk7cUZKM6OIVOY36kS5lbAFDu0zkmOok97uMVxVgTLUqj4pGDkKMc4O UZr8campxZSoYyIbrNctOZajy3YllVD5YqhNNVcmFbylndC6qHFpPX198oEUCXwYNH 9egicTpspIuocgmrdJO8tySbKsZx9m525wsOtlno= To: libcamera-devel@lists.libcamera.org Date: Mon, 13 Jun 2022 16:28:44 +0200 Message-Id: <20220613142853.98484-2-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> References: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 01/10] ipa: raspberrypi: Introduce an autofocus 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: Jean-Michel Hautbois via libcamera-devel From: Jean-Michel Hautbois Reply-To: Jean-Michel Hautbois Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Now that the ancillary links are plumbed and we can set the lens position, implement a contrast-based algorithm for RPi. This algorithm is adapted from the one proposed for the IPU3 IPA. It is currently taking all the regions and tries to make the focus on the global scene in a first attempt. Signed-off-by: Jean-Michel Hautbois --- .../raspberrypi/controller/af_algorithm.hpp | 33 +++ src/ipa/raspberrypi/controller/af_status.h | 21 ++ src/ipa/raspberrypi/controller/iob/af.cpp | 212 ++++++++++++++++++ src/ipa/raspberrypi/controller/iob/af.h | 62 +++++ src/ipa/raspberrypi/meson.build | 1 + 5 files changed, 329 insertions(+) create mode 100644 src/ipa/raspberrypi/controller/af_algorithm.hpp create mode 100644 src/ipa/raspberrypi/controller/af_status.h create mode 100644 src/ipa/raspberrypi/controller/iob/af.cpp create mode 100644 src/ipa/raspberrypi/controller/iob/af.h diff --git a/src/ipa/raspberrypi/controller/af_algorithm.hpp b/src/ipa/raspberrypi/controller/af_algorithm.hpp new file mode 100644 index 00000000..1e7aaa45 --- /dev/null +++ b/src/ipa/raspberrypi/controller/af_algorithm.hpp @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (C) 2022, Raspberry Pi (Trading) Limited + * + * af_algorithm.hpp - autofocus control algorithm interface + */ +#pragma once + +#include + +#include "algorithm.hpp" + +namespace RPiController { + +class AfAlgorithm : public Algorithm +{ +public: + AfAlgorithm(Controller *controller) : Algorithm(controller) {} + // An af algorithm must provide the following: + virtual void SetMode(const uint32_t &mode) = 0; + // start a cycle (in auto mode) + virtual void Trigger() = 0; + // cancel a cycle (in auto mode) + virtual void Cancel() = 0; + // set AF windows + virtual void SetWindows(const libcamera::Rectangle &afWindows) = 0; + // set AF range + virtual void SetRange(const uint32_t &range) = 0; + // set AF speed + virtual void setSpeed(const uint32_t &speed) = 0; +}; + +} // namespace RPiController diff --git a/src/ipa/raspberrypi/controller/af_status.h b/src/ipa/raspberrypi/controller/af_status.h new file mode 100644 index 00000000..f8cb1301 --- /dev/null +++ b/src/ipa/raspberrypi/controller/af_status.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (C) 2022, Raspberry Pi (Trading) Limited + * Copyright (C) 2022, Ideas On Board + * + * af_status.h - autofocus measurement status + */ +#pragma once + +#include + +/* + * The focus algorithm should post the following structure into the image's + * "af.status" metadata. + */ + +struct AfStatus { + uint32_t lensPosition; + uint32_t state; + libcamera::Rectangle windows; +}; diff --git a/src/ipa/raspberrypi/controller/iob/af.cpp b/src/ipa/raspberrypi/controller/iob/af.cpp new file mode 100644 index 00000000..12d41c81 --- /dev/null +++ b/src/ipa/raspberrypi/controller/iob/af.cpp @@ -0,0 +1,212 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Red Hat + * Copyright (C) 2022, Ideas On Board + * + * af.cpp - automatic contrast-based focus algorithm + */ +#include + +#include + +#include + +#include "af.h" + +using namespace RPiController; +using namespace libcamera; + +LOG_DEFINE_CATEGORY(IoBAf) + +#define NAME "iob.af" + +/* + * Maximum focus steps of the VCM control + * \todo should be obtained from the VCM driver + */ +static constexpr uint32_t kMaxFocusSteps = 1023; + +/* Minimum focus step for searching appropriate focus */ +static constexpr uint32_t kCoarseSearchStep = 30; +static constexpr uint32_t kFineSearchStep = 1; + +/* Max ratio of variance change, 0.0 < kMaxChange < 1.0 */ +static constexpr double kMaxChange = 0.5; + +/* Fine scan range 0 < kFineRange < 1 */ +static constexpr double kFineRange = 0.05; + +Af::Af(Controller *controller) + : AfAlgorithm(controller), focus_(0), bestFocus_(0), + currentContrast_(0.0), previousContrast_(0.0), maxContrast_(0.0), + maxStep_(0), coarseCompleted_(false), fineCompleted_(false), + mode_(0) +{ +} + +char const *Af::Name() const +{ + return NAME; +} + +void Af::SetMode([[maybe_unused]] const uint32_t &mode) +{ + mode_ = mode; +} + +void Af::Trigger() +{ +} + +void Af::Cancel() +{ +} + +void Af::SetWindows([[maybe_unused]] const libcamera::Rectangle &afWindows) +{ +} + +void Af::SetRange([[maybe_unused]] const uint32_t &range) +{ +} + +void Af::setSpeed([[maybe_unused]] const uint32_t &speed) +{ +} + +void Af::Initialise() +{ + status_.lensPosition = 0.0; + maxContrast_ = 0.0; + status_.state = 1; +} + +void Af::Prepare(Metadata *image_metadata) +{ + image_metadata->Set("af.status", status_); +} + +void Af::afCoarseScan() +{ + if (coarseCompleted_) + return; + + if (afScan(kCoarseSearchStep)) { + coarseCompleted_ = true; + maxContrast_ = 0; + focus_ = status_.lensPosition - (status_.lensPosition * kFineRange); + status_.lensPosition = focus_; + previousContrast_ = 0; + maxStep_ = std::clamp(focus_ + static_cast((focus_ * kFineRange)), + 0U, kMaxFocusSteps); + } +} + +void Af::afFineScan() +{ + if (!coarseCompleted_) + return; + + if (afScan(kFineSearchStep)) { + LOG(IoBAf, Debug) << "AF found the best focus position !"; + status_.state = 2; + fineCompleted_ = true; + } +} + +bool Af::afScan(uint32_t minSteps) +{ + if (focus_ > maxStep_) { + /* If the max step is reached, move lens to the position. */ + status_.lensPosition = bestFocus_; + return true; + } else { + /* + * Find the maximum of the variance by estimating its + * derivative. If the direction changes, it means we have passed + * a maximum one step before. + */ + if ((currentContrast_ - maxContrast_) >= -(maxContrast_ * 0.1)) { + /* + * Positive and zero derivative: + * The variance is still increasing. The focus could be + * increased for the next comparison. Also, the max + * variance and previous focus value are updated. + */ + bestFocus_ = focus_; + focus_ += minSteps; + maxContrast_ = currentContrast_; + status_.lensPosition = focus_; + } else { + /* + * Negative derivative: + * The variance starts to decrease which means the maximum + * variance is found. Set focus step to previous good one + * then return immediately. + */ + status_.lensPosition = bestFocus_; + return true; + } + } + + previousContrast_ = currentContrast_; + LOG(IoBAf, Debug) << " Previous step is " + << bestFocus_ + << " Current step is " + << focus_; + return false; +} + +void Af::afReset() +{ + LOG(IoBAf, Debug) << "Reset AF parameters"; + status_.lensPosition = 0; + focus_ = 0; + status_.state = 0; + previousContrast_ = 0.0; + coarseCompleted_ = false; + fineCompleted_ = false; + maxStep_ = kMaxFocusSteps; + maxContrast_ = 0.0; +} + +bool Af::afIsOutOfFocus() +{ + const uint32_t diff_var = std::abs(currentContrast_ - + maxContrast_); + const double var_ratio = diff_var / maxContrast_; + LOG(IoBAf, Debug) << "Variance change rate: " + << var_ratio + << " Current VCM step: " + << status_.lensPosition; + if (var_ratio > kMaxChange) + return true; + else + return false; +} + +void Af::Process(StatisticsPtr &stats, [[maybe_unused]] Metadata *image_metadata) +{ + unsigned int i; + currentContrast_ = 0.0; + + /* Use the second filter results only, and cache those. */ + for (i = 0; i < FOCUS_REGIONS; i++) + currentContrast_ += stats->focus_stats[i].contrast_val[1][1] + / stats->focus_stats[i].contrast_val_num[1][1]; + + if (status_.state != 2) { + afCoarseScan(); + afFineScan(); + } else { + if (afIsOutOfFocus()) + afReset(); + } +} + +/* Register algorithm with the system. */ +static Algorithm *Create(Controller *controller) +{ + return new Af(controller); +} +static RegisterAlgorithm reg(NAME, &Create); diff --git a/src/ipa/raspberrypi/controller/iob/af.h b/src/ipa/raspberrypi/controller/iob/af.h new file mode 100644 index 00000000..4ed50cfb --- /dev/null +++ b/src/ipa/raspberrypi/controller/iob/af.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Red Hat + * Copyright (C) 2022, Ideas On Board + * + * af.h - automatic contrast-based focus algorithm + */ +#pragma once + +#include + +#include "../af_algorithm.hpp" +#include "../af_status.h" +#include "../metadata.hpp" + +namespace RPiController { + +class Af : public AfAlgorithm +{ +public: + Af(Controller *controller); + char const *Name() const override; + void Initialise() override; + void Prepare(Metadata *image_metadata) override; + void Process(StatisticsPtr &stats, Metadata *image_metadata) override; + void SetMode(const uint32_t &mode) override; + void Trigger() override; + void Cancel() override; + void SetWindows(const libcamera::Rectangle &afWindows) override; + void SetRange(const uint32_t &range) override; + void setSpeed(const uint32_t &speed) override; +private: + bool afNeedIgnoreFrame(); + void afCoarseScan(); + void afFineScan(); + bool afScan(uint32_t minSteps); + void afReset(); + bool afIsOutOfFocus(); + + AfStatus status_; + + /* VCM step configuration. It is the current setting of the VCM step. */ + uint32_t focus_; + /* The best VCM step. It is a local optimum VCM step during scanning. */ + uint32_t bestFocus_; + + /* Current AF statistic contrast. */ + double currentContrast_; + /* It is used to determine the derivative during scanning */ + double previousContrast_; + double maxContrast_; + /* The designated maximum range of focus scanning. */ + uint32_t maxStep_; + /* If the coarse scan completes, it is set to true. */ + bool coarseCompleted_; + /* If the fine scan completes, it is set to true. */ + bool fineCompleted_; + + uint32_t mode_; +}; + +} /* namespace RPiController */ diff --git a/src/ipa/raspberrypi/meson.build b/src/ipa/raspberrypi/meson.build index 32897e07..37068ecc 100644 --- a/src/ipa/raspberrypi/meson.build +++ b/src/ipa/raspberrypi/meson.build @@ -28,6 +28,7 @@ rpi_ipa_sources = files([ 'controller/controller.cpp', 'controller/histogram.cpp', 'controller/algorithm.cpp', + 'controller/iob/af.cpp', 'controller/rpi/alsc.cpp', 'controller/rpi/awb.cpp', 'controller/rpi/sharpen.cpp', From patchwork Mon Jun 13 14:28:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 16211 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 0BE32C3274 for ; Mon, 13 Jun 2022 14:29:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id ABD5365641; Mon, 13 Jun 2022 16:29:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1655130544; bh=BfG8mLPyRgMbK5UtRblM/WXf8sFjwr0mQ1tQGW7PjHc=; 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=3Q77JQfaakhU1Eh7Lc+pJtXEQootR7K93ouqUcXYv5gBS2Df6Zo68DuPPuny/qjpx g85eSr0WitQNXvkrgNUT96dK+n0k1clK4Pb6EtYDufakoHZdohACo1LyomTcUUwxck GwCXzN/tj0+3H/1AmT6bBCHdivQ5u9W8X66aiXJKVVEmNOTBwxLHDss6PbHrktfjoC j9gzcSwE5PcU4DtySEtjte8E9uZR/FqP/tHF8uc/JOcKg6RAiLaIuJ3Kn/grmt/kPd kK7cxRoMnNUZKgaYqDW0Io8082udBOO3FMErCL0awbzEsMrG8nnD8V8u0C7REdSby2 LjPy6+7nm/wCA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6856065632 for ; Mon, 13 Jun 2022 16:29:00 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="azF//k2j"; dkim-atps=neutral Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:a1c7:c28c:7720:9b30]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0C1C0835; Mon, 13 Jun 2022 16:29:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1655130540; bh=BfG8mLPyRgMbK5UtRblM/WXf8sFjwr0mQ1tQGW7PjHc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=azF//k2jiqtbH5oG0BrbHpssj4XwCo3m4+DWMi7DjeswzkZH9q5o6QCsg4F1pFhlU dsTzYF0EpmzyX0VeTtqE6NCn3y2TEd+SLp6MLhiYE+kd2bAhS9VrpdMTXUfC5NWLNn CrVdwoSFBHdPmpj0LhT6qFqORplxKmSdGp6RVM7M= To: libcamera-devel@lists.libcamera.org Date: Mon, 13 Jun 2022 16:28:45 +0200 Message-Id: <20220613142853.98484-3-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> References: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 02/10] libcamera: raspberrypi: Control the lens from pipeline 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: Jean-Michel Hautbois via libcamera-devel From: Jean-Michel Hautbois Reply-To: Jean-Michel Hautbois Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The lens focus is controled by a VCM, which is linked to the sensor using the ancillary links. Pass the control to the config info structure and make it possible to update by the IPA. Signed-off-by: Jean-Michel Hautbois --- include/libcamera/ipa/raspberrypi.mojom | 1 + .../pipeline/raspberrypi/raspberrypi.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/include/libcamera/ipa/raspberrypi.mojom b/include/libcamera/ipa/raspberrypi.mojom index a60c3bb4..42c5134b 100644 --- a/include/libcamera/ipa/raspberrypi.mojom +++ b/include/libcamera/ipa/raspberrypi.mojom @@ -131,4 +131,5 @@ interface IPARPiEventInterface { embeddedComplete(uint32 bufferId); setIspControls(libcamera.ControlList controls); setDelayedControls(libcamera.ControlList controls); + setLensControls(libcamera.ControlList controls); }; diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index adc397e8..90ea7eaa 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -33,6 +33,7 @@ #include "libcamera/internal/bayer_format.h" #include "libcamera/internal/camera.h" +#include "libcamera/internal/camera_lens.h" #include "libcamera/internal/camera_sensor.h" #include "libcamera/internal/delayed_controls.h" #include "libcamera/internal/device_enumerator.h" @@ -211,6 +212,7 @@ public: void setDelayedControls(const ControlList &controls); void setSensorControls(ControlList &controls); void unicamTimeout(); + void setLensControls(const ControlList &controls); /* bufferComplete signal handlers. */ void unicamBufferDequeue(FrameBuffer *buffer); @@ -1521,6 +1523,7 @@ int RPiCameraData::loadIPA(ipa::RPi::SensorConfig *sensorConfig) ipa_->embeddedComplete.connect(this, &RPiCameraData::embeddedComplete); ipa_->setIspControls.connect(this, &RPiCameraData::setIspControls); ipa_->setDelayedControls.connect(this, &RPiCameraData::setDelayedControls); + ipa_->setLensControls.connect(this, &RPiCameraData::setLensControls); /* * The configuration (tuning file) is made from the sensor name unless @@ -1557,6 +1560,10 @@ int RPiCameraData::configureIPA(const CameraConfiguration *config, ipa::RPi::IPA entityControls.emplace(0, sensor_->controls()); entityControls.emplace(1, isp_[Isp::Input].dev()->controls()); + CameraLens *lens = sensor_->focusLens(); + if (lens) + entityControls.emplace(2, lens->controls()); + /* Always send the user transform to the IPA. */ ipaConfig.transform = static_cast(config->transform); @@ -1773,6 +1780,16 @@ void RPiCameraData::setDelayedControls(const ControlList &controls) handleState(); } +void RPiCameraData::setLensControls(const ControlList &ctrls) +{ + CameraLens *lens = sensor_->focusLens(); + if (!lens) + return; + + /* \todo Should we keep track of the latest value applied ? */ + lens->setFocusPosition(ctrls.get(V4L2_CID_FOCUS_ABSOLUTE).get()); +} + void RPiCameraData::setSensorControls(ControlList &controls) { /* From patchwork Mon Jun 13 14:28:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 16212 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 DC6FFC3275 for ; Mon, 13 Jun 2022 14:29:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2BD9565652; Mon, 13 Jun 2022 16:29:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1655130546; bh=rdz4OCdCQzkW6WAN4X6RgX/WInxGu7PZPMZvTejgqEo=; 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=l9EkuC31EkcGMw9VcL28eFznJBMgAwv0WzSqZtin8oK2Ls+zukQu/8naQznSEFl9a QJskUt/nAwpXXdc4RGan79i/3gOFEggqc458sqmS5EjrcUq+FArGnslvM9drZeddKW 36DX2BBJfalLvk0jlUw6cv3tkAQlf1IKBX7B5bbJ/6BH5L1EeJmnOYxkmuMY1dqNry OqbOY7uyLmeElKg7dfH/hTIrQrBSiOannMSrcn30XwyFNaluwi2rPkahqxikrHo9lB IJTcKSrDv6rE308Tt/Af7wmcNe9bmnqi3M3e8lhToBq459TO89nVvxmM6dorOuNsgH iYzWCdLhJlQPA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 93884600F1 for ; Mon, 13 Jun 2022 16:29:00 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="rMv4jRdn"; dkim-atps=neutral Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:a1c7:c28c:7720:9b30]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 41ABD305; Mon, 13 Jun 2022 16:29:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1655130540; bh=rdz4OCdCQzkW6WAN4X6RgX/WInxGu7PZPMZvTejgqEo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rMv4jRdnc3hxEteD2SudNS6QnkKP2C370z9kFiZ2g8gyAJ+sn/c/7VKlU4vH3LTr1 lMwo4tCwcc7gWVO4HxEzaIEEqyapuJpkRI/nK+IfoYtLXc+EIdnaGgPndW9Sn52hIi TQ7VgDdrH8Be10Mo2Tjn0hifXbwX+bxm0RMik+zU= To: libcamera-devel@lists.libcamera.org Date: Mon, 13 Jun 2022 16:28:46 +0200 Message-Id: <20220613142853.98484-4-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> References: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 03/10] ipa: raspberrypi: Control the lens position 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: Jean-Michel Hautbois via libcamera-devel From: Jean-Michel Hautbois Reply-To: Jean-Michel Hautbois Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Now that the ancillary links are configured, we can use the CameraLens class and control the VCM through the IPA. Signed-off-by: Jean-Michel Hautbois --- src/ipa/raspberrypi/raspberrypi.cpp | 30 ++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 3b126bb5..1e9e2e61 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -30,6 +30,7 @@ #include "libcamera/internal/mapped_framebuffer.h" +#include "af_status.h" #include "agc_algorithm.hpp" #include "agc_status.h" #include "alsc_status.h" @@ -110,6 +111,7 @@ private: void setMode(const IPACameraSensorInfo &sensorInfo); bool validateSensorControls(); bool validateIspControls(); + bool validateLensControls(); void queueRequest(const ControlList &controls); void returnEmbeddedBuffer(unsigned int bufferId); void prepareISP(const ISPConfig &data); @@ -134,6 +136,7 @@ private: ControlInfoMap sensorCtrls_; ControlInfoMap ispCtrls_; + ControlInfoMap lensCtrls_; ControlList libcameraMetadata_; /* Camera sensor params. */ @@ -346,7 +349,7 @@ int IPARPi::configure(const IPACameraSensorInfo &sensorInfo, const IPAConfig &ipaConfig, ControlList *controls, IPAConfigResult *result) { - if (entityControls.size() != 2) { + if (entityControls.size() < 2) { LOG(IPARPI, Error) << "No ISP or sensor controls found."; return -1; } @@ -354,6 +357,14 @@ int IPARPi::configure(const IPACameraSensorInfo &sensorInfo, sensorCtrls_ = entityControls.at(0); ispCtrls_ = entityControls.at(1); + /* Lens may not be present, don't make it an hard assumption. */ + auto lensControl = entityControls.find(2); + if (lensControl != entityControls.end()) { + lensCtrls_ = lensControl->second; + if (!validateLensControls()) + LOG(IPARPI, Error) << "Lens control validation failed."; + } + if (!validateSensorControls()) { LOG(IPARPI, Error) << "Sensor control validation failed."; return -1; @@ -585,6 +596,23 @@ bool IPARPi::validateIspControls() return true; } +bool IPARPi::validateLensControls() +{ + static const uint32_t ctrls[] = { + V4L2_CID_FOCUS_ABSOLUTE, + }; + + for (auto c : ctrls) { + if (lensCtrls_.find(c) == lensCtrls_.end()) { + LOG(IPARPI, Error) << "Unable to find lens control " + << utils::hex(c); + return false; + } + } + + return true; +} + /* * Converting between enums (used in the libcamera API) and the names that * we use to identify different modes. Unfortunately, the conversion tables From patchwork Mon Jun 13 14:28:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 16213 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 C3F82C3276 for ; Mon, 13 Jun 2022 14:29:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 80D6F65637; Mon, 13 Jun 2022 16:29:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1655130547; bh=kWPYmsC3gArNgGN0Lgmk04URpBFgcaidkxOv3EkffAE=; 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=OOQDcdUAFHlW2jkNNYs0kHBJRPhCJxNGiaVOpYjXHo6QdXe+2Fc3TdpJKvAavHH1K 73e7sWk46ztOMXX1FlmjvSJAgJI8VX9qIdKMBDPTbBnhylLWN7sVBrMM2rJ4rwVcUi RtwzloTXcP+L+kvZy4RxrukYZKiQFRkwK8pXZgUKvUZzeI3mdspnZ8VkdlESIp+Em9 Espm7A2aRRM9uBz+LpIFJ/W/tVo3sl0pCpkw57AgDo8AIGl5FnPRr5eogxNjpBdNvf 2Oozf0wJbPqnj+Z5ySo6QQVfaYV3nBxGoT6ZY8ZtYTa93XOJL8EB1BYyiFDnsLvga9 vP9KPaJFTEMAQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C472D65635 for ; Mon, 13 Jun 2022 16:29:00 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="SP3rZjTI"; dkim-atps=neutral Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:a1c7:c28c:7720:9b30]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7845687B; Mon, 13 Jun 2022 16:29:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1655130540; bh=kWPYmsC3gArNgGN0Lgmk04URpBFgcaidkxOv3EkffAE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SP3rZjTI3x4nX6UHx+BTIkqjPv3I7Si0WAGKpkcL97A2RmAx16l4UnJGQhEUtz6CD AwzqaaJRLUTz8cyZHrNC8Ov0TaPKlRXh4idRfPjVu6MlP9SWIxkwm1c+YYXnpT9rJ7 3l4iP6+L0p9nVQ2w+q9knEvgQdZGGsBB7vUUGDv4= To: libcamera-devel@lists.libcamera.org Date: Mon, 13 Jun 2022 16:28:47 +0200 Message-Id: <20220613142853.98484-5-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> References: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 04/10] ipa: raspberrypi: Send the AF status back 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: Jean-Michel Hautbois via libcamera-devel From: Jean-Michel Hautbois Reply-To: Jean-Michel Hautbois Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The user can read the status for each frame with the AfState control value. Populate the AF status into the metadata when it is available. Signed-off-by: Jean-Michel Hautbois --- include/libcamera/ipa/raspberrypi.h | 3 ++- src/ipa/raspberrypi/raspberrypi.cpp | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h index 6a56b008..519f7160 100644 --- a/include/libcamera/ipa/raspberrypi.h +++ b/include/libcamera/ipa/raspberrypi.h @@ -45,7 +45,8 @@ static const ControlInfoMap Controls({ { &controls::ColourCorrectionMatrix, ControlInfo(-16.0f, 16.0f) }, { &controls::ScalerCrop, ControlInfo(Rectangle{}, Rectangle(65535, 65535, 65535, 65535), Rectangle{}) }, { &controls::FrameDurationLimits, ControlInfo(INT64_C(1000), INT64_C(1000000000)) }, - { &controls::draft::NoiseReductionMode, ControlInfo(controls::draft::NoiseReductionModeValues) } + { &controls::draft::NoiseReductionMode, ControlInfo(controls::draft::NoiseReductionModeValues) }, + { &controls::AfState, ControlInfo(controls::AfStateValues) } }, controls::controls); } /* namespace RPi */ diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 1e9e2e61..a4e1c834 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -547,6 +547,11 @@ void IPARPi::reportMetadata() m[i] = ccmStatus->matrix[i]; libcameraMetadata_.set(controls::ColourCorrectionMatrix, m); } + + AfStatus *afStatus = rpiMetadata_.GetLocked("af.status"); + if (afStatus) { + libcameraMetadata_.set(controls::AfState, afStatus->state); + } } bool IPARPi::validateSensorControls() @@ -1101,6 +1106,14 @@ void IPARPi::processStats(unsigned int bufferId) setDelayedControls.emit(ctrls); } + + struct AfStatus afStatus; + if (rpiMetadata_.Get("af.status", afStatus) == 0) { + ControlList lensCtrls(lensCtrls_); + lensCtrls.set(V4L2_CID_FOCUS_ABSOLUTE, + static_cast(afStatus.lensPosition)); + setLensControls.emit(lensCtrls); + } } void IPARPi::applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls) From patchwork Mon Jun 13 14:28:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 16214 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 268C4C3277 for ; Mon, 13 Jun 2022 14:29:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C94C46563F; Mon, 13 Jun 2022 16:29:08 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1655130549; bh=8qgOFag72F04VxPWN61txryRmlxFyVU8SBwJO0kuhFY=; 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=DOEfRgKMykN8WmOW+H+DeHsRvAM2wjjYmn1bmSJ95Pyex1NN0mxrPR94CIMkFAm5O exLLvuhj/BMLC/DF5ltgr4p5HJQZPjxe1qYToYiDvLINq2vJstuUDPfU2Ef/yZu3QI lnN1qBnXrl+KeZWPssHT4dl6Phn+TlNOT+8M16YP8yI11YRRFuVL7WgekbixmQdMiA wVr3dIp1HnCceYWP6pU0/Yw+cxaaKfZssEiMJ47gvoUh0SQU5k+tJ4rTQ7CzR5ZtWS MHmLuu+yBSxdXfIgbs7kA1lRLZ/quBi+sA1M+rd644dSD+dg0d9N3TehxWL7pRGAIJ h00XHlqA8tT8g== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 07C4E65631 for ; Mon, 13 Jun 2022 16:29:01 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ia2q/OSK"; dkim-atps=neutral Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:a1c7:c28c:7720:9b30]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B0363440; Mon, 13 Jun 2022 16:29:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1655130540; bh=8qgOFag72F04VxPWN61txryRmlxFyVU8SBwJO0kuhFY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ia2q/OSKhvF+p5JkZCaeuxONOzUDaOtgHorPNN0b96q5Aedy/ryYN7q0pk6giskJ2 a5rx2iusiR/jBdNdP42r+MJY51E9IHvO3N3mbPlmXItfUURqZxBDathrXEdBfHvrbJ Nk8RlYw7AtIGQUMRVYDCsXYnqfq9wCZPE8TBMvds= To: libcamera-devel@lists.libcamera.org Date: Mon, 13 Jun 2022 16:28:48 +0200 Message-Id: <20220613142853.98484-6-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> References: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 05/10] ipa: raspberrypi: Af: Add AfState 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: Jean-Michel Hautbois via libcamera-devel From: Jean-Michel Hautbois Reply-To: Jean-Michel Hautbois Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Now that controls are introduced, use the AfState to control the algorithm. Signed-off-by: Jean-Michel Hautbois --- src/ipa/raspberrypi/controller/af_status.h | 5 +++-- src/ipa/raspberrypi/controller/iob/af.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/ipa/raspberrypi/controller/af_status.h b/src/ipa/raspberrypi/controller/af_status.h index f8cb1301..3428d032 100644 --- a/src/ipa/raspberrypi/controller/af_status.h +++ b/src/ipa/raspberrypi/controller/af_status.h @@ -7,15 +7,16 @@ */ #pragma once +#include +#include #include /* * The focus algorithm should post the following structure into the image's * "af.status" metadata. */ - struct AfStatus { uint32_t lensPosition; - uint32_t state; + libcamera::controls::AfStateEnum state; libcamera::Rectangle windows; }; diff --git a/src/ipa/raspberrypi/controller/iob/af.cpp b/src/ipa/raspberrypi/controller/iob/af.cpp index 12d41c81..b03e52c5 100644 --- a/src/ipa/raspberrypi/controller/iob/af.cpp +++ b/src/ipa/raspberrypi/controller/iob/af.cpp @@ -78,7 +78,7 @@ void Af::Initialise() { status_.lensPosition = 0.0; maxContrast_ = 0.0; - status_.state = 1; + status_.state = libcamera::controls::AfStateScanning; } void Af::Prepare(Metadata *image_metadata) @@ -109,7 +109,7 @@ void Af::afFineScan() if (afScan(kFineSearchStep)) { LOG(IoBAf, Debug) << "AF found the best focus position !"; - status_.state = 2; + status_.state = libcamera::controls::AfStateFocused; fineCompleted_ = true; } } @@ -162,7 +162,7 @@ void Af::afReset() LOG(IoBAf, Debug) << "Reset AF parameters"; status_.lensPosition = 0; focus_ = 0; - status_.state = 0; + status_.state = libcamera::controls::AfStateIdle; previousContrast_ = 0.0; coarseCompleted_ = false; fineCompleted_ = false; @@ -195,7 +195,7 @@ void Af::Process(StatisticsPtr &stats, [[maybe_unused]] Metadata *image_metadata currentContrast_ += stats->focus_stats[i].contrast_val[1][1] / stats->focus_stats[i].contrast_val_num[1][1]; - if (status_.state != 2) { + if (status_.state != libcamera::controls::AfStateFocused) { afCoarseScan(); afFineScan(); } else { From patchwork Mon Jun 13 14:28:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 16215 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 04E2BC3278 for ; Mon, 13 Jun 2022 14:29:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6B0806564A; Mon, 13 Jun 2022 16:29:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1655130549; bh=L0NjK6mBDyCL2ThmuccyDqBNjZ8Igse88Op1rmrJkK0=; 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=Po31hqHw94zpesI5L95cP+tXY61SAD6Fa/TFQ7lsot1OIT2WXPF3jrQYqYMBnZHDc KzOueWYiPmKxn1C2ivVFNRrsxo+XqixOs0cfKYwQZfr29NMwTBsmjPay5zkr20gTNT s54WLNglOrfWHE/hnS0viZJytFj8B503+TZ18xgursidz2QZ4QAUjjp+xMwZDxSH5T kQzM42AvaaYewv9q18Pk27W7KbUPeC5GYqnlT4dWghu9eARY4+NGBTZk4qx/CuiuDF GFz72bZx/9o51rsKNkpo49LVaszll+0fj4aHEJ8ORxkGJTC+gokfgDaTxsuGLw2Nbk z6rlAK9ULIMcw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4BA226563A for ; Mon, 13 Jun 2022 16:29:01 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="b1emh2kn"; dkim-atps=neutral Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:a1c7:c28c:7720:9b30]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E8050835; Mon, 13 Jun 2022 16:29:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1655130541; bh=L0NjK6mBDyCL2ThmuccyDqBNjZ8Igse88Op1rmrJkK0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=b1emh2knyX0to0UU2/15ZqmSg9YNCfW2AKlJrLQAjV1eDICVfuqdbJqqmhSvwlM9b DxeE+MSMrRneg7i/9Qq9N3f+ESAAXw6GOqD0Dy7VOf+5s4dE2ry54h1kBP8Cv5PHcA bOZpqHdabQUFwvBq39/t3yChcPd+xiICEZlFGHIQ= To: libcamera-devel@lists.libcamera.org Date: Mon, 13 Jun 2022 16:28:49 +0200 Message-Id: <20220613142853.98484-7-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> References: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 06/10] ipa: raspberrypi: Add AfMode control 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: Jean-Michel Hautbois via libcamera-devel From: Jean-Michel Hautbois Reply-To: Jean-Michel Hautbois Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Implement the AfMode control to allow the user to switch between manual, auto or continuous mode. As the mode changes, the AfState value is updated and lets the user follow the algorithm state. Signed-off-by: Jean-Michel Hautbois --- include/libcamera/ipa/raspberrypi.h | 3 ++- src/ipa/raspberrypi/controller/iob/af.cpp | 24 ++++++++++++++++------- src/ipa/raspberrypi/raspberrypi.cpp | 15 ++++++++++++++ 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h index 519f7160..5bc14f4e 100644 --- a/include/libcamera/ipa/raspberrypi.h +++ b/include/libcamera/ipa/raspberrypi.h @@ -46,7 +46,8 @@ static const ControlInfoMap Controls({ { &controls::ScalerCrop, ControlInfo(Rectangle{}, Rectangle(65535, 65535, 65535, 65535), Rectangle{}) }, { &controls::FrameDurationLimits, ControlInfo(INT64_C(1000), INT64_C(1000000000)) }, { &controls::draft::NoiseReductionMode, ControlInfo(controls::draft::NoiseReductionModeValues) }, - { &controls::AfState, ControlInfo(controls::AfStateValues) } + { &controls::AfMode, ControlInfo(controls::AfModeValues) }, + { &controls::AfState, ControlInfo(controls::AfStateValues) }, }, controls::controls); } /* namespace RPi */ diff --git a/src/ipa/raspberrypi/controller/iob/af.cpp b/src/ipa/raspberrypi/controller/iob/af.cpp index b03e52c5..e09514c4 100644 --- a/src/ipa/raspberrypi/controller/iob/af.cpp +++ b/src/ipa/raspberrypi/controller/iob/af.cpp @@ -40,7 +40,7 @@ Af::Af(Controller *controller) : AfAlgorithm(controller), focus_(0), bestFocus_(0), currentContrast_(0.0), previousContrast_(0.0), maxContrast_(0.0), maxStep_(0), coarseCompleted_(false), fineCompleted_(false), - mode_(0) + mode_(libcamera::controls::AfModeManual) { } @@ -49,9 +49,13 @@ char const *Af::Name() const return NAME; } -void Af::SetMode([[maybe_unused]] const uint32_t &mode) +void Af::SetMode(const uint32_t &mode) { - mode_ = mode; + if (mode != mode_) { + LOG(IoBAf, Debug) << "Switched AF mode from " << mode_ + << " to " << mode; + mode_ = mode; + } } void Af::Trigger() @@ -78,7 +82,7 @@ void Af::Initialise() { status_.lensPosition = 0.0; maxContrast_ = 0.0; - status_.state = libcamera::controls::AfStateScanning; + status_.state = libcamera::controls::AfStateIdle; } void Af::Prepare(Metadata *image_metadata) @@ -162,7 +166,7 @@ void Af::afReset() LOG(IoBAf, Debug) << "Reset AF parameters"; status_.lensPosition = 0; focus_ = 0; - status_.state = libcamera::controls::AfStateIdle; + status_.state = libcamera::controls::AfStateScanning; previousContrast_ = 0.0; coarseCompleted_ = false; fineCompleted_ = false; @@ -195,12 +199,18 @@ void Af::Process(StatisticsPtr &stats, [[maybe_unused]] Metadata *image_metadata currentContrast_ += stats->focus_stats[i].contrast_val[1][1] / stats->focus_stats[i].contrast_val_num[1][1]; + /* Depending on the mode, we may or may not process the stats */ + if (status_.state == libcamera::controls::AfStateIdle) + return; + if (status_.state != libcamera::controls::AfStateFocused) { afCoarseScan(); afFineScan(); } else { - if (afIsOutOfFocus()) - afReset(); + /* We can re-start the scan at any moment in AfModeContinuous */ + if (mode_ == libcamera::controls::AfModeContinuous) + if (afIsOutOfFocus()) + afReset(); } } diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index a4e1c834..226388a7 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -30,6 +30,7 @@ #include "libcamera/internal/mapped_framebuffer.h" +#include "af_algorithm.hpp" #include "af_status.h" #include "agc_algorithm.hpp" #include "agc_status.h" @@ -956,6 +957,20 @@ void IPARPi::queueRequest(const ControlList &controls) break; } + case controls::AF_MODE: { + RPiController::AfAlgorithm *af = dynamic_cast( + controller_.GetAlgorithm("iob.af")); + if (!af) { + LOG(IPARPI, Warning) + << "Could not set AF_MODE - no AF algorithm"; + break; + } + + int32_t idx = ctrl.second.get(); + af->SetMode(idx); + break; + } + default: LOG(IPARPI, Warning) << "Ctrl " << controls::controls.at(ctrl.first)->name() From patchwork Mon Jun 13 14:28:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 16217 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 B25E1BD161 for ; Mon, 13 Jun 2022 14:29:11 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7C22865651; Mon, 13 Jun 2022 16:29:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1655130550; bh=4gOouZ4scIBgUXuj6+zedJHsGvyIrkic8SgL+Nkiv2w=; 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=C0B4AEnhoBjyu5BjZH4BzRB3mQn1//DG4uPNMJssOiLXg06n9a0sIkG10shVbo8dr /wl66k6aqXr/KJI08pkfas7+7uBkA54E89py1jku7yk2uf+CcSQE3XtwQfF9rz+0Nv 6f4koITEue0aI7gd43m2FjYQKNAL+zOTp7Lkv5qvhvoNwPnxemKJTDJVTljfSJG3/u hzs4OPOi4BkA6iqSl9eUPzz8iCDgJA+oIifYvkf5BuJRxLByXCI4QnzHnEZn/UCmOy BCwBQR9Ip97/TPPORcw9Gr3gupCvfiXhZJrU7TqT4Jw+h3Y2j0tB89U4xDMgPipbNJ umTiNFbVxgtyw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7F0166563D for ; Mon, 13 Jun 2022 16:29:01 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="V0GZrOMW"; dkim-atps=neutral Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:a1c7:c28c:7720:9b30]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2A99E305; Mon, 13 Jun 2022 16:29:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1655130541; bh=4gOouZ4scIBgUXuj6+zedJHsGvyIrkic8SgL+Nkiv2w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=V0GZrOMW0Gu0MWTRVK7LRb1rma7z0vbTcidnSR6qOYeZb0jS41BDvcLWQGXQkevwH cHFrYWjxjeFYKI6isZCtFxkJkGBQN2nOUk9vtvcA41HB2xx3AbHQKaEnVCAdjArbUz EBTRBSdsb9O3q80XDxUUyE6DMHnyfz3EkeNkYAY4= To: libcamera-devel@lists.libcamera.org Date: Mon, 13 Jun 2022 16:28:50 +0200 Message-Id: <20220613142853.98484-8-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> References: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 07/10] ipa: raspberrypi: Introduce AfPause and AfPauseState 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: Jean-Michel Hautbois via libcamera-devel From: Jean-Michel Hautbois Reply-To: Jean-Michel Hautbois Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" In the continuous mode, the algorithm can be paused and resumed by the user using the AfPause control. Introduce the state machine associated with this call, and populate a specific pause state which will populate the AfPauseState control. Signed-off-by: Jean-Michel Hautbois --- include/libcamera/ipa/raspberrypi.h | 2 ++ src/ipa/raspberrypi/controller/af_algorithm.hpp | 2 ++ src/ipa/raspberrypi/controller/af_status.h | 1 + src/ipa/raspberrypi/controller/iob/af.cpp | 14 +++++++++++++- src/ipa/raspberrypi/controller/iob/af.h | 1 + src/ipa/raspberrypi/raspberrypi.cpp | 15 +++++++++++++++ 6 files changed, 34 insertions(+), 1 deletion(-) diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h index 5bc14f4e..a7a15904 100644 --- a/include/libcamera/ipa/raspberrypi.h +++ b/include/libcamera/ipa/raspberrypi.h @@ -48,6 +48,8 @@ static const ControlInfoMap Controls({ { &controls::draft::NoiseReductionMode, ControlInfo(controls::draft::NoiseReductionModeValues) }, { &controls::AfMode, ControlInfo(controls::AfModeValues) }, { &controls::AfState, ControlInfo(controls::AfStateValues) }, + { &controls::AfPause, ControlInfo(controls::AfPauseValues) }, + { &controls::AfPauseState, ControlInfo(controls::AfPauseStateValues) }, }, controls::controls); } /* namespace RPi */ diff --git a/src/ipa/raspberrypi/controller/af_algorithm.hpp b/src/ipa/raspberrypi/controller/af_algorithm.hpp index 1e7aaa45..ac34e3b6 100644 --- a/src/ipa/raspberrypi/controller/af_algorithm.hpp +++ b/src/ipa/raspberrypi/controller/af_algorithm.hpp @@ -22,6 +22,8 @@ public: virtual void Trigger() = 0; // cancel a cycle (in auto mode) virtual void Cancel() = 0; + // pause the continuous mode + virtual void Pause(const uint32_t &pause) = 0; // set AF windows virtual void SetWindows(const libcamera::Rectangle &afWindows) = 0; // set AF range diff --git a/src/ipa/raspberrypi/controller/af_status.h b/src/ipa/raspberrypi/controller/af_status.h index 3428d032..aa412ef6 100644 --- a/src/ipa/raspberrypi/controller/af_status.h +++ b/src/ipa/raspberrypi/controller/af_status.h @@ -18,5 +18,6 @@ struct AfStatus { uint32_t lensPosition; libcamera::controls::AfStateEnum state; + libcamera::controls::AfPauseStateEnum pauseState; libcamera::Rectangle windows; }; diff --git a/src/ipa/raspberrypi/controller/iob/af.cpp b/src/ipa/raspberrypi/controller/iob/af.cpp index e09514c4..2efc12f5 100644 --- a/src/ipa/raspberrypi/controller/iob/af.cpp +++ b/src/ipa/raspberrypi/controller/iob/af.cpp @@ -54,6 +54,7 @@ void Af::SetMode(const uint32_t &mode) if (mode != mode_) { LOG(IoBAf, Debug) << "Switched AF mode from " << mode_ << " to " << mode; + status_.pauseState = libcamera::controls::AfPauseStateRunning; mode_ = mode; } } @@ -62,8 +63,15 @@ void Af::Trigger() { } -void Af::Cancel() +void Af::Pause(const uint32_t &pause) { + /* \todo: add the AfPauseDeferred mode */ + if (mode_ == libcamera::controls::AfModeContinuous) { + if (pause == libcamera::controls::AfPauseImmediate) + status_.pauseState = libcamera::controls::AfPauseStatePaused; + else if (pause == libcamera::controls::AfPauseResume) + status_.pauseState = libcamera::controls::AfPauseStateRunning; + } } void Af::SetWindows([[maybe_unused]] const libcamera::Rectangle &afWindows) @@ -199,6 +207,10 @@ void Af::Process(StatisticsPtr &stats, [[maybe_unused]] Metadata *image_metadata currentContrast_ += stats->focus_stats[i].contrast_val[1][1] / stats->focus_stats[i].contrast_val_num[1][1]; + /* If we are in a paused state, we won't process the stats */ + if (status_.pauseState == libcamera::controls::AfPauseStatePaused) + return; + /* Depending on the mode, we may or may not process the stats */ if (status_.state == libcamera::controls::AfStateIdle) return; diff --git a/src/ipa/raspberrypi/controller/iob/af.h b/src/ipa/raspberrypi/controller/iob/af.h index 4ed50cfb..c4ab3574 100644 --- a/src/ipa/raspberrypi/controller/iob/af.h +++ b/src/ipa/raspberrypi/controller/iob/af.h @@ -26,6 +26,7 @@ public: void SetMode(const uint32_t &mode) override; void Trigger() override; void Cancel() override; + void Pause(const uint32_t &pause) override; void SetWindows(const libcamera::Rectangle &afWindows) override; void SetRange(const uint32_t &range) override; void setSpeed(const uint32_t &speed) override; diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 226388a7..8c6f213f 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -552,6 +552,7 @@ void IPARPi::reportMetadata() AfStatus *afStatus = rpiMetadata_.GetLocked("af.status"); if (afStatus) { libcameraMetadata_.set(controls::AfState, afStatus->state); + libcameraMetadata_.set(controls::AfPauseState, afStatus->pauseState); } } @@ -971,6 +972,20 @@ void IPARPi::queueRequest(const ControlList &controls) break; } + case controls::AF_PAUSE: { + RPiController::AfAlgorithm *af = dynamic_cast( + controller_.GetAlgorithm("iob.af")); + if (!af) { + LOG(IPARPI, Warning) + << "Could not set AF_MODE - no AF algorithm"; + break; + } + + af->Pause(ctrl.second.get()); + + break; + } + default: LOG(IPARPI, Warning) << "Ctrl " << controls::controls.at(ctrl.first)->name() From patchwork Mon Jun 13 14:28:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 16216 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 31D5BC3279 for ; Mon, 13 Jun 2022 14:29:11 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D70D86564F; Mon, 13 Jun 2022 16:29:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1655130549; bh=3d3YCVuSR1T5JIzEhU3hNZBepDk383+F08oRIFv/9+g=; 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=2FNkTBfI4EEgf5Mp2zfMMbh4Qa7Y4PFe9MLAa8jol7RK1XWPrdlPnL1FgdY2S5Swe Dcyt78n+Xzm5EBp237gSISN7X63NnyxTWLjrryd0W6176CM0LS/6Xm/3c+o+ovwaUJ lLRyX12FOM8Vz2mbRxtq+YW4gnebs/UExD6zTgWtbY04LP/hEuvd6hyw/i9V34EqKq VLBCK55Zqyt5vtmgQBfkk73KSgKxcR0BR/SWH8LiTVkbgvT7lBQGFP/764FPrkr5bw 13Qxyowg2qCSWTKlqJVlCbH2Fxt/w5j0uqMkVPTrd2WnyJ16lfmLh88ZQXZn9tFbw7 hjIFVVey8FnbA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B2A9365636 for ; Mon, 13 Jun 2022 16:29:01 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="t4m203rm"; dkim-atps=neutral Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:a1c7:c28c:7720:9b30]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 60FCC87B; Mon, 13 Jun 2022 16:29:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1655130541; bh=3d3YCVuSR1T5JIzEhU3hNZBepDk383+F08oRIFv/9+g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=t4m203rmCcGT7h8puhZ6aoRQmAFbEt/GOqwi7Y9bGseanGFqjAvojgjlpYTwUGRRy abOI4ADKn9WQENst+L4CriDrdva3/rYVFlWz8at2d/gExaRxMdvsDKHjVcl8qPt6Af X1os7yrCl5bI/RgeeK5tuJUrM9bvIDXp50Q5LBn8= To: libcamera-devel@lists.libcamera.org Date: Mon, 13 Jun 2022 16:28:51 +0200 Message-Id: <20220613142853.98484-9-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> References: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 08/10] ipa: raspberrypi: Introduce AfTrigger control 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: Jean-Michel Hautbois via libcamera-devel From: Jean-Michel Hautbois Reply-To: Jean-Michel Hautbois Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" When the algorithm is in auto mode, it will start a new scan, and either end in the AfStateFocused ot AfStateFailed state. The user may decide to trigger a new scan, passing the AfTrigger control down to the pipeline handler. Implement a simple trigger operation in the IPA and call it from the pipeline handler when the control is passed. Signed-off-by: Jean-Michel Hautbois --- include/libcamera/ipa/raspberrypi.h | 1 + src/ipa/raspberrypi/controller/af_algorithm.hpp | 2 +- src/ipa/raspberrypi/controller/iob/af.cpp | 12 ++++++++++-- src/ipa/raspberrypi/controller/iob/af.h | 2 +- src/ipa/raspberrypi/raspberrypi.cpp | 14 ++++++++++++++ 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h index a7a15904..17c7de72 100644 --- a/include/libcamera/ipa/raspberrypi.h +++ b/include/libcamera/ipa/raspberrypi.h @@ -50,6 +50,7 @@ static const ControlInfoMap Controls({ { &controls::AfState, ControlInfo(controls::AfStateValues) }, { &controls::AfPause, ControlInfo(controls::AfPauseValues) }, { &controls::AfPauseState, ControlInfo(controls::AfPauseStateValues) }, + { &controls::AfTrigger, ControlInfo(controls::AfTriggerValues) }, }, controls::controls); } /* namespace RPi */ diff --git a/src/ipa/raspberrypi/controller/af_algorithm.hpp b/src/ipa/raspberrypi/controller/af_algorithm.hpp index ac34e3b6..925b2d03 100644 --- a/src/ipa/raspberrypi/controller/af_algorithm.hpp +++ b/src/ipa/raspberrypi/controller/af_algorithm.hpp @@ -19,7 +19,7 @@ public: // An af algorithm must provide the following: virtual void SetMode(const uint32_t &mode) = 0; // start a cycle (in auto mode) - virtual void Trigger() = 0; + virtual void Trigger(const uint32_t &trigger) = 0; // cancel a cycle (in auto mode) virtual void Cancel() = 0; // pause the continuous mode diff --git a/src/ipa/raspberrypi/controller/iob/af.cpp b/src/ipa/raspberrypi/controller/iob/af.cpp index 2efc12f5..1d9bc2bc 100644 --- a/src/ipa/raspberrypi/controller/iob/af.cpp +++ b/src/ipa/raspberrypi/controller/iob/af.cpp @@ -59,8 +59,16 @@ void Af::SetMode(const uint32_t &mode) } } -void Af::Trigger() -{ +void Af::Trigger(const uint32_t &trigger) +{ + LOG(IoBAf, Debug) << "Trigger called in mode " << mode_ + << " with " << trigger; + if (mode_ == libcamera::controls::AfModeAuto) { + if (trigger == libcamera::controls::AfTriggerStart) + afReset(); + else + status_.state = libcamera::controls::AfStateIdle; + } } void Af::Pause(const uint32_t &pause) diff --git a/src/ipa/raspberrypi/controller/iob/af.h b/src/ipa/raspberrypi/controller/iob/af.h index c4ab3574..12d7bbbd 100644 --- a/src/ipa/raspberrypi/controller/iob/af.h +++ b/src/ipa/raspberrypi/controller/iob/af.h @@ -24,7 +24,7 @@ public: void Prepare(Metadata *image_metadata) override; void Process(StatisticsPtr &stats, Metadata *image_metadata) override; void SetMode(const uint32_t &mode) override; - void Trigger() override; + void Trigger(const uint32_t &trigger) override; void Cancel() override; void Pause(const uint32_t &pause) override; void SetWindows(const libcamera::Rectangle &afWindows) override; diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 8c6f213f..673a2e79 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -986,6 +986,20 @@ void IPARPi::queueRequest(const ControlList &controls) break; } + case controls::AF_TRIGGER: { + RPiController::AfAlgorithm *af = dynamic_cast( + controller_.GetAlgorithm("iob.af")); + if (!af) { + LOG(IPARPI, Warning) + << "Could not set AF_MODE - no AF algorithm"; + break; + } + + af->Trigger(ctrl.second.get()); + + break; + } + default: LOG(IPARPI, Warning) << "Ctrl " << controls::controls.at(ctrl.first)->name() From patchwork Mon Jun 13 14:28:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 16218 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 6A0B4C327A for ; Mon, 13 Jun 2022 14:29:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E54FE65657; Mon, 13 Jun 2022 16:29:11 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1655130551; bh=iWjADkK045MYS1Dm7UxHvu762oUHDwJbDtPi/pi8KmE=; 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=Qe+zXQBN/MFQvgju6b9BXwokkYvoH2lmGjO5qKhN4H136i9Gon3E5lk7mcFQ8CZRr Qb2Dv1bvK5bGtXSNYcAt3VxF7T5Pe64C43VngRUJ2BwStcxEvB0a9dRvsVEbEm4BqH fMq5Pf9T/gwA7EYLLc6PfpOi+6F0vJUjEJ/yDUZeiNRL3u3ZUYiBD+46hMZQDir7qZ Z4bvXj9VfULCfIXErGutvrLRwn3/+utclKTLf+6CpCqWaqQ0HH6ksnUJTVESNSnO1l RDVHTTEz3s6lj9RCgsSBln82T0yID+FvEvIzJvgqSCU6Zn/eqi/KWr/HsP7SrmVQrc g4t/kJVFcZSXQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E870465643 for ; Mon, 13 Jun 2022 16:29:01 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="csmdBXU+"; dkim-atps=neutral Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:a1c7:c28c:7720:9b30]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 97BDB440; Mon, 13 Jun 2022 16:29:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1655130541; bh=iWjADkK045MYS1Dm7UxHvu762oUHDwJbDtPi/pi8KmE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=csmdBXU+9pfhcUtIBzW7Hxi8wgadCaB2pOQ5YysGg4SQ6SfQu7I/afqL/wxuCeviv goZY/gGkvi7u1amCorlexKuMg43G8ZFJ8oObf7Hsnrl077z+FEjTHj9hIFK91aWX2W 2HNmnM/1OTuI0ebKQwQsCC+MKAt7j1GZnwYA1uYg= To: libcamera-devel@lists.libcamera.org Date: Mon, 13 Jun 2022 16:28:52 +0200 Message-Id: <20220613142853.98484-10-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> References: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 09/10] ipa: raspberrypi: Set a constrained range 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: Jean-Michel Hautbois via libcamera-devel From: Jean-Michel Hautbois Reply-To: Jean-Michel Hautbois Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Give the algorithm a way to have a constrained range for the lens. Add a default SetRange() call and implement it to set the low bound and high bound for the search. There is no functionnal change expected but gives the ability for the pipeline handler to set the range at runtime. Signed-off-by: Jean-Michel Hautbois --- .../raspberrypi/controller/af_algorithm.hpp | 2 ++ src/ipa/raspberrypi/controller/iob/af.cpp | 24 ++++++++++++++----- src/ipa/raspberrypi/controller/iob/af.h | 4 ++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/ipa/raspberrypi/controller/af_algorithm.hpp b/src/ipa/raspberrypi/controller/af_algorithm.hpp index 925b2d03..0008113b 100644 --- a/src/ipa/raspberrypi/controller/af_algorithm.hpp +++ b/src/ipa/raspberrypi/controller/af_algorithm.hpp @@ -28,6 +28,8 @@ public: virtual void SetWindows(const libcamera::Rectangle &afWindows) = 0; // set AF range virtual void SetRange(const uint32_t &range) = 0; + // set Lens Range + virtual void SetLensRange(const uint32_t &low, const uint32_t &high) = 0; // set AF speed virtual void setSpeed(const uint32_t &speed) = 0; }; diff --git a/src/ipa/raspberrypi/controller/iob/af.cpp b/src/ipa/raspberrypi/controller/iob/af.cpp index 1d9bc2bc..a10e1d0a 100644 --- a/src/ipa/raspberrypi/controller/iob/af.cpp +++ b/src/ipa/raspberrypi/controller/iob/af.cpp @@ -40,7 +40,7 @@ Af::Af(Controller *controller) : AfAlgorithm(controller), focus_(0), bestFocus_(0), currentContrast_(0.0), previousContrast_(0.0), maxContrast_(0.0), maxStep_(0), coarseCompleted_(false), fineCompleted_(false), - mode_(libcamera::controls::AfModeManual) + mode_(libcamera::controls::AfModeManual), lowStep_(0), highStep_(kMaxFocusSteps) { } @@ -90,6 +90,18 @@ void Af::SetRange([[maybe_unused]] const uint32_t &range) { } +void Af::SetLensRange(const uint32_t &low, const uint32_t &high) +{ + lowStep_ = low; + highStep_ = high; + + LOG(IoBAf, Debug) << "Lens range set between " << lowStep_ + << " and " << highStep_; + + focus_ = lowStep_; + maxStep_ = highStep_; +} + void Af::setSpeed([[maybe_unused]] const uint32_t &speed) { } @@ -118,7 +130,7 @@ void Af::afCoarseScan() status_.lensPosition = focus_; previousContrast_ = 0; maxStep_ = std::clamp(focus_ + static_cast((focus_ * kFineRange)), - 0U, kMaxFocusSteps); + 0U, highStep_); } } @@ -136,7 +148,7 @@ void Af::afFineScan() bool Af::afScan(uint32_t minSteps) { - if (focus_ > maxStep_) { + if (focus_ + minSteps > maxStep_) { /* If the max step is reached, move lens to the position. */ status_.lensPosition = bestFocus_; return true; @@ -180,13 +192,13 @@ bool Af::afScan(uint32_t minSteps) void Af::afReset() { LOG(IoBAf, Debug) << "Reset AF parameters"; - status_.lensPosition = 0; - focus_ = 0; + status_.lensPosition = lowStep_; + focus_ = lowStep_; + maxStep_ = highStep_; status_.state = libcamera::controls::AfStateScanning; previousContrast_ = 0.0; coarseCompleted_ = false; fineCompleted_ = false; - maxStep_ = kMaxFocusSteps; maxContrast_ = 0.0; } diff --git a/src/ipa/raspberrypi/controller/iob/af.h b/src/ipa/raspberrypi/controller/iob/af.h index 12d7bbbd..52b9c37d 100644 --- a/src/ipa/raspberrypi/controller/iob/af.h +++ b/src/ipa/raspberrypi/controller/iob/af.h @@ -29,6 +29,7 @@ public: void Pause(const uint32_t &pause) override; void SetWindows(const libcamera::Rectangle &afWindows) override; void SetRange(const uint32_t &range) override; + void SetLensRange(const uint32_t &low, const uint32_t &high) override; void setSpeed(const uint32_t &speed) override; private: bool afNeedIgnoreFrame(); @@ -58,6 +59,9 @@ private: bool fineCompleted_; uint32_t mode_; + + uint32_t lowStep_; + uint32_t highStep_; }; } /* namespace RPiController */ From patchwork Mon Jun 13 14:28:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 16219 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 F3F5DC327B for ; Mon, 13 Jun 2022 14:29:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 563BC65658; Mon, 13 Jun 2022 16:29:12 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1655130552; bh=tBokIjL+Kgf/D3u4E77nHBWGNk/M5DqFYsM05lkiDyE=; 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=B3JA3zpCJKQMGTs+4WOTBtJ3nH0bZzXnACCt2RM42bOCJdO0JttOXs6hY8OoPTxmo mqGK8inYlHDwcgNHhDhjz1ZooVCqDM7M1oq2Vtlv85JLg6QdCYU7oTifBFzx0JPtaV /JrXXlN7pXamAPsrOvSyr4p4ywhg6w9Ry6PqPPI3Yyx8JNqZoDZq8RIDXrIYEV5CsE tpNmC1itAcUAUBECygirTwMFnFEH0QphaAxsLD040Fqij3Tc5VQ4J6GTjfwO352bBQ wH7CTq+lokYcqZUDXEMpEzALWa7pVMn7NV7aEW1wgVnFum5FF8pWmRkYvXyIXMquQ+ pc3kQu3bGzGag== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2DA6165645 for ; Mon, 13 Jun 2022 16:29:02 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="RJVNTYW0"; dkim-atps=neutral Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:a1c7:c28c:7720:9b30]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id CE226835; Mon, 13 Jun 2022 16:29:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1655130541; bh=tBokIjL+Kgf/D3u4E77nHBWGNk/M5DqFYsM05lkiDyE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RJVNTYW0bZsbVXVdMFwy7WQVZ9Z/bZRJqEwbXt6PuA1EyQM/+OMDJUuavPhLb6vIy CrsSyveihH/HjADBL2hHwIeRb6qh2yvHtbDuNKC0EyhN0xK14uyIfFvI7GaRNSNqzJ m4NEP8piyy3BDKswyQFI8ljU4v063KVAkqwAe9wM= To: libcamera-devel@lists.libcamera.org Date: Mon, 13 Jun 2022 16:28:53 +0200 Message-Id: <20220613142853.98484-11-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> References: <20220613142853.98484-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 10/10] test: af: Introduce a capture script test file 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: Jean-Michel Hautbois via libcamera-devel From: Jean-Michel Hautbois Reply-To: Jean-Michel Hautbois Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" When testing the autofocus state machine, it is useful to know which state is expected for a given frame. Introduce a yaml file to set the AF controls at given points in time to ease debugging the state machine Signed-off-by: Jean-Michel Hautbois --- test/af/af-state-machine.yaml | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 test/af/af-state-machine.yaml diff --git a/test/af/af-state-machine.yaml b/test/af/af-state-machine.yaml new file mode 100644 index 00000000..54da3fe2 --- /dev/null +++ b/test/af/af-state-machine.yaml @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: CC0-1.0 + +# AF controls test script +# +# A capture script allows to associate a list of AF controls and their values +# to frame numbers. + +# Manual mode +# State should be AfStateIdle +# We can still change LensPosition +frames: + - 1: + AfMode: 0 + LensPosition: 0.0 + + - 5: + LensPosition: 100.0 + + - 10: + LensPosition: 500.0 + + - 15: + LensPosition: 0.0 + + - 50: +# Change to continuous mode +# State should immediately be AfStateScanning +# The algorithm should start a scan +# It will settle on AfStateFocused or AfStateFailed + AfMode: 2 + + - 80: +# Change to auto mode +# The Lens or state should not change until AfTrigger is received +# Entering this mode will report AfStateIdle + AfMode: 1 + - 90: +# Start the scan + AfTrigger: 0 + # - 110: +#Cancel the scan + AfTrigger: 1 + + - 100: +# Switch back to continuous + AfMode: 2