Patch Detail
Show a patch.
GET /api/1.1/patches/22953/?format=api
{ "id": 22953, "url": "https://patchwork.libcamera.org/api/1.1/patches/22953/?format=api", "web_url": "https://patchwork.libcamera.org/patch/22953/", "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": "<20250314174220.1015597-2-barnabas.pocze@ideasonboard.com>", "date": "2025-03-14T17:42:18", "name": "[v4,1/2] apps: lc-compliance: Support multiple streams in helpers", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "6fb58058f14e0fad34d28be5dd40de2c04e69b75", "submitter": { "id": 216, "url": "https://patchwork.libcamera.org/api/1.1/people/216/?format=api", "name": "Barnabás Pőcze", "email": "barnabas.pocze@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/22953/mbox/", "series": [ { "id": 5060, "url": "https://patchwork.libcamera.org/api/1.1/series/5060/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5060", "date": "2025-03-14T17:42:17", "name": "apps: lc-compliance: Multi-stream tests", "version": 4, "mbox": "https://patchwork.libcamera.org/series/5060/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/22953/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/22953/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 EAA3FC32F7\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 14 Mar 2025 17:42:26 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 68ABF6894D;\n\tFri, 14 Mar 2025 18:42:26 +0100 (CET)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id A1F8E68946\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 14 Mar 2025 18:42:23 +0100 (CET)", "from pb-laptop.local (185.221.143.221.nat.pool.zt.hu\n\t[185.221.143.221])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 4C487842\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 14 Mar 2025 18:40:44 +0100 (CET)" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"LAj+IzxV\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1741974044;\n\tbh=/QFfEbvgSHSuyA1vcYwIaRA3fGlJ7YCG3d/4tnsg5l4=;\n\th=From:To:Subject:Date:In-Reply-To:References:From;\n\tb=LAj+IzxV0ZWlun7bbZb/ks62pOUykq5dwcJ3tewl3ZBIZIeET28hRHOI+0+0MJEpf\n\tzTEmv3+oGwF7VaQxkjan6eUnKu5N0q7Y7EganjIgyp6Sq/mQNnZHvO21rUXW/PYY+q\n\tLkf4A1nOFllBLfIynFKh8Bc0DgW7WxtDGMRZVSXU=", "From": "=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Subject": "[PATCH v4 1/2] apps: lc-compliance: Support multiple streams in\n\thelpers", "Date": "Fri, 14 Mar 2025 18:42:18 +0100", "Message-ID": "<20250314174220.1015597-2-barnabas.pocze@ideasonboard.com>", "X-Mailer": "git-send-email 2.48.1", "In-Reply-To": "<20250314174220.1015597-1-barnabas.pocze@ideasonboard.com>", "References": "<20250314174220.1015597-1-barnabas.pocze@ideasonboard.com>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "8bit", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "<libcamera-devel.lists.libcamera.org>", "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>", "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>", "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>", "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>", "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "Prepare to add a test suite for capture operations with multiple\nstreams.\n\nModify the Capture helper class to support multiple roles and streams\nin the configure() and capture() operations. The buffer count\nof each stream is asserted to be the same.\n\nMulti-stream support will be added in next patches.\n\nSigned-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n---\n src/apps/lc-compliance/helpers/capture.cpp | 64 ++++++++++++++-----\n src/apps/lc-compliance/helpers/capture.h | 2 +-\n src/apps/lc-compliance/tests/capture_test.cpp | 6 +-\n 3 files changed, 51 insertions(+), 21 deletions(-)", "diff": "diff --git a/src/apps/lc-compliance/helpers/capture.cpp b/src/apps/lc-compliance/helpers/capture.cpp\nindex f2c6d58ce..2a3fa3b68 100644\n--- a/src/apps/lc-compliance/helpers/capture.cpp\n+++ b/src/apps/lc-compliance/helpers/capture.cpp\n@@ -23,12 +23,29 @@ Capture::~Capture()\n \tstop();\n }\n \n-void Capture::configure(StreamRole role)\n+void Capture::configure(libcamera::Span<const libcamera::StreamRole> roles)\n {\n-\tconfig_ = camera_->generateConfiguration({ role });\n+\tassert(!roles.empty());\n \n+\tconfig_ = camera_->generateConfiguration(roles);\n \tif (!config_)\n-\t\tGTEST_SKIP() << \"Role not supported by camera\";\n+\t\tGTEST_SKIP() << \"Roles not supported by camera\";\n+\n+\tASSERT_EQ(config_->size(), roles.size()) << \"Unexpected number of streams in configuration\";\n+\n+\t/*\n+\t * Set the buffers count to the largest value across all streams.\n+\t * \\todo: Should all streams from a Camera have the same buffer count ?\n+\t */\n+\tauto largest =\n+\t\tstd::max_element(config_->begin(), config_->end(),\n+\t\t\t\t [](const StreamConfiguration &l, const StreamConfiguration &r)\n+\t\t\t\t { return l.bufferCount < r.bufferCount; });\n+\n+\tassert(largest != config_->end());\n+\n+\tfor (auto &cfg : *config_)\n+\t\tcfg.bufferCount = largest->bufferCount;\n \n \tif (config_->validate() != CameraConfiguration::Valid) {\n \t\tconfig_.reset();\n@@ -103,29 +120,37 @@ void Capture::start()\n \tassert(!allocator_.allocated());\n \tassert(requests_.empty());\n \n-\tStream *stream = config_->at(0).stream();\n-\tint count = allocator_.allocate(stream);\n-\n-\tASSERT_GE(count, 0) << \"Failed to allocate buffers\";\n-\tEXPECT_EQ(count, config_->at(0).bufferCount) << \"Allocated less buffers than expected\";\n-\n-\tconst std::vector<std::unique_ptr<FrameBuffer>> &buffers = allocator_.buffers(stream);\n+\tconst auto bufferCount = config_->at(0).bufferCount;\n \n \t/* No point in testing less requests then the camera depth. */\n-\tif (queueLimit_ && *queueLimit_ < buffers.size()) {\n-\t\tGTEST_SKIP() << \"Camera needs \" << buffers.size()\n+\tif (queueLimit_ && *queueLimit_ < bufferCount) {\n+\t\tGTEST_SKIP() << \"Camera needs \" << bufferCount\n \t\t\t << \" requests, can't test only \" << *queueLimit_;\n \t}\n \n-\tfor (const std::unique_ptr<FrameBuffer> &buffer : buffers) {\n+\tfor (std::size_t i = 0; i < bufferCount; i++) {\n \t\tstd::unique_ptr<Request> request = camera_->createRequest();\n \t\tASSERT_TRUE(request) << \"Can't create request\";\n+\t\trequests_.push_back(std::move(request));\n+\t}\n \n-\t\tASSERT_EQ(request->addBuffer(stream, buffer.get()), 0) << \"Can't set buffer for request\";\n+\tfor (const auto &cfg : *config_) {\n+\t\tStream *stream = cfg.stream();\n \n-\t\trequests_.push_back(std::move(request));\n+\t\tint count = allocator_.allocate(stream);\n+\t\tASSERT_GE(count, 0) << \"Failed to allocate buffers\";\n+\n+\t\tconst auto &buffers = allocator_.buffers(stream);\n+\t\tASSERT_EQ(buffers.size(), bufferCount) << \"Mismatching buffer count\";\n+\n+\t\tfor (std::size_t i = 0; i < bufferCount; i++) {\n+\t\t\tASSERT_EQ(requests_[i]->addBuffer(stream, buffers[i].get()), 0)\n+\t\t\t\t<< \"Failed to add buffer to request\";\n+\t\t}\n \t}\n \n+\tASSERT_TRUE(allocator_.allocated());\n+\n \tcamera_->requestCompleted.connect(this, &Capture::requestComplete);\n \n \tASSERT_EQ(camera_->start(), 0) << \"Failed to start camera\";\n@@ -140,7 +165,12 @@ void Capture::stop()\n \n \tcamera_->requestCompleted.disconnect(this);\n \n-\tStream *stream = config_->at(0).stream();\n \trequests_.clear();\n-\tallocator_.free(stream);\n+\n+\tfor (const auto &cfg : *config_) {\n+\t\tEXPECT_EQ(allocator_.free(cfg.stream()), 0)\n+\t\t\t<< \"Failed to free buffers associated with stream\";\n+\t}\n+\n+\tEXPECT_FALSE(allocator_.allocated());\n }\ndiff --git a/src/apps/lc-compliance/helpers/capture.h b/src/apps/lc-compliance/helpers/capture.h\nindex 0e7b848fb..ea01c11c1 100644\n--- a/src/apps/lc-compliance/helpers/capture.h\n+++ b/src/apps/lc-compliance/helpers/capture.h\n@@ -20,7 +20,7 @@ public:\n \tCapture(std::shared_ptr<libcamera::Camera> camera);\n \t~Capture();\n \n-\tvoid configure(libcamera::StreamRole role);\n+\tvoid configure(libcamera::Span<const libcamera::StreamRole> roles);\n \tvoid run(unsigned int captureLimit, std::optional<unsigned int> queueLimit = {});\n \n private:\ndiff --git a/src/apps/lc-compliance/tests/capture_test.cpp b/src/apps/lc-compliance/tests/capture_test.cpp\nindex 93bed48f0..06f15bdb4 100644\n--- a/src/apps/lc-compliance/tests/capture_test.cpp\n+++ b/src/apps/lc-compliance/tests/capture_test.cpp\n@@ -89,7 +89,7 @@ TEST_P(SingleStream, Capture)\n \n \tCapture capture(camera_);\n \n-\tcapture.configure(role);\n+\tcapture.configure({ { role } });\n \n \tcapture.run(numRequests, numRequests);\n }\n@@ -108,7 +108,7 @@ TEST_P(SingleStream, CaptureStartStop)\n \n \tCapture capture(camera_);\n \n-\tcapture.configure(role);\n+\tcapture.configure({ { role } });\n \n \tfor (unsigned int starts = 0; starts < numRepeats; starts++)\n \t\tcapture.run(numRequests, numRequests);\n@@ -127,7 +127,7 @@ TEST_P(SingleStream, UnbalancedStop)\n \n \tCapture capture(camera_);\n \n-\tcapture.configure(role);\n+\tcapture.configure({ { role } });\n \n \tcapture.run(numRequests);\n }\n", "prefixes": [ "v4", "1/2" ] }