From patchwork Thu Jun 30 13:38:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16475 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 2429DBE173 for ; Thu, 30 Jun 2022 13:39:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B43BC65696; Thu, 30 Jun 2022 15:39:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656596389; bh=4rac9Rtmiyxlxc19x7gSaPtGSORbrQUteRJ1HerjVew=; 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=iPo78SBra71VkV0QZEhIdu3HFYlQAUCuEt2MLNSlV50p9yOF5yU2CNbrG1U/hnx6b QUcvU03xAZ/k3VI+6/Pd+q0DrSg3wjpdt2K+WeoU4npG8now5ydCBf3PKpdIqnNEJn 8Ujfy1ccjDJBVa6PvM56SpJ7PHNgdMZZwLHYAdMRRFBUEwGdVVT99NtxErdU1qAsnY BS1KkUe3RWJn8YdpwQLDwtplb4ACkHhJilNlKNr3Q1Q6UypQVfc5FGyWbSqCozdZKO JjHN5+lxAK5gAcmBeaXZy9axIhQfT7Xf+UA2WPSkKu81ifb6ELGXnbG0tFGlDyo5TA gb6nh2SY0TnIw== Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D0BD96569B for ; Thu, 30 Jun 2022 15:39:41 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id B402924000F; Thu, 30 Jun 2022 13:39:39 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Jun 2022 15:38:56 +0200 Message-Id: <20220630133902.321099-18-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220630133902.321099-1-jacopo@jmondi.org> References: <20220630133902.321099-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 17/23] ipa: ipu3: Configure IPA with libcamera 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: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Pass to the IPA configure() function the list of libcamera controls::internal controls in place of sending to the IPA the raw V4L2 control values. As V4L2 controls are removed from the list of arguments passed to IPA::configure(), fetch the vertical blanking value from the CameraSensorInfo now that it is available there. While at it, rationalize the sequence of operations IPA::configure() to: - check the validity of the configuration - update the session configuration - configure algorithm - assign class member variables Signed-off-by: Jacopo Mondi --- src/ipa/ipu3/ipa_context.cpp | 4 +- src/ipa/ipu3/ipa_context.h | 2 +- src/ipa/ipu3/ipu3.cpp | 79 +++++++++++----------------- src/libcamera/pipeline/ipu3/ipu3.cpp | 2 +- 4 files changed, 36 insertions(+), 51 deletions(-) diff --git a/src/ipa/ipu3/ipa_context.cpp b/src/ipa/ipu3/ipa_context.cpp index 13cdb835ef7f..06fdf2a1efc7 100644 --- a/src/ipa/ipu3/ipa_context.cpp +++ b/src/ipa/ipu3/ipa_context.cpp @@ -126,8 +126,8 @@ namespace libcamera::ipa::ipu3 { * \var IPASessionConfiguration::sensor.lineDuration * \brief Line duration in microseconds * - * \var IPASessionConfiguration::sensor.defVBlank - * \brief The default vblank value of the sensor + * \var IPASessionConfiguration::sensor.vBlank + * \brief The vertical blanking expressed in number of lines */ /** diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h index 42e11141d3a1..a5b878ab7792 100644 --- a/src/ipa/ipu3/ipa_context.h +++ b/src/ipa/ipu3/ipa_context.h @@ -43,7 +43,7 @@ struct IPASessionConfiguration { } agc; struct { - int32_t defVBlank; + int32_t vBlank; utils::Duration lineDuration; } sensor; }; diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index a6e5dcbaada9..44a7d13225df 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -28,6 +28,7 @@ #include #include +#include "libcamera/internal/control_ids.h" #include "libcamera/internal/mapped_framebuffer.h" #include "algorithms/af.h" @@ -148,9 +149,9 @@ public: const uint32_t bufferId, const ControlList &sensorControls) override; private: - void updateSessionConfiguration(const ControlInfoMap &sensorControls); + void updateSessionConfiguration(const IPAConfigInfo &info); - bool validateSensorControls(); + bool validateSensorControls(const ControlInfoMap &sensorControls); void setControls(unsigned int frame); void calculateBdsGrid(const Size &bdsOutputSize); @@ -176,18 +177,12 @@ private: * \brief Compute IPASessionConfiguration using the sensor information and the * sensor V4L2 controls */ -void IPAIPU3::updateSessionConfiguration(const ControlInfoMap &sensorControls) +void IPAIPU3::updateSessionConfiguration(const IPAConfigInfo &info) { - const ControlInfo vBlank = sensorControls.find(V4L2_CID_VBLANK)->second; - context_.configuration.sensor.defVBlank = vBlank.def().get(); + const IPACameraSensorInfo &sensorInfo = info.sensorInfo; + context_.configuration.sensor.vBlank = sensorInfo.vblank; - const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second; - int32_t minExposure = v4l2Exposure.min().get(); - int32_t maxExposure = v4l2Exposure.max().get(); - - const ControlInfo &v4l2Gain = sensorControls.find(V4L2_CID_ANALOGUE_GAIN)->second; - int32_t minGain = v4l2Gain.min().get(); - int32_t maxGain = v4l2Gain.max().get(); + const ControlInfoMap &sensorControls = info.sensorControls; /* * When the AGC computes the new exposure values for a frame, it needs @@ -196,27 +191,30 @@ void IPAIPU3::updateSessionConfiguration(const ControlInfoMap &sensorControls) * * \todo take VBLANK into account for maximum shutter speed */ - context_.configuration.agc.minShutterSpeed = minExposure * context_.configuration.sensor.lineDuration; - context_.configuration.agc.maxShutterSpeed = maxExposure * context_.configuration.sensor.lineDuration; - context_.configuration.agc.minAnalogueGain = camHelper_->gain(minGain); - context_.configuration.agc.maxAnalogueGain = camHelper_->gain(maxGain); + const ControlInfo &exposure = sensorControls.at(&controls::internal::ExposureTime); + context_.configuration.agc.minShutterSpeed = exposure.min().get() * 1.0us; + context_.configuration.agc.maxShutterSpeed = exposure.max().get() * 1.0us; + + const ControlInfo &gain = sensorControls.at(&controls::internal::AnalogueGain); + context_.configuration.agc.minAnalogueGain = gain.min().get(); + context_.configuration.agc.maxAnalogueGain = gain.max().get(); } /** * \brief Validate that the sensor controls mandatory for the IPA exists */ -bool IPAIPU3::validateSensorControls() +bool IPAIPU3::validateSensorControls(const ControlInfoMap &sensorControls) { - static const uint32_t ctrls[] = { - V4L2_CID_ANALOGUE_GAIN, - V4L2_CID_EXPOSURE, - V4L2_CID_VBLANK, + static constexpr std::array ctrls = { + &controls::internal::ExposureTime, + &controls::internal::FrameDuration, + &controls::internal::AnalogueGain, }; - for (auto c : ctrls) { - if (sensorCtrls_.find(c) == sensorCtrls_.end()) { + for (const ControlId *c : ctrls) { + if (sensorControls.find(c) == sensorControls.end()) { LOG(IPAIPU3, Error) << "Unable to find sensor control " - << utils::hex(c); + << c->name(); return false; } } @@ -362,35 +360,19 @@ void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize) */ int IPAIPU3::configure(const IPAConfigInfo &configInfo) { - if (configInfo.sensorControls.empty()) { - LOG(IPAIPU3, Error) << "No sensor controls provided"; - return -ENODATA; + if (!validateSensorControls(configInfo.sensorControls)) { + LOG(IPAIPU3, Error) << "Sensor control validation failed."; + return -EINVAL; } - sensorInfo_ = configInfo.sensorInfo; - - lensCtrls_ = configInfo.lensControls; - - /* - * Compute the sensor V4L2 controls to be used by the algorithms and - * to be set on the sensor. - */ - sensorCtrls_ = configInfo.sensorControls; - - calculateBdsGrid(configInfo.bdsOutputSize); - /* Clean IPAActiveState at each reconfiguration. */ context_.activeState = {}; IPAFrameContext initFrameContext; context_.frameContexts.fill(initFrameContext); - if (!validateSensorControls()) { - LOG(IPAIPU3, Error) << "Sensor control validation failed."; - return -EINVAL; - } - /* Update the IPASessionConfiguration using the sensor settings. */ - updateSessionConfiguration(sensorCtrls_); + updateSessionConfiguration(configInfo); + calculateBdsGrid(configInfo.bdsOutputSize); for (auto const &algo : algorithms_) { int ret = algo->configure(context_, configInfo); @@ -398,6 +380,10 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo) return ret; } + sensorInfo_ = configInfo.sensorInfo; + lensCtrls_ = configInfo.lensControls; + sensorCtrls_ = configInfo.sensorControls; + return 0; } @@ -500,7 +486,7 @@ void IPAIPU3::processStatsBuffer(const uint32_t frame, frameContext.sensor.gain = camHelper_->gain(sensorControls.get(V4L2_CID_ANALOGUE_GAIN).get()); double lineDuration = context_.configuration.sensor.lineDuration.get(); - int32_t vBlank = context_.configuration.sensor.defVBlank; + int32_t vBlank = context_.configuration.sensor.vBlank; ControlList ctrls(controls::controls); for (auto const &algo : algorithms_) @@ -508,7 +494,6 @@ void IPAIPU3::processStatsBuffer(const uint32_t frame, setControls(frame); - /* \todo Use VBlank value calculated from each frame exposure. */ int64_t frameDuration = (vBlank + sensorInfo_.outputSize.height) * lineDuration; ctrls.set(controls::FrameDuration, frameDuration); diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 8c5b6c36ae0b..ce207c968075 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -659,7 +659,7 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) } ipa::ipu3::IPAConfigInfo configInfo; - configInfo.sensorControls = data->cio2_.sensor()->v4l2Controls(); + configInfo.sensorControls = data->cio2_.sensor()->controls(); CameraLens *lens = data->cio2_.sensor()->focusLens(); if (lens)