From patchwork Sun Oct 30 23:04:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Roth X-Patchwork-Id: 17731 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 DA737BD16B for ; Sun, 30 Oct 2022 23:05:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 91DC86303B; Mon, 31 Oct 2022 00:05:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1667171122; bh=NUlh5POdicEvwiEE6SOqJlrUM4OBdNHXOkVKtYNrgYE=; 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=120rAWBstOklaOi0ZAgUeELn/iZAwKQ6JqpWcLCRiorx9Ghxy23Z8uDrQRG3UxQk8 COPbAD1Pbsj0aEXBilaGAphK1yOEFszDbxoReyjE8v4+wRe7/Zao4lgb3Vn/K61tx/ U5dWgRacOmQItPKSojNAgcT8VQsJWZvBb2uUQudH7SJ6ne7eRAtpbsR1bWKyPCOCe/ PcZFz+//Ys+X6hALfgNBkBS0TA+SvqiXgNAYoEA2qQO5JLrF8YeDWkQYp1bcL79MT9 xXmkVLvRDw1ugtVKOVQNlKMYLCR9X++CMZkHEdE0FtuqUQS21XtkfMIox+LnqRm6Dz I5ebmzxS25QlQ== Received: from mail-oi1-x22c.google.com (mail-oi1-x22c.google.com [IPv6:2607:f8b0:4864:20::22c]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1C79E6302B for ; Mon, 31 Oct 2022 00:05:19 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=rothemail-net.20210112.gappssmtp.com header.i=@rothemail-net.20210112.gappssmtp.com header.b="X8OFbwgS"; dkim-atps=neutral Received: by mail-oi1-x22c.google.com with SMTP id u132so11464884oib.0 for ; Sun, 30 Oct 2022 16:05:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rothemail-net.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=E5rYlHmHyHLxAeMcW9QRK0c92nButyvzD61yfmD0Lpo=; b=X8OFbwgSH1yzU4BmimpijD8ctqzhYYCUwfIZD58QeTl+g4C9VNxvnAH8zZRyUQequV QKXFJ2gCaGaazgUMZfqnoe/QbiAKOPN8QWzpuF7e8w4qxDLM3T37sfsB/MHRJSIKz/96 2THPh7wF2R399Qpn91hQUqaqqnvB7zA+KvPmB2Gq4ornp/ddh9El6uDjlOVjofLxfizH 5Nkd1BbvrBgGNIgbiNi6YHxpx8aoSRr1HrlvNAj4Y9bJFDVJpJ6qHS80dDvswxAn7BiS ltN989xPFHFCbqrVgrth/lD0kHnVDMVScefncoFjFvGqDQ+xrgijx7UpToPUH5WCRDPX IXzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=E5rYlHmHyHLxAeMcW9QRK0c92nButyvzD61yfmD0Lpo=; b=uqwqHEbemqwYhUoA2+bZSVCleMSZ+5nIvd1n0Rqi/xKB27aL8AsAhqSc4igYvEEImd PZThYc7EWqomKYwCBdNu1QBFAahrt2dzjC2HA1lDyWj86+jJbGntktuECqI7euM1VysF fkTc2GBCQqm/P5SjgIIWgMqanMCvblaGZRiZW3Gk37yblSxkJ7xBHO5nQaYcSViEdVTQ a6MeHthzR6kTAfl9oIfbT6L6Ce/BL673oZhfrCul+YggZcBHAOLXzLyy+/uesctmxqFh 0Y8cQ8EBWBawvg0ntvJvCW+Q1gfc4rnrXcaJmOiobBYFGcc8k4cpg1QLXA3N8pYpk8gB f5cA== X-Gm-Message-State: ACrzQf2lM/i2TFR6u47g2pcAsLiLzNcP7SlIHYi8m2ByTLDlJXP8MGXT ArZjzlHHqxeg4C//rFnAtij/00zw/DPZJw== X-Google-Smtp-Source: AMsMyM5MefH7rgoPIQzleI91iuvZqb76wOlU9OKmiNrDZeigxASQNI7gKSVrkAxd7oRJvd1HyVeLvg== X-Received: by 2002:a05:6808:1a13:b0:354:b339:25f2 with SMTP id bk19-20020a0568081a1300b00354b33925f2mr13400510oib.285.1667171117380; Sun, 30 Oct 2022 16:05:17 -0700 (PDT) Received: from nroth-pc.attlocal.net (104-5-61-214.lightspeed.austtx.sbcglobal.net. [104.5.61.214]) by smtp.gmail.com with ESMTPSA id u4-20020a056871008400b0013c8ae74a14sm2269403oaa.42.2022.10.30.16.05.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 30 Oct 2022 16:05:17 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Sun, 30 Oct 2022 18:04:57 -0500 Message-Id: <20221030230500.74842-3-nicholas@rothemail.net> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221030230500.74842-1-nicholas@rothemail.net> References: <20221030230500.74842-1-nicholas@rothemail.net> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v6 2/5] 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: Nicholas Roth via libcamera-devel From: Nicholas Roth Reply-To: Nicholas Roth Cc: Nicholas Roth Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" 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 --- include/libcamera/ipa/rkisp1.mojom | 6 ++- src/ipa/rkisp1/rkisp1.cpp | 57 +++++++++++++++++++++--- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 12 +++-- 3 files changed, 64 insertions(+), 11 deletions(-) diff --git a/include/libcamera/ipa/rkisp1.mojom b/include/libcamera/ipa/rkisp1.mojom index eaf3955e..86ff6d0e 100644 --- a/include/libcamera/ipa/rkisp1.mojom +++ b/include/libcamera/ipa/rkisp1.mojom @@ -10,7 +10,9 @@ import "include/libcamera/ipa/core.mojom"; 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(); @@ -18,7 +20,7 @@ interface IPARkISP1Interface { configure(libcamera.IPACameraSensorInfo sensorInfo, map streamConfig, map entityControls) - => (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 069c901b..49239a87 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -49,13 +49,16 @@ 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 IPACameraSensorInfo &info, const std::map &streamConfig, - const std::map &entityControls) override; + const std::map &entityControls, + ControlInfoMap *ipaControls) override; void mapBuffers(const std::vector &buffers) override; void unmapBuffers(const std::vector &ids) override; @@ -68,6 +71,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_; @@ -115,6 +121,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; } @@ -207,7 +214,8 @@ void IPARkISP1::stop() */ int IPARkISP1::configure([[maybe_unused]] const IPACameraSensorInfo &info, [[maybe_unused]] const std::map &streamConfig, - const std::map &entityControls) + const std::map &entityControls, + ControlInfoMap *ipaControls) { if (entityControls.empty()) return -EINVAL; @@ -249,6 +257,9 @@ int IPARkISP1::configure([[maybe_unused]] const IPACameraSensorInfo &info, 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, ctrls_, ipaControls); + /* * When the AGC computes the new exposure values for a frame, it needs * to know the limits for shutter speed and analogue gain. @@ -349,6 +360,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 455ee2a0..dae29a2c 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -340,15 +340,19 @@ int RkISP1CameraData::loadIPA(unsigned int hwRevision) /* * If the tuning file isn't found, fall back to the * 'uncalibrated' configuration file. - */ + */ if (ipaTuningFile.empty()) ipaTuningFile = ipa_->configurationFile("uncalibrated.yaml"); } else { ipaTuningFile = std::string(configFromEnv); } - int ret = ipa_->init({ ipaTuningFile, sensor_->model() }, hwRevision, - &controlInfo_); + IPACameraSensorInfo sensorInfo{}; + int ret = sensor_->sensorInfo(&sensorInfo); + if (ret) + return ret; + ret = ipa_->init({ ipaTuningFile, sensor_->model() }, hwRevision, + sensorInfo, sensor_->controls(), &controlInfo_); if (ret < 0) { LOG(RkISP1, Error) << "IPA initialization failure"; return ret; @@ -725,7 +729,7 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) std::map entityControls; entityControls.emplace(0, data->sensor_->controls()); - ret = data->ipa_->configure(sensorInfo, streamConfig, entityControls); + ret = data->ipa_->configure(sensorInfo, streamConfig, entityControls, &data->controlInfo_); if (ret) { LOG(RkISP1, Error) << "failed configuring IPA (" << ret << ")"; return ret;