From patchwork Wed Nov 23 13:43:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 17850 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 72682BE08B for ; Wed, 23 Nov 2022 13:44:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1FFA663313; Wed, 23 Nov 2022 14:44:03 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1669211043; bh=Nu8fAcglarQ1J/JjWXeW4NbEtZjXEed4s6EarGgVuVk=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=03O2iNd97up/508Md91oNrXKAB8OBK8D9RxGyPU4gk/qStZrP88AGsP8oJk9jYE78 MsbEXq3RE/488GfBgPZqOnxODj6C4LWsLtti3AZhtuUaV2AuEI15aUIh5VVPoy55hm SsPmkNHCU9oFor+eGz05iIBGhYzZzjR0SgyiGupD5k3HYBkjxH1YyqBABjEea68cAL Iu30a5HrkppiaVWW+sYBDxABqTn26Y2jQvAZmfvFljDcUitvepnScBb0YWkDJ0rGv3 AHzGtrjnWxQH8JZJiCPcqfzUOvRXyoYJcHTAKAPSUgfRAppjBMvbCQ1cS/YfbkNAEJ 2mF1yJrDxUAbQ== Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::224]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 38C0E63313 for ; Wed, 23 Nov 2022 14:44:01 +0100 (CET) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 7A980E000F; Wed, 23 Nov 2022 13:44:00 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Wed, 23 Nov 2022 14:43:46 +0100 Message-Id: <20221123134346.129807-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221123134346.129807-1-jacopo@jmondi.org> References: <20221123134346.129807-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 4/4] ipa: rkisp1: add FrameDurationLimits 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: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: Nicholas Roth Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Nicholas Roth Currently, the Android HAL does not work on rkisp1-based devices because required FrameDurationLimits metadata is missing from the IPA implementation. This change sets FrameDurationLimits for rkisp1 based on the existing ipu3 implementation, using the sensor's reported range of vertical blanking intervals with the minimum reported horizontal blanking interval. Signed-off-by: Nicholas Roth Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- include/libcamera/ipa/rkisp1.mojom | 6 ++- src/ipa/rkisp1/rkisp1.cpp | 57 +++++++++++++++++++++--- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 17 ++++--- 3 files changed, 67 insertions(+), 13 deletions(-) diff --git a/include/libcamera/ipa/rkisp1.mojom b/include/libcamera/ipa/rkisp1.mojom index 36bf291e8a51..1009e970a1b5 100644 --- a/include/libcamera/ipa/rkisp1.mojom +++ b/include/libcamera/ipa/rkisp1.mojom @@ -15,14 +15,16 @@ struct IPAConfigInfo { interface IPARkISP1Interface { init(libcamera.IPASettings settings, - uint32 hwRevision) + uint32 hwRevision, + libcamera.IPACameraSensorInfo sensorInfo, + libcamera.ControlInfoMap sensorControls) => (int32 ret, libcamera.ControlInfoMap ipaControls); start() => (int32 ret); stop(); configure(IPAConfigInfo configInfo, map streamConfig) - => (int32 ret); + => (int32 ret, libcamera.ControlInfoMap ipaControls); mapBuffers(array buffers); unmapBuffers(array ids); diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index a9e144303072..9265d3c9f53c 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -49,12 +49,15 @@ public: IPARkISP1(); int init(const IPASettings &settings, unsigned int hwRevision, + const IPACameraSensorInfo &sensorInfo, + const ControlInfoMap &sensorControls, ControlInfoMap *ipaControls) override; int start() override; void stop() override; int configure(const IPAConfigInfo &ipaConfig, - const std::map &streamConfig) override; + const std::map &streamConfig, + ControlInfoMap *ipaControls) override; void mapBuffers(const std::vector &buffers) override; void unmapBuffers(const std::vector &ids) override; @@ -67,6 +70,9 @@ protected: std::string logPrefix() const override; private: + void updateControls(const IPACameraSensorInfo &sensorInfo, + const ControlInfoMap &sensorControls, + ControlInfoMap *ipaControls); void setControls(unsigned int frame); std::map buffers_; @@ -114,6 +120,8 @@ std::string IPARkISP1::logPrefix() const } int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision, + const IPACameraSensorInfo &sensorInfo, + const ControlInfoMap &sensorControls, ControlInfoMap *ipaControls) { /* \todo Add support for other revisions */ @@ -180,9 +188,8 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision, if (ret) return ret; - /* Return the controls handled by the IPA. */ - ControlInfoMap::Map ctrlMap = rkisp1Controls; - *ipaControls = ControlInfoMap(std::move(ctrlMap), controls::controls); + /* Initialize controls. */ + updateControls(sensorInfo, sensorControls, ipaControls); return 0; } @@ -200,7 +207,8 @@ void IPARkISP1::stop() } int IPARkISP1::configure(const IPAConfigInfo &ipaConfig, - [[maybe_unused]] const std::map &streamConfig) + [[maybe_unused]] const std::map &streamConfig, + ControlInfoMap *ipaControls) { sensorControls_ = ipaConfig.sensorControls; @@ -230,6 +238,9 @@ int IPARkISP1::configure(const IPAConfigInfo &ipaConfig, context_.configuration.sensor.size = info.outputSize; context_.configuration.sensor.lineDuration = info.minLineLength * 1.0s / info.pixelRate; + /* Update the camera controls using the new sensor settings. */ + updateControls(info, sensorControls_, ipaControls); + /* * When the AGC computes the new exposure values for a frame, it needs * to know the limits for shutter speed and analogue gain. @@ -332,6 +343,42 @@ void IPARkISP1::processStatsBuffer(const uint32_t frame, const uint32_t bufferId metadataReady.emit(frame, metadata); } +void IPARkISP1::updateControls(const IPACameraSensorInfo &sensorInfo, + const ControlInfoMap &sensorControls, + ControlInfoMap *ipaControls) +{ + ControlInfoMap::Map ctrlMap = rkisp1Controls; + + /* + * Compute the frame duration limits. + * + * The frame length is computed assuming a fixed line length combined + * with the vertical frame sizes. + */ + const ControlInfo &v4l2HBlank = sensorControls.find(V4L2_CID_HBLANK)->second; + uint32_t hblank = v4l2HBlank.def().get(); + uint32_t lineLength = sensorInfo.outputSize.width + hblank; + + const ControlInfo &v4l2VBlank = sensorControls.find(V4L2_CID_VBLANK)->second; + std::array frameHeights{ + v4l2VBlank.min().get() + sensorInfo.outputSize.height, + v4l2VBlank.max().get() + sensorInfo.outputSize.height, + v4l2VBlank.def().get() + sensorInfo.outputSize.height, + }; + + std::array frameDurations; + for (unsigned int i = 0; i < frameHeights.size(); ++i) { + uint64_t frameSize = lineLength * frameHeights[i]; + frameDurations[i] = frameSize / (sensorInfo.pixelRate / 1000000U); + } + + ctrlMap[&controls::FrameDurationLimits] = ControlInfo(frameDurations[0], + frameDurations[1], + frameDurations[2]); + + *ipaControls = ControlInfoMap(std::move(ctrlMap), controls::controls); +} + void IPARkISP1::setControls(unsigned int frame) { /* diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index e946ccc4c930..231b16eca110 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -347,8 +347,15 @@ int RkISP1CameraData::loadIPA(unsigned int hwRevision) ipaTuningFile = std::string(configFromEnv); } - int ret = ipa_->init({ ipaTuningFile, sensor_->model() }, hwRevision, - &controlInfo_); + IPACameraSensorInfo sensorInfo{}; + int ret = sensor_->sensorInfo(&sensorInfo); + if (ret) { + LOG(RkISP1, Error) << "Camera sensor information not available"; + return ret; + } + + ret = ipa_->init({ ipaTuningFile, sensor_->model() }, hwRevision, + sensorInfo, sensor_->controls(), &controlInfo_); if (ret < 0) { LOG(RkISP1, Error) << "IPA initialization failure"; return ret; @@ -718,14 +725,12 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) ipa::rkisp1::IPAConfigInfo ipaConfig{}; ret = data->sensor_->sensorInfo(&ipaConfig.sensorInfo); - if (ret) { - LOG(RkISP1, Error) << "Camera sensor information not available"; + if (ret) return ret; - } ipaConfig.sensorControls = data->sensor_->controls(); - ret = data->ipa_->configure(ipaConfig, streamConfig); + ret = data->ipa_->configure(ipaConfig, streamConfig, &data->controlInfo_); if (ret) { LOG(RkISP1, Error) << "failed configuring IPA (" << ret << ")"; return ret;