Patch Detail
Show a patch.
GET /api/1.1/patches/26180/?format=api
{ "id": 26180, "url": "https://patchwork.libcamera.org/api/1.1/patches/26180/?format=api", "web_url": "https://patchwork.libcamera.org/patch/26180/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/1.1/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20260216203034.27558-12-mzamazal@redhat.com>", "date": "2026-02-16T20:30:30", "name": "[RFC,v2,11/14] libcamera: software_isp: Allocate statistics buffers", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "ec3f49e1e6894d9913eaad37c0b439392d072e46", "submitter": { "id": 177, "url": "https://patchwork.libcamera.org/api/1.1/people/177/?format=api", "name": "Milan Zamazal", "email": "mzamazal@redhat.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/26180/mbox/", "series": [ { "id": 5795, "url": "https://patchwork.libcamera.org/api/1.1/series/5795/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5795", "date": "2026-02-16T20:30:19", "name": "Software ISP: Share params and stats buffers", "version": 2, "mbox": "https://patchwork.libcamera.org/series/5795/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/26180/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/26180/checks/", "tags": {}, "headers": { "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>", "X-Original-To": "parsemail@patchwork.libcamera.org", "Delivered-To": "parsemail@patchwork.libcamera.org", "Received": [ "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 49CB4C3240\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 16 Feb 2026 20:31:06 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id EDFC86222C;\n\tMon, 16 Feb 2026 21:31:05 +0100 (CET)", "from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.129.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 265DD62224\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 16 Feb 2026 21:31:04 +0100 (CET)", "from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com\n\t(ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63])\n\tby relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n\tcipher=TLS_AES_256_GCM_SHA384) id us-mta-687-QlIaCc4PMh6aAPZD6NmqyQ-1;\n\tMon, 16 Feb 2026 15:31:01 -0500", "from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com\n\t(mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com\n\t[10.30.177.93])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\tkey-exchange X25519 server-signature RSA-PSS (2048 bits)\n\tserver-digest SHA256) (No client certificate requested)\n\tby mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTPS\n\tid BDE4B1955D7A for <libcamera-devel@lists.libcamera.org>;\n\tMon, 16 Feb 2026 20:31:00 +0000 (UTC)", "from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.32.25])\n\tby mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTP id CF5471800464; Mon, 16 Feb 2026 20:30:59 +0000 (UTC)" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"eydUWpuS\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1771273862;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tcontent-transfer-encoding:content-transfer-encoding:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=8t55nI6D1EYbu6IgY5PHIuQ7Fz+F54TF3djZPCk9duM=;\n\tb=eydUWpuSA20ZRA7ilr9FGZJXvwWsWsr30ISv6ct4BADUbvkw0RgW8zNCL4/iekmKYU84vs\n\tPurrDngvSj2SIAHfOJlmRPnMHLiDslv0Ci4Xq+2IKxQKyQ54IovT5dEoeGoJ8xORSbzVu8\n\teHihxA0AJQKhLT7Qn1Nt1rsP9ychkH0=", "X-MC-Unique": "QlIaCc4PMh6aAPZD6NmqyQ-1", "X-Mimecast-MFC-AGG-ID": "QlIaCc4PMh6aAPZD6NmqyQ_1771273860", "From": "Milan Zamazal <mzamazal@redhat.com>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Milan Zamazal <mzamazal@redhat.com>", "Subject": "[RFC PATCH v2 11/14] libcamera: software_isp: Allocate statistics\n\tbuffers", "Date": "Mon, 16 Feb 2026 21:30:30 +0100", "Message-ID": "<20260216203034.27558-12-mzamazal@redhat.com>", "In-Reply-To": "<20260216203034.27558-1-mzamazal@redhat.com>", "References": "<20260216203034.27558-1-mzamazal@redhat.com>", "MIME-Version": "1.0", "X-Scanned-By": "MIMEDefang 3.4.1 on 10.30.177.93", "X-Mimecast-Spam-Score": "0", "X-Mimecast-MFC-PROC-ID": "fqEfazGj2z0u9lXfPjExe1yTLe4mJp-8i7QxlVowlo0_1771273860", "X-Mimecast-Originator": "redhat.com", "Content-Transfer-Encoding": "8bit", "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": "<libcamera-devel.lists.libcamera.org>", "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>", "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>", "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>", "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>", "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "In order to be able to use multiple shared statistics buffers, we must\nallocate them. They are allocated in SoftwareIsp and passed to\nSwIspStats. This changes the previous behavior when the (single) shared\nstatistics buffer was created in SwIspStats. Centralizing it to\nSoftwareIsp makes sharing multiple buffers with IPA easier.\n\nCurrently only one of the allocated buffers is used. This will be\nchanged once the buffers are shared with IPA in a followup patch.\n\nSigned-off-by: Milan Zamazal <mzamazal@redhat.com>\n---\n .../internal/software_isp/software_isp.h | 5 +++\n .../internal/software_isp/swstats_cpu.h | 9 ++--\n src/libcamera/software_isp/software_isp.cpp | 45 ++++++++++++++++---\n src/libcamera/software_isp/swstats_cpu.cpp | 15 ++++---\n 4 files changed, 56 insertions(+), 18 deletions(-)", "diff": "diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h\nindex 519dfc71a..1f3eb75f6 100644\n--- a/include/libcamera/internal/software_isp/software_isp.h\n+++ b/include/libcamera/internal/software_isp/software_isp.h\n@@ -34,6 +34,7 @@\n #include \"libcamera/internal/pipeline_handler.h\"\n #include \"libcamera/internal/shared_mem_object.h\"\n #include \"libcamera/internal/software_isp/debayer_params.h\"\n+#include \"libcamera/internal/software_isp/swstats_cpu.h\"\n \n namespace libcamera {\n \n@@ -103,6 +104,10 @@ private:\n \tDebayerParams debayerParams_;\n \tstd::queue<uint32_t> availableParams_;\n \tbool allocateParamsBuffers(const unsigned int bufferCount);\n+\tstd::unique_ptr<SwStatsCpu> allocateStatsBuffers(\n+\t\tconst GlobalConfiguration &configuration,\n+\t\tstd::vector<SharedFD> &fdStats,\n+\t\tconst unsigned int bufferCount);\n \tDmaBufAllocator dmaHeap_;\n \tbool ccmEnabled_;\n \ndiff --git a/include/libcamera/internal/software_isp/swstats_cpu.h b/include/libcamera/internal/software_isp/swstats_cpu.h\nindex ae8ce1e59..050b13ec1 100644\n--- a/include/libcamera/internal/software_isp/swstats_cpu.h\n+++ b/include/libcamera/internal/software_isp/swstats_cpu.h\n@@ -11,6 +11,7 @@\n \n #pragma once\n \n+#include <map>\n #include <stdint.h>\n \n #include <libcamera/base/signal.h>\n@@ -34,7 +35,7 @@ struct StreamConfiguration;\n class SwStatsCpu\n {\n public:\n-\tSwStatsCpu(const GlobalConfiguration &configuration);\n+\tSwStatsCpu(const GlobalConfiguration &configuration, std::unique_ptr<std::map<uint32_t, SharedMemObject<SwIspStats>>> sharedStats);\n \t~SwStatsCpu() = default;\n \n \t/*\n@@ -45,9 +46,9 @@ public:\n \t */\n \tstatic constexpr uint32_t kStatPerNumFrames = 4;\n \n-\tbool isValid() const { return sharedStats_.fd().isValid(); }\n+\tbool isValid() const { return sharedStats_->begin()->second.fd().isValid(); }\n \n-\tconst SharedFD &getStatsFD() { return sharedStats_.fd(); }\n+\tconst SharedFD &getStatsFD() { return sharedStats_->begin()->second.fd(); }\n \n \tconst Size &patternSize() { return patternSize_; }\n \n@@ -116,7 +117,7 @@ private:\n \tunsigned int xShift_;\n \tunsigned int stride_;\n \n-\tSharedMemObject<SwIspStats> sharedStats_;\n+\tstd::unique_ptr<std::map<uint32_t, SharedMemObject<SwIspStats>>> sharedStats_;\n \tSwIspStats stats_;\n \tBenchmark bench_;\n };\ndiff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp\nindex 04aaf7a8c..a1a9ddbf4 100644\n--- a/src/libcamera/software_isp/software_isp.cpp\n+++ b/src/libcamera/software_isp/software_isp.cpp\n@@ -12,6 +12,8 @@\n #include <sys/mman.h>\n #include <sys/types.h>\n #include <unistd.h>\n+#include <utility>\n+#include <vector>\n \n #include <libcamera/base/log.h>\n #include <libcamera/base/shared_fd.h>\n@@ -24,7 +26,9 @@\n \n #include \"libcamera/internal/framebuffer.h\"\n #include \"libcamera/internal/ipa_manager.h\"\n+#include \"libcamera/internal/shared_mem_object.h\"\n #include \"libcamera/internal/software_isp/debayer_params.h\"\n+#include \"libcamera/internal/software_isp/swisp_stats.h\"\n \n #include \"debayer_cpu.h\"\n #if HAVE_DEBAYER_EGL\n@@ -95,17 +99,15 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,\n \n \tconst GlobalConfiguration &configuration = pipe->cameraManager()->_d()->configuration();\n \n-\tauto stats = std::make_unique<SwStatsCpu>(configuration);\n-\tif (!stats->isValid()) {\n-\t\tLOG(SoftwareIsp, Error) << \"Failed to create SwStatsCpu object\";\n-\t\treturn;\n-\t}\n-\tstats->statsReady.connect(this, &SoftwareIsp::statsReady);\n-\n \tstd::vector<SharedFD> fdParams;\n \tfor (auto &item : sharedParams_)\n \t\tfdParams.emplace_back(item.second.fd());\n \n+\tstd::vector<SharedFD> fdStats;\n+\tauto stats = allocateStatsBuffers(configuration, fdStats, bufferCount);\n+\tif (!stats)\n+\t\treturn;\n+\n #if HAVE_DEBAYER_EGL\n \tstd::optional<std::string> softISPMode = configuration.envOption(\"LIBCAMERA_SOFTISP_MODE\", { \"software_isp\", \"mode\" });\n \tif (softISPMode) {\n@@ -199,6 +201,35 @@ bool SoftwareIsp::allocateParamsBuffers(const unsigned int bufferCount)\n \treturn true;\n }\n \n+std::unique_ptr<SwStatsCpu> SoftwareIsp::allocateStatsBuffers(\n+\tconst GlobalConfiguration &configuration,\n+\tstd::vector<SharedFD> &fdStats,\n+\tconst unsigned int bufferCount)\n+{\n+\tauto sharedStats = std::make_unique<std::map<uint32_t, SharedMemObject<SwIspStats>>>();\n+\tfor (unsigned int i = 0; i < bufferCount; i++) {\n+\t\tauto shared = SharedMemObject<SwIspStats>(\"softIsp_stats\");\n+\t\tif (!shared) {\n+\t\t\tLOG(SoftwareIsp, Error) << \"Failed to create shared memory for statistics\";\n+\t\t\treturn std::unique_ptr<SwStatsCpu>();\n+\t\t}\n+\t\tif (!shared.fd().isValid()) {\n+\t\t\tLOG(SoftwareIsp, Error) << \"Invalid fd of shared statistics\";\n+\t\t\treturn std::unique_ptr<SwStatsCpu>();\n+\t\t}\n+\n+\t\tASSERT(shared.fd().get() >= 0);\n+\t\tunsigned int bufferId = shared.fd().get();\n+\t\tfdStats.emplace_back(shared.fd());\n+\t\tsharedStats->emplace(bufferId, std::move(shared));\n+\t}\n+\n+\tauto stats = std::make_unique<SwStatsCpu>(configuration, std::move(sharedStats));\n+\tstats->statsReady.connect(this, &SoftwareIsp::statsReady);\n+\n+\treturn stats;\n+}\n+\n /**\n * \\fn int SoftwareIsp::loadConfiguration([[maybe_unused]] const std::string &filename)\n * \\brief Load a configuration from a file\ndiff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp\nindex a3b11c443..b9f36b383 100644\n--- a/src/libcamera/software_isp/swstats_cpu.cpp\n+++ b/src/libcamera/software_isp/swstats_cpu.cpp\n@@ -11,6 +11,8 @@\n \n #include \"libcamera/internal/software_isp/swstats_cpu.h\"\n \n+#include <memory>\n+\n #include <libcamera/base/log.h>\n \n #include <libcamera/stream.h>\n@@ -36,9 +38,11 @@ namespace libcamera {\n */\n \n /**\n- * \\fn SwStatsCpu::SwStatsCpu(const GlobalConfiguration &configuration)\n+ * \\fn SwStatsCpu::SwStatsCpu(const GlobalConfiguration &configuration, std::unique_ptr<std::map<uint32_t, SharedMemObject<SwIspStats>>> sharedStats)\n * \\brief Construct a SwStatsCpu object\n * \\param[in] configuration Global configuration reference\n+ * \\param [in] sharedStats Mapping of statistics buffer ids to statistics\n+ * instances that are shared with the IPA\n *\n * Creates a SwStatsCpu object and initialises shared memory for statistics\n * exchange.\n@@ -154,12 +158,9 @@ namespace libcamera {\n \n LOG_DEFINE_CATEGORY(SwStatsCpu)\n \n-SwStatsCpu::SwStatsCpu(const GlobalConfiguration &configuration)\n-\t: sharedStats_(\"softIsp_stats\"), bench_(configuration)\n+SwStatsCpu::SwStatsCpu(const GlobalConfiguration &configuration, std::unique_ptr<std::map<uint32_t, SharedMemObject<SwIspStats>>> sharedStats)\n+\t: sharedStats_(std::move(sharedStats)), bench_(configuration)\n {\n-\tif (!sharedStats_)\n-\t\tLOG(SwStatsCpu, Error)\n-\t\t\t<< \"Failed to create shared memory for statistics\";\n }\n \n static constexpr unsigned int kRedYMul = 77; /* 0.299 * 256 */\n@@ -348,7 +349,7 @@ void SwStatsCpu::finishFrame(uint32_t frame,\n \t\t\t const uint32_t statsBufferId)\n {\n \tstats_.valid = frame % kStatPerNumFrames == 0;\n-\t*sharedStats_ = stats_;\n+\t*(sharedStats_->at(statsBufferId)) = stats_;\n \tstatsReady.emit(frame, statsBufferId);\n }\n \n", "prefixes": [ "RFC", "v2", "11/14" ] }