From patchwork Mon Jun 8 15:03:30 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26845 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 AAC52C328C for ; Mon, 8 Jun 2026 15:04:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E0D2461EE7; Mon, 8 Jun 2026 17:04:07 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="H3iNDc5Y"; 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 93EA361E78 for ; Mon, 8 Jun 2026 17:04:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780931044; 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=j6P8vCKDoZyku2m3y1U6lCT63YwFL275jeehKbTTEc4=; b=H3iNDc5YfQ5mlXJcFscoMFvCsOINBuwEtmZ8PzjtEwL1abotBtyFYX6wv/7EGplTRYkijl niBaYH/sPYpO0zTRYafSF2EfkFBQK99wQ5Od6JcIpHPn/WMUuRbYJgDopl9yoQ3iOepRso y88HBGPGOr6W3RpeJLVduBDKj+2EPrQ= 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-653-HbXtsfFcPemyCgOzWJXW4g-1; Mon, 08 Jun 2026 11:04:00 -0400 X-MC-Unique: HbXtsfFcPemyCgOzWJXW4g-1 X-Mimecast-MFC-AGG-ID: HbXtsfFcPemyCgOzWJXW4g_1780931039 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (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 3F87B1801BE3; Mon, 8 Jun 2026 15:03:59 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.51]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 587D11800351; Mon, 8 Jun 2026 15:03:56 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , johannes.goede@oss.qualcomm.com Subject: [RFC PATCH v4 01/17] libcamera: software_isp: Fix misplacement in SoftwareIsp docstring Date: Mon, 8 Jun 2026 17:03:30 +0200 Message-ID: <20260608150349.134371-2-mzamazal@redhat.com> In-Reply-To: <20260608150349.134371-1-mzamazal@redhat.com> References: <20260608150349.134371-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 7fbWwvm7cSaGGHj-lwM65cL-GAri5EgxR49W-xvSC1A_1780931039 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. Reviewed-by: Kieran Bingham 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 Mon Jun 8 15:03:31 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26847 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 4A189C328C for ; Mon, 8 Jun 2026 15:04:14 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 52EF061EFB; Mon, 8 Jun 2026 17:04:13 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="d8XSPOX3"; 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 726D961ED7 for ; Mon, 8 Jun 2026 17:04:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780931048; 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=fW+na+Fqr4LPOHgft2h50ooOqd8NAiIWylxyllqdgtM=; b=d8XSPOX3a369gp5bvE9KZNnUmM0LT0Brvjgd3bFSZfN0v6HALeY279hlz4VEk1izqRhYst uaz/qg1fTsdJbgcdHI70LaqASFgcRkWCMAp0uPTWVFut44zXs2Tjs0jAv7WdWFZwhSu2Lr rfJ13IDuZYWnfKbxPmJWp9mgss5w2YM= 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-471-UKgfMssBNzCqW_vYcNCOMg-1; Mon, 08 Jun 2026 11:04:03 -0400 X-MC-Unique: UKgfMssBNzCqW_vYcNCOMg-1 X-Mimecast-MFC-AGG-ID: UKgfMssBNzCqW_vYcNCOMg_1780931042 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (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 B20E81954B2C; Mon, 8 Jun 2026 15:04:01 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.51]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D2E6D1800361; Mon, 8 Jun 2026 15:03:59 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , johannes.goede@oss.qualcomm.com Subject: [RFC PATCH v4 02/17] libcamera: ipa: simple: Rename setIspParams to paramsComputed Date: Mon, 8 Jun 2026 17:03:31 +0200 Message-ID: <20260608150349.134371-3-mzamazal@redhat.com> In-Reply-To: <20260608150349.134371-1-mzamazal@redhat.com> References: <20260608150349.134371-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: Haf3ULw-1rbpJ04_7dYzfVEs6FIpZrRKHVQgUPVDSvc_1780931042 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. Reviewed-by: Kieran Bingham 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 Mon Jun 8 15:03:32 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26846 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 79C26C328C for ; Mon, 8 Jun 2026 15:04:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 298FF61EEF; Mon, 8 Jun 2026 17:04:12 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="WPTXrhMZ"; 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 4570D61EF3 for ; Mon, 8 Jun 2026 17:04:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780931047; 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=k9NvvxEehqT51Hh8ug4frNDBv4XbQcdkjJmClu3+nfA=; b=WPTXrhMZV3E179iNz/1GeSYlalIg2dq2gbwp/Xpesbtj4PG3SyxBsQi6NyFbfoXwu+hRsC gJhtsRNJ0+1PHTFN4mCpTv6kgAKZd+YngeTCwszZ1X4SmK8U+N6a3hHl7W7G0UrP3EO3kc TKnwZ1csGJqcawUixQhXQQZ+qdKOW0E= 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-427-xge5s6A9NSW2XwNl5lxtKA-1; Mon, 08 Jun 2026 11:04:05 -0400 X-MC-Unique: xge5s6A9NSW2XwNl5lxtKA-1 X-Mimecast-MFC-AGG-ID: xge5s6A9NSW2XwNl5lxtKA_1780931044 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (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 44E90195609F; Mon, 8 Jun 2026 15:04:04 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.51]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 339801800351; Mon, 8 Jun 2026 15:04:02 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , johannes.goede@oss.qualcomm.com Subject: [RFC PATCH v4 03/17] libcamera: software_isp: Queue the input buffer per each output Date: Mon, 8 Jun 2026 17:03:32 +0200 Message-ID: <20260608150349.134371-4-mzamazal@redhat.com> In-Reply-To: <20260608150349.134371-1-mzamazal@redhat.com> References: <20260608150349.134371-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: lBiNApSFk2MKLxdEWucg6isZd3qNWXt2xbgTubZXYU0_1780931044 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" Multiple outputs are not supported, but if they were, the input buffer should be queued for each of them because each output buffer processing emits inputBufferReady. Currently, with a single output, it doesn't change anything. Reviewed-by: Kieran Bingham Signed-off-by: Milan Zamazal --- src/libcamera/software_isp/software_isp.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index f5b44f4e5..f17f1ca1f 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -342,9 +342,8 @@ int SoftwareIsp::queueBuffers(uint32_t frame, FrameBuffer *input, return -EINVAL; } - queuedInputBuffers_.push_back(input); - for (const auto &[stream, buffer] : outputs) { + queuedInputBuffers_.push_back(input); queuedOutputBuffers_.push_back(buffer); process(frame, input, buffer); } From patchwork Mon Jun 8 15:03:33 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26849 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 9C44FC328C for ; Mon, 8 Jun 2026 15:04:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1CAFA61EF3; Mon, 8 Jun 2026 17:04:19 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="HbS6sdxd"; 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 4FCE861EF6 for ; Mon, 8 Jun 2026 17:04:14 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780931053; 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=HbS6sdxdvTQ5A+aSUskGMgsAewLPJ9B5KmHvW6Aq7TI/l4SXnAWYX21cz0V6YFPBHKRrUh z/lZ48DM11QqnaiV6lWJjFitZnPuZ8F9T5LP9rLhR/WpLWKQrEl38L7962+nG2vxlzdsCu 579q9X2hvkUGugUAFlmgumbPXs/X0Xw= 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-286-1jf0U38kM5WMeqrQby5g2A-1; Mon, 08 Jun 2026 11:04:08 -0400 X-MC-Unique: 1jf0U38kM5WMeqrQby5g2A-1 X-Mimecast-MFC-AGG-ID: 1jf0U38kM5WMeqrQby5g2A_1780931046 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (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 B33591955F03; Mon, 8 Jun 2026 15:04:06 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.51]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D384C18005B5; Mon, 8 Jun 2026 15:04:04 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , johannes.goede@oss.qualcomm.com Subject: [RFC PATCH v4 04/17] libcamera: software_isp: Handle queueBuffers failure Date: Mon, 8 Jun 2026 17:03:33 +0200 Message-ID: <20260608150349.134371-5-mzamazal@redhat.com> In-Reply-To: <20260608150349.134371-1-mzamazal@redhat.com> References: <20260608150349.134371-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: StRpZu8WNKayBTfgJTmhr2V8N1786L2W0__T5JVbLa4_1780931046 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 Mon Jun 8 15:03:34 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26848 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 DDF70C328C for ; Mon, 8 Jun 2026 15:04:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 99C4261EF7; Mon, 8 Jun 2026 17:04:17 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="Lu1armHg"; 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 B73C461EF3 for ; Mon, 8 Jun 2026 17:04:12 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780931051; 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=aQMa1+3DbfdEOVfC3pqw28lU1qTF8B1OPAYkVJ306ds=; b=Lu1armHgOeJ2p3nGn74GfNudKq4fPW3iukmTjnCB6CV2sRiH9jaSqg6oTtIWcskP7/xWDQ jbjOu/J8h7bDohlci13Lu6Mkc+DP3dd95PtWCj694Gu66f652b8HJQ6gi9qkVP6bBmkxJO oNSYkVCaREe5AifOksHLFRtVv61bphc= 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-649-yv2qlJPSMRKBwJ49rCIImA-1; Mon, 08 Jun 2026 11:04:10 -0400 X-MC-Unique: yv2qlJPSMRKBwJ49rCIImA-1 X-Mimecast-MFC-AGG-ID: yv2qlJPSMRKBwJ49rCIImA_1780931049 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (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 3DAA41955DB4; Mon, 8 Jun 2026 15:04:09 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.51]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 4FF511800351; Mon, 8 Jun 2026 15:04:07 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , johannes.goede@oss.qualcomm.com Subject: [RFC PATCH v4 05/17] libcamera: software_isp: Introduce arguments for parameters buffers Date: Mon, 8 Jun 2026 17:03:34 +0200 Message-ID: <20260608150349.134371-6-mzamazal@redhat.com> In-Reply-To: <20260608150349.134371-1-mzamazal@redhat.com> References: <20260608150349.134371-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: Bd6IfrXkMWqbAuzgVUlzt7NvrlUgXK0nluHtUZVRqmA_1780931049 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::paramsComputed, 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. Reviewed-by: Kieran Bingham 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 d2596d32b..21ce22c0d 100644 --- a/src/libcamera/software_isp/debayer_cpu.cpp +++ b/src/libcamera/software_isp/debayer_cpu.cpp @@ -1069,7 +1069,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(); @@ -1079,6 +1081,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 5281c65cb..9f8389623 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 8e52b45ae..e3429f47f 100644 --- a/src/libcamera/software_isp/debayer_egl.cpp +++ b/src/libcamera/software_isp/debayer_egl.cpp @@ -555,7 +555,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(); @@ -572,6 +574,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; @@ -602,6 +605,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 Mon Jun 8 15:03:35 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26860 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 D768FC328C for ; Mon, 8 Jun 2026 15:04:45 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8A22961F41; Mon, 8 Jun 2026 17:04:45 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="SZEy+pq3"; 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 8B34B61F11 for ; Mon, 8 Jun 2026 17:04:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780931082; 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=QLC/OakYvH/Ux84MQPiYzTVtOWfPZGqFARTI2h3ydrQ=; b=SZEy+pq3isWjQeAqlIaK1JfBIg/+vSx1wiQWqa+qxJOus0GkTvPVrSS5CpTNJftdWydJ38 5J5/ZQRSntERzfnqe0SNhdYYqNIT8KamE5enHcowdXxf6RiNPeDUWM4i1G1kcxPwu3Kqnx O5A4kAAAVLqDXG3wAT5fkT6YMR0uewk= 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-645-JBiF0lNVO9iGb3BvEZvYUA-1; Mon, 08 Jun 2026 11:04:19 -0400 X-MC-Unique: JBiF0lNVO9iGb3BvEZvYUA-1 X-Mimecast-MFC-AGG-ID: JBiF0lNVO9iGb3BvEZvYUA_1780931051 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (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 9F1701955DA0; Mon, 8 Jun 2026 15:04:11 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.51]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D0CA71800351; Mon, 8 Jun 2026 15:04:09 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , johannes.goede@oss.qualcomm.com Subject: [RFC PATCH v4 06/17] libcamera: software_isp: Separate allocation of the parameters buffer Date: Mon, 8 Jun 2026 17:03:35 +0200 Message-ID: <20260608150349.134371-7-mzamazal@redhat.com> In-Reply-To: <20260608150349.134371-1-mzamazal@redhat.com> References: <20260608150349.134371-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: L6RtnG1LSyELHtzypGTZ4mUIFkq07_VYMMCdthU_yWQ_1780931051 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" There will be some additions to that code in followup patches and let's not blow the code in SoftwareIsp constructor even more. Reviewed-by: Kieran Bingham Signed-off-by: Milan Zamazal --- .../internal/software_isp/software_isp.h | 1 + src/libcamera/software_isp/software_isp.cpp | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h index 85c9059e2..f97d25f0a 100644 --- a/include/libcamera/internal/software_isp/software_isp.h +++ b/include/libcamera/internal/software_isp/software_isp.h @@ -90,6 +90,7 @@ public: private: void saveIspParams(const uint32_t paramsBufferId); void paramsBufferReady(const uint32_t paramsBufferId); + bool allocateParamsBuffers(); void setSensorCtrls(const ControlList &sensorControls); void statsReady(uint32_t frame, uint32_t bufferId); void inputReady(FrameBuffer *input); diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index a1200e924..774f2bf75 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -90,12 +90,8 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, LOG(SoftwareIsp, Error) << "Failed to create DmaBufAllocator object"; return; } - - sharedParams_ = SharedMemObject("softIsp_params"); - if (!sharedParams_) { - LOG(SoftwareIsp, Error) << "Failed to create shared memory for parameters"; + if (!allocateParamsBuffers()) return; - } const CameraManager &cm = *pipe->cameraManager(); @@ -181,6 +177,17 @@ SoftwareIsp::~SoftwareIsp() debayer_.reset(); } +bool SoftwareIsp::allocateParamsBuffers() +{ + sharedParams_ = SharedMemObject("softIsp_params"); + if (!sharedParams_) { + LOG(SoftwareIsp, Error) << "Failed to create shared memory for parameters"; + return false; + } + + return true; +} + /** * \fn int SoftwareIsp::loadConfiguration([[maybe_unused]] const std::string &filename) * \brief Load a configuration from a file From patchwork Mon Jun 8 15:03:36 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26856 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 36A8EC328C for ; Mon, 8 Jun 2026 15:04:38 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C564461F1B; Mon, 8 Jun 2026 17:04:37 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="J1peoxoI"; 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 03D7D61F00 for ; Mon, 8 Jun 2026 17:04:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780931073; 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=J1peoxoIdVpb77axm5R78YtknLFSXARwYhHPS9nr2m6Bu5WP7i2kh0q59oX1W91HUykSIs VZ9UIKwasnJcb3a3BwZ5EH9e0NOGdMrtl74qDRo+lfnOg/TzzcfKNcUHNyw38Nr3aDYdOR KjfB98nOY+yYcuXmL4w8Y5X3vKpNZ/E= 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-103-Luh4S9tlNRaod2-3MdTlzQ-1; Mon, 08 Jun 2026 11:04:15 -0400 X-MC-Unique: Luh4S9tlNRaod2-3MdTlzQ-1 X-Mimecast-MFC-AGG-ID: Luh4S9tlNRaod2-3MdTlzQ_1780931054 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (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 DBEBF1800847; Mon, 8 Jun 2026 15:04:13 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.51]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 3A5CD1800351; Mon, 8 Jun 2026 15:04:11 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , johannes.goede@oss.qualcomm.com Subject: [RFC PATCH v4 07/17] libcamera: software_isp: Track unused parameters buffers Date: Mon, 8 Jun 2026 17:03:36 +0200 Message-ID: <20260608150349.134371-8-mzamazal@redhat.com> In-Reply-To: <20260608150349.134371-1-mzamazal@redhat.com> References: <20260608150349.134371-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: JYyxR0JUegyBuU0SEZPdui3z3RItDRfLTN5VaBSjR5g_1780931054 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 Mon Jun 8 15:03:37 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26850 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 4EBF6C328C for ; Mon, 8 Jun 2026 15:04:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0A79A61EFA; Mon, 8 Jun 2026 17:04:22 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="cW6feOb+"; 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 CDF1B61EFA for ; Mon, 8 Jun 2026 17:04:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780931058; 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=cW6feOb+GCoIjhDqjquhfQQS952r4UnEkmVcsDE60sGnKQOOCssBGm9ar1jW620dG1CTgP EI14Hz6YTwpQfdb7BFG7Z9lF9yzrQY3ym4nIPWEYp3T/05pngKr6RWgCgnKJ+whRDdW1zL BsFCIL4lr40yVd4ScelFp5XcKmEg5uY= 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-654-K5Vk8R6HO7WRHEyOyk5MsA-1; Mon, 08 Jun 2026 11:04:17 -0400 X-MC-Unique: K5Vk8R6HO7WRHEyOyk5MsA-1 X-Mimecast-MFC-AGG-ID: K5Vk8R6HO7WRHEyOyk5MsA_1780931056 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (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 5445A1955D71; Mon, 8 Jun 2026 15:04:16 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.51]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 6103A1800361; Mon, 8 Jun 2026 15:04:14 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , johannes.goede@oss.qualcomm.com Subject: [RFC PATCH v4 08/17] libcamera: software_isp: Allocation of multiple params buffers Date: Mon, 8 Jun 2026 17:03:37 +0200 Message-ID: <20260608150349.134371-9-mzamazal@redhat.com> In-Reply-To: <20260608150349.134371-1-mzamazal@redhat.com> References: <20260608150349.134371-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: IsVCLRFtl-VDg0onzuQ__V_4Sk18p3iyhZxWH-c1WS0_1780931056 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 Mon Jun 8 15:03:38 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26851 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 D319DC328C for ; Mon, 8 Jun 2026 15:04:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 96AA461F00; Mon, 8 Jun 2026 17:04:28 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="R8ukTjg2"; 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 7D87E61EE7 for ; Mon, 8 Jun 2026 17:04:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780931065; 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=R8ukTjg2eJk0oUvlqbh3uPScbwtNmveg+kdCI89xBRFS1VcokGBuhP/OnTZsflVtAPQWtj 26tw+Qqy5jdLZYXyuZVJL0pDSO1urRhycCAMYU9pJ/kc3Mhz7NtLyoEHXpyikcud2dFpPc 1TbCQqvSoMt8zZWCtun5aeMTy0UjXSk= 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-262-zouugvlLOmKsGZ5UcbEF5Q-1; Mon, 08 Jun 2026 11:04:20 -0400 X-MC-Unique: zouugvlLOmKsGZ5UcbEF5Q-1 X-Mimecast-MFC-AGG-ID: zouugvlLOmKsGZ5UcbEF5Q_1780931059 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (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 1E5911800594; Mon, 8 Jun 2026 15:04:19 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.51]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E7DA41800361; Mon, 8 Jun 2026 15:04:16 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , johannes.goede@oss.qualcomm.com Subject: [RFC PATCH v4 09/17] libcamera: software_isp: Allocate multiple parameters buffers Date: Mon, 8 Jun 2026 17:03:38 +0200 Message-ID: <20260608150349.134371-10-mzamazal@redhat.com> In-Reply-To: <20260608150349.134371-1-mzamazal@redhat.com> References: <20260608150349.134371-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 2Dr-YqVs7d8etSp-et8XB7QCB2tJEqWwSXprolZqvzE_1780931059 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 Mon Jun 8 15:03:39 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26852 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 0108BC328C for ; Mon, 8 Jun 2026 15:04:31 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 865AF61F0E; Mon, 8 Jun 2026 17:04:30 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="fnHZGv2a"; 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 4BFBD61EF3 for ; Mon, 8 Jun 2026 17:04:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780931067; 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=fnHZGv2aqvuQCpNrSBtlJayJS8luE6vywJTY/hSWBVooN/8Idss7PjQPEsKVpXVF0CH6HS +XZb4mlLrrDg+zzAQP9+wtMEyVUqX4SnnyTBG3BzFT3VUnqulBhPgcc7bYmS2qJmRhoifj Cam8YycYp4ltwLXnksnxEBLWSWG0bYU= 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-455-jZF5YDPBPUe0W8Nz6a5wrg-1; Mon, 08 Jun 2026 11:04:22 -0400 X-MC-Unique: jZF5YDPBPUe0W8Nz6a5wrg-1 X-Mimecast-MFC-AGG-ID: jZF5YDPBPUe0W8Nz6a5wrg_1780931061 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (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 BFFD81800590; Mon, 8 Jun 2026 15:04:21 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.51]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id C7B911800361; Mon, 8 Jun 2026 15:04:19 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , johannes.goede@oss.qualcomm.com Subject: [RFC PATCH v4 10/17] libcamera: software_isp: Use multiple parameters buffers in IPA Date: Mon, 8 Jun 2026 17:03:39 +0200 Message-ID: <20260608150349.134371-11-mzamazal@redhat.com> In-Reply-To: <20260608150349.134371-1-mzamazal@redhat.com> References: <20260608150349.134371-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: SZNlQ7usiNXP1MDnLJTg8nvSLgdrDi_OpG7PvSNCPOg_1780931061 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 Mon Jun 8 15:03:40 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26853 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 A78F5C328C for ; Mon, 8 Jun 2026 15:04:32 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5047161F04; Mon, 8 Jun 2026 17:04:32 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="bzSGxadf"; 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 C9B0261EF3 for ; Mon, 8 Jun 2026 17:04:29 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780931068; 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=eOTl/dhElN1S6LTb941TqfLtMsJGLLcpaCsDYwz5j04=; b=bzSGxadf5u6x0ySnZ5bAxjxQLdKc6nGbIKz4v7e9Kfwx8ZcIAfz5rUZf2A4dSjms+6bFLN /RKXaqxvbhWn84xLzpXWfSwCU92VLrBobYpIZzJ5a0svFIC4eUaKsxpc21q0jEIYhQxNEL DDmCL53GQ0IClxNbXNVdovi0gkJ4090= 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-623-lzLsk2XMPd-syTh0vc0_Ew-1; Mon, 08 Jun 2026 11:04:25 -0400 X-MC-Unique: lzLsk2XMPd-syTh0vc0_Ew-1 X-Mimecast-MFC-AGG-ID: lzLsk2XMPd-syTh0vc0_Ew_1780931064 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (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 7001A1955DB5; Mon, 8 Jun 2026 15:04:24 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.51]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 45A551800351; Mon, 8 Jun 2026 15:04:22 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , johannes.goede@oss.qualcomm.com Subject: [RFC PATCH v4 11/17] libcamera: software_isp: Share parameters buffers with debayering Date: Mon, 8 Jun 2026 17:03:40 +0200 Message-ID: <20260608150349.134371-12-mzamazal@redhat.com> In-Reply-To: <20260608150349.134371-1-mzamazal@redhat.com> References: <20260608150349.134371-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: gry6bqs3MTM7vxkUX_5DGMpJBUP4cgcA6RsfTs5u1No_1780931064 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 21ce22c0d..eb30ae047 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. @@ -977,13 +980,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++) { @@ -1007,12 +1010,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); @@ -1023,7 +1026,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_; @@ -1031,21 +1034,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_; @@ -1060,18 +1063,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(); @@ -1079,8 +1081,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 9f8389623..dc626f55c 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; @@ -128,8 +130,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 e3429f47f..a0a957db7 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)) { } @@ -556,8 +559,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(); @@ -570,11 +572,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; @@ -605,7 +609,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 Mon Jun 8 15:03:41 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26854 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 AACE6C328C for ; Mon, 8 Jun 2026 15:04:34 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 52F7261F13; Mon, 8 Jun 2026 17:04:34 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="JI6Hd5z2"; 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 0734161F13 for ; Mon, 8 Jun 2026 17:04:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780931072; 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=JI6Hd5z2IO5aWbUiA8DaKZHD5A3wAa0GTtI67hE49yIqt2gqaEH0SZhG23RHwakvX+RKlw BjkksXUIpelM3jG+fKJEslDxgxcxLICfb/S49wzCzCvNQdQkVmI4Dkpkl8hNiwaxmmn1b+ F78Qw7KSin/I0SXbSkKZoEFlL1jVAxg= 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-456-yq6fGoP1PMCK3zYs24qmXQ-1; Mon, 08 Jun 2026 11:04:27 -0400 X-MC-Unique: yq6fGoP1PMCK3zYs24qmXQ-1 X-Mimecast-MFC-AGG-ID: yq6fGoP1PMCK3zYs24qmXQ_1780931066 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (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 78ECB19560AA; Mon, 8 Jun 2026 15:04:26 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.51]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B7D7D180058F; Mon, 8 Jun 2026 15:04:24 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , johannes.goede@oss.qualcomm.com Subject: [RFC PATCH v4 12/17] libcamera: software_isp: Remove per-frame params buffers TODO item Date: Mon, 8 Jun 2026 17:03:41 +0200 Message-ID: <20260608150349.134371-13-mzamazal@redhat.com> In-Reply-To: <20260608150349.134371-1-mzamazal@redhat.com> References: <20260608150349.134371-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: penf81JRpUpRWbYrfqQomWYZxEqSPjLW30X8VVGR-tU_1780931066 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 Mon Jun 8 15:03:42 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26855 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 63713C328C for ; Mon, 8 Jun 2026 15:04:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1A43561F12; Mon, 8 Jun 2026 17:04:37 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="PbW5qVIF"; 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 98DB761EFD for ; Mon, 8 Jun 2026 17:04:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780931073; 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=ZY5jrFxSrfVkFtU7ZTE7IPoXxigiYpFUwKYixWmzeWk=; b=PbW5qVIFtsbfCk6q29hY+mqUqw7fjD/Kuq1PiWX5UrY1ULbUqbYGQtZx2UHf5EjXVIShRV 7uuILIms/XaZBoFrW89YEjO3U9UfOSQ/pH0AgidaN/0UsncYHztj2PL1ZvkCYcbMei+TuD XuAR/PkmB6V7jVkW3QO1jPItZMAsCDQ= 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-462-MjBNZcMVPtqValL1WO0dOg-1; Mon, 08 Jun 2026 11:04:30 -0400 X-MC-Unique: MjBNZcMVPtqValL1WO0dOg-1 X-Mimecast-MFC-AGG-ID: MjBNZcMVPtqValL1WO0dOg_1780931069 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (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 0DA9F1800867; Mon, 8 Jun 2026 15:04:29 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.51]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 1583B1800361; Mon, 8 Jun 2026 15:04:26 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , johannes.goede@oss.qualcomm.com Subject: [RFC PATCH v4 13/17] libcamera: software_isp: Introduce arguments for statistics buffers Date: Mon, 8 Jun 2026 17:03:42 +0200 Message-ID: <20260608150349.134371-14-mzamazal@redhat.com> In-Reply-To: <20260608150349.134371-1-mzamazal@redhat.com> References: <20260608150349.134371-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: BLMFDJSgUkzKLLyL8Zm-i1U21_9LutphUES152XBTjM_1780931069 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 551870921..4356eb826 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 eb30ae047..148841809 100644 --- a/src/libcamera/software_isp/debayer_cpu.cpp +++ b/src/libcamera/software_isp/debayer_cpu.cpp @@ -1072,8 +1072,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(); @@ -1124,12 +1127,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 dc626f55c..8f8b2d6b1 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 a0a957db7..aacaaa66e 100644 --- a/src/libcamera/software_isp/debayer_egl.cpp +++ b/src/libcamera/software_isp/debayer_egl.cpp @@ -558,8 +558,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 7fb77ce7d..a10535004 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 @@ -398,11 +398,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; @@ -419,7 +420,7 @@ void SwStatsCpu::finishFrame(uint32_t frame, uint32_t bufferId) } sharedStats_->valid = valid; - statsReady.emit(frame, bufferId); + statsReady.emit(frame, statsBufferId); } /** @@ -597,22 +598,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 Mon Jun 8 15:03: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: 26857 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 09BD2C328C for ; Mon, 8 Jun 2026 15:04:40 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A456B61F17; Mon, 8 Jun 2026 17:04:39 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="HCXHLClf"; 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 8FD7961F17 for ; Mon, 8 Jun 2026 17:04:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780931076; 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=zWeLxjDraEA849kiojcF/8v79ehP0dh5ZDYofMM4Ksk=; b=HCXHLClfSTrnX28RF+tlJr7PKLd2W6OBon4yBpilMkHipJULBQc14rNRPaXRuzoisbZFs3 JsjZzGPzdJwNUYC5DuXp4r6/eGSWXBsssdwgefRNKuhvC3eXFG0q4NoyhIJwo0yiUMxw0U 4XdbGWdFdBHnjuRRBUAQP15M/uenfVY= 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-GN0p5DgMNfWq-7D05UGImg-1; Mon, 08 Jun 2026 11:04:32 -0400 X-MC-Unique: GN0p5DgMNfWq-7D05UGImg-1 X-Mimecast-MFC-AGG-ID: GN0p5DgMNfWq-7D05UGImg_1780931071 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (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 7E0F91801BDB; Mon, 8 Jun 2026 15:04:31 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.51]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 70998180058F; Mon, 8 Jun 2026 15:04:29 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , johannes.goede@oss.qualcomm.com Subject: [RFC PATCH v4 14/17] libcamera: software_isp: Allocate statistics buffers Date: Mon, 8 Jun 2026 17:03:43 +0200 Message-ID: <20260608150349.134371-15-mzamazal@redhat.com> In-Reply-To: <20260608150349.134371-1-mzamazal@redhat.com> References: <20260608150349.134371-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: y-QcyD1bi5-qHSilh6r3vJJePVNjGj4AyLFQtk-ddx8_1780931071 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 4356eb826..7a66c9367 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_; } @@ -122,7 +123,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 a10535004..15eca4769 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 */ @@ -406,20 +407,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 Mon Jun 8 15:03: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: 26858 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 ADAD9C328C for ; Mon, 8 Jun 2026 15:04:42 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 668F861F2B; Mon, 8 Jun 2026 17:04:42 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="KNzLYBwn"; 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 CC8AE61F00 for ; Mon, 8 Jun 2026 17:04:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780931079; 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=m+olcwCj5Ulh/lBxoFrBk2sY2gZlONais/vMZvoQpzI=; b=KNzLYBwnhb1SJGDZrhVcKZR8mwdgPAnfe1aWLrzBZwUf3/JW87wgfJL54TV/95cvEAaUB6 jAz0HpW1yDbJxoXWUQkNH/knEvKbDEH/09Mh9BOiLpSM5QC5q2iEDUWOhuE8UqMtSK4HzG OhtQYjtznDFGBQhz2GgSNgux+MuKmDo= 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-64-fhUOWtPbM7msSJ-ckZ2T-A-1; Mon, 08 Jun 2026 11:04:35 -0400 X-MC-Unique: fhUOWtPbM7msSJ-ckZ2T-A-1 X-Mimecast-MFC-AGG-ID: fhUOWtPbM7msSJ-ckZ2T-A_1780931074 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (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 2ADB81956060; Mon, 8 Jun 2026 15:04:34 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.51]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 199E51800361; Mon, 8 Jun 2026 15:04:31 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , johannes.goede@oss.qualcomm.com Subject: [RFC PATCH v4 15/17] libcamera: software_isp: Track statistics buffers Date: Mon, 8 Jun 2026 17:03:44 +0200 Message-ID: <20260608150349.134371-16-mzamazal@redhat.com> In-Reply-To: <20260608150349.134371-1-mzamazal@redhat.com> References: <20260608150349.134371-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: lCiaCTHW3Rgud8tl8nFKjE6lEeSqI-pqzNQSO67aUAE_1780931074 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 aacaaa66e..f5a74637d 100644 --- a/src/libcamera/software_isp/debayer_egl.cpp +++ b/src/libcamera/software_isp/debayer_egl.cpp @@ -559,7 +559,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) @@ -599,7 +599,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 Mon Jun 8 15:03: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: 26859 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 482BAC328C for ; Mon, 8 Jun 2026 15:04:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id F2DF761F37; Mon, 8 Jun 2026 17:04:42 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="Tx5WEudA"; 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 EE88561F0F for ; Mon, 8 Jun 2026 17:04:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780931079; 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=7SsbtO8egQymtUpgnE/ezOZ9vnLT1vLbyMEOW3CMceQ=; b=Tx5WEudAY6x+VnPQIT2W15uV03Kc3H6dVKBJUffnLTMDrSfqbKmmMg60Hxg6xpLFgz4Un7 tJ7oFZp8UYXj3Hzwgv9WNtWSbQV1IjXTmGNfF9np7Lab1VDN3tMTNDqBXF7GdJveoIObgH ImJ3Up4znJtwIyvcT7H1AG49Ywf0HiU= 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-492-Mk2iwlmsOQuiku_BvfqtYA-1; Mon, 08 Jun 2026 11:04:37 -0400 X-MC-Unique: Mk2iwlmsOQuiku_BvfqtYA-1 X-Mimecast-MFC-AGG-ID: Mk2iwlmsOQuiku_BvfqtYA_1780931076 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (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 CCF93180075E; Mon, 8 Jun 2026 15:04:36 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.51]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id BB6DA1800351; Mon, 8 Jun 2026 15:04:34 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , johannes.goede@oss.qualcomm.com Subject: [RFC PATCH v4 16/17] libcamera: software_isp: Share statistics buffers with IPA Date: Mon, 8 Jun 2026 17:03:45 +0200 Message-ID: <20260608150349.134371-17-mzamazal@redhat.com> In-Reply-To: <20260608150349.134371-1-mzamazal@redhat.com> References: <20260608150349.134371-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: K716Wd0B4-gzt9tZ4t-d1A1ptZXVGYhfhaqSkph4z9s_1780931076 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 7a66c9367..4ec13c4da 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 8f8b2d6b1..e018567f4 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 15eca4769..2f490af51 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 @@ -407,21 +393,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 Mon Jun 8 15:03:46 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26861 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 73DE2C328C for ; Mon, 8 Jun 2026 15:04:49 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1D23B61F41; Mon, 8 Jun 2026 17:04:49 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="GvANSb0s"; 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 5256261F1B for ; Mon, 8 Jun 2026 17:04:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1780931084; 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=GvANSb0s8O2g1C96NvAjGtzq4hqBaorEJZ4t43elDDMLjxAv1d7e/a0GOyKIk2mFWbo+l6 XU/T/0gOrN26KH7YwMVENvqcRKrySINpVSo5VYy2vrEitwFiEWXSSxVkMxXal7fxIamBM1 WfOuLXEWJGPDOxCt7VTRkI/IkRBvVJQ= 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-43-A9Ul4M2HOQCTuwnjnuuaig-1; Mon, 08 Jun 2026 11:04:40 -0400 X-MC-Unique: A9Ul4M2HOQCTuwnjnuuaig-1 X-Mimecast-MFC-AGG-ID: A9Ul4M2HOQCTuwnjnuuaig_1780931079 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (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 61832180058C; Mon, 8 Jun 2026 15:04:39 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.51]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 68DAD18005B3; Mon, 8 Jun 2026 15:04:37 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , johannes.goede@oss.qualcomm.com Subject: [RFC PATCH v4 17/17] libcamera: software_isp: Remove stats-sharing TODO item Date: Mon, 8 Jun 2026 17:03:46 +0200 Message-ID: <20260608150349.134371-18-mzamazal@redhat.com> In-Reply-To: <20260608150349.134371-1-mzamazal@redhat.com> References: <20260608150349.134371-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: EVAZV1RRT9_1lJlIEYPaKqjFZP5baNgt_2OyBNwj01Q_1780931079 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 ```