From patchwork Tue Sep 28 07:49:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 13961 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 0723DBDC71 for ; Tue, 28 Sep 2021 07:50:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B9C6869193; Tue, 28 Sep 2021 09:50:20 +0200 (CEST) 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="BglQDsbl"; dkim-atps=neutral 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 006BC6918B for ; Tue, 28 Sep 2021 09:50:17 +0200 (CEST) Received: from pyrite.rasen.tech (unknown [IPv6:2400:4051:61:600:2c71:1b79:d06d:5032]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 8C6313F6; Tue, 28 Sep 2021 09:50:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1632815417; bh=jmN6IIaNhDD+vaYXmVAhwXMLVZyuUaWQdDJb0Op7NPI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BglQDsblhWPLHQiCXu4Jos/Nv4h+SO6jGSDkfT/SHpM4qxBRRAEaRVWOISmLD71jb d7nkJjZjPXir0Y1w9UsISGy0ZB0oVIWmX0xC4kjJ2zkaoYKzhhrX6sPaxwtKytUgZ5 W4iLyOCIAmxbrblxMBuyFZPhMM6mKEuOqpB5ANYQ= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Tue, 28 Sep 2021 16:49:57 +0900 Message-Id: <20210928074959.3489544-3-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210928074959.3489544-1-paul.elder@ideasonboard.com> References: <20210928074959.3489544-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 2/4] 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. Signed-off-by: Paul Elder --- 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 +- src/ipa/raspberrypi/controller/rpi/agc.cpp | 18 ++++++++- src/ipa/raspberrypi/controller/rpi/agc.hpp | 5 +++ src/ipa/raspberrypi/raspberrypi.cpp | 42 ++++++++++++++++---- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 17 ++++---- 5 files changed, 67 insertions(+), 18 deletions(-) diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h index 521eaecd..363ea038 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/rpi/agc.cpp b/src/ipa/raspberrypi/controller/rpi/agc.cpp index 289c1fce..b45ea454 100644 --- a/src/ipa/raspberrypi/controller/rpi/agc.cpp +++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp @@ -203,14 +203,30 @@ bool Agc::IsPaused() const } void Agc::Pause() +{ +} + +void Agc::Resume() +{ +} + +void Agc::PauseExposure() { fixed_shutter_ = status_.shutter_time; +} + +void Agc::PauseGain() +{ fixed_analogue_gain_ = status_.analogue_gain; } -void Agc::Resume() +void Agc::ResumeExposure() { 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 82063636..7ca3ca2f 100644 --- a/src/ipa/raspberrypi/controller/rpi/agc.hpp +++ b/src/ipa/raspberrypi/controller/rpi/agc.hpp @@ -92,6 +92,11 @@ public: void Prepare(Metadata *image_metadata) override; void Process(StatisticsPtr &stats, Metadata *image_metadata) override; + void PauseExposure(); + void PauseGain(); + void ResumeExposure(); + void ResumeGain(); + private: void updateLockStatus(DeviceStatus const &device_status); AgcConfig config_; diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 047123ab..99935515 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; @@ -478,7 +480,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); } @@ -623,20 +628,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::Algorithm *algo = controller_.GetAlgorithm("agc"); + RPiController::Agc *agc = reinterpret_cast(algo); 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->PauseExposure(); else - agc->Resume(); + agc->ResumeExposure(); - libcameraMetadata_.set(controls::AeEnable, ctrl.second.get()); + libcameraMetadata_.set(controls::ExposureTimeMode, + ctrl.second.get()); break; } @@ -656,6 +663,25 @@ void IPARPi::queueRequest(const ControlList &controls) break; } + case controls::ANALOGUE_GAIN_MODE: { + RPiController::Algorithm *algo = controller_.GetAlgorithm("agc"); + RPiController::Agc *agc = reinterpret_cast(algo); + 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")); diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index c227d885..3a9c3b8d 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -309,25 +309,25 @@ int PipelineHandlerUVC::processControl(ControlList *controls, unsigned int id, /* \todo Make this nicer. */ int32_t ivalue; if (id == controls::ExposureTimeMode && exposureSet) { - int32_t exposureMode = controls->get(V4L2_CID_EXPOSURE_AUTO); - ivalue = value.get() == ExposureTimeModeAuto + int32_t exposureMode = controls->get(V4L2_CID_EXPOSURE_AUTO).get(); + ivalue = value.get() == controls::ExposureTimeModeAuto ? (exposureMode == V4L2_EXPOSURE_SHUTTER_PRIORITY ? V4L2_EXPOSURE_AUTO : V4L2_EXPOSURE_APERTURE_PRIORITY) : V4L2_EXPOSURE_MANUAL; } else if (id == controls::ExposureTimeMode && !exposureSet) { - ivalue = value.get() == ExposureTimeModeAuto + ivalue = value.get() == controls::ExposureTimeModeAuto ? V4L2_EXPOSURE_APERTURE_PRIORITY : V4L2_EXPOSURE_MANUAL; } else if (id == controls::AnalogueGainMode && exposureSet) { - int32_t exposureMode = controls->get(V4L2_CID_EXPOSURE_AUTO); - ivalue = value.get() == AnalogueGainModeAuto + int32_t exposureMode = controls->get(V4L2_CID_EXPOSURE_AUTO).get(); + ivalue = value.get() == controls::AnalogueGainModeAuto ? (exposureMode == V4L2_EXPOSURE_APERTURE_PRIORITY ? V4L2_EXPOSURE_AUTO : V4L2_EXPOSURE_SHUTTER_PRIORITY) : V4L2_EXPOSURE_MANUAL; } else if (id == controls::AnalogueGainMode && !exposureSet) { - ivalue = value.get() == AnalogueGainModeAuto + ivalue = value.get() == controls::AnalogueGainModeAuto ? V4L2_EXPOSURE_SHUTTER_PRIORITY : V4L2_EXPOSURE_MANUAL; } @@ -636,8 +636,9 @@ void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info, break; case V4L2_CID_EXPOSURE_AUTO: - info = ControlInfo{ { ExposureTimeModeAuto, ExposureTimeModeDisabled }, - ExposureTimeModeDisabled }; + info = ControlInfo{ { controls::ExposureTimeModeAuto, + controls::ExposureTimeModeDisabled }, + controls::ExposureTimeModeDisabled }; break; case V4L2_CID_EXPOSURE_ABSOLUTE: