From patchwork Mon Sep 14 14:02:43 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 28274 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 2763DC3272 for ; Mon, 14 Sep 2026 14:04:47 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D3C50686F2; Mon, 14 Sep 2026 16:04:46 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="NAV84mGN"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9199F686F2 for ; Mon, 14 Sep 2026 16:04:45 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:a279:75fa:1f6c:7f40]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 9389B9A4; Mon, 14 Sep 2026 16:03:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1789394585; bh=kiKlq85KJtU0lcsJeo7KzKJVQVlty/L7aIWxMyr6LrI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NAV84mGNcnfTsXR14JTGOhaUGLVjP40hib5ozIXvCkBuWRU8ltYbibU7H4CprpdzB bWFS1RDw5Jx8AAhTg3ewlHBDoItI1GHu6dTaPQYCDDD7fmMkmwhQMvgTjsOdtPiuR5 aICnPf7u/J/xbjTrStefTTuM5qfujtcitM1y9bQU= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH v3 30/41] pipeline: rkisp1: Correctly handle params buffer for frame 0 Date: Mon, 14 Sep 2026 16:02:43 +0200 Message-ID: <20260914140309.3354666-31-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260914140309.3354666-1-stefan.klug@ideasonboard.com> References: <20260914140309.3354666-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 --- Changes in v3: - Moved bufferId== 0 check out of computeParamsInternal for better readability - setSensorControls is now emitted after paramsComputed but that must not be a problem - Dropped rby tag due to bigger changes Changes in v2: - Small cleanup - Fixed crash in raw case where a null buffer is passed on start - Collected tag --- include/libcamera/ipa/rkisp1.mojom | 5 +++- src/ipa/rkisp1/rkisp1.cpp | 35 ++++++++++++++++++------ src/libcamera/pipeline/rkisp1/rkisp1.cpp | 18 +++++++++++- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/include/libcamera/ipa/rkisp1.mojom b/include/libcamera/ipa/rkisp1.mojom index 04230d0f852e..6571a6d096f0 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 3a65dab75cb7..b8b4a79830c8 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -54,7 +54,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, @@ -74,6 +75,8 @@ protected: std::string logPrefix() const override; private: + uint32_t computeParamsInternal(IPAFrameContext &frameContext, const uint32_t bufferId); + void updateControls(ControlInfoMap *ipaControls); ControlList getSensorControls(const IPAFrameContext &context); @@ -210,9 +213,17 @@ 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 = context_.frameContexts.getOrInitContext(0, controls); + + if (paramBufferId != 0) + result->paramBufferBytesUsed = computeParamsInternal(frameContext, + paramBufferId); + else + result->paramBufferBytesUsed = 0; + result->controls = getSensorControls(frameContext); result->code = 0; } @@ -312,18 +323,24 @@ void IPARkISP1::initializeFrameContext(IPAFrameContext &fc, const ControlList &c } } +uint32_t IPARkISP1::computeParamsInternal(IPAFrameContext &frameContext, const uint32_t bufferId) +{ + RkISP1Params params(context_.configuration.paramFormat, + mappedBuffers_.at(bufferId).planes()[0]); + + for (const auto &algo : algorithms()) + algo->prepare(context_, frameContext.frame(), frameContext, ¶ms); + + return params.bytesused(); +} + void IPARkISP1::computeParams(const uint32_t frame, const uint32_t bufferId) { IPAFrameContext &frameContext = context_.frameContexts.getOrInitContext(frame); if (bufferId != 0) { - RkISP1Params params(context_.configuration.paramFormat, - mappedBuffers_.at(bufferId).planes()[0]); - - for (const auto &algo : algorithms()) - algo->prepare(context_, frame, frameContext, ¶ms); - - paramsComputed.emit(frame, bufferId, params.bytesused()); + uint32_t size = computeParamsInternal(frameContext, bufferId); + paramsComputed.emit(frame, bufferId, size); } ControlList ctrls = getSensorControls(frameContext); diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 832f58e95d37..b051dd21fb4c 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -104,8 +104,8 @@ public: bool canUseDewarper_; bool usesDewarper_; -private: void paramsComputed(unsigned int frame, unsigned int bufferId, unsigned int bytesused); +private: void setSensorControls(unsigned int frame, const ControlList &sensorControls); @@ -1200,14 +1200,30 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL nextStatsToProcess_ = 0; data->frame_ = 0; + uint32_t paramBufferId = 0; + FrameBuffer *paramBuffer = nullptr; + if (!isRaw_) { + paramBuffer = availableParamBuffers_.front(); + paramBufferId = paramBuffer->cookie(); + } + ipa::rkisp1::StartResult res; data->ipa_->start(controls ? *controls : ControlList{ controls::controls }, + 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, paramBufferId, res.paramBufferBytesUsed); + } + actions += [&]() { data->ipa_->stop(); }; data->sensor_->setControls(&res.controls); data->delayedCtrls_->reset();