From patchwork Tue Dec 21 04:36:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 15181 X-Patchwork-Delegate: paul.elder@ideasonboard.com 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 E2C18C3258 for ; Tue, 21 Dec 2021 04:36:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5B71B608FD; Tue, 21 Dec 2021 05:36:26 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="pjmfHhYy"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CCF94608E8 for ; Tue, 21 Dec 2021 05:36:22 +0100 (CET) Received: from pyrite.mediacom.info (unknown [IPv6:2604:2d80:ad90:fb00:96fd:8874:873:6c16]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0B8D2881; Tue, 21 Dec 2021 05:36:21 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1640061382; bh=xeuyaNCaNS1VCUnxH5qrJU+44XXUrBA/zwpl1s4vbto=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pjmfHhYyEGo4t7xMK3N6kS1ZluiEtQNreteTu9HssvSE2jZITFrWNUSbDieJGadYn oG4EXVc02QsYZxZuDDSeFLRfOBb8RX56ZDjI3GbMdRjbN7YRPMAP8kbcQCqJWReeSD 07cfBs6oO54rT/Nl5GKDWeLpZMAWIuOG1L6mwj9k= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Mon, 20 Dec 2021 22:36:05 -0600 Message-Id: <20211221043610.2512334-4-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211221043610.2512334-1-paul.elder@ideasonboard.com> References: <20211221043610.2512334-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 3/8] libcamera: pipeline: raspberrypi: Support the new AE controls 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add support for the new AE controls in the raspberrypi pipeline handler, and in the IPA. Bug: https://bugs.libcamera.org/show_bug.cgi?id=42 Bug: https://bugs.libcamera.org/show_bug.cgi?id=43 Signed-off-by: Paul Elder --- Changes in v3: - s/Exposure/Shutter/ - move the new Pause/Resume functions to AgcAlgorithm - update callers as appropriate - make the original Pause/Resume functions call the new ones Changes in v2: - fix the rebase error where some uvc stuff was in rasberrypi - i haven't yet taken in the comments to move the new Pause/Resume functions Initial versoin: This is very hacky. I wasn't sure what the best way was to plumb it into the raspberrypi IPA as it was a bit hairy... --- include/libcamera/ipa/raspberrypi.h | 3 +- .../raspberrypi/controller/agc_algorithm.hpp | 4 ++ src/ipa/raspberrypi/controller/rpi/agc.cpp | 22 +++++++++- src/ipa/raspberrypi/controller/rpi/agc.hpp | 5 +++ src/ipa/raspberrypi/raspberrypi.cpp | 42 +++++++++++++++---- 5 files changed, 66 insertions(+), 10 deletions(-) diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h index 7f705e49..672b85a5 100644 --- a/include/libcamera/ipa/raspberrypi.h +++ b/include/libcamera/ipa/raspberrypi.h @@ -28,8 +28,9 @@ namespace RPi { * unsupported control is encountered. */ static const ControlInfoMap Controls({ - { &controls::AeEnable, ControlInfo(false, true) }, + { &controls::ExposureTimeMode, ControlInfo(controls::ExposureTimeModeValues) }, { &controls::ExposureTime, ControlInfo(0, 999999) }, + { &controls::AnalogueGainMode, ControlInfo(controls::AnalogueGainModeValues) }, { &controls::AnalogueGain, ControlInfo(1.0f, 32.0f) }, { &controls::AeMeteringMode, ControlInfo(controls::AeMeteringModeValues) }, { &controls::AeConstraintMode, ControlInfo(controls::AeConstraintModeValues) }, diff --git a/src/ipa/raspberrypi/controller/agc_algorithm.hpp b/src/ipa/raspberrypi/controller/agc_algorithm.hpp index 61595ea2..538cfa88 100644 --- a/src/ipa/raspberrypi/controller/agc_algorithm.hpp +++ b/src/ipa/raspberrypi/controller/agc_algorithm.hpp @@ -27,6 +27,10 @@ public: virtual void SetExposureMode(std::string const &exposure_mode_name) = 0; virtual void SetConstraintMode(std::string const &contraint_mode_name) = 0; + virtual void PauseShutter(); + virtual void PauseGain(); + virtual void ResumeShutter(); + virtual void ResumeGain(); }; } // namespace RPiController diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp b/src/ipa/raspberrypi/controller/rpi/agc.cpp index f6a9cb0a..14d6e024 100644 --- a/src/ipa/raspberrypi/controller/rpi/agc.cpp +++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp @@ -210,14 +210,34 @@ bool Agc::IsPaused() const } void Agc::Pause() +{ + PauseShutter(); + PauseGain(); +} + +void Agc::Resume() +{ + ResumeShutter(); + ResumeGain(); +} + +void Agc::PauseShutter() { fixed_shutter_ = status_.shutter_time; +} + +void Agc::PauseGain() +{ fixed_analogue_gain_ = status_.analogue_gain; } -void Agc::Resume() +void Agc::ResumeShutter() { fixed_shutter_ = 0s; +} + +void Agc::ResumeGain() +{ fixed_analogue_gain_ = 0; } diff --git a/src/ipa/raspberrypi/controller/rpi/agc.hpp b/src/ipa/raspberrypi/controller/rpi/agc.hpp index c100d312..af4c72ff 100644 --- a/src/ipa/raspberrypi/controller/rpi/agc.hpp +++ b/src/ipa/raspberrypi/controller/rpi/agc.hpp @@ -90,6 +90,11 @@ public: void Prepare(Metadata *image_metadata) override; void Process(StatisticsPtr &stats, Metadata *image_metadata) override; + void PauseShutter() override; + void PauseGain() override; + void ResumeShutter() override; + void ResumeGain() override; + private: void updateLockStatus(DeviceStatus const &device_status); AgcConfig config_; diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 0ed41385..9bea16e7 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -53,6 +53,8 @@ #include "sharpen_algorithm.hpp" #include "sharpen_status.h" +#include "controller/rpi/agc.hpp" + namespace libcamera { using namespace std::literals::chrono_literals; @@ -483,7 +485,10 @@ void IPARPi::reportMetadata() AgcStatus *agcStatus = rpiMetadata_.GetLocked("agc.status"); if (agcStatus) { - libcameraMetadata_.set(controls::AeLocked, agcStatus->locked); + libcameraMetadata_.set(controls::AeState, + agcStatus->locked ? + controls::AeStateConverged : + controls::AeStateSearching); libcameraMetadata_.set(controls::DigitalGain, agcStatus->digital_gain); } @@ -628,20 +633,22 @@ void IPARPi::queueRequest(const ControlList &controls) << " = " << ctrl.second.toString(); switch (ctrl.first) { - case controls::AE_ENABLE: { - RPiController::Algorithm *agc = controller_.GetAlgorithm("agc"); + case controls::EXPOSURE_TIME_MODE: { + RPiController::AgcAlgorithm *agc = dynamic_cast( + controller_.GetAlgorithm("agc")); if (!agc) { LOG(IPARPI, Warning) - << "Could not set AE_ENABLE - no AGC algorithm"; + << "Could not set EXPOSURE_TIME_MODE - no AGC algorithm"; break; } - if (ctrl.second.get() == false) - agc->Pause(); + if (ctrl.second.get() == controls::ExposureTimeModeDisabled) + agc->PauseShutter(); else - agc->Resume(); + agc->ResumeShutter(); - libcameraMetadata_.set(controls::AeEnable, ctrl.second.get()); + libcameraMetadata_.set(controls::ExposureTimeMode, + ctrl.second.get()); break; } @@ -661,6 +668,25 @@ void IPARPi::queueRequest(const ControlList &controls) break; } + case controls::ANALOGUE_GAIN_MODE: { + RPiController::AgcAlgorithm *agc = dynamic_cast( + controller_.GetAlgorithm("agc")); + if (!agc) { + LOG(IPARPI, Warning) + << "Could not set ANALOGUE_GAIN_MODE - no AGC algorithm"; + break; + } + + if (ctrl.second.get() == controls::AnalogueGainModeDisabled) + agc->PauseGain(); + else + agc->ResumeGain(); + + libcameraMetadata_.set(controls::AnalogueGainMode, + ctrl.second.get()); + break; + } + case controls::ANALOGUE_GAIN: { RPiController::AgcAlgorithm *agc = dynamic_cast( controller_.GetAlgorithm("agc"));