{"id":24796,"url":"https://patchwork.libcamera.org/api/patches/24796/?format=json","web_url":"https://patchwork.libcamera.org/patch/24796/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20251024085130.995967-31-stefan.klug@ideasonboard.com>","date":"2025-10-24T08:50:54","name":"[v1,30/35] pipeline: rkisp1: Correctly handle params buffer for frame 0","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"d11fc55a2223bbc48b9fd263b0f15b7119fef231","submitter":{"id":184,"url":"https://patchwork.libcamera.org/api/people/184/?format=json","name":"Stefan Klug","email":"stefan.klug@ideasonboard.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/24796/mbox/","series":[{"id":5524,"url":"https://patchwork.libcamera.org/api/series/5524/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=5524","date":"2025-10-24T08:50:24","name":"rkisp1: pipeline rework for PFC","version":1,"mbox":"https://patchwork.libcamera.org/series/5524/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/24796/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/24796/checks/","tags":{},"headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 35801BE080\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 24 Oct 2025 08:53:10 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id EAD2E60963;\n\tFri, 24 Oct 2025 10:53:09 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id EF85F60938\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 24 Oct 2025 10:53:08 +0200 (CEST)","from ideasonboard.com (unknown\n\t[IPv6:2a00:6020:448c:6c00:7edc:62f4:c118:1549])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 71F5C4B17; \n\tFri, 24 Oct 2025 10:51:23 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"C9vcULdf\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1761295883;\n\tbh=bDOfUmyAm/mN+cuZdw6wBlZilzXFIYveLc6YHvQBc4Y=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=C9vcULdfalzF9JVce1pIJNRrEANAeiwC3TMy7LST7eV3XGE9ftsfw1SMotCXnT5xC\n\titreD+xqtnWsoIlBV4PIzKfg+UdEgciiCmk+RpLG+4D8KAgQnGfZbPz1odMPzJ9JrY\n\tz6iR8cgEdf/Rbqe/bgtHIvRX+2Njh09X2xkDN1PU=","From":"Stefan Klug <stefan.klug@ideasonboard.com>","To":"libcamera-devel@lists.libcamera.org","Cc":"Stefan Klug <stefan.klug@ideasonboard.com>","Subject":"[PATCH v1 30/35] pipeline: rkisp1: Correctly handle params buffer\n\tfor 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","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"The parameters for frame 0 are only active on frame 0 if the\ncorresponding parameter buffer is queued before STREAMON is called on\nthe isp. Therefore the normal mechanics of calling ipa->computeParams()\ndo not work, as it gets called after the first request is queued and\ntherefore the isp is already started. To fix that, handle the parameter\nbuffer the same way the initial sensor controls are handled by passing\nit to the ipa->start() function and then queuing the params buffer\nbefore starting the isp.\n\nSigned-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n---\n include/libcamera/ipa/rkisp1.mojom       |  5 +++-\n src/ipa/rkisp1/rkisp1.cpp                | 31 +++++++++++++++++-------\n src/libcamera/pipeline/rkisp1/rkisp1.cpp | 31 ++++++++++++++++++------\n 3 files changed, 49 insertions(+), 18 deletions(-)","diff":"diff --git a/include/libcamera/ipa/rkisp1.mojom b/include/libcamera/ipa/rkisp1.mojom\nindex 4c29b53cd7f9..56c9fe8ab92a 100644\n--- a/include/libcamera/ipa/rkisp1.mojom\n+++ b/include/libcamera/ipa/rkisp1.mojom\n@@ -17,6 +17,7 @@ struct IPAConfigInfo {\n struct StartResult {\n \tlibcamera.ControlList controls;\n \tint32 code;\n+\tuint32 paramBufferBytesUsed;\n };\n \n interface IPARkISP1Interface {\n@@ -25,7 +26,9 @@ interface IPARkISP1Interface {\n \t     libcamera.IPACameraSensorInfo sensorInfo,\n \t     libcamera.ControlInfoMap sensorControls)\n \t\t=> (int32 ret, libcamera.ControlInfoMap ipaControls);\n-\tstart(libcamera.ControlList controls) => (StartResult result);\n+\tstart(libcamera.ControlList controls,\n+\t      uint32 paramBufferId)\n+\t\t=> (StartResult result);\n \tstop();\n \n \tconfigure(IPAConfigInfo configInfo,\ndiff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp\nindex b714e2f10c65..a887214c63a9 100644\n--- a/src/ipa/rkisp1/rkisp1.cpp\n+++ b/src/ipa/rkisp1/rkisp1.cpp\n@@ -56,7 +56,8 @@ public:\n \t\t const IPACameraSensorInfo &sensorInfo,\n \t\t const ControlInfoMap &sensorControls,\n \t\t ControlInfoMap *ipaControls) override;\n-\tvoid start(const ControlList &controls, StartResult *result) override;\n+\tvoid start(const ControlList &controls, const uint32_t paramBufferId,\n+\t\t   StartResult *result) override;\n \tvoid stop() override;\n \n \tint configure(const IPAConfigInfo &ipaConfig,\n@@ -77,6 +78,8 @@ protected:\n \tstd::string logPrefix() const override;\n \n private:\n+\tuint32_t computeParamsInternal(IPAFrameContext &frameContext, const uint32_t bufferId);\n+\n \tvoid updateControls(const IPACameraSensorInfo &sensorInfo,\n \t\t\t    const ControlInfoMap &sensorControls,\n \t\t\t    ControlInfoMap *ipaControls);\n@@ -216,10 +219,12 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,\n \treturn 0;\n }\n \n-void IPARkISP1::start(const ControlList &controls, StartResult *result)\n+void IPARkISP1::start(const ControlList &controls, const uint32_t paramBufferId,\n+\t\t      StartResult *result)\n {\n \tIPAFrameContext frameContext = {};\n \tinitializeFrameContext(0, frameContext, controls);\n+\tresult->paramBufferBytesUsed = computeParamsInternal(frameContext, paramBufferId);\n \tresult->controls = getSensorControls(frameContext);\n \tresult->code = 0;\n }\n@@ -373,6 +378,19 @@ void IPARkISP1::initializeFrameContext(const uint32_t frame,\n \tcontrolsToApply_.clear();\n }\n \n+uint32_t IPARkISP1::computeParamsInternal(IPAFrameContext &frameContext, const uint32_t bufferId)\n+{\n+\tASSERT(bufferId);\n+\n+\tRkISP1Params params(context_.configuration.paramFormat,\n+\t\t\t    mappedBuffers_.at(bufferId).planes()[0]);\n+\n+\tfor (auto const &algo : algorithms())\n+\t\talgo->prepare(context_, frameContext.frame(), frameContext, &params);\n+\n+\treturn params.size();\n+}\n+\n void IPARkISP1::computeParams(const uint32_t frame, const uint32_t bufferId)\n {\n \tIPAFrameContext &frameContext = context_.frameContexts.get(frame);\n@@ -390,16 +408,11 @@ void IPARkISP1::computeParams(const uint32_t frame, const uint32_t bufferId)\n \t\treturn;\n \t}\n \n-\tRkISP1Params params(context_.configuration.paramFormat,\n-\t\t\t    mappedBuffers_.at(bufferId).planes()[0]);\n-\n-\tfor (auto const &algo : algorithms())\n-\t\talgo->prepare(context_, frame, frameContext, &params);\n-\n+\tuint32_t size = computeParamsInternal(frameContext, bufferId);\n \tControlList ctrls = getSensorControls(frameContext);\n \tsetSensorControls.emit(frame, ctrls);\n \n-\tparamsComputed.emit(frame, params.size());\n+\tparamsComputed.emit(frame, size);\n }\n \n void IPARkISP1::processStats(const uint32_t frame, const uint32_t bufferId,\ndiff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\nindex 2d78721be63a..1e39acc5cc37 100644\n--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n@@ -110,8 +110,8 @@ public:\n \tbool canUseDewarper_;\n \tbool usesDewarper_;\n \n-private:\n \tvoid paramsComputed(unsigned int frame, unsigned int bytesused);\n+private:\n \tvoid setSensorControls(unsigned int frame,\n \t\t\t       const ControlList &sensorControls);\n \n@@ -1251,23 +1251,38 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL\n \tif (!!controls)\n \t\tctrls = *controls;\n \n+\tdata->frame_ = 0;\n+\tnextParamsSequence_ = 0;\n+\tnextStatsToProcess_ = 0;\n+\tparamsSyncHelper_.reset();\n+\timageSyncHelper_.reset();\n+\n+\tuint32_t paramBufferId = 0;\n+\tFrameBuffer *paramBuffer = nullptr;\n+\tif (!isRaw_) {\n+\t\tparamBuffer = availableParamBuffers_.front();\n+\t\tparamBufferId = paramBuffer->cookie();\n+\t}\n+\n \tipa::rkisp1::StartResult res;\n-\tdata->ipa_->start(ctrls, &res);\n+\tdata->ipa_->start(ctrls, paramBufferId, &res);\n \tif (res.code) {\n \t\tLOG(RkISP1, Error)\n \t\t\t<< \"Failed to start IPA \" << camera->id();\n \t\treturn ret;\n \t}\n+\n+\tif (paramBuffer) {\n+\t\tavailableParamBuffers_.pop();\n+\t\tcomputingParamBuffers_.push({ paramBuffer, nextParamsSequence_++ });\n+\t\tparamsSyncHelper_.pushCorrection(0);\n+\t\tdata->paramsComputed(0, res.paramBufferBytesUsed);\n+\t}\n+\n \tactions += [&]() { data->ipa_->stop(); };\n \tdata->sensor_->setControls(&res.controls);\n \tdata->delayedCtrls_->reset();\n \n-\tdata->frame_ = 0;\n-\tnextParamsSequence_ = 0;\n-\tnextStatsToProcess_ = 0;\n-\tparamsSyncHelper_.reset();\n-\timageSyncHelper_.reset();\n-\n \tif (!isRaw_) {\n \t\tret = param_->streamOn();\n \t\tif (ret) {\n","prefixes":["v1","30/35"]}