From patchwork Fri Oct 24 08:50:54 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 24796 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 35801BE080 for ; Fri, 24 Oct 2025 08:53:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EAD2E60963; Fri, 24 Oct 2025 10:53:09 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="C9vcULdf"; 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 EF85F60938 for ; Fri, 24 Oct 2025 10:53:08 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:7edc:62f4:c118:1549]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 71F5C4B17; Fri, 24 Oct 2025 10:51:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761295883; bh=bDOfUmyAm/mN+cuZdw6wBlZilzXFIYveLc6YHvQBc4Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=C9vcULdfalzF9JVce1pIJNRrEANAeiwC3TMy7LST7eV3XGE9ftsfw1SMotCXnT5xC itreD+xqtnWsoIlBV4PIzKfg+UdEgciiCmk+RpLG+4D8KAgQnGfZbPz1odMPzJ9JrY z6iR8cgEdf/Rbqe/bgtHIvRX+2Njh09X2xkDN1PU= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH v1 30/35] pipeline: rkisp1: Correctly handle params buffer for frame 0 Date: Fri, 24 Oct 2025 10:50:54 +0200 Message-ID: <20251024085130.995967-31-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20251024085130.995967-1-stefan.klug@ideasonboard.com> References: <20251024085130.995967-1-stefan.klug@ideasonboard.com> MIME-Version: 1.0 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" The parameters for frame 0 are only active on frame 0 if the corresponding parameter buffer is queued before STREAMON is called on the isp. Therefore the normal mechanics of calling ipa->computeParams() do not work, as it gets called after the first request is queued and therefore the isp is already started. To fix that, handle the parameter buffer the same way the initial sensor controls are handled by passing it to the ipa->start() function and then queuing the params buffer before starting the isp. Signed-off-by: Stefan Klug --- include/libcamera/ipa/rkisp1.mojom | 5 +++- src/ipa/rkisp1/rkisp1.cpp | 31 +++++++++++++++++------- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 31 ++++++++++++++++++------ 3 files changed, 49 insertions(+), 18 deletions(-) diff --git a/include/libcamera/ipa/rkisp1.mojom b/include/libcamera/ipa/rkisp1.mojom index 4c29b53cd7f9..56c9fe8ab92a 100644 --- a/include/libcamera/ipa/rkisp1.mojom +++ b/include/libcamera/ipa/rkisp1.mojom @@ -17,6 +17,7 @@ struct IPAConfigInfo { struct StartResult { libcamera.ControlList controls; int32 code; + uint32 paramBufferBytesUsed; }; interface IPARkISP1Interface { @@ -25,7 +26,9 @@ interface IPARkISP1Interface { libcamera.IPACameraSensorInfo sensorInfo, libcamera.ControlInfoMap sensorControls) => (int32 ret, libcamera.ControlInfoMap ipaControls); - start(libcamera.ControlList controls) => (StartResult result); + start(libcamera.ControlList controls, + uint32 paramBufferId) + => (StartResult result); stop(); configure(IPAConfigInfo configInfo, diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index b714e2f10c65..a887214c63a9 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -56,7 +56,8 @@ public: const IPACameraSensorInfo &sensorInfo, const ControlInfoMap &sensorControls, ControlInfoMap *ipaControls) override; - void start(const ControlList &controls, StartResult *result) override; + void start(const ControlList &controls, const uint32_t paramBufferId, + StartResult *result) override; void stop() override; int configure(const IPAConfigInfo &ipaConfig, @@ -77,6 +78,8 @@ protected: std::string logPrefix() const override; private: + uint32_t computeParamsInternal(IPAFrameContext &frameContext, const uint32_t bufferId); + void updateControls(const IPACameraSensorInfo &sensorInfo, const ControlInfoMap &sensorControls, ControlInfoMap *ipaControls); @@ -216,10 +219,12 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision, return 0; } -void IPARkISP1::start(const ControlList &controls, StartResult *result) +void IPARkISP1::start(const ControlList &controls, const uint32_t paramBufferId, + StartResult *result) { IPAFrameContext frameContext = {}; initializeFrameContext(0, frameContext, controls); + result->paramBufferBytesUsed = computeParamsInternal(frameContext, paramBufferId); result->controls = getSensorControls(frameContext); result->code = 0; } @@ -373,6 +378,19 @@ void IPARkISP1::initializeFrameContext(const uint32_t frame, controlsToApply_.clear(); } +uint32_t IPARkISP1::computeParamsInternal(IPAFrameContext &frameContext, const uint32_t bufferId) +{ + ASSERT(bufferId); + + RkISP1Params params(context_.configuration.paramFormat, + mappedBuffers_.at(bufferId).planes()[0]); + + for (auto const &algo : algorithms()) + algo->prepare(context_, frameContext.frame(), frameContext, ¶ms); + + return params.size(); +} + void IPARkISP1::computeParams(const uint32_t frame, const uint32_t bufferId) { IPAFrameContext &frameContext = context_.frameContexts.get(frame); @@ -390,16 +408,11 @@ void IPARkISP1::computeParams(const uint32_t frame, const uint32_t bufferId) return; } - RkISP1Params params(context_.configuration.paramFormat, - mappedBuffers_.at(bufferId).planes()[0]); - - for (auto const &algo : algorithms()) - algo->prepare(context_, frame, frameContext, ¶ms); - + uint32_t size = computeParamsInternal(frameContext, bufferId); ControlList ctrls = getSensorControls(frameContext); setSensorControls.emit(frame, ctrls); - paramsComputed.emit(frame, params.size()); + paramsComputed.emit(frame, size); } void IPARkISP1::processStats(const uint32_t frame, const uint32_t bufferId, diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 2d78721be63a..1e39acc5cc37 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -110,8 +110,8 @@ public: bool canUseDewarper_; bool usesDewarper_; -private: void paramsComputed(unsigned int frame, unsigned int bytesused); +private: void setSensorControls(unsigned int frame, const ControlList &sensorControls); @@ -1251,23 +1251,38 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL if (!!controls) ctrls = *controls; + data->frame_ = 0; + nextParamsSequence_ = 0; + nextStatsToProcess_ = 0; + paramsSyncHelper_.reset(); + imageSyncHelper_.reset(); + + uint32_t paramBufferId = 0; + FrameBuffer *paramBuffer = nullptr; + if (!isRaw_) { + paramBuffer = availableParamBuffers_.front(); + paramBufferId = paramBuffer->cookie(); + } + ipa::rkisp1::StartResult res; - data->ipa_->start(ctrls, &res); + data->ipa_->start(ctrls, paramBufferId, &res); if (res.code) { LOG(RkISP1, Error) << "Failed to start IPA " << camera->id(); return ret; } + + if (paramBuffer) { + availableParamBuffers_.pop(); + computingParamBuffers_.push({ paramBuffer, nextParamsSequence_++ }); + paramsSyncHelper_.pushCorrection(0); + data->paramsComputed(0, res.paramBufferBytesUsed); + } + actions += [&]() { data->ipa_->stop(); }; data->sensor_->setControls(&res.controls); data->delayedCtrls_->reset(); - data->frame_ = 0; - nextParamsSequence_ = 0; - nextStatsToProcess_ = 0; - paramsSyncHelper_.reset(); - imageSyncHelper_.reset(); - if (!isRaw_) { ret = param_->streamOn(); if (ret) {