From patchwork Thu Jun 4 09:50:55 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26834 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 592CEC328C for ; Thu, 4 Jun 2026 09:51:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 016CC6373D; Thu, 4 Jun 2026 11:51:52 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="cyuaDlsq"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 93D4B635D6 for ; Thu, 4 Jun 2026 11:51:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780566709; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TlKNsR/BeKHwujDXFx60lIWHMGzlR97Igis2R06KzJY=; b=cyuaDlsq/Zsi8zsQsFIRgVDfLRAXxTC2FGC0lQLk8zc+z8y/yE+BSxyAmDUZsJFSXSpjsx KGOoLSnqUzNBWRs1ypEGObu/xIqgt/DhPTsKMhdiRLeRv4p0+A2h5Cy1kNkkjG70isG56R kK4f9cjS+zVGX4Fqrvx1Xp2K6nxr5zg= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-553-tCC9yfFdNzKbH8xMvwKK0A-1; Thu, 04 Jun 2026 05:51:45 -0400 X-MC-Unique: tCC9yfFdNzKbH8xMvwKK0A-1 X-Mimecast-MFC-AGG-ID: tCC9yfFdNzKbH8xMvwKK0A_1780566704 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 788191956095; Thu, 4 Jun 2026 09:51:44 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.34.156]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id C99D230001A1; Thu, 4 Jun 2026 09:51:42 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , =?utf-8?b?QmFybmFiw6FzIFDFkWN6?= =?utf-8?q?e?= , johannes.goede@oss.qualcomm.com Subject: [RFC PATCH v3 09/17] libcamera: software_isp: Allocate multiple parameters buffers Date: Thu, 4 Jun 2026 11:50:55 +0200 Message-ID: <20260604095105.68798-14-mzamazal@redhat.com> In-Reply-To: <20260604095105.68798-1-mzamazal@redhat.com> References: <20260604095105.68798-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 4Qj7HBaIpp06SekYucbUCd7EP6rrmbsaYUsRwOdrqHU_1780566704 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" We want to use more than one parameters buffer. Processing statistics (and setting the corresponding parameters) is asynchronous and may work with a parameters buffer while the last parameters buffer may be in or wait for use in debayering. The question is how many buffer we need. A starting idea might be to use the same number as for input and output buffers. This may not be necessarily the best or even correct idea, but if the number of those buffers is sufficient now then perhaps the same number of the parameters buffers (and later statistics buffers) would work. Unless multiple streams are used... Nevertheless, the number of the input and output buffers is currently fixed, which makes it possible to use in init, before configure, where the current single buffer is allocated. It just requires to make the given constant public in SimplePipelineHandler so that it can be passed to the SoftwareIsp constructor. Another alternative would be to determine the right number of buffers in SoftwareIsp::configure. This would be more complicated as it would require some more refactoring, allocating the buffers in configure and passing their file descriptors to the IPA and debayering on demand. Only the first allocated buffer is actually used at the moment. This will be changed in the followup patches once support for multiple buffers is added to the IPA and debayering. Signed-off-by: Milan Zamazal --- .../internal/software_isp/software_isp.h | 6 +++--- src/libcamera/pipeline/simple/simple.cpp | 6 ++++-- src/libcamera/software_isp/software_isp.cpp | 18 ++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h index b77793713..e3419305b 100644 --- a/include/libcamera/internal/software_isp/software_isp.h +++ b/include/libcamera/internal/software_isp/software_isp.h @@ -48,7 +48,8 @@ class SoftwareIsp : public Object { public: SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, - ControlInfoMap *ipaControls); + ControlInfoMap *ipaControls, + const unsigned int bufferCount); ~SoftwareIsp(); int loadConfiguration([[maybe_unused]] const std::string &filename) { return 0; } @@ -90,14 +91,13 @@ public: private: void saveIspParams(const uint32_t paramsBufferId); void paramsBufferReady(const uint32_t paramsBufferId); - bool allocateParamsBuffers(); + bool allocateParamsBuffers(const unsigned int bufferCount); void setSensorCtrls(const ControlList &sensorControls); void statsReady(uint32_t frame, uint32_t bufferId); void inputReady(FrameBuffer *input); void outputReady(FrameBuffer *output); std::unique_ptr debayer_; Thread ispWorkerThread_; - static constexpr unsigned int kParamStatBufferCount = 1; std::map> sharedParams_; DebayerParams debayerParams_; std::vector availableParams_; diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 93899699e..b49f372a6 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -428,12 +428,13 @@ public: std::shared_ptr converter() { return converter_; } bool swIspEnabled() const { return swIspEnabled_; } + static constexpr unsigned int kNumInternalBuffers = 4; + protected: int queueRequestDevice(Camera *camera, Request *request) override; private: static constexpr unsigned int kMaxQueuedRequestsDevice = 4; - static constexpr unsigned int kNumInternalBuffers = 4; struct EntityData { std::unique_ptr video; @@ -615,7 +616,8 @@ int SimpleCameraData::init() * Instantiate Soft ISP if this is enabled for the given driver and no converter is used. */ if (!converter_ && pipe->swIspEnabled()) { - swIsp_ = std::make_unique(pipe, sensor_.get(), &controlInfo_); + swIsp_ = std::make_unique(pipe, sensor_.get(), &controlInfo_, + pipe->kNumInternalBuffers); if (!swIsp_->isValid()) { LOG(SimplePipeline, Warning) << "Failed to create software ISP, disabling software debayering"; diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index 6596e6fdb..97b423434 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -72,20 +72,18 @@ LOG_DEFINE_CATEGORY(SoftwareIsp) * ready */ -/** - * \var SoftwareIsp::kParamStatBufferCount - * \brief The number of stats and params buffers (each of them) - */ - /** * \brief Constructs SoftwareIsp object * \param[in] pipe The pipeline handler in use * \param[in] sensor Pointer to the CameraSensor instance owned by the pipeline * handler * \param[out] ipaControls The IPA controls to update + * \param[in] bufferCount Number of parameters buffers and stats buffers to allocate */ -SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, - ControlInfoMap *ipaControls) +SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, + const CameraSensor *sensor, + ControlInfoMap *ipaControls, + const unsigned int bufferCount) : ispWorkerThread_("SWIspWorker"), dmaHeap_(DmaBufAllocator::DmaBufAllocatorFlag::CmaHeap | DmaBufAllocator::DmaBufAllocatorFlag::SystemHeap | @@ -95,7 +93,7 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, LOG(SoftwareIsp, Error) << "Failed to create DmaBufAllocator object"; return; } - if (!allocateParamsBuffers()) + if (!allocateParamsBuffers(bufferCount)) return; const CameraManager &cm = *pipe->cameraManager(); @@ -182,9 +180,9 @@ SoftwareIsp::~SoftwareIsp() debayer_.reset(); } -bool SoftwareIsp::allocateParamsBuffers() +bool SoftwareIsp::allocateParamsBuffers(const unsigned int bufferCount) { - for (unsigned int bufferId = 0; bufferId < kParamStatBufferCount; bufferId++) { + for (unsigned int bufferId = 0; bufferId < bufferCount; bufferId++) { auto params = SharedMemObject("softIsp_params"); if (!params) { LOG(SoftwareIsp, Error) << "Failed to create shared memory for parameters";