From patchwork Thu Jun 4 09:50:43 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26822 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 6BB01C328C for ; Thu, 4 Jun 2026 09:51:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 06E46633F1; Thu, 4 Jun 2026 11:51:23 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="fSTCfEeD"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3DD2962DC4 for ; Thu, 4 Jun 2026 11:51:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780566680; 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=pLOq4AJyNcOIzivE6pytHW99jdKU74/OMlkcVotbq8Y=; b=fSTCfEeDwwUOMleurszNOD85jeCu/xUXqDQPuZPL2ik8NEEXJciOgTp/iEd+TL8lVZ0feL 70Uos1839Fmh6gaCosoh1sheZ+7vZ/bzTCEPrwyVjlggwVkzjwjy2KNOLG919XVNcmmELV P4hwA4NFjrfDnLnQBhOVEtcXbntvl6w= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-660-Ha1MKms-NBanWCjYzAj9cg-1; Thu, 04 Jun 2026 05:51:16 -0400 X-MC-Unique: Ha1MKms-NBanWCjYzAj9cg-1 X-Mimecast-MFC-AGG-ID: Ha1MKms-NBanWCjYzAj9cg_1780566675 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-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B52BF1800361; Thu, 4 Jun 2026 09:51:15 +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 CE1693000210; Thu, 4 Jun 2026 09:51:13 +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 01/17] libcamera: software_isp: Fix misplacement in SoftwareIsp docstring Date: Thu, 4 Jun 2026 11:50:43 +0200 Message-ID: <20260604095105.68798-2-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: AzSwnQZ4NiCathy2XgQLwLZhZvEqDBNKnQJ9QNqXAKY_1780566675 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" A new parameter line was inserted at a wrong position previously. Signed-off-by: Milan Zamazal --- src/libcamera/software_isp/software_isp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index 781cf02f8..224a2fa7c 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -76,8 +76,8 @@ LOG_DEFINE_CATEGORY(SoftwareIsp) * \brief Constructs SoftwareIsp object * \param[in] pipe The pipeline handler in use * \param[in] sensor Pointer to the CameraSensor instance owned by the pipeline - * \param[out] ipaControls The IPA controls to update * handler + * \param[out] ipaControls The IPA controls to update */ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, ControlInfoMap *ipaControls) From patchwork Thu Jun 4 09:50:44 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26823 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 0AEBDC328C for ; Thu, 4 Jun 2026 09:51:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B9800633C9; Thu, 4 Jun 2026 11:51:25 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="WRQpB5O7"; 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 A44AC632B1 for ; Thu, 4 Jun 2026 11:51:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780566682; 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=K+Q6pcsqu6yLpUtmH5cnrwW6Czo6+a2wr6NusK2cflU=; b=WRQpB5O7LyGcT/WDoCUsHFNwIF/mqlIRdofuBvgZfmAo29h9ifXVdoehSQvP2GrifUTKA3 zud2+E7QDOsEb/TVmRNta+JG3wC/UMMYtWhMlFxmwRn/q+7DzSSuQVC4jv/jZ1knWfFcWI JUIuj7nB3L1NqqqvAZpqVhn2tYdgeU4= Received: from mx-prod-mc-03.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-615-DPh17l5KPf-Lva8U046gGw-1; Thu, 04 Jun 2026 05:51:19 -0400 X-MC-Unique: DPh17l5KPf-Lva8U046gGw-1 X-Mimecast-MFC-AGG-ID: DPh17l5KPf-Lva8U046gGw_1780566678 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-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 110DA1956046; Thu, 4 Jun 2026 09:51:18 +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 4A82230001A1; Thu, 4 Jun 2026 09:51:15 +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 02/17] libcamera: ipa: simple: Rename setIspParams to paramsComputed Date: Thu, 4 Jun 2026 11:50:44 +0200 Message-ID: <20260604095105.68798-3-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: yy3zyoLlxejiFxr19l3VGA8BuEAxA67Z9GPkryQsSKw_1780566678 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" For better consistency with other pipelines. Signed-off-by: Milan Zamazal --- include/libcamera/ipa/soft.mojom | 2 +- src/ipa/simple/soft_simple.cpp | 2 +- src/libcamera/software_isp/software_isp.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/libcamera/ipa/soft.mojom b/include/libcamera/ipa/soft.mojom index 77328c5fd..e75b03a3d 100644 --- a/include/libcamera/ipa/soft.mojom +++ b/include/libcamera/ipa/soft.mojom @@ -33,6 +33,6 @@ interface IPASoftInterface { interface IPASoftEventInterface { setSensorControls(libcamera.ControlList sensorControls); - setIspParams(); + paramsComputed(); metadataReady(uint32 frame, libcamera.ControlList metadata); }; diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp index 629e1a32d..cfc1389e4 100644 --- a/src/ipa/simple/soft_simple.cpp +++ b/src/ipa/simple/soft_simple.cpp @@ -292,7 +292,7 @@ void IPASoftSimple::computeParams(const uint32_t frame) algo->prepare(context_, frame, frameContext, params_); params_->combinedMatrix = context_.activeState.combinedMatrix; - setIspParams.emit(); + paramsComputed.emit(); } void IPASoftSimple::processStats(const uint32_t frame, diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index 224a2fa7c..f5b44f4e5 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -164,7 +164,7 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, return; } - ipa_->setIspParams.connect(this, &SoftwareIsp::saveIspParams); + ipa_->paramsComputed.connect(this, &SoftwareIsp::saveIspParams); ipa_->metadataReady.connect(this, [this](uint32_t frame, const ControlList &metadata) { metadataReady.emit(frame, metadata); From patchwork Thu Jun 4 09:50:45 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26824 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 D7EF8C328C for ; Thu, 4 Jun 2026 09:51:27 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 903A463400; Thu, 4 Jun 2026 11:51:27 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="CqQtoyRx"; 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 4D86E63405 for ; Thu, 4 Jun 2026 11:51:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780566685; 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=Uz5aThJ4d3bzZWKmb1zpf3sXYWK5Xf99hfndUNykDCQ=; b=CqQtoyRxGutXWGthy/LBX+uc9nmiucZaNxB3HKbo5ZRBwIqVT/r12PQR/sXqJdGB3oWc3T 3BcmQQn0tEbwpcNZoDPVtzx5yHtCix87EuwxGNi4kgl6YMc+PqwoNxdUZU5zkDtg/tHUNR Uh1kfML+HiYukAGqXXXa6sB7Hgjuj+o= Received: from mx-prod-mc-03.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-173-qwDcFb6UONiAuWbd57YVbg-1; Thu, 04 Jun 2026 05:51:21 -0400 X-MC-Unique: qwDcFb6UONiAuWbd57YVbg-1 X-Mimecast-MFC-AGG-ID: qwDcFb6UONiAuWbd57YVbg_1780566680 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-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 661651956059; Thu, 4 Jun 2026 09:51:20 +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 A18B330001A1; Thu, 4 Jun 2026 09:51:18 +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 03/17] libcamera: software_isp: Introduce arguments for parameters buffers Date: Thu, 4 Jun 2026 11:50:45 +0200 Message-ID: <20260604095105.68798-4-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: Y6ZH-p8n_Qb7_Sg91nnoYxrumqc3BhpwU-2pM_O9-qc_1780566680 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" Processing parameters in software ISP are currently passed by value. This is unlike hardware pipelines, which use a ring of buffers for the purpose and pass references to the buffers currently selected from the ring rather than passing the whole parameters buffers. This is a preparatory patch to introduce a similar mechanism in software ISP, in order to resolve TODO #5. It adds a new argument paramsBufferId for the future parameters buffer ids passed to the calls. The buffer ids must be passed to the following groups of methods: - IPASoftSimple::prepare, in order to create the parameters in the given buffer for the corresponding frame processing. - SoftwareIsp::saveIspParams, in order to signal that the parameters are set by the IPA. - Debayer::process, in order to get the buffer with the processing parameters. - SoftwareIsp::paramsBufferReady, in order to signal that the selected parameters buffer from the ring is no longer needed for the given frame and can be reused. This is a newly introduced signal. The type of the buffer id parameter is set to uint32_t because: - It can be used in mojom. - It is consistent with the similar types in the hardware pipelines. - It covers file descriptor number range, which will be used as buffer ids (more on this in followup patches). This patch doesn't do more than adding the arguments, to keep the patch simple. The buffer handling will be implemented in the followup patches. Signed-off-by: Milan Zamazal --- .../libcamera/internal/software_isp/software_isp.h | 3 ++- include/libcamera/ipa/soft.mojom | 4 ++-- src/ipa/simple/soft_simple.cpp | 8 +++++--- src/libcamera/software_isp/debayer.cpp | 8 +++++++- src/libcamera/software_isp/debayer.h | 6 +++++- src/libcamera/software_isp/debayer_cpu.cpp | 6 +++++- src/libcamera/software_isp/debayer_cpu.h | 4 +++- src/libcamera/software_isp/debayer_egl.cpp | 6 +++++- src/libcamera/software_isp/debayer_egl.h | 4 +++- src/libcamera/software_isp/software_isp.cpp | 14 +++++++++++--- 10 files changed, 48 insertions(+), 15 deletions(-) diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h index 86cb8f8de..85c9059e2 100644 --- a/include/libcamera/internal/software_isp/software_isp.h +++ b/include/libcamera/internal/software_isp/software_isp.h @@ -88,7 +88,8 @@ public: Signal setSensorControls; private: - void saveIspParams(); + void saveIspParams(const uint32_t paramsBufferId); + void paramsBufferReady(const uint32_t paramsBufferId); void setSensorCtrls(const ControlList &sensorControls); void statsReady(uint32_t frame, uint32_t bufferId); void inputReady(FrameBuffer *input); diff --git a/include/libcamera/ipa/soft.mojom b/include/libcamera/ipa/soft.mojom index e75b03a3d..18789d5de 100644 --- a/include/libcamera/ipa/soft.mojom +++ b/include/libcamera/ipa/soft.mojom @@ -25,7 +25,7 @@ interface IPASoftInterface { => (int32 ret); [async] queueRequest(uint32 frame, libcamera.ControlList sensorControls); - [async] computeParams(uint32 frame); + [async] computeParams(uint32 frame, uint32 paramsBufferId); [async] processStats(uint32 frame, uint32 bufferId, libcamera.ControlList sensorControls); @@ -33,6 +33,6 @@ interface IPASoftInterface { interface IPASoftEventInterface { setSensorControls(libcamera.ControlList sensorControls); - paramsComputed(); + paramsComputed(uint32 paramsBufferId); metadataReady(uint32 frame, libcamera.ControlList metadata); }; diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp index cfc1389e4..69bfef302 100644 --- a/src/ipa/simple/soft_simple.cpp +++ b/src/ipa/simple/soft_simple.cpp @@ -64,7 +64,8 @@ public: void stop() override; void queueRequest(const uint32_t frame, const ControlList &controls) override; - void computeParams(const uint32_t frame) override; + void computeParams(const uint32_t frame, + const uint32_t paramsBufferId) override; void processStats(const uint32_t frame, const uint32_t bufferId, const ControlList &sensorControls) override; @@ -283,7 +284,8 @@ void IPASoftSimple::queueRequest(const uint32_t frame, const ControlList &contro algo->queueRequest(context_, frame, frameContext, controls); } -void IPASoftSimple::computeParams(const uint32_t frame) +void IPASoftSimple::computeParams(const uint32_t frame, + const uint32_t paramsBufferId) { context_.activeState.combinedMatrix = Matrix::identity(); @@ -292,7 +294,7 @@ void IPASoftSimple::computeParams(const uint32_t frame) algo->prepare(context_, frame, frameContext, params_); params_->combinedMatrix = context_.activeState.combinedMatrix; - paramsComputed.emit(); + paramsComputed.emit(paramsBufferId); } void IPASoftSimple::processStats(const uint32_t frame, diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp index 2d7abfb83..7b1be52b2 100644 --- a/src/libcamera/software_isp/debayer.cpp +++ b/src/libcamera/software_isp/debayer.cpp @@ -104,9 +104,10 @@ Debayer::~Debayer() */ /** - * \fn void Debayer::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, DebayerParams params) + * \fn void Debayer::process(uint32_t frame, const uint32_t paramsBufferId, FrameBuffer *input, FrameBuffer *output, DebayerParams params) * \brief Process the bayer data into the requested format * \param[in] frame The frame number + * \param[in] paramsBufferId The id of the params buffer in use * \param[in] input The input buffer * \param[in] output The output buffer * \param[in] params The parameters to be used in debayering @@ -142,6 +143,11 @@ Debayer::~Debayer() * current stream. */ +/** + * \var Debayer::paramsBufferReady + * \brief Signals when the processing params are no longer needed + */ + /** * \var Signal Debayer::inputBufferReady * \brief Signals when the input buffer is ready diff --git a/src/libcamera/software_isp/debayer.h b/src/libcamera/software_isp/debayer.h index a2a17ec18..9a97851b7 100644 --- a/src/libcamera/software_isp/debayer.h +++ b/src/libcamera/software_isp/debayer.h @@ -47,7 +47,10 @@ public: virtual std::tuple strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) = 0; - virtual void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms) = 0; + virtual void process(uint32_t frame, + const uint32_t paramsBufferId, + FrameBuffer *input, FrameBuffer *output, + const DebayerParams ¶ms) = 0; virtual int start() { return 0; } virtual void stop() {} @@ -59,6 +62,7 @@ public: Signal inputBufferReady; Signal outputBufferReady; + Signal paramsBufferReady; struct DebayerInputConfig { Size patternSize; diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp index 1f9b24da0..51b58fce5 100644 --- a/src/libcamera/software_isp/debayer_cpu.cpp +++ b/src/libcamera/software_isp/debayer_cpu.cpp @@ -971,7 +971,9 @@ void DebayerCpu::updateLookupTables(const DebayerParams ¶ms) params_ = params; } -void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms) +void DebayerCpu::process(uint32_t frame, const uint32_t paramsBufferId, + FrameBuffer *input, FrameBuffer *output, + const DebayerParams ¶ms) { bench_.startFrame(); @@ -981,6 +983,8 @@ void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output updateLookupTables(params); + paramsBufferReady.emit(paramsBufferId); + /* Copy metadata from the input buffer */ FrameMetadata &metadata = output->_d()->metadata(); metadata.status = input->metadata().status; diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h index 68da95083..1b4e8548a 100644 --- a/src/libcamera/software_isp/debayer_cpu.h +++ b/src/libcamera/software_isp/debayer_cpu.h @@ -42,7 +42,9 @@ public: std::vector formats(PixelFormat input) override; std::tuple strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) override; - void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms) override; + void process(uint32_t frame, const uint32_t paramsBufferId, + FrameBuffer *input, FrameBuffer *output, + const DebayerParams ¶ms) override; int start() override; void stop() override; SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) override; diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp index 99825d49e..60fd5463f 100644 --- a/src/libcamera/software_isp/debayer_egl.cpp +++ b/src/libcamera/software_isp/debayer_egl.cpp @@ -546,7 +546,9 @@ int DebayerEGL::debayerGPU(FrameBuffer *input, FrameBuffer *output, const Debaye return 0; } -void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms) +void DebayerEGL::process(uint32_t frame, const uint32_t paramsBufferId, + FrameBuffer *input, FrameBuffer *output, + const DebayerParams ¶ms) { bench_.startFrame(); @@ -563,6 +565,7 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output LOG(Debayer, Error) << "debayerGPU failed"; goto error; } + paramsBufferReady.emit(paramsBufferId); metadata.planes()[0].bytesused = output->planes()[0].length; @@ -593,6 +596,7 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output return; error: + paramsBufferReady.emit(paramsBufferId); bench_.finishFrame(); metadata.status = FrameMetadata::FrameError; return; diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h index 875e7cfc5..a3a4448e7 100644 --- a/src/libcamera/software_isp/debayer_egl.h +++ b/src/libcamera/software_isp/debayer_egl.h @@ -51,7 +51,9 @@ public: std::vector formats(PixelFormat input) override; std::tuple strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) override; - void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms) override; + void process(uint32_t frame, const uint32_t paramsBufferId, + FrameBuffer *input, FrameBuffer *output, + const DebayerParams ¶ms) override; int start() override; void stop() override; diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index f5b44f4e5..3d1dec21d 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -128,6 +128,7 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, debayer_->inputBufferReady.connect(this, &SoftwareIsp::inputReady); debayer_->outputBufferReady.connect(this, &SoftwareIsp::outputReady); + debayer_->paramsBufferReady.connect(this, &SoftwareIsp::paramsBufferReady); ipa_ = pipe->createIPA(0, 0); if (!ipa_) { @@ -409,16 +410,23 @@ void SoftwareIsp::stop() */ void SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output) { - ipa_->computeParams(frame); + /* \todo Provide a real value */ + constexpr uint32_t paramsBufferId = 0; + ipa_->computeParams(frame, paramsBufferId); debayer_->invokeMethod(&Debayer::process, - ConnectionTypeQueued, frame, input, output, debayerParams_); + ConnectionTypeQueued, frame, paramsBufferId, + input, output, debayerParams_); } -void SoftwareIsp::saveIspParams() +void SoftwareIsp::saveIspParams([[maybe_unused]] const uint32_t paramsBufferId) { debayerParams_ = *sharedParams_; } +void SoftwareIsp::paramsBufferReady([[maybe_unused]] const uint32_t paramsBufferId) +{ +} + void SoftwareIsp::setSensorCtrls(const ControlList &sensorControls) { setSensorControls.emit(sensorControls); From patchwork Thu Jun 4 09:50:47 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26826 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 0DE12C328C for ; Thu, 4 Jun 2026 09:51:32 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B644063405; Thu, 4 Jun 2026 11:51:31 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="eaiLraev"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AE70C63320 for ; Thu, 4 Jun 2026 11:51:30 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780566689; 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=Pdj1d1iFnuLGusyDEGVbK/OY2aqBoDaArNpkJMmf3as=; b=eaiLraevCVRf719BQxfOa5nlPjFR+ryxlzbDeQdo3uoZqZNYo6HTXjyz5My+6Xqyk+WN8J zAykbOfnA49XA9MV/EVf53jPlyz9SHa+aRgsjz2n/AoInu2jw8eWqaXVyAnqgox8rMtiT7 0gjSw3JTMxZxvqP++Ga3HVYD56S2GQo= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-670-Ot8PRYpxOgS4cG1D1qoCZQ-1; Thu, 04 Jun 2026 05:51:26 -0400 X-MC-Unique: Ot8PRYpxOgS4cG1D1qoCZQ-1 X-Mimecast-MFC-AGG-ID: Ot8PRYpxOgS4cG1D1qoCZQ_1780566685 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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 20C6618002C1; Thu, 4 Jun 2026 09:51:25 +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 2887A30001A1; Thu, 4 Jun 2026 09:51:22 +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 04/17] libcamera: software_isp: Handle queueBuffers failure Date: Thu, 4 Jun 2026 11:50:47 +0200 Message-ID: <20260604095105.68798-6-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: ppc4LHw1lizz-X3BnQKkpbXpy9FOHsJC3FDUKAbio8I_1780566685 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" Currently, if a call to queueBuffers fails, the error is ignored. Which means buffers are not returned back, as would be the case at the end of normal processing. Let's cancel the request, which also returns the output buffers. The input buffer is returned as well in case of raw streams and must be returned manually in case of non-raw streams. Signed-off-by: Milan Zamazal --- src/libcamera/pipeline/simple/simple.cpp | 28 +++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index c6fe12d65..93899699e 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -955,16 +955,34 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer) return; } - if (converter_) - converter_->queueBuffers(buffer, conversionQueue_.front().outputs); - else + int ret; + if (converter_) { + ret = converter_->queueBuffers(buffer, conversionQueue_.front().outputs); + } else { /* * request->sequence() cannot be retrieved from `buffer' inside * queueBuffers because unique_ptr's make buffer->request() invalid * already here. */ - swIsp_->queueBuffers(request->sequence(), buffer, - conversionQueue_.front().outputs); + ret = swIsp_->queueBuffers(request->sequence(), buffer, + conversionQueue_.front().outputs); + } + + if (ret < 0) { + LOG(SimplePipeline, Error) + << "Failed to queue buffers for conversion: " + << strerror(-ret); + /* + * The buffers were rejected before starting any processing, so the + * output buffers will not be returned via the normal done + * signals. Cancel the request; this handles the output buffers and + * also the input buffer if it's a raw stream buffer. For non-raw + * streams, return the input buffer to the video device manually. + */ + pipe->cancelRequest(request); + if (!rawStream_) + video_->queueBuffer(buffer); + } conversionQueue_.pop(); return; From patchwork Thu Jun 4 09:50:49 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26828 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 47A1BC328C for ; Thu, 4 Jun 2026 09:51:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id F1A3363403; Thu, 4 Jun 2026 11:51:35 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="G+mS1vZR"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 62C5563400 for ; Thu, 4 Jun 2026 11:51:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780566693; 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=b5bFoNg+hoimeYs6xplOIwMunOFAxEdn+UAcs2um9uM=; b=G+mS1vZReSwcd9B4APeAEFZ5nWbxBzzidH316pw8nIGv2pxN8XPb6c2Mlg88jk9Ugo4VPY e/0GwvmCUCg8OIfwUoDu6lnCJYim9/4tCfaSRSrD18Wsr1poJPrE1Mk1/UbgYK64zbQsE0 NMSoc0ZI+I97k+DMbd+DyhSXvrO/Kdk= 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-550-_Bb0TlE2O06WCqjVr1xvoA-1; Thu, 04 Jun 2026 05:51:31 -0400 X-MC-Unique: _Bb0TlE2O06WCqjVr1xvoA-1 X-Mimecast-MFC-AGG-ID: _Bb0TlE2O06WCqjVr1xvoA_1780566690 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 40FB3195609F; Thu, 4 Jun 2026 09:51:30 +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 460DE30001A1; Thu, 4 Jun 2026 09:51:27 +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 05/17] libcamera: software_isp: Introduce arguments for parameters buffers Date: Thu, 4 Jun 2026 11:50:49 +0200 Message-ID: <20260604095105.68798-8-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: sy2U9bcqv-i2Zv9525rqOxnHsKOc-tO69mKaM3GorUQ_1780566690 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" Processing parameters in software ISP are currently passed by value. This is unlike hardware pipelines, which use a ring of buffers for the purpose and pass references to the buffers currently selected from the ring rather than passing the whole parameters buffers. This is a preparatory patch to introduce a similar mechanism in software ISP, in order to resolve TODO #5. It adds a new argument paramsBufferId for the future parameters buffer ids passed to the calls. The buffer ids must be passed to the following groups of methods: - IPASoftSimple::prepare, in order to create the parameters in the given buffer for the corresponding frame processing. - SoftwareIsp::saveIspParams, in order to signal that the parameters are set by the IPA. - Debayer::process, in order to get the buffer with the processing parameters. - SoftwareIsp::paramsBufferReady, in order to signal that the selected parameters buffer from the ring is no longer needed for the given frame and can be reused. This is a newly introduced signal. The type of the buffer id parameter is set to uint32_t because: - It can be used in mojom. - It is consistent with the similar types in the hardware pipelines. - It covers file descriptor number range, which will be used as buffer ids (more on this in followup patches). This patch doesn't do more than adding the arguments, to keep the patch simple. The buffer handling will be implemented in the followup patches. Signed-off-by: Milan Zamazal --- .../libcamera/internal/software_isp/software_isp.h | 3 ++- include/libcamera/ipa/soft.mojom | 4 ++-- src/ipa/simple/soft_simple.cpp | 8 +++++--- src/libcamera/software_isp/debayer.cpp | 8 +++++++- src/libcamera/software_isp/debayer.h | 6 +++++- src/libcamera/software_isp/debayer_cpu.cpp | 6 +++++- src/libcamera/software_isp/debayer_cpu.h | 4 +++- src/libcamera/software_isp/debayer_egl.cpp | 6 +++++- src/libcamera/software_isp/debayer_egl.h | 4 +++- src/libcamera/software_isp/software_isp.cpp | 14 +++++++++++--- 10 files changed, 48 insertions(+), 15 deletions(-) diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h index 86cb8f8de..85c9059e2 100644 --- a/include/libcamera/internal/software_isp/software_isp.h +++ b/include/libcamera/internal/software_isp/software_isp.h @@ -88,7 +88,8 @@ public: Signal setSensorControls; private: - void saveIspParams(); + void saveIspParams(const uint32_t paramsBufferId); + void paramsBufferReady(const uint32_t paramsBufferId); void setSensorCtrls(const ControlList &sensorControls); void statsReady(uint32_t frame, uint32_t bufferId); void inputReady(FrameBuffer *input); diff --git a/include/libcamera/ipa/soft.mojom b/include/libcamera/ipa/soft.mojom index e75b03a3d..18789d5de 100644 --- a/include/libcamera/ipa/soft.mojom +++ b/include/libcamera/ipa/soft.mojom @@ -25,7 +25,7 @@ interface IPASoftInterface { => (int32 ret); [async] queueRequest(uint32 frame, libcamera.ControlList sensorControls); - [async] computeParams(uint32 frame); + [async] computeParams(uint32 frame, uint32 paramsBufferId); [async] processStats(uint32 frame, uint32 bufferId, libcamera.ControlList sensorControls); @@ -33,6 +33,6 @@ interface IPASoftInterface { interface IPASoftEventInterface { setSensorControls(libcamera.ControlList sensorControls); - paramsComputed(); + paramsComputed(uint32 paramsBufferId); metadataReady(uint32 frame, libcamera.ControlList metadata); }; diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp index cfc1389e4..69bfef302 100644 --- a/src/ipa/simple/soft_simple.cpp +++ b/src/ipa/simple/soft_simple.cpp @@ -64,7 +64,8 @@ public: void stop() override; void queueRequest(const uint32_t frame, const ControlList &controls) override; - void computeParams(const uint32_t frame) override; + void computeParams(const uint32_t frame, + const uint32_t paramsBufferId) override; void processStats(const uint32_t frame, const uint32_t bufferId, const ControlList &sensorControls) override; @@ -283,7 +284,8 @@ void IPASoftSimple::queueRequest(const uint32_t frame, const ControlList &contro algo->queueRequest(context_, frame, frameContext, controls); } -void IPASoftSimple::computeParams(const uint32_t frame) +void IPASoftSimple::computeParams(const uint32_t frame, + const uint32_t paramsBufferId) { context_.activeState.combinedMatrix = Matrix::identity(); @@ -292,7 +294,7 @@ void IPASoftSimple::computeParams(const uint32_t frame) algo->prepare(context_, frame, frameContext, params_); params_->combinedMatrix = context_.activeState.combinedMatrix; - paramsComputed.emit(); + paramsComputed.emit(paramsBufferId); } void IPASoftSimple::processStats(const uint32_t frame, diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp index 2d7abfb83..7b1be52b2 100644 --- a/src/libcamera/software_isp/debayer.cpp +++ b/src/libcamera/software_isp/debayer.cpp @@ -104,9 +104,10 @@ Debayer::~Debayer() */ /** - * \fn void Debayer::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, DebayerParams params) + * \fn void Debayer::process(uint32_t frame, const uint32_t paramsBufferId, FrameBuffer *input, FrameBuffer *output, DebayerParams params) * \brief Process the bayer data into the requested format * \param[in] frame The frame number + * \param[in] paramsBufferId The id of the params buffer in use * \param[in] input The input buffer * \param[in] output The output buffer * \param[in] params The parameters to be used in debayering @@ -142,6 +143,11 @@ Debayer::~Debayer() * current stream. */ +/** + * \var Debayer::paramsBufferReady + * \brief Signals when the processing params are no longer needed + */ + /** * \var Signal Debayer::inputBufferReady * \brief Signals when the input buffer is ready diff --git a/src/libcamera/software_isp/debayer.h b/src/libcamera/software_isp/debayer.h index a2a17ec18..9a97851b7 100644 --- a/src/libcamera/software_isp/debayer.h +++ b/src/libcamera/software_isp/debayer.h @@ -47,7 +47,10 @@ public: virtual std::tuple strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) = 0; - virtual void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms) = 0; + virtual void process(uint32_t frame, + const uint32_t paramsBufferId, + FrameBuffer *input, FrameBuffer *output, + const DebayerParams ¶ms) = 0; virtual int start() { return 0; } virtual void stop() {} @@ -59,6 +62,7 @@ public: Signal inputBufferReady; Signal outputBufferReady; + Signal paramsBufferReady; struct DebayerInputConfig { Size patternSize; diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp index 1f9b24da0..51b58fce5 100644 --- a/src/libcamera/software_isp/debayer_cpu.cpp +++ b/src/libcamera/software_isp/debayer_cpu.cpp @@ -971,7 +971,9 @@ void DebayerCpu::updateLookupTables(const DebayerParams ¶ms) params_ = params; } -void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms) +void DebayerCpu::process(uint32_t frame, const uint32_t paramsBufferId, + FrameBuffer *input, FrameBuffer *output, + const DebayerParams ¶ms) { bench_.startFrame(); @@ -981,6 +983,8 @@ void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output updateLookupTables(params); + paramsBufferReady.emit(paramsBufferId); + /* Copy metadata from the input buffer */ FrameMetadata &metadata = output->_d()->metadata(); metadata.status = input->metadata().status; diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h index 68da95083..1b4e8548a 100644 --- a/src/libcamera/software_isp/debayer_cpu.h +++ b/src/libcamera/software_isp/debayer_cpu.h @@ -42,7 +42,9 @@ public: std::vector formats(PixelFormat input) override; std::tuple strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) override; - void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms) override; + void process(uint32_t frame, const uint32_t paramsBufferId, + FrameBuffer *input, FrameBuffer *output, + const DebayerParams ¶ms) override; int start() override; void stop() override; SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) override; diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp index 99825d49e..60fd5463f 100644 --- a/src/libcamera/software_isp/debayer_egl.cpp +++ b/src/libcamera/software_isp/debayer_egl.cpp @@ -546,7 +546,9 @@ int DebayerEGL::debayerGPU(FrameBuffer *input, FrameBuffer *output, const Debaye return 0; } -void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms) +void DebayerEGL::process(uint32_t frame, const uint32_t paramsBufferId, + FrameBuffer *input, FrameBuffer *output, + const DebayerParams ¶ms) { bench_.startFrame(); @@ -563,6 +565,7 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output LOG(Debayer, Error) << "debayerGPU failed"; goto error; } + paramsBufferReady.emit(paramsBufferId); metadata.planes()[0].bytesused = output->planes()[0].length; @@ -593,6 +596,7 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output return; error: + paramsBufferReady.emit(paramsBufferId); bench_.finishFrame(); metadata.status = FrameMetadata::FrameError; return; diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h index 875e7cfc5..a3a4448e7 100644 --- a/src/libcamera/software_isp/debayer_egl.h +++ b/src/libcamera/software_isp/debayer_egl.h @@ -51,7 +51,9 @@ public: std::vector formats(PixelFormat input) override; std::tuple strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) override; - void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms) override; + void process(uint32_t frame, const uint32_t paramsBufferId, + FrameBuffer *input, FrameBuffer *output, + const DebayerParams ¶ms) override; int start() override; void stop() override; diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index f17f1ca1f..a1200e924 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -128,6 +128,7 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, debayer_->inputBufferReady.connect(this, &SoftwareIsp::inputReady); debayer_->outputBufferReady.connect(this, &SoftwareIsp::outputReady); + debayer_->paramsBufferReady.connect(this, &SoftwareIsp::paramsBufferReady); ipa_ = pipe->createIPA(0, 0); if (!ipa_) { @@ -408,16 +409,23 @@ void SoftwareIsp::stop() */ void SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output) { - ipa_->computeParams(frame); + /* \todo Provide a real value */ + constexpr uint32_t paramsBufferId = 0; + ipa_->computeParams(frame, paramsBufferId); debayer_->invokeMethod(&Debayer::process, - ConnectionTypeQueued, frame, input, output, debayerParams_); + ConnectionTypeQueued, frame, paramsBufferId, + input, output, debayerParams_); } -void SoftwareIsp::saveIspParams() +void SoftwareIsp::saveIspParams([[maybe_unused]] const uint32_t paramsBufferId) { debayerParams_ = *sharedParams_; } +void SoftwareIsp::paramsBufferReady([[maybe_unused]] const uint32_t paramsBufferId) +{ +} + void SoftwareIsp::setSensorCtrls(const ControlList &sensorControls) { setSensorControls.emit(sensorControls); From patchwork Thu Jun 4 09:50:51 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26830 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 8CF0CC328C for ; Thu, 4 Jun 2026 09:51:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4B0D66347A; Thu, 4 Jun 2026 11:51:41 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="iwauqoSQ"; 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 90BF063403 for ; Thu, 4 Jun 2026 11:51:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780566697; 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=Pdj1d1iFnuLGusyDEGVbK/OY2aqBoDaArNpkJMmf3as=; b=iwauqoSQBFXYwPATwcAs78+rcc5bZnLJcHywSBmmo8t6iaKgdLO9HA6v4nC3/jcWiIuaq0 LFGAXWUSuJjDB7n3Y0yJ9StphiPir80+oxF4GJZiBea5WvF3mdL02O0PuwBy4tanORWvv6 OxNU2+FIcdRXUe2CuqS/M/QXBtSGsM0= Received: from mx-prod-mc-05.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-77-QsGTM7gyNmaZHlmaQWMBDw-1; Thu, 04 Jun 2026 05:51:36 -0400 X-MC-Unique: QsGTM7gyNmaZHlmaQWMBDw-1 X-Mimecast-MFC-AGG-ID: QsGTM7gyNmaZHlmaQWMBDw_1780566695 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-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 44035195608B; Thu, 4 Jun 2026 09:51:35 +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 49E5D30001A1; Thu, 4 Jun 2026 09:51:32 +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 06/17] libcamera: software_isp: Handle queueBuffers failure Date: Thu, 4 Jun 2026 11:50:51 +0200 Message-ID: <20260604095105.68798-10-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: 5eKS6iPOvZs0AzcdvDduIlLpIlBZxrKNuFyynFvqh3M_1780566695 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" Currently, if a call to queueBuffers fails, the error is ignored. Which means buffers are not returned back, as would be the case at the end of normal processing. Let's cancel the request, which also returns the output buffers. The input buffer is returned as well in case of raw streams and must be returned manually in case of non-raw streams. Signed-off-by: Milan Zamazal --- src/libcamera/pipeline/simple/simple.cpp | 28 +++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index c6fe12d65..93899699e 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -955,16 +955,34 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer) return; } - if (converter_) - converter_->queueBuffers(buffer, conversionQueue_.front().outputs); - else + int ret; + if (converter_) { + ret = converter_->queueBuffers(buffer, conversionQueue_.front().outputs); + } else { /* * request->sequence() cannot be retrieved from `buffer' inside * queueBuffers because unique_ptr's make buffer->request() invalid * already here. */ - swIsp_->queueBuffers(request->sequence(), buffer, - conversionQueue_.front().outputs); + ret = swIsp_->queueBuffers(request->sequence(), buffer, + conversionQueue_.front().outputs); + } + + if (ret < 0) { + LOG(SimplePipeline, Error) + << "Failed to queue buffers for conversion: " + << strerror(-ret); + /* + * The buffers were rejected before starting any processing, so the + * output buffers will not be returned via the normal done + * signals. Cancel the request; this handles the output buffers and + * also the input buffer if it's a raw stream buffer. For non-raw + * streams, return the input buffer to the video device manually. + */ + pipe->cancelRequest(request); + if (!rawStream_) + video_->queueBuffer(buffer); + } conversionQueue_.pop(); return; From patchwork Thu Jun 4 09:50:53 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26832 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 E4B45C328C for ; Thu, 4 Jun 2026 09:51:47 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9BD9E63733; Thu, 4 Jun 2026 11:51:47 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="a81Vmlax"; 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 4F49263403 for ; Thu, 4 Jun 2026 11:51:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780566704; 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=4tddGy712352sjbLd3X1jE2tUkVJDxQazhu578EYriU=; b=a81VmlaxCxdbBpthvMVe8HJ2XEyKIcHyE0soq0y0/JVuf2DPK2sXpkA1y7xFsqmjIyNHRb yQx6WspMO1eOtydQcgRImE8fdsHYBGWBt4LcfCqIx0I3EGWZJK9zBsLSdlHyNnwXcnvnE5 hzanjnk3FpeXYsrHdoKNTKwaIFmGwn8= 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-27-pBEYiPsfOIe74P_rUOfmgg-1; Thu, 04 Jun 2026 05:51:41 -0400 X-MC-Unique: pBEYiPsfOIe74P_rUOfmgg-1 X-Mimecast-MFC-AGG-ID: pBEYiPsfOIe74P_rUOfmgg_1780566700 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 F30B41956096; Thu, 4 Jun 2026 09:51:39 +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 356A430001A1; Thu, 4 Jun 2026 09:51:37 +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 07/17] libcamera: software_isp: Track unused parameters buffers Date: Thu, 4 Jun 2026 11:50:53 +0200 Message-ID: <20260604095105.68798-12-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: DkfIqckHxouaskLkK9HHUNzar5x9gCR8z5X2dQXARMw_1780566700 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" As a preparation for introducing a ring of parameters buffers, this patch introduces tracking of parameters buffers available for use. SoftwareIsp::availableParams_ is a vector of ids of the buffers available for use. When a fresh parameter buffer is needed, its id is retrieved from there and once the buffer is no longer needed, it's put back there, in a method invoked by a signal. This is similar to what the hardware pipelines do. If a parameters buffer is requested but there is no free available, it is an erroneous situation. To recover from it, we have currently no better mechanism than to wait for an available buffer. Simply returning from the processing would mean the finishing signals are not called, resulting in e.g. the input buffer not being returned. This is different from the hardware pipelines, which are structured somewhat differently. We use 0 as the buffer id for now. In followup patches, we will have to make and pass a special id->buffer mapping to the IPA and debayering on initialisation. Note that the parameters buffer id is still actually unused and the only buffer currently used is still copied when passed to debayering. This patch is just preparation for followup patches that will introduce multiple buffers. Signed-off-by: Milan Zamazal --- .../internal/software_isp/software_isp.h | 3 ++- src/libcamera/software_isp/software_isp.cpp | 27 +++++++++++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h index f97d25f0a..58fb9d752 100644 --- a/include/libcamera/internal/software_isp/software_isp.h +++ b/include/libcamera/internal/software_isp/software_isp.h @@ -79,7 +79,7 @@ public: int queueBuffers(uint32_t frame, FrameBuffer *input, const std::map &outputs); - void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output); + int process(uint32_t frame, FrameBuffer *input, FrameBuffer *output); Signal inputBufferReady; Signal outputBufferReady; @@ -99,6 +99,7 @@ private: Thread ispWorkerThread_; SharedMemObject sharedParams_; DebayerParams debayerParams_; + std::vector availableParams_; DmaBufAllocator dmaHeap_; bool ccmEnabled_; diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index 774f2bf75..d48cd00ad 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -185,6 +185,9 @@ bool SoftwareIsp::allocateParamsBuffers() return false; } + /* Just a single buffer for now, let's use 0 as its id. */ + availableParams_.push_back(0); + return true; } @@ -353,7 +356,12 @@ int SoftwareIsp::queueBuffers(uint32_t frame, FrameBuffer *input, for (const auto &[stream, buffer] : outputs) { queuedInputBuffers_.push_back(input); queuedOutputBuffers_.push_back(buffer); - process(frame, input, buffer); + int ret = process(frame, input, buffer); + if (ret) { + queuedInputBuffers_.pop_back(); + queuedOutputBuffers_.pop_back(); + return ret; + } } return 0; @@ -413,15 +421,23 @@ void SoftwareIsp::stop() * \param[in] frame The frame number * \param[in] input The input framebuffer * \param[out] output The framebuffer to write the processed frame to + * \return 0 on success, -EAGAIN if a parameter buffer underrun occurs */ -void SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output) +int SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output) { - /* \todo Provide a real value */ - constexpr uint32_t paramsBufferId = 0; + if (availableParams_.empty()) { + LOG(SoftwareIsp, Error) << "Parameters buffer underrun"; + return -EAGAIN; + } + + const uint32_t paramsBufferId = availableParams_.back(); + availableParams_.pop_back(); ipa_->computeParams(frame, paramsBufferId); debayer_->invokeMethod(&Debayer::process, ConnectionTypeQueued, frame, paramsBufferId, input, output, debayerParams_); + + return 0; } void SoftwareIsp::saveIspParams([[maybe_unused]] const uint32_t paramsBufferId) @@ -429,8 +445,9 @@ void SoftwareIsp::saveIspParams([[maybe_unused]] const uint32_t paramsBufferId) debayerParams_ = *sharedParams_; } -void SoftwareIsp::paramsBufferReady([[maybe_unused]] const uint32_t paramsBufferId) +void SoftwareIsp::paramsBufferReady(const uint32_t paramsBufferId) { + availableParams_.push_back(paramsBufferId); } void SoftwareIsp::setSensorCtrls(const ControlList &sensorControls) From patchwork Thu Jun 4 09:50:54 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26833 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 92D8AC328C for ; Thu, 4 Jun 2026 09:51:49 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3CD8663741; Thu, 4 Jun 2026 11:51:49 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="McCszPp+"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7FE3D63403 for ; Thu, 4 Jun 2026 11:51:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780566706; 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=00G6fCl+VrAiAKncqdFqlnHj8CGJ2JX9e4VeeAibcj8=; b=McCszPp+2sfFcKgKodCmbiZw+zClV1Xf2kYdKYnMfkksr0ALF7nzSoJthOT5uGuFXGaK/K HWT2QxyMOzQgdU8WxiUh6nm5QYz/PTqdMJTrxDAr229gTO67GpNYcgwpt2NUWMS20aeA5+ m0qBQ7k3OLDi+ZpZIpdylof4Wt/8tOQ= Received: from mx-prod-mc-03.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-650-VdEE4mczPISTqC6Niid6xQ-1; Thu, 04 Jun 2026 05:51:43 -0400 X-MC-Unique: VdEE4mczPISTqC6Niid6xQ-1 X-Mimecast-MFC-AGG-ID: VdEE4mczPISTqC6Niid6xQ_1780566702 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-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 53A341956050; Thu, 4 Jun 2026 09:51:42 +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 8C35030001A1; Thu, 4 Jun 2026 09:51:40 +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 08/17] libcamera: software_isp: Allocation of multiple params buffers Date: Thu, 4 Jun 2026 11:50:54 +0200 Message-ID: <20260604095105.68798-13-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: EjBymKknOC_6Xvu6nvBqpH0cpLssvoZEGrCAr4zKIpk_1780566702 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" SoftwareIsp::sharedParams_ is changed from a single buffer to a map of multiple buffer ids and the corresponding buffers. This requires some code rearranging within SoftwareIsp::allocateParamsBuffers to keep the right sequence of actions. Currently, only a single buffer is allocated, this will be changed in a followup patch. Signed-off-by: Milan Zamazal --- .../internal/software_isp/software_isp.h | 3 ++- src/libcamera/software_isp/software_isp.cpp | 25 ++++++++++++------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h index 58fb9d752..b77793713 100644 --- a/include/libcamera/internal/software_isp/software_isp.h +++ b/include/libcamera/internal/software_isp/software_isp.h @@ -97,7 +97,8 @@ private: void outputReady(FrameBuffer *output); std::unique_ptr debayer_; Thread ispWorkerThread_; - SharedMemObject sharedParams_; + static constexpr unsigned int kParamStatBufferCount = 1; + std::map> sharedParams_; DebayerParams debayerParams_; std::vector availableParams_; DmaBufAllocator dmaHeap_; diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index d48cd00ad..6596e6fdb 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -72,6 +72,11 @@ 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 @@ -150,7 +155,7 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, ret = ipa_->init(IPASettings{ ipaTuningFile, sensor->model() }, debayer_->getStatsFD(), - sharedParams_.fd(), + sharedParams_.begin()->second.fd(), sensorInfo, sensor->controls(), ipaControls, @@ -179,14 +184,16 @@ SoftwareIsp::~SoftwareIsp() bool SoftwareIsp::allocateParamsBuffers() { - sharedParams_ = SharedMemObject("softIsp_params"); - if (!sharedParams_) { - LOG(SoftwareIsp, Error) << "Failed to create shared memory for parameters"; - return false; - } + for (unsigned int bufferId = 0; bufferId < kParamStatBufferCount; bufferId++) { + auto params = SharedMemObject("softIsp_params"); + if (!params) { + LOG(SoftwareIsp, Error) << "Failed to create shared memory for parameters"; + return false; + } - /* Just a single buffer for now, let's use 0 as its id. */ - availableParams_.push_back(0); + availableParams_.push_back(bufferId); + sharedParams_.emplace(bufferId, std::move(params)); + } return true; } @@ -442,7 +449,7 @@ int SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output void SoftwareIsp::saveIspParams([[maybe_unused]] const uint32_t paramsBufferId) { - debayerParams_ = *sharedParams_; + debayerParams_ = *sharedParams_.begin()->second; } void SoftwareIsp::paramsBufferReady(const uint32_t paramsBufferId) 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"; From patchwork Thu Jun 4 09:50:56 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26835 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 44B0AC328C for ; Thu, 4 Jun 2026 09:51:54 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id ECE3163741; Thu, 4 Jun 2026 11:51:53 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="UmfBPmX+"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5EA3363745 for ; Thu, 4 Jun 2026 11:51:52 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780566711; 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=682wowaOie8lHYf8tLjJbnf75N3CCILappnXvI/DGMs=; b=UmfBPmX+acTs7Pw+HcrvhPWv2gJ+n1CrlYktoTXjx95I2iXRc0qWR5ZpsKu6yaa8IRuLTk GROcu5svw9thLd/aaCSbSWaGaPqvWAatONdymu9Hg3pGOjLBMoNAjSugXdphEGby80NJ1h FIzmdUSucQMymi1MlDvIilaY0t2UOrU= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-412-xEBsNBoYPVmrcmdJy0vTgg-1; Thu, 04 Jun 2026 05:51:48 -0400 X-MC-Unique: xEBsNBoYPVmrcmdJy0vTgg-1 X-Mimecast-MFC-AGG-ID: xEBsNBoYPVmrcmdJy0vTgg_1780566707 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-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2401018004BB; Thu, 4 Jun 2026 09:51:47 +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 1328D3000210; Thu, 4 Jun 2026 09:51:44 +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 10/17] libcamera: software_isp: Use multiple parameters buffers in IPA Date: Thu, 4 Jun 2026 11:50:56 +0200 Message-ID: <20260604095105.68798-15-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: W9M_x_mgvFx46ko69XbJqwcD_Ua7iUAVvrSvLOarn9k_1780566707 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" Instead of the single parameters buffer file descriptor, pass the file descriptors of all the parameters buffers to the IPA and let it use them according to the passed buffer id. This means: - The file descriptors of all the buffers must be passed to the IPA. - The IPA must store mappings of the buffer ids to the corresponding buffers. - The current buffer id is passed to/from the IPA. The parameters buffers are still copied for debayering, this will be addressed in the next patch. Signed-off-by: Milan Zamazal --- include/libcamera/ipa/soft.mojom | 2 +- src/ipa/simple/soft_simple.cpp | 40 ++++++++++----------- src/libcamera/software_isp/software_isp.cpp | 10 ++++-- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/include/libcamera/ipa/soft.mojom b/include/libcamera/ipa/soft.mojom index 18789d5de..f348f582d 100644 --- a/include/libcamera/ipa/soft.mojom +++ b/include/libcamera/ipa/soft.mojom @@ -15,7 +15,7 @@ struct IPAConfigInfo { interface IPASoftInterface { init(libcamera.IPASettings settings, libcamera.SharedFD fdStats, - libcamera.SharedFD fdParams, + map fdParams, libcamera.IPACameraSensorInfo sensorInfo, libcamera.ControlInfoMap sensorControls) => (int32 ret, libcamera.ControlInfoMap ipaControls, bool ccmEnabled); diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp index 69bfef302..0212a3b52 100644 --- a/src/ipa/simple/soft_simple.cpp +++ b/src/ipa/simple/soft_simple.cpp @@ -53,7 +53,7 @@ public: int init(const IPASettings &settings, const SharedFD &fdStats, - const SharedFD &fdParams, + const std::map &fdParams, const IPACameraSensorInfo &sensorInfo, const ControlInfoMap &sensorControls, ControlInfoMap *ipaControls, @@ -75,7 +75,7 @@ protected: private: void updateExposure(double exposureMSV); - DebayerParams *params_; + std::map paramsBuffers_; SwIspStats *stats_; std::unique_ptr camHelper_; ControlInfoMap sensorInfoMap_; @@ -88,13 +88,13 @@ IPASoftSimple::~IPASoftSimple() { if (stats_) munmap(stats_, sizeof(SwIspStats)); - if (params_) - munmap(params_, sizeof(DebayerParams)); + for (auto &item : paramsBuffers_) + munmap(item.second, sizeof(DebayerParams)); } int IPASoftSimple::init(const IPASettings &settings, const SharedFD &fdStats, - const SharedFD &fdParams, + const std::map &fdParams, const IPACameraSensorInfo &sensorInfo, const ControlInfoMap &sensorControls, ControlInfoMap *ipaControls, @@ -137,8 +137,6 @@ int IPASoftSimple::init(const IPASettings &settings, return ret; *ccmEnabled = context_.ccmEnabled; - - params_ = nullptr; stats_ = nullptr; if (!fdStats.isValid()) { @@ -146,25 +144,26 @@ int IPASoftSimple::init(const IPASettings &settings, return -ENODEV; } - if (!fdParams.isValid()) { - LOG(IPASoft, Error) << "Invalid Parameters handle"; - return -ENODEV; - } + for (auto &[bufferId, sharedFd] : fdParams) { + if (!sharedFd.isValid()) { + LOG(IPASoft, Error) << "Invalid Parameters handle"; + return -ENODEV; + } - { void *mem = mmap(nullptr, sizeof(DebayerParams), PROT_WRITE, - MAP_SHARED, fdParams.get(), 0); + MAP_SHARED, sharedFd.get(), 0); if (mem == MAP_FAILED) { LOG(IPASoft, Error) << "Unable to map Parameters"; return -errno; } - params_ = static_cast(mem); - params_->blackLevel = { { 0.0, 0.0, 0.0 } }; - params_->gamma = 1.0 / algorithms::kDefaultGamma; - params_->contrastExp = 1.0; - params_->gains = { { 1.0, 1.0, 1.0 } }; + DebayerParams *params = static_cast(mem); + params->blackLevel = { { 0.0, 0.0, 0.0 } }; + params->gamma = 1.0 / algorithms::kDefaultGamma; + params->contrastExp = 1.0; + params->gains = { { 1.0, 1.0, 1.0 } }; /* combinedMatrix is reset for each frame. */ + paramsBuffers_[bufferId] = params; } { @@ -290,9 +289,10 @@ void IPASoftSimple::computeParams(const uint32_t frame, context_.activeState.combinedMatrix = Matrix::identity(); IPAFrameContext &frameContext = context_.frameContexts.get(frame); + DebayerParams *params = paramsBuffers_.at(paramsBufferId); for (const auto &algo : algorithms()) - algo->prepare(context_, frame, frameContext, params_); - params_->combinedMatrix = context_.activeState.combinedMatrix; + algo->prepare(context_, frame, frameContext, params); + params->combinedMatrix = context_.activeState.combinedMatrix; paramsComputed.emit(paramsBufferId); } diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index 97b423434..7f3bfe812 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -125,6 +126,9 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, if (!debayer_) debayer_ = std::make_unique(std::move(stats), cm); + std::map fdParams; + for (auto &[bufferId, item] : sharedParams_) + fdParams[bufferId] = item.fd(); debayer_->inputBufferReady.connect(this, &SoftwareIsp::inputReady); debayer_->outputBufferReady.connect(this, &SoftwareIsp::outputReady); debayer_->paramsBufferReady.connect(this, &SoftwareIsp::paramsBufferReady); @@ -153,7 +157,7 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, ret = ipa_->init(IPASettings{ ipaTuningFile, sensor->model() }, debayer_->getStatsFD(), - sharedParams_.begin()->second.fd(), + fdParams, sensorInfo, sensor->controls(), ipaControls, @@ -445,9 +449,9 @@ int SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output return 0; } -void SoftwareIsp::saveIspParams([[maybe_unused]] const uint32_t paramsBufferId) +void SoftwareIsp::saveIspParams(const uint32_t paramsBufferId) { - debayerParams_ = *sharedParams_.begin()->second; + debayerParams_ = *sharedParams_.at(paramsBufferId); } void SoftwareIsp::paramsBufferReady(const uint32_t paramsBufferId) From patchwork Thu Jun 4 09:50:57 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26836 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 D2476C328C for ; Thu, 4 Jun 2026 09:51:56 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8A09263741; Thu, 4 Jun 2026 11:51:56 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="MLRYCo3s"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E2A9E63733 for ; Thu, 4 Jun 2026 11:51:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780566713; 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=7euhAtbwddrv5/CMcfmu7aeGVYwz3eIBeIEaZt1wgWs=; b=MLRYCo3s65lxx01SRQWZRs6Hi0RLQcFziBvrqTdMx4XFJ3Zrolfl9V8Wq/lVnx/TcV8nYx uWb7Q9UACGlgZfe5AOCA1tBa3U8pUe8/fH0ncyR6sNe1jscUHofKyN8H6WK7KGK+ebb4GW QFFaDltCZhTyVrj4NSa7/9OsM7rHTXw= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-470-CwXj_GaaPzusu6B1lrUEOw-1; Thu, 04 Jun 2026 05:51:50 -0400 X-MC-Unique: CwXj_GaaPzusu6B1lrUEOw-1 X-Mimecast-MFC-AGG-ID: CwXj_GaaPzusu6B1lrUEOw_1780566709 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-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 7C1CD180047F; Thu, 4 Jun 2026 09:51:49 +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 9BFB130001A1; Thu, 4 Jun 2026 09:51:47 +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 11/17] libcamera: software_isp: Share parameters buffers with debayering Date: Thu, 4 Jun 2026 11:50:57 +0200 Message-ID: <20260604095105.68798-16-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: _SoqBzod-b_wHCsRWFDp6jKTlEx-uLP3Mz0Nl-EyG6U_1780566709 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" Share the multiple parameters buffers with debayering rather than copying the current parameters buffer there. This is done in a similar way as sharing the buffers with IPA in the preceding patch. Signed-off-by: Milan Zamazal --- .../internal/software_isp/software_isp.h | 2 - src/libcamera/software_isp/debayer.cpp | 29 ++++++-- src/libcamera/software_isp/debayer.h | 9 +-- src/libcamera/software_isp/debayer_cpu.cpp | 66 ++++++++++--------- src/libcamera/software_isp/debayer_cpu.h | 12 ++-- src/libcamera/software_isp/debayer_egl.cpp | 15 +++-- src/libcamera/software_isp/debayer_egl.h | 7 +- src/libcamera/software_isp/software_isp.cpp | 21 +++--- 8 files changed, 91 insertions(+), 70 deletions(-) diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h index e3419305b..9ea0ed4db 100644 --- a/include/libcamera/internal/software_isp/software_isp.h +++ b/include/libcamera/internal/software_isp/software_isp.h @@ -89,7 +89,6 @@ public: Signal setSensorControls; private: - void saveIspParams(const uint32_t paramsBufferId); void paramsBufferReady(const uint32_t paramsBufferId); bool allocateParamsBuffers(const unsigned int bufferCount); void setSensorCtrls(const ControlList &sensorControls); @@ -99,7 +98,6 @@ private: std::unique_ptr debayer_; Thread ispWorkerThread_; std::map> sharedParams_; - DebayerParams debayerParams_; std::vector availableParams_; DmaBufAllocator dmaHeap_; bool ccmEnabled_; diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp index 7b1be52b2..28e04d0df 100644 --- a/src/libcamera/software_isp/debayer.cpp +++ b/src/libcamera/software_isp/debayer.cpp @@ -11,6 +11,8 @@ #include "debayer.h" +#include + namespace libcamera { /** @@ -54,15 +56,29 @@ LOG_DEFINE_CATEGORY(Debayer) /** * \brief Construct a Debayer object + * \param[in] paramsBuffers ids and SharedFDs of parameter buffers * \param[in] cm The camera manager */ -Debayer::Debayer(const CameraManager &cm) +Debayer::Debayer(const std::map ¶msBuffers, const CameraManager &cm) : bench_(cm, "Debayer") { + for (auto &[bufferId, sharedFd] : paramsBuffers) { + void *mem = mmap(nullptr, sizeof(DebayerParams), + PROT_READ | PROT_WRITE, MAP_SHARED, + sharedFd.get(), 0); + if (mem == MAP_FAILED) { + LOG(Debayer, Error) << "Unable to map Parameters"; + return; + } + + paramsBuffers_[bufferId] = static_cast(mem); + } } Debayer::~Debayer() { + for (auto &item : paramsBuffers_) + munmap(item.second, sizeof(DebayerParams)); } /** @@ -104,16 +120,12 @@ Debayer::~Debayer() */ /** - * \fn void Debayer::process(uint32_t frame, const uint32_t paramsBufferId, FrameBuffer *input, FrameBuffer *output, DebayerParams params) + * \fn void Debayer::process(uint32_t frame, const uint32_t paramsBufferId, FrameBuffer *input, FrameBuffer *output) * \brief Process the bayer data into the requested format * \param[in] frame The frame number * \param[in] paramsBufferId The id of the params buffer in use * \param[in] input The input buffer * \param[in] output The output buffer - * \param[in] params The parameters to be used in debayering - * - * \note DebayerParams is passed by value deliberately so that a copy is passed - * when this is run in another thread by invokeMethod(). */ /** @@ -240,6 +252,11 @@ Debayer::~Debayer() * reversed. */ +/** + * \var Debayer::paramsBuffers_ + * \brief Ring of debayering parameters buffers + */ + /** * \var Debayer::bench_ * \brief Benchmarking utility instance for performance measurements diff --git a/src/libcamera/software_isp/debayer.h b/src/libcamera/software_isp/debayer.h index 9a97851b7..6cefa4c01 100644 --- a/src/libcamera/software_isp/debayer.h +++ b/src/libcamera/software_isp/debayer.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * Copyright (C) 2023, Linaro Ltd - * Copyright (C) 2023, Red Hat Inc. + * Copyright (C) 2023-2026 Red Hat Inc. * * Authors: * Hans de Goede @@ -35,7 +35,8 @@ LOG_DECLARE_CATEGORY(Debayer) class Debayer : public Object { public: - Debayer(const CameraManager &cm); + Debayer(const std::map ¶msBuffers, + const CameraManager &cm); virtual ~Debayer() = 0; virtual int configure(const StreamConfiguration &inputCfg, @@ -49,8 +50,7 @@ public: virtual void process(uint32_t frame, const uint32_t paramsBufferId, - FrameBuffer *input, FrameBuffer *output, - const DebayerParams ¶ms) = 0; + FrameBuffer *input, FrameBuffer *output) = 0; virtual int start() { return 0; } virtual void stop() {} @@ -83,6 +83,7 @@ public: PixelFormat inputPixelFormat_; PixelFormat outputPixelFormat_; bool swapRedBlueGains_; + std::map paramsBuffers_; Benchmark bench_; private: diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp index 51b58fce5..7813eb695 100644 --- a/src/libcamera/software_isp/debayer_cpu.cpp +++ b/src/libcamera/software_isp/debayer_cpu.cpp @@ -12,12 +12,12 @@ #include "debayer_cpu.h" #include -#include #include #include #include +#include #include #include @@ -90,10 +90,13 @@ DebayerCpuThread::DebayerCpuThread(DebayerCpu *debayer, unsigned int threadIndex /** * \brief Constructs a DebayerCpu object * \param[in] stats Pointer to the stats object to use + * \param[in] paramsBuffers SharedFDs of parameter buffers * \param[in] cm The camera manager */ -DebayerCpu::DebayerCpu(std::unique_ptr stats, const CameraManager &cm) - : Debayer(cm), stats_(std::move(stats)) +DebayerCpu::DebayerCpu(std::unique_ptr stats, + const std::map ¶msBuffers, + const CameraManager &cm) + : Debayer(paramsBuffers, cm), stats_(std::move(stats)) { /* * Reading from uncached buffers may be very slow. @@ -879,13 +882,13 @@ void DebayerCpuThread::process4(uint32_t frame, const uint8_t *src, uint8_t *dst } } -void DebayerCpu::updateGammaTable(const DebayerParams ¶ms) +void DebayerCpu::updateGammaTable(const DebayerParams *params) { - const RGB blackLevel = params.blackLevel; + const RGB blackLevel = params->blackLevel; /* Take let's say the green channel black level */ const unsigned int blackIndex = blackLevel[1] * gammaTable_.size(); - const float gamma = params.gamma; - const float contrastExp = params.contrastExp; + const float gamma = params->gamma; + const float contrastExp = params->contrastExp; const float divisor = gammaTable_.size() - blackIndex - 1.0; for (unsigned int i = blackIndex; i < gammaTable_.size(); i++) { @@ -909,12 +912,12 @@ void DebayerCpu::updateGammaTable(const DebayerParams ¶ms) gammaTable_[blackIndex]); } -void DebayerCpu::updateLookupTables(const DebayerParams ¶ms) +void DebayerCpu::updateLookupTables(const DebayerParams *params) { const bool gammaUpdateNeeded = - params.gamma != params_.gamma || - params.blackLevel != params_.blackLevel || - params.contrastExp != params_.contrastExp; + params->gamma != params_.gamma || + params->blackLevel != params_.blackLevel || + params->contrastExp != params_.contrastExp; if (gammaUpdateNeeded) updateGammaTable(params); @@ -925,7 +928,7 @@ void DebayerCpu::updateLookupTables(const DebayerParams ¶ms) const double div = static_cast(kRGBLookupSize) / gammaTableSize; if (ccmEnabled_) { if (gammaUpdateNeeded || - matrixChanged(params.combinedMatrix, params_.combinedMatrix)) { + matrixChanged(params->combinedMatrix, params_.combinedMatrix)) { auto &red = swapRedBlueGains_ ? blueCcm_ : redCcm_; auto &green = greenCcm_; auto &blue = swapRedBlueGains_ ? redCcm_ : blueCcm_; @@ -933,21 +936,21 @@ void DebayerCpu::updateLookupTables(const DebayerParams ¶ms) const unsigned int greenIndex = 1; const unsigned int blueIndex = swapRedBlueGains_ ? 0 : 2; for (unsigned int i = 0; i < kRGBLookupSize; i++) { - red[i].r = std::round(i * params.combinedMatrix[redIndex][0]); - red[i].g = std::round(i * params.combinedMatrix[greenIndex][0]); - red[i].b = std::round(i * params.combinedMatrix[blueIndex][0]); - green[i].r = std::round(i * params.combinedMatrix[redIndex][1]); - green[i].g = std::round(i * params.combinedMatrix[greenIndex][1]); - green[i].b = std::round(i * params.combinedMatrix[blueIndex][1]); - blue[i].r = std::round(i * params.combinedMatrix[redIndex][2]); - blue[i].g = std::round(i * params.combinedMatrix[greenIndex][2]); - blue[i].b = std::round(i * params.combinedMatrix[blueIndex][2]); + red[i].r = std::round(i * params->combinedMatrix[redIndex][0]); + red[i].g = std::round(i * params->combinedMatrix[greenIndex][0]); + red[i].b = std::round(i * params->combinedMatrix[blueIndex][0]); + green[i].r = std::round(i * params->combinedMatrix[redIndex][1]); + green[i].g = std::round(i * params->combinedMatrix[greenIndex][1]); + green[i].b = std::round(i * params->combinedMatrix[blueIndex][1]); + blue[i].r = std::round(i * params->combinedMatrix[redIndex][2]); + blue[i].g = std::round(i * params->combinedMatrix[greenIndex][2]); + blue[i].b = std::round(i * params->combinedMatrix[blueIndex][2]); gammaLut_[i] = gammaTable_[i / div]; } } } else { - if (gammaUpdateNeeded || params.gains != params_.gains) { - auto &gains = params.gains; + if (gammaUpdateNeeded || params->gains != params_.gains) { + auto &gains = params->gains; auto &red = swapRedBlueGains_ ? blue_ : red_; auto &green = green_; auto &blue = swapRedBlueGains_ ? red_ : blue_; @@ -962,18 +965,17 @@ void DebayerCpu::updateLookupTables(const DebayerParams ¶ms) } LOG(Debayer, Debug) - << "Debayer parameters: blackLevel=" << params.blackLevel - << "; gamma=" << params.gamma - << "; contrastExp=" << params.contrastExp - << "; gains=" << params.gains - << "; matrix=" << params.combinedMatrix; + << "Debayer parameters: blackLevel=" << params->blackLevel + << "; gamma=" << params->gamma + << "; contrastExp=" << params->contrastExp + << "; gains=" << params->gains + << "; matrix=" << params->combinedMatrix; - params_ = params; + params_ = *params; } void DebayerCpu::process(uint32_t frame, const uint32_t paramsBufferId, - FrameBuffer *input, FrameBuffer *output, - const DebayerParams ¶ms) + FrameBuffer *input, FrameBuffer *output) { bench_.startFrame(); @@ -981,8 +983,8 @@ void DebayerCpu::process(uint32_t frame, const uint32_t paramsBufferId, dmaSyncBegin(dmaSyncers, input, output); + DebayerParams *params = paramsBuffers_.at(paramsBufferId); updateLookupTables(params); - paramsBufferReady.emit(paramsBufferId); /* Copy metadata from the input buffer */ diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h index 1b4e8548a..56d9087da 100644 --- a/src/libcamera/software_isp/debayer_cpu.h +++ b/src/libcamera/software_isp/debayer_cpu.h @@ -17,6 +17,7 @@ #include #include +#include #include @@ -32,7 +33,9 @@ class DebayerCpuThread; class DebayerCpu : public Debayer { public: - DebayerCpu(std::unique_ptr stats, const CameraManager &cm); + DebayerCpu(std::unique_ptr stats, + const std::map ¶msBuffers, + const CameraManager &cm); ~DebayerCpu(); int configure(const StreamConfiguration &inputCfg, @@ -43,8 +46,7 @@ public: std::tuple strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) override; void process(uint32_t frame, const uint32_t paramsBufferId, - FrameBuffer *input, FrameBuffer *output, - const DebayerParams ¶ms) override; + FrameBuffer *input, FrameBuffer *output) override; int start() override; void stop() override; SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) override; @@ -119,8 +121,8 @@ private: int setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputFormat, bool ccmEnabled); - void updateGammaTable(const DebayerParams ¶ms); - void updateLookupTables(const DebayerParams ¶ms); + void updateGammaTable(const DebayerParams *params); + void updateLookupTables(const DebayerParams *params); static constexpr unsigned int kRGBLookupSize = 256; static constexpr unsigned int kGammaLookupSize = 1024; diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp index 60fd5463f..77696f1e7 100644 --- a/src/libcamera/software_isp/debayer_egl.cpp +++ b/src/libcamera/software_isp/debayer_egl.cpp @@ -37,10 +37,13 @@ namespace libcamera { /** * \brief Construct a DebayerEGL object * \param[in] stats Statistics processing object + * \param[in] paramsBuffers SharedFDs of parameter buffers * \param[in] cm The camera manager */ -DebayerEGL::DebayerEGL(std::unique_ptr stats, const CameraManager &cm) - : Debayer(cm), stats_(std::move(stats)) +DebayerEGL::DebayerEGL(std::unique_ptr stats, + const std::map ¶msBuffers, + const CameraManager &cm) + : Debayer(paramsBuffers, cm), stats_(std::move(stats)) { } @@ -547,8 +550,7 @@ int DebayerEGL::debayerGPU(FrameBuffer *input, FrameBuffer *output, const Debaye } void DebayerEGL::process(uint32_t frame, const uint32_t paramsBufferId, - FrameBuffer *input, FrameBuffer *output, - const DebayerParams ¶ms) + FrameBuffer *input, FrameBuffer *output) { bench_.startFrame(); @@ -561,11 +563,13 @@ void DebayerEGL::process(uint32_t frame, const uint32_t paramsBufferId, std::optional inMapped; std::optional inDmaSyncer; + DebayerParams params = *paramsBuffers_.at(paramsBufferId); + paramsBufferReady.emit(paramsBufferId); + if (debayerGPU(input, output, params, &inMapped, &inDmaSyncer)) { LOG(Debayer, Error) << "debayerGPU failed"; goto error; } - paramsBufferReady.emit(paramsBufferId); metadata.planes()[0].bytesused = output->planes()[0].length; @@ -596,7 +600,6 @@ void DebayerEGL::process(uint32_t frame, const uint32_t paramsBufferId, return; error: - paramsBufferReady.emit(paramsBufferId); bench_.finishFrame(); metadata.status = FrameMetadata::FrameError; return; diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h index a3a4448e7..43e3dcb15 100644 --- a/src/libcamera/software_isp/debayer_egl.h +++ b/src/libcamera/software_isp/debayer_egl.h @@ -39,7 +39,9 @@ class CameraManager; class DebayerEGL : public Debayer { public: - DebayerEGL(std::unique_ptr stats, const CameraManager &cm); + DebayerEGL(std::unique_ptr stats, + const std::map ¶msBuffers, + const CameraManager &cm); ~DebayerEGL(); int configure(const StreamConfiguration &inputCfg, @@ -52,8 +54,7 @@ public: std::tuple strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) override; void process(uint32_t frame, const uint32_t paramsBufferId, - FrameBuffer *input, FrameBuffer *output, - const DebayerParams ¶ms) override; + FrameBuffer *input, FrameBuffer *output) override; int start() override; void stop() override; diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index 7f3bfe812..dbe4cc270 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -106,6 +106,10 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, } stats->statsReady.connect(this, &SoftwareIsp::statsReady); + std::map fdParams; + for (auto &[bufferId, item] : sharedParams_) + fdParams[bufferId] = item.fd(); + #if HAVE_DEBAYER_EGL const GlobalConfiguration &configuration = cm._d()->configuration(); std::optional softISPMode = configuration.option({ "software_isp", "mode" }); @@ -120,15 +124,14 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, } if (!softISPMode || softISPMode == "gpu") - debayer_ = std::make_unique(std::move(stats), cm); + debayer_ = std::make_unique(std::move(stats), fdParams, + cm); #endif if (!debayer_) - debayer_ = std::make_unique(std::move(stats), cm); + debayer_ = std::make_unique(std::move(stats), fdParams, + cm); - std::map fdParams; - for (auto &[bufferId, item] : sharedParams_) - fdParams[bufferId] = item.fd(); debayer_->inputBufferReady.connect(this, &SoftwareIsp::inputReady); debayer_->outputBufferReady.connect(this, &SoftwareIsp::outputReady); debayer_->paramsBufferReady.connect(this, &SoftwareIsp::paramsBufferReady); @@ -168,7 +171,6 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, return; } - ipa_->paramsComputed.connect(this, &SoftwareIsp::saveIspParams); ipa_->metadataReady.connect(this, [this](uint32_t frame, const ControlList &metadata) { metadataReady.emit(frame, metadata); @@ -444,16 +446,11 @@ int SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output ipa_->computeParams(frame, paramsBufferId); debayer_->invokeMethod(&Debayer::process, ConnectionTypeQueued, frame, paramsBufferId, - input, output, debayerParams_); + input, output); return 0; } -void SoftwareIsp::saveIspParams(const uint32_t paramsBufferId) -{ - debayerParams_ = *sharedParams_.at(paramsBufferId); -} - void SoftwareIsp::paramsBufferReady(const uint32_t paramsBufferId) { availableParams_.push_back(paramsBufferId); From patchwork Thu Jun 4 09:50:58 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26837 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 9C9F8C328C for ; Thu, 4 Jun 2026 09:51:59 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 52EE563748; Thu, 4 Jun 2026 11:51:59 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="RSdiRCs2"; 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 868AE6373C for ; Thu, 4 Jun 2026 11:51:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780566714; 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=rCKk1ldTDS+4T43X5M3WrUPIYIV1fc+fXNa+4lZ0FXI=; b=RSdiRCs2hAwqir0bfeQLsBYWx55R/CFZFE/TlOaUeM+xHwgTjElRkLu5/vlsDkNpabv3wf vbzQJGFKiX5wzHU8hel/BZBiTmRFO3JDoQILZbK35GDlPmvIlWsLYeYGw+KzxobWldhzkV 6Kzolu1WkMQXyTI5ItobOOEzZAncBYs= Received: from mx-prod-mc-05.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-125-1angchQUOcOQ3Ej0UzF71A-1; Thu, 04 Jun 2026 05:51:52 -0400 X-MC-Unique: 1angchQUOcOQ3Ej0UzF71A-1 X-Mimecast-MFC-AGG-ID: 1angchQUOcOQ3Ej0UzF71A_1780566712 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-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id ECB121956095; Thu, 4 Jun 2026 09:51:51 +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 30FB930001A1; Thu, 4 Jun 2026 09:51:49 +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 12/17] libcamera: software_isp: Remove per-frame params buffers TODO item Date: Thu, 4 Jun 2026 11:50:58 +0200 Message-ID: <20260604095105.68798-17-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: 7oilGfin0ei8Q8_MXJkv1Z8vnvF6NzxB7mJf3uYICE8_1780566712 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" Parameters are stored in per-frame buffers and shared properly now. Signed-off-by: Milan Zamazal --- src/libcamera/software_isp/TODO.md | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/libcamera/software_isp/TODO.md b/src/libcamera/software_isp/TODO.md index 0f27da2d2..f4e5190e0 100644 --- a/src/libcamera/software_isp/TODO.md +++ b/src/libcamera/software_isp/TODO.md @@ -65,24 +65,6 @@ addressed now, I think it would be part of a larger refactoring stats in hardware, such as the i.MX7), but please keep it on your radar. ``` -### Store ISP parameters in per-frame buffers - -``` -> /** -> * \fn void Debayer::process(FrameBuffer *input, FrameBuffer *output, DebayerParams params) -> * \brief Process the bayer data into the requested format. -> * \param[in] input The input buffer. -> * \param[in] output The output buffer. -> * \param[in] params The parameters to be used in debayering. -> * -> * \note DebayerParams is passed by value deliberately so that a copy is passed -> * when this is run in another thread by invokeMethod(). -> */ - -Possibly something to address later, by storing ISP parameters in -per-frame buffers like we do for hardware ISPs. -``` - ### DebayerCpu cleanups ``` From patchwork Thu Jun 4 09:50:59 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26838 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 6331BC328C for ; Thu, 4 Jun 2026 09:52:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1CA606374B; Thu, 4 Jun 2026 11:52:02 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="Tauiyv0/"; 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 C75D76374A for ; Thu, 4 Jun 2026 11:51:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780566718; 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=e2ZtmP9i4oRflFR1R1thyUdJEmfiEJhXTTAsM32ddmw=; b=Tauiyv0//k4iHiiWNJK7hWtV5EknRC35s/SaKXXhNHtmmgu3FXkyvKeJlAqxsIl5dZdwQ2 GFFNGUiZphF7/cJiqjspunZ8vNzL6dnvySbmqqjD0cXLrzeN7hDFzM4ljnnVFv9i23PeSS nSwjZlzh8Hyg92IgBB1Yvai8S/28Y58= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-631-gsJ-CtwtOwimgVwDCVAAEQ-1; Thu, 04 Jun 2026 05:51:55 -0400 X-MC-Unique: gsJ-CtwtOwimgVwDCVAAEQ-1 X-Mimecast-MFC-AGG-ID: gsJ-CtwtOwimgVwDCVAAEQ_1780566714 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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1DBF418004A9; Thu, 4 Jun 2026 09:51:54 +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 6E57A30001A1; Thu, 4 Jun 2026 09:51:52 +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 13/17] libcamera: software_isp: Introduce arguments for statistics buffers Date: Thu, 4 Jun 2026 11:50:59 +0200 Message-ID: <20260604095105.68798-18-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: -h4M4nOAYnJPFaVsLdfUrv6cWMU8mlNd5csFdXv_1Ls_1780566714 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" Statistics in software ISP is held in two fixed buffers, copying the statistics from the working one to the shared one in SwIspStats::finishFrame. This patch introduces support for a ring of statistics buffers that are never copied, similarly to parameters buffers and to how hardware pipelines operate. This is to address software ISP TODO #2. The patch adds a new argument statsBufferId for the future statistics buffer ids passed to the calls. The buffer ids must be passed to the following groups of methods: - Debayer::process, to signal what statistics buffer is started and stopped being used to gather the statistics. - SoftwareIsp::statsProcessed, a new signal to indicate that the given statistics buffer contents is no longer needed. The type of the buffer id statistics is set to uint32_t because: - It can be used in mojom. - The same type is used for parameters buffers. - It is consistent with the similar types in the hardware pipelines. - It covers file descriptor number range, which will be used as buffer ids. Already provided statistics buffer arguments are renamed from bufferId to statsBufferId for consistency and to avoid confusion between statistics and parameters buffer id arguments. This patch doesn't do more than adding the arguments, to keep the patch simple. The buffer handling will be implemented in the followup patches. Statistics and parameters buffers use is coupled to much extent. It can be tempting to perhaps use the same buffer ids and perhaps some common signals. But it's better to keep them separate to avoid contingent future refactoring in case this coupling becomes less tight in future. Signed-off-by: Milan Zamazal --- .../internal/software_isp/software_isp.h | 3 ++- .../internal/software_isp/swstats_cpu.h | 4 ++-- include/libcamera/ipa/soft.mojom | 3 ++- src/ipa/simple/soft_simple.cpp | 3 ++- src/libcamera/pipeline/simple/simple.cpp | 7 ++++--- src/libcamera/software_isp/debayer.cpp | 3 ++- src/libcamera/software_isp/debayer.h | 1 + src/libcamera/software_isp/debayer_cpu.cpp | 14 ++++++-------- src/libcamera/software_isp/debayer_cpu.h | 7 +++++-- src/libcamera/software_isp/debayer_egl.cpp | 7 +++++-- src/libcamera/software_isp/debayer_egl.h | 7 +++++-- src/libcamera/software_isp/software_isp.cpp | 14 ++++++++++---- src/libcamera/software_isp/swstats_cpu.cpp | 17 +++++++++-------- 13 files changed, 55 insertions(+), 35 deletions(-) diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h index 9ea0ed4db..3e879c630 100644 --- a/include/libcamera/internal/software_isp/software_isp.h +++ b/include/libcamera/internal/software_isp/software_isp.h @@ -92,7 +92,8 @@ private: void paramsBufferReady(const uint32_t paramsBufferId); bool allocateParamsBuffers(const unsigned int bufferCount); void setSensorCtrls(const ControlList &sensorControls); - void statsReady(uint32_t frame, uint32_t bufferId); + void statsReady(uint32_t frame, const uint32_t statsBufferId); + void statsProcessed(const uint32_t statsBufferId); void inputReady(FrameBuffer *input); void outputReady(FrameBuffer *output); std::unique_ptr debayer_; diff --git a/include/libcamera/internal/software_isp/swstats_cpu.h b/include/libcamera/internal/software_isp/swstats_cpu.h index 686e3d981..fd3f97cbb 100644 --- a/include/libcamera/internal/software_isp/swstats_cpu.h +++ b/include/libcamera/internal/software_isp/swstats_cpu.h @@ -55,8 +55,8 @@ public: int configure(const StreamConfiguration &inputCfg, unsigned int statsBufferCount = 1); void setWindow(const Rectangle &window); void startFrame(uint32_t frame); - void finishFrame(uint32_t frame, uint32_t bufferId); - void processFrame(uint32_t frame, uint32_t bufferId, MappedFrameBuffer &input); + void finishFrame(uint32_t frame, uint32_t statsBufferId); + void processFrame(uint32_t frame, uint32_t statsBufferId, MappedFrameBuffer &input); void processLine0(uint32_t frame, unsigned int y, const uint8_t *src[], unsigned int statsBufferIndex = 0) { diff --git a/include/libcamera/ipa/soft.mojom b/include/libcamera/ipa/soft.mojom index f348f582d..c2c5fe382 100644 --- a/include/libcamera/ipa/soft.mojom +++ b/include/libcamera/ipa/soft.mojom @@ -27,12 +27,13 @@ interface IPASoftInterface { [async] queueRequest(uint32 frame, libcamera.ControlList sensorControls); [async] computeParams(uint32 frame, uint32 paramsBufferId); [async] processStats(uint32 frame, - uint32 bufferId, + uint32 statsBufferId, libcamera.ControlList sensorControls); }; interface IPASoftEventInterface { setSensorControls(libcamera.ControlList sensorControls); + statsProcessed(uint32 statsBufferId); paramsComputed(uint32 paramsBufferId); metadataReady(uint32 frame, libcamera.ControlList metadata); }; diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp index 0212a3b52..ded75a970 100644 --- a/src/ipa/simple/soft_simple.cpp +++ b/src/ipa/simple/soft_simple.cpp @@ -298,7 +298,7 @@ void IPASoftSimple::computeParams(const uint32_t frame, } void IPASoftSimple::processStats(const uint32_t frame, - [[maybe_unused]] const uint32_t bufferId, + const uint32_t statsBufferId, const ControlList &sensorControls) { IPAFrameContext &frameContext = context_.frameContexts.get(frame); @@ -312,6 +312,7 @@ void IPASoftSimple::processStats(const uint32_t frame, for (const auto &algo : algorithms()) algo->process(context_, frame, frameContext, stats_, metadata); metadataReady.emit(frame, metadata); + statsProcessed.emit(statsBufferId); /* Sanity check */ if (!sensorControls.contains(V4L2_CID_EXPOSURE) || diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index b49f372a6..2e6bff146 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -369,7 +369,7 @@ private: void conversionInputDone(FrameBuffer *buffer); void conversionOutputDone(FrameBuffer *buffer); - void ispStatsReady(uint32_t frame, uint32_t bufferId); + void ispStatsReady(uint32_t frame, const uint32_t statsBufferId); void metadataReady(uint32_t frame, const ControlList &metadata); void setSensorControls(const ControlList &sensorControls); }; @@ -1044,9 +1044,10 @@ void SimpleCameraData::conversionOutputDone(FrameBuffer *buffer) tryCompleteRequest(request); } -void SimpleCameraData::ispStatsReady(uint32_t frame, uint32_t bufferId) +void SimpleCameraData::ispStatsReady(uint32_t frame, + const uint32_t statsBufferId) { - swIsp_->processStats(frame, bufferId, + swIsp_->processStats(frame, statsBufferId, delayedCtrls_->get(frame)); } diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp index 28e04d0df..341930e5b 100644 --- a/src/libcamera/software_isp/debayer.cpp +++ b/src/libcamera/software_isp/debayer.cpp @@ -120,9 +120,10 @@ Debayer::~Debayer() */ /** - * \fn void Debayer::process(uint32_t frame, const uint32_t paramsBufferId, FrameBuffer *input, FrameBuffer *output) + * \fn void Debayer::process(uint32_t frame, const uint32_t statsBufferId, const uint32_t paramsBufferId, FrameBuffer *input, FrameBuffer *output) * \brief Process the bayer data into the requested format * \param[in] frame The frame number + * \param[in] statsBufferId The id of the stats buffer to use * \param[in] paramsBufferId The id of the params buffer in use * \param[in] input The input buffer * \param[in] output The output buffer diff --git a/src/libcamera/software_isp/debayer.h b/src/libcamera/software_isp/debayer.h index 6cefa4c01..259261b1a 100644 --- a/src/libcamera/software_isp/debayer.h +++ b/src/libcamera/software_isp/debayer.h @@ -49,6 +49,7 @@ public: strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) = 0; virtual void process(uint32_t frame, + const uint32_t statsBufferId, const uint32_t paramsBufferId, FrameBuffer *input, FrameBuffer *output) = 0; virtual int start() { return 0; } diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp index 7813eb695..d00830960 100644 --- a/src/libcamera/software_isp/debayer_cpu.cpp +++ b/src/libcamera/software_isp/debayer_cpu.cpp @@ -974,8 +974,11 @@ void DebayerCpu::updateLookupTables(const DebayerParams *params) params_ = *params; } -void DebayerCpu::process(uint32_t frame, const uint32_t paramsBufferId, - FrameBuffer *input, FrameBuffer *output) +void DebayerCpu::process(uint32_t frame, + const uint32_t statsBufferId, + const uint32_t paramsBufferId, + FrameBuffer *input, + FrameBuffer *output) { bench_.startFrame(); @@ -1026,12 +1029,7 @@ void DebayerCpu::process(uint32_t frame, const uint32_t paramsBufferId, /* Measure before emitting signals */ bench_.finishFrame(); - /* - * Buffer ids are currently not used, so pass zeros as its parameter. - * - * \todo Pass real bufferId once stats buffer passing is changed. - */ - stats_->finishFrame(frame, 0); + stats_->finishFrame(frame, statsBufferId); outputBufferReady.emit(output); inputBufferReady.emit(input); } diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h index 56d9087da..37e45e9ea 100644 --- a/src/libcamera/software_isp/debayer_cpu.h +++ b/src/libcamera/software_isp/debayer_cpu.h @@ -45,8 +45,11 @@ public: std::vector formats(PixelFormat input) override; std::tuple strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) override; - void process(uint32_t frame, const uint32_t paramsBufferId, - FrameBuffer *input, FrameBuffer *output) override; + void process(uint32_t frame, + const uint32_t statsBufferId, + const uint32_t paramsBufferId, + FrameBuffer *input, + FrameBuffer *output) override; int start() override; void stop() override; SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) override; diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp index 77696f1e7..09e7833ed 100644 --- a/src/libcamera/software_isp/debayer_egl.cpp +++ b/src/libcamera/software_isp/debayer_egl.cpp @@ -549,8 +549,11 @@ int DebayerEGL::debayerGPU(FrameBuffer *input, FrameBuffer *output, const Debaye return 0; } -void DebayerEGL::process(uint32_t frame, const uint32_t paramsBufferId, - FrameBuffer *input, FrameBuffer *output) +void DebayerEGL::process(uint32_t frame, + [[maybe_unused]] const uint32_t statsBufferId, + const uint32_t paramsBufferId, + FrameBuffer *input, + FrameBuffer *output) { bench_.startFrame(); diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h index 43e3dcb15..36c856c10 100644 --- a/src/libcamera/software_isp/debayer_egl.h +++ b/src/libcamera/software_isp/debayer_egl.h @@ -53,8 +53,11 @@ public: std::vector formats(PixelFormat input) override; std::tuple strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) override; - void process(uint32_t frame, const uint32_t paramsBufferId, - FrameBuffer *input, FrameBuffer *output) override; + void process(uint32_t frame, + const uint32_t statsBufferId, + const uint32_t paramsBufferId, + FrameBuffer *input, + FrameBuffer *output) override; int start() override; void stop() override; diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index dbe4cc270..c44e035b8 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -171,6 +171,7 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, return; } + ipa_->statsProcessed.connect(this, &SoftwareIsp::statsProcessed); ipa_->metadataReady.connect(this, [this](uint32_t frame, const ControlList &metadata) { metadataReady.emit(frame, metadata); @@ -444,9 +445,10 @@ int SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output const uint32_t paramsBufferId = availableParams_.back(); availableParams_.pop_back(); ipa_->computeParams(frame, paramsBufferId); + const uint32_t statsBufferId = 0; debayer_->invokeMethod(&Debayer::process, - ConnectionTypeQueued, frame, paramsBufferId, - input, output); + ConnectionTypeQueued, frame, + statsBufferId, paramsBufferId, input, output); return 0; } @@ -461,9 +463,13 @@ void SoftwareIsp::setSensorCtrls(const ControlList &sensorControls) setSensorControls.emit(sensorControls); } -void SoftwareIsp::statsReady(uint32_t frame, uint32_t bufferId) +void SoftwareIsp::statsReady(uint32_t frame, const uint32_t statsBufferId) +{ + ispStatsReady.emit(frame, statsBufferId); +} + +void SoftwareIsp::statsProcessed([[maybe_unused]] const uint32_t statsBufferId) { - ispStatsReady.emit(frame, bufferId); } void SoftwareIsp::inputReady(FrameBuffer *input) diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp index fb7a5301d..0e645f7e1 100644 --- a/src/libcamera/software_isp/swstats_cpu.cpp +++ b/src/libcamera/software_isp/swstats_cpu.cpp @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * Copyright (C) 2023, Linaro Ltd - * Copyright (C) 2023, Red Hat Inc. + * Copyright (C) 2023-2026 Red Hat Inc. * * Authors: * Hans de Goede @@ -346,11 +346,12 @@ void SwStatsCpu::startFrame(uint32_t frame) /** * \brief Finish statistics calculation for the current frame * \param[in] frame The frame number - * \param[in] bufferId ID of the statistics buffer + * \param[in] statsBufferId ID of the statistics buffer * * This may only be called after a successful setWindow() call. */ -void SwStatsCpu::finishFrame(uint32_t frame, uint32_t bufferId) +void SwStatsCpu::finishFrame(uint32_t frame, + const uint32_t statsBufferId) { bool valid = frame % kStatPerNumFrames == 0; @@ -367,7 +368,7 @@ void SwStatsCpu::finishFrame(uint32_t frame, uint32_t bufferId) } sharedStats_->valid = valid; - statsReady.emit(frame, bufferId); + statsReady.emit(frame, statsBufferId); } /** @@ -538,22 +539,22 @@ void SwStatsCpu::processBayerFrame2(MappedFrameBuffer &in) /** * \brief Calculate statistics for a frame in one go * \param[in] frame The frame number - * \param[in] bufferId ID of the statistics buffer + * \param[in] statsBufferId ID of the statistics buffer * \param[in] input The frame to process * * This may only be called after a successful setWindow() call. */ -void SwStatsCpu::processFrame(uint32_t frame, uint32_t bufferId, MappedFrameBuffer &input) +void SwStatsCpu::processFrame(uint32_t frame, uint32_t statsBufferId, MappedFrameBuffer &input) { if (frame % kStatPerNumFrames) { - finishFrame(frame, bufferId); + finishFrame(frame, statsBufferId); return; } bench_.startFrame(); startFrame(frame); (this->*processFrame_)(input); - finishFrame(frame, bufferId); + finishFrame(frame, statsBufferId); bench_.finishFrame(); } From patchwork Thu Jun 4 09:51:00 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26839 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 08405C328C for ; Thu, 4 Jun 2026 09:52:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B48946374A; Thu, 4 Jun 2026 11:52:03 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="NwdleBNV"; 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 9E0846373C for ; Thu, 4 Jun 2026 11:52:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780566720; 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=mfsp11yEJ9c7syjjVm8HIxehAwxPUcdZ65gDFl06Xuk=; b=NwdleBNVWxXZeRmrAvIPXL5cTD7d1OeVhn9qDWjCI2hOs+ag74jtIRvIFRhPjfIiK/Ed30 xSlAkxaQrl9/J1LJC1cipsusnSk9Cn9nvAjrRwZ2xNKUqroV90uu9bxvXOix3Esz08fA4x wkYkT8uX5GbUiGIWm66VO2a1RMOf/ME= Received: from mx-prod-mc-05.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-475-vh6V6PanOwSPzOFGy25GTw-1; Thu, 04 Jun 2026 05:51:57 -0400 X-MC-Unique: vh6V6PanOwSPzOFGy25GTw-1 X-Mimecast-MFC-AGG-ID: vh6V6PanOwSPzOFGy25GTw_1780566716 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-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 739E5195608B; Thu, 4 Jun 2026 09:51:56 +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 ABF4430001A1; Thu, 4 Jun 2026 09:51:54 +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 14/17] libcamera: software_isp: Allocate statistics buffers Date: Thu, 4 Jun 2026 11:51:00 +0200 Message-ID: <20260604095105.68798-19-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: eh7a3t8lalC9VIZIc-eXN83M3PuSUVDXlqBar3NjyKA_1780566716 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" In order to be able to use multiple shared statistics buffers, we must allocate them. They are allocated in SoftwareIsp and passed to SwIspStats. This changes the previous behavior when the (single) shared statistics buffer was created in SwIspStats. Centralizing it to SoftwareIsp makes sharing multiple buffers with IPA easier. Currently only one of the allocated buffers is used. This will be changed once the buffers are shared with IPA in a followup patch. Signed-off-by: Milan Zamazal --- .../internal/software_isp/software_isp.h | 5 +++ .../internal/software_isp/swstats_cpu.h | 11 ++--- src/libcamera/software_isp/software_isp.cpp | 44 ++++++++++++++++--- src/libcamera/software_isp/swstats_cpu.cpp | 26 ++++++----- 4 files changed, 62 insertions(+), 24 deletions(-) diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h index 3e879c630..451596163 100644 --- a/include/libcamera/internal/software_isp/software_isp.h +++ b/include/libcamera/internal/software_isp/software_isp.h @@ -33,6 +33,7 @@ #include "libcamera/internal/pipeline_handler.h" #include "libcamera/internal/shared_mem_object.h" #include "libcamera/internal/software_isp/debayer_params.h" +#include "libcamera/internal/software_isp/swstats_cpu.h" namespace libcamera { @@ -91,6 +92,10 @@ public: private: void paramsBufferReady(const uint32_t paramsBufferId); bool allocateParamsBuffers(const unsigned int bufferCount); + std::unique_ptr allocateStatsBuffers( + const CameraManager &cm, + std::map &fdStats, + const unsigned int bufferCount); void setSensorCtrls(const ControlList &sensorControls); void statsReady(uint32_t frame, const uint32_t statsBufferId); void statsProcessed(const uint32_t statsBufferId); diff --git a/include/libcamera/internal/software_isp/swstats_cpu.h b/include/libcamera/internal/software_isp/swstats_cpu.h index fd3f97cbb..cf2f88fcb 100644 --- a/include/libcamera/internal/software_isp/swstats_cpu.h +++ b/include/libcamera/internal/software_isp/swstats_cpu.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * Copyright (C) 2023, Linaro Ltd - * Copyright (C) 2023, Red Hat Inc. + * Copyright (C) 2023-2026 Red Hat Inc. * * Authors: * Hans de Goede @@ -11,6 +11,7 @@ #pragma once +#include #include #include @@ -35,7 +36,7 @@ struct StreamConfiguration; class SwStatsCpu { public: - SwStatsCpu(const CameraManager &cm); + SwStatsCpu(const CameraManager &cm, std::unique_ptr>> sharedStats); ~SwStatsCpu() = default; /* @@ -46,9 +47,9 @@ public: */ static constexpr uint32_t kStatPerNumFrames = 4; - bool isValid() const { return sharedStats_.fd().isValid(); } + bool isValid() const { return sharedStats_->begin()->second.fd().isValid(); } - const SharedFD &getStatsFD() { return sharedStats_.fd(); } + const SharedFD &getStatsFD() { return sharedStats_->begin()->second.fd(); } const Size &patternSize() { return patternSize_; } @@ -119,7 +120,7 @@ private: unsigned int sumShift_; std::vector stats_; - SharedMemObject sharedStats_; + std::unique_ptr>> sharedStats_; Benchmark bench_; }; diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index c44e035b8..c4da647e8 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include @@ -26,7 +28,10 @@ #include "libcamera/internal/bayer_format.h" #include "libcamera/internal/framebuffer.h" +#include "libcamera/internal/ipa_manager.h" +#include "libcamera/internal/shared_mem_object.h" #include "libcamera/internal/software_isp/debayer_params.h" +#include "libcamera/internal/software_isp/swisp_stats.h" #include "debayer_cpu.h" #if HAVE_DEBAYER_EGL @@ -99,17 +104,15 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraManager &cm = *pipe->cameraManager(); - auto stats = std::make_unique(cm); - if (!stats->isValid()) { - LOG(SoftwareIsp, Error) << "Failed to create SwStatsCpu object"; - return; - } - stats->statsReady.connect(this, &SoftwareIsp::statsReady); - std::map fdParams; for (auto &[bufferId, item] : sharedParams_) fdParams[bufferId] = item.fd(); + std::map fdStats; + auto stats = allocateStatsBuffers(cm, fdStats, bufferCount); + if (!stats) + return; + #if HAVE_DEBAYER_EGL const GlobalConfiguration &configuration = cm._d()->configuration(); std::optional softISPMode = configuration.option({ "software_isp", "mode" }); @@ -203,6 +206,33 @@ bool SoftwareIsp::allocateParamsBuffers(const unsigned int bufferCount) return true; } +std::unique_ptr SoftwareIsp::allocateStatsBuffers( + const CameraManager &cm, + std::map &fdStats, + const unsigned int bufferCount) +{ + auto sharedStats = std::make_unique>>(); + for (unsigned int bufferId = 0; bufferId < bufferCount; bufferId++) { + auto shared = SharedMemObject("softIsp_stats"); + if (!shared) { + LOG(SoftwareIsp, Error) << "Failed to create shared memory for statistics"; + return nullptr; + } + if (!shared.fd().isValid()) { + LOG(SoftwareIsp, Error) << "Invalid fd of shared statistics"; + return nullptr; + } + + fdStats[bufferId] = shared.fd(); + sharedStats->emplace(bufferId, std::move(shared)); + } + + auto stats = std::make_unique(cm, std::move(sharedStats)); + stats->statsReady.connect(this, &SoftwareIsp::statsReady); + + return stats; +} + /** * \fn int SoftwareIsp::loadConfiguration([[maybe_unused]] const std::string &filename) * \brief Load a configuration from a file diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp index 0e645f7e1..e6beb9692 100644 --- a/src/libcamera/software_isp/swstats_cpu.cpp +++ b/src/libcamera/software_isp/swstats_cpu.cpp @@ -11,6 +11,8 @@ #include "libcamera/internal/software_isp/swstats_cpu.h" +#include + #include #include @@ -36,9 +38,11 @@ namespace libcamera { */ /** - * \fn SwStatsCpu::SwStatsCpu(const CameraManager &cm) + * \fn SwStatsCpu::SwStatsCpu(const CameraManager &cm, std::unique_ptr>> sharedStats) * \brief Construct a SwStatsCpu object * \param[in] cm The camera manager + * \param[in] sharedStats Mapping of statistics buffer ids to statistics + * instances that are shared with the IPA * * Creates a SwStatsCpu object and initialises shared memory for statistics * exchange. @@ -159,12 +163,9 @@ namespace libcamera { LOG_DEFINE_CATEGORY(SwStatsCpu) -SwStatsCpu::SwStatsCpu(const CameraManager &cm) - : sharedStats_("softIsp_stats"), bench_(cm, "CPU stats") +SwStatsCpu::SwStatsCpu(const CameraManager &cm, std::unique_ptr>> sharedStats) + : sharedStats_(std::move(sharedStats)), bench_(cm, "CPU stats") { - if (!sharedStats_) - LOG(SwStatsCpu, Error) - << "Failed to create shared memory for statistics"; } static constexpr unsigned int kRedYMul = 77; /* 0.299 * 256 */ @@ -354,20 +355,21 @@ void SwStatsCpu::finishFrame(uint32_t frame, const uint32_t statsBufferId) { bool valid = frame % kStatPerNumFrames == 0; + SharedMemObject &stats = sharedStats_->at(statsBufferId); if (valid) { - sharedStats_->sum_ = RGB({ 0, 0, 0 }); - sharedStats_->yHistogram.fill(0); + stats->sum_ = RGB({ 0, 0, 0 }); + stats->yHistogram.fill(0); for (const auto &s : stats_) { - sharedStats_->sum_ += s.sum_; + stats->sum_ += s.sum_; for (unsigned int j = 0; j < SwIspStats::kYHistogramSize; j++) - sharedStats_->yHistogram[j] += s.yHistogram[j]; + stats->yHistogram[j] += s.yHistogram[j]; } - sharedStats_->sum_ >>= sumShift_; + stats->sum_ >>= sumShift_; } - sharedStats_->valid = valid; + stats->valid = valid; statsReady.emit(frame, statsBufferId); } From patchwork Thu Jun 4 09:51:01 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26842 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 2467FC328C for ; Thu, 4 Jun 2026 09:52:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D18EE63753; Thu, 4 Jun 2026 11:52:12 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="aBbuX2gK"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2003B63748 for ; Thu, 4 Jun 2026 11:52:11 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780566730; 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=/pVyXU9ODvW1xeZOT50dH3wf/Nr7GfnYPORLey+RyMY=; b=aBbuX2gKqpRAS/z0SxbucRb41H/ySombrm9dA4dxWofHT1ohtHNfZsq63znuHh/cppJbE5 vtzSY4LuIgJPHP3ee8MwejvJW4QJViya/5aTpRGVH5/tWRhEz/Rbrx0ZcuV2cIJbwLMBed CWT7KbJ2mUnIeTl9eFnrT8UbkTal6mA= Received: from mx-prod-mc-05.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-288-8r9NjJUFM0ON8lE9AP7uUA-1; Thu, 04 Jun 2026 05:52:04 -0400 X-MC-Unique: 8r9NjJUFM0ON8lE9AP7uUA-1 X-Mimecast-MFC-AGG-ID: 8r9NjJUFM0ON8lE9AP7uUA_1780566720 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-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 6707F19560B5; Thu, 4 Jun 2026 09:51:58 +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 D5B4E30001A1; Thu, 4 Jun 2026 09:51:56 +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 15/17] libcamera: software_isp: Track statistics buffers Date: Thu, 4 Jun 2026 11:51:01 +0200 Message-ID: <20260604095105.68798-20-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: LOKtckIONx6JRPX8WUnCzWaKpwcew5WxK_qEr9jeEUM_1780566720 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" As a preparation for passing the shared statistics buffers to IPA, this patch introduces tracking statistics buffer ids. SofwareIsp::availableStats_ is a vector of ids of the buffers available for use. When a fresh statistics buffer is needed, its id is retrieved from there and once the buffer is no longer needed, it's put back there, in a method invoked by a signal. This is similar to what the hardware pipelines do. We use buffers' file descriptors as buffer ids. The statistics buffers will be shared with the IPA, SwIspStats and debayering and we need their common identification everywhere. The buffer file descriptors are shared unchanged so they can be used for the purpose, avoiding a need to pass a special mapping to the IPA and debayering on initialization. Note that the statistics buffer id is still actually unused, this will be changed once the buffers are shared with the IPA. Signed-off-by: Milan Zamazal --- .../libcamera/internal/software_isp/software_isp.h | 1 + src/libcamera/software_isp/debayer_egl.cpp | 4 ++-- src/libcamera/software_isp/software_isp.cpp | 14 +++++++++++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h index 451596163..24eeaeb86 100644 --- a/include/libcamera/internal/software_isp/software_isp.h +++ b/include/libcamera/internal/software_isp/software_isp.h @@ -105,6 +105,7 @@ private: Thread ispWorkerThread_; std::map> sharedParams_; std::vector availableParams_; + std::vector availableStats_; DmaBufAllocator dmaHeap_; bool ccmEnabled_; diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp index 09e7833ed..f43428432 100644 --- a/src/libcamera/software_isp/debayer_egl.cpp +++ b/src/libcamera/software_isp/debayer_egl.cpp @@ -550,7 +550,7 @@ int DebayerEGL::debayerGPU(FrameBuffer *input, FrameBuffer *output, const Debaye } void DebayerEGL::process(uint32_t frame, - [[maybe_unused]] const uint32_t statsBufferId, + const uint32_t statsBufferId, const uint32_t paramsBufferId, FrameBuffer *input, FrameBuffer *output) @@ -590,7 +590,7 @@ void DebayerEGL::process(uint32_t frame, inDmaSyncer.emplace(input->planes()[0].fd, DmaSyncer::SyncType::Read); inMapped.emplace(input, MappedFrameBuffer::MapFlag::Read); } - stats_->processFrame(frame, 0, inMapped.value()); + stats_->processFrame(frame, statsBufferId, inMapped.value()); } inDmaSyncer.reset(); diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index c4da647e8..2a019e6bc 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -225,6 +225,7 @@ std::unique_ptr SoftwareIsp::allocateStatsBuffers( fdStats[bufferId] = shared.fd(); sharedStats->emplace(bufferId, std::move(shared)); + availableStats_.push_back(bufferId); } auto stats = std::make_unique(cm, std::move(sharedStats)); @@ -463,7 +464,8 @@ void SoftwareIsp::stop() * \param[in] frame The frame number * \param[in] input The input framebuffer * \param[out] output The framebuffer to write the processed frame to - * \return 0 on success, -EAGAIN if a parameter buffer underrun occurs + * \return 0 on success, -EAGAIN if a parameter or statistics buffer underrun + * occurs */ int SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output) { @@ -471,11 +473,16 @@ int SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output LOG(SoftwareIsp, Error) << "Parameters buffer underrun"; return -EAGAIN; } + if (availableStats_.empty()) { + LOG(SoftwareIsp, Error) << "Statistics buffer underrun"; + return -EAGAIN; + } const uint32_t paramsBufferId = availableParams_.back(); availableParams_.pop_back(); + const uint32_t statsBufferId = availableStats_.back(); + availableStats_.pop_back(); ipa_->computeParams(frame, paramsBufferId); - const uint32_t statsBufferId = 0; debayer_->invokeMethod(&Debayer::process, ConnectionTypeQueued, frame, statsBufferId, paramsBufferId, input, output); @@ -498,8 +505,9 @@ void SoftwareIsp::statsReady(uint32_t frame, const uint32_t statsBufferId) ispStatsReady.emit(frame, statsBufferId); } -void SoftwareIsp::statsProcessed([[maybe_unused]] const uint32_t statsBufferId) +void SoftwareIsp::statsProcessed(const uint32_t statsBufferId) { + availableStats_.push_back(statsBufferId); } void SoftwareIsp::inputReady(FrameBuffer *input) From patchwork Thu Jun 4 09:51:02 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26840 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 A2F22C328C for ; Thu, 4 Jun 2026 09:52:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5A2096374E; Thu, 4 Jun 2026 11:52:08 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="DKFdrE9i"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 238FF63282 for ; Thu, 4 Jun 2026 11:52:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780566726; 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=BP/CI+Knz7wRLzbuGBA2ELDt8uLx0ag7k7fD9ZXPSE4=; b=DKFdrE9il2Y01leDVR7yrFPikvR7Qka741LcD41bfPNLZ1X0gMvWKiexLx3+rQbtTtLO4S XlP7mPrO30BwevGSQK0G+Or8gD2wY2Q7quG38j26V21XAAOjPOVFlUfVpDvfD3JCq58D2Q W4JWb4+HDWvxT+CWM52NtK+kKilXj7g= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-322-HH73T_iWOCaCmv-zWXH0BQ-1; Thu, 04 Jun 2026 05:52:01 -0400 X-MC-Unique: HH73T_iWOCaCmv-zWXH0BQ-1 X-Mimecast-MFC-AGG-ID: HH73T_iWOCaCmv-zWXH0BQ_1780566720 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-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 597431800350; Thu, 4 Jun 2026 09:52:00 +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 DC40C30001A1; Thu, 4 Jun 2026 09:51:58 +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 16/17] libcamera: software_isp: Share statistics buffers with IPA Date: Thu, 4 Jun 2026 11:51:02 +0200 Message-ID: <20260604095105.68798-21-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: qYXt8pm0NZ8OEn2gnnZopTQE9mH6pVf7ODnwoweGqlM_1780566720 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" The last step to complete statistics buffer sharing is to pass all the allocated statistics buffers to the IPA and refer to them using their ids. This allows to remove the buffer copying in SwStatsCpu::finishFrame. We can also remove now the methods that served for handling the former single buffer shared between debayering and IPA. Signed-off-by: Milan Zamazal --- .../internal/software_isp/swstats_cpu.h | 5 +-- include/libcamera/ipa/soft.mojom | 2 +- src/ipa/simple/soft_simple.cpp | 42 +++++++++---------- src/libcamera/software_isp/debayer.cpp | 10 ----- src/libcamera/software_isp/debayer.h | 2 - src/libcamera/software_isp/debayer_cpu.h | 1 - src/libcamera/software_isp/debayer_egl.h | 2 - src/libcamera/software_isp/software_isp.cpp | 2 +- src/libcamera/software_isp/swstats_cpu.cpp | 28 ++++--------- 9 files changed, 31 insertions(+), 63 deletions(-) diff --git a/include/libcamera/internal/software_isp/swstats_cpu.h b/include/libcamera/internal/software_isp/swstats_cpu.h index cf2f88fcb..74d70bd20 100644 --- a/include/libcamera/internal/software_isp/swstats_cpu.h +++ b/include/libcamera/internal/software_isp/swstats_cpu.h @@ -12,6 +12,7 @@ #pragma once #include +#include #include #include @@ -47,10 +48,6 @@ public: */ static constexpr uint32_t kStatPerNumFrames = 4; - bool isValid() const { return sharedStats_->begin()->second.fd().isValid(); } - - const SharedFD &getStatsFD() { return sharedStats_->begin()->second.fd(); } - const Size &patternSize() { return patternSize_; } int configure(const StreamConfiguration &inputCfg, unsigned int statsBufferCount = 1); diff --git a/include/libcamera/ipa/soft.mojom b/include/libcamera/ipa/soft.mojom index c2c5fe382..a3739de00 100644 --- a/include/libcamera/ipa/soft.mojom +++ b/include/libcamera/ipa/soft.mojom @@ -14,7 +14,7 @@ struct IPAConfigInfo { interface IPASoftInterface { init(libcamera.IPASettings settings, - libcamera.SharedFD fdStats, + map fdStats, map fdParams, libcamera.IPACameraSensorInfo sensorInfo, libcamera.ControlInfoMap sensorControls) diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp index ded75a970..ff585b75e 100644 --- a/src/ipa/simple/soft_simple.cpp +++ b/src/ipa/simple/soft_simple.cpp @@ -52,7 +52,7 @@ public: ~IPASoftSimple(); int init(const IPASettings &settings, - const SharedFD &fdStats, + const std::map &fdStats, const std::map &fdParams, const IPACameraSensorInfo &sensorInfo, const ControlInfoMap &sensorControls, @@ -76,7 +76,7 @@ private: void updateExposure(double exposureMSV); std::map paramsBuffers_; - SwIspStats *stats_; + std::map statsBuffers_; std::unique_ptr camHelper_; ControlInfoMap sensorInfoMap_; @@ -86,14 +86,14 @@ private: IPASoftSimple::~IPASoftSimple() { - if (stats_) - munmap(stats_, sizeof(SwIspStats)); + for (auto &item : statsBuffers_) + munmap(item.second, sizeof(SwIspStats)); for (auto &item : paramsBuffers_) munmap(item.second, sizeof(DebayerParams)); } int IPASoftSimple::init(const IPASettings &settings, - const SharedFD &fdStats, + const std::map &fdStats, const std::map &fdParams, const IPACameraSensorInfo &sensorInfo, const ControlInfoMap &sensorControls, @@ -137,11 +137,20 @@ int IPASoftSimple::init(const IPASettings &settings, return ret; *ccmEnabled = context_.ccmEnabled; - stats_ = nullptr; + for (auto &[bufferId, sharedFd] : fdStats) { + if (!sharedFd.isValid()) { + LOG(IPASoft, Error) << "Invalid Statistics handle"; + return -ENODEV; + } + + void *mem = mmap(nullptr, sizeof(SwIspStats), PROT_READ, + MAP_SHARED, sharedFd.get(), 0); + if (mem == MAP_FAILED) { + LOG(IPASoft, Error) << "Unable to map Statistics"; + return -errno; + } - if (!fdStats.isValid()) { - LOG(IPASoft, Error) << "Invalid Statistics handle"; - return -ENODEV; + statsBuffers_[bufferId] = static_cast(mem); } for (auto &[bufferId, sharedFd] : fdParams) { @@ -166,17 +175,6 @@ int IPASoftSimple::init(const IPASettings &settings, paramsBuffers_[bufferId] = params; } - { - void *mem = mmap(nullptr, sizeof(SwIspStats), PROT_READ, - MAP_SHARED, fdStats.get(), 0); - if (mem == MAP_FAILED) { - LOG(IPASoft, Error) << "Unable to map Statistics"; - return -errno; - } - - stats_ = static_cast(mem); - } - ControlInfoMap::Map ctrlMap = context_.ctrlMap; *ipaControls = ControlInfoMap(std::move(ctrlMap), controls::controls); @@ -303,6 +301,8 @@ void IPASoftSimple::processStats(const uint32_t frame, { IPAFrameContext &frameContext = context_.frameContexts.get(frame); + const SwIspStats *stats = statsBuffers_.at(statsBufferId); + frameContext.sensor.exposure = sensorControls.get(V4L2_CID_EXPOSURE).get(); int32_t again = sensorControls.get(V4L2_CID_ANALOGUE_GAIN).get(); @@ -310,7 +310,7 @@ void IPASoftSimple::processStats(const uint32_t frame, ControlList metadata(controls::controls); for (const auto &algo : algorithms()) - algo->process(context_, frame, frameContext, stats_, metadata); + algo->process(context_, frame, frameContext, stats, metadata); metadataReady.emit(frame, metadata); statsProcessed.emit(statsBufferId); diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp index 341930e5b..533311200 100644 --- a/src/libcamera/software_isp/debayer.cpp +++ b/src/libcamera/software_isp/debayer.cpp @@ -138,16 +138,6 @@ Debayer::~Debayer() * \return The valid size ranges or an empty range if there are none */ -/** - * \fn const SharedFD &Debayer::getStatsFD() - * \brief Get the file descriptor for the statistics - * - * This file descriptor provides access to the output statistics buffer - * associated with the current debayering process. - * - * \return The file descriptor pointing to the statistics data - */ - /** * \fn unsigned int Debayer::frameSize() * \brief Get the output frame size diff --git a/src/libcamera/software_isp/debayer.h b/src/libcamera/software_isp/debayer.h index 259261b1a..b0a1ed151 100644 --- a/src/libcamera/software_isp/debayer.h +++ b/src/libcamera/software_isp/debayer.h @@ -57,8 +57,6 @@ public: virtual SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) = 0; - virtual const SharedFD &getStatsFD() = 0; - unsigned int frameSize() { return outputConfig_.frameSize; } Signal inputBufferReady; diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h index 37e45e9ea..62b43c4a9 100644 --- a/src/libcamera/software_isp/debayer_cpu.h +++ b/src/libcamera/software_isp/debayer_cpu.h @@ -53,7 +53,6 @@ public: int start() override; void stop() override; SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) override; - const SharedFD &getStatsFD() override { return stats_->getStatsFD(); } private: friend class DebayerCpuThread; diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h index 36c856c10..d7d1bc618 100644 --- a/src/libcamera/software_isp/debayer_egl.h +++ b/src/libcamera/software_isp/debayer_egl.h @@ -61,8 +61,6 @@ public: int start() override; void stop() override; - const SharedFD &getStatsFD() override { return stats_->getStatsFD(); } - SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) override; private: diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index 2a019e6bc..020226585 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -162,7 +162,7 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, } ret = ipa_->init(IPASettings{ ipaTuningFile, sensor->model() }, - debayer_->getStatsFD(), + fdStats, fdParams, sensorInfo, sensor->controls(), diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp index e6beb9692..0269e8249 100644 --- a/src/libcamera/software_isp/swstats_cpu.cpp +++ b/src/libcamera/software_isp/swstats_cpu.cpp @@ -48,20 +48,6 @@ namespace libcamera { * exchange. */ -/** - * \fn bool SwStatsCpu::isValid() const - * \brief Gets whether the statistics object is valid - * - * \return True if it's valid, false otherwise - */ - -/** - * \fn const SharedFD &SwStatsCpu::getStatsFD() - * \brief Get the file descriptor for the statistics - * - * \return The file descriptor - */ - /** * \fn const Size &SwStatsCpu::patternSize() * \brief Get the pattern size @@ -355,21 +341,21 @@ void SwStatsCpu::finishFrame(uint32_t frame, const uint32_t statsBufferId) { bool valid = frame % kStatPerNumFrames == 0; - SharedMemObject &stats = sharedStats_->at(statsBufferId); + SharedMemObject &shared = sharedStats_->at(statsBufferId); if (valid) { - stats->sum_ = RGB({ 0, 0, 0 }); - stats->yHistogram.fill(0); + shared->sum_ = RGB({ 0, 0, 0 }); + shared->yHistogram.fill(0); for (const auto &s : stats_) { - stats->sum_ += s.sum_; + shared->sum_ += s.sum_; for (unsigned int j = 0; j < SwIspStats::kYHistogramSize; j++) - stats->yHistogram[j] += s.yHistogram[j]; + shared->yHistogram[j] += s.yHistogram[j]; } - stats->sum_ >>= sumShift_; + shared->sum_ >>= sumShift_; } - stats->valid = valid; + shared->valid = valid; statsReady.emit(frame, statsBufferId); } From patchwork Thu Jun 4 09:51:03 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26841 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 7A6E2C328C for ; Thu, 4 Jun 2026 09:52:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 32CC963753; Thu, 4 Jun 2026 11:52:10 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="d4lqvweU"; 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 0674B63748 for ; Thu, 4 Jun 2026 11:52:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780566727; 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=PUQ3rffI/BqzXYrzqqZr/7ddTTGPMDReNYc7sL2Z3O0=; b=d4lqvweUN7pmDs22Ko6Tvb+IsVLdIJeOsHuSFvF3VrEbkLHDy4l+64lG4tsW/Iy1e93hsF BxXVSGMBioywU5MRMjUvkpFtmAlFLqCBJEZh57PWVEda0sfvLUjleaFv4aPJnkOUu3/33o Prj/eJ9tfnilLjrKx6xpZbPP1/wBRT8= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-507-yoXpOossPjSd_HRvjn_Row-1; Thu, 04 Jun 2026 05:52:03 -0400 X-MC-Unique: yoXpOossPjSd_HRvjn_Row-1 X-Mimecast-MFC-AGG-ID: yoXpOossPjSd_HRvjn_Row_1780566722 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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 7F70E1800473; Thu, 4 Jun 2026 09:52:02 +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 CF04230001A1; Thu, 4 Jun 2026 09:52:00 +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 17/17] libcamera: software_isp: Remove stats-sharing TODO item Date: Thu, 4 Jun 2026 11:51:03 +0200 Message-ID: <20260604095105.68798-22-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: e657CyJQiX53mlVZ6gZFxcNDHc24xn64rPx4sFnbN6A_1780566722 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" Shared per-frame statistics buffers are implemented, we can remove TODO #2. Signed-off-by: Milan Zamazal --- src/libcamera/software_isp/TODO.md | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/src/libcamera/software_isp/TODO.md b/src/libcamera/software_isp/TODO.md index f4e5190e0..dcdfd109f 100644 --- a/src/libcamera/software_isp/TODO.md +++ b/src/libcamera/software_isp/TODO.md @@ -10,33 +10,6 @@ The TODO items in this section gather comments from patch review that were not deemed to require being addressed right away. The text in block quotes is copied directly from e-mail review. -### Reconsider stats sharing - -``` ->>> +void SwStatsCpu::finishFrame(void) ->>> +{ ->>> + *sharedStats_ = stats_; ->> ->> Is it more efficient to copy the stats instead of operating directly on ->> the shared memory ? -> -> I inherited doing things this way from Andrey. I kept this because -> we don't really have any synchronization with the IPA reading this. -> -> So the idea is to only touch this when the next set of statistics -> is ready since we don't know when the IPA is done with accessing -> the previous set of statistics ... -> -> This is both something which seems mostly a theoretic problem, -> yet also definitely something which I think we need to fix. -> -> Maybe use a ringbuffer of stats buffers and pass the index into -> the ringbuffer to the emit signal ? - -That would match how we deal with hardware ISPs, and I think that's a -good idea. It will help decoupling the processing side from the IPA. -``` - ### Remove statsReady signal ```