{"id":23282,"url":"https://patchwork.libcamera.org/api/patches/23282/?format=json","web_url":"https://patchwork.libcamera.org/patch/23282/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20250428090413.38234-11-s.pueschel@pengutronix.de>","date":"2025-04-28T09:02:35","name":"[v11,10/19] v4l2: Allocate buffers based on requested count and MinimumRequests","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"61d252d0fa8402a9124acf0cacaf2a5490d6f809","submitter":{"id":225,"url":"https://patchwork.libcamera.org/api/people/225/?format=json","name":"Sven Püschel","email":"s.pueschel@pengutronix.de"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/23282/mbox/","series":[{"id":5148,"url":"https://patchwork.libcamera.org/api/series/5148/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=5148","date":"2025-04-28T09:02:25","name":"lc-compliance: Add test to queue more requests than hardware depth","version":11,"mbox":"https://patchwork.libcamera.org/series/5148/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/23282/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/23282/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 08626C32A2\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 28 Apr 2025 09:05:29 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 034BB68B3B;\n\tMon, 28 Apr 2025 11:05:28 +0200 (CEST)","from metis.whiteo.stw.pengutronix.de\n\t(metis.whiteo.stw.pengutronix.de [IPv6:2a0a:edc0:2:b01:1d::104])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B20E968AD8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 28 Apr 2025 11:05:07 +0200 (CEST)","from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77]\n\thelo=peter.guest.stw.pengutronix.de)\n\tby metis.whiteo.stw.pengutronix.de with esmtp (Exim 4.92)\n\t(envelope-from <s.pueschel@pengutronix.de>)\n\tid 1u9KQF-0001au-DP; Mon, 28 Apr 2025 11:05:07 +0200"],"From":"=?utf-8?q?Sven_P=C3=BCschel?= <s.pueschel@pengutronix.de>","To":"libcamera-devel@lists.libcamera.org","Cc":"=?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= <nfraprado@collabora.com>,\n\tPaul Elder <paul.elder@ideasonboard.com>, =?utf-8?q?Sven_P=C3=BCschel?=\n\t<s.pueschel@pengutronix.de>","Subject":"[PATCH v11 10/19] v4l2: Allocate buffers based on requested count\n\tand MinimumRequests","Date":"Mon, 28 Apr 2025 11:02:35 +0200","Message-ID":"<20250428090413.38234-11-s.pueschel@pengutronix.de>","X-Mailer":"git-send-email 2.49.0","In-Reply-To":"<20250428090413.38234-1-s.pueschel@pengutronix.de>","References":"<20250428090413.38234-1-s.pueschel@pengutronix.de>","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","X-SA-Exim-Connect-IP":"2a0a:edc0:0:900:1d::77","X-SA-Exim-Mail-From":"s.pueschel@pengutronix.de","X-SA-Exim-Scanned":"No (on metis.whiteo.stw.pengutronix.de);\n\tSAEximRunCond expanded to false","X-PTX-Original-Recipient":"libcamera-devel@lists.libcamera.org","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":"From: Nícolas F. R. A. Prado <nfraprado@collabora.com>\n\nCurrently the number of buffers allocated is based on bufferCount, which\nis hardcoded to 1. Instead allocate buffers based on the requested count\nand on the MinimumRequests property for the camera, which is accessed\nthrough a newly added getter.\n\nThis allows the removal of bufferCount.\n\nWhile at it, fix a typo: s/interval/internal/.\n\nSigned-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>\nReviewed-by: Paul Elder <paul.elder@ideasonboard.com>\nSigned-off-by: Paul Elder <paul.elder@ideasonboard.com>\nSigned-off-by: Sven Püschel <s.pueschel@pengutronix.de>\n\n---\nChanges in v11:\n- rebased\n\nChanges in v9:\n- rebased\n\nChanges in v8:\n- New\n- Fixed typo: s/interval/internal/\n---\n src/v4l2/v4l2_camera.cpp       | 19 ++++++++++++-------\n src/v4l2/v4l2_camera.h         |  5 +++--\n src/v4l2/v4l2_camera_proxy.cpp | 10 +++++-----\n 3 files changed, 20 insertions(+), 14 deletions(-)","diff":"diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp\nindex a4b0e562..feb6d405 100644\n--- a/src/v4l2/v4l2_camera.cpp\n+++ b/src/v4l2/v4l2_camera.cpp\n@@ -13,6 +13,7 @@\n #include <libcamera/base/log.h>\n \n #include <libcamera/control_ids.h>\n+#include <libcamera/property_ids.h>\n \n using namespace libcamera;\n \n@@ -108,15 +109,13 @@ void V4L2Camera::requestComplete(Request *request)\n }\n \n int V4L2Camera::configure(StreamConfiguration *streamConfigOut,\n-\t\t\t  const Size &size, const PixelFormat &pixelformat,\n-\t\t\t  unsigned int bufferCount)\n+\t\t\t  const Size &size, const PixelFormat &pixelformat)\n {\n \tStreamConfiguration &streamConfig = config_->at(0);\n \tstreamConfig.size.width = size.width;\n \tstreamConfig.size.height = size.height;\n \tstreamConfig.pixelFormat = pixelformat;\n-\tstreamConfig.bufferCount = bufferCount;\n-\t/* \\todo memoryType (interval vs external) */\n+\t/* \\todo memoryType (internal vs external) */\n \n \tCameraConfiguration::Status validation = config_->validate();\n \tif (validation == CameraConfiguration::Invalid) {\n@@ -147,7 +146,6 @@ int V4L2Camera::validateConfiguration(const PixelFormat &pixelFormat,\n \tStreamConfiguration &cfg = config->at(0);\n \tcfg.size = size;\n \tcfg.pixelFormat = pixelFormat;\n-\tcfg.bufferCount = 1;\n \n \tCameraConfiguration::Status validation = config->validate();\n \tif (validation == CameraConfiguration::Invalid)\n@@ -166,7 +164,9 @@ int V4L2Camera::allocBuffers(unsigned int count)\n \tif (ret < 0)\n \t\treturn ret;\n \n-\tfor (unsigned int i = 0; i < count; i++) {\n+\tunsigned int allocatedCount = ret;\n+\n+\tfor (unsigned int i = 0; i < allocatedCount; i++) {\n \t\tstd::unique_ptr<Request> request = camera_->createRequest(i);\n \t\tif (!request) {\n \t\t\trequestPool_.clear();\n@@ -175,7 +175,7 @@ int V4L2Camera::allocBuffers(unsigned int count)\n \t\trequestPool_.push_back(std::move(request));\n \t}\n \n-\treturn ret;\n+\treturn allocatedCount;\n }\n \n void V4L2Camera::freeBuffers()\n@@ -304,3 +304,8 @@ bool V4L2Camera::isRunning()\n {\n \treturn isRunning_;\n }\n+\n+unsigned int V4L2Camera::minimumRequests()\n+{\n+\treturn camera_->properties().get(properties::MinimumRequests).value();\n+}\ndiff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h\nindex 9bd161b9..402a7a76 100644\n--- a/src/v4l2/v4l2_camera.h\n+++ b/src/v4l2/v4l2_camera.h\n@@ -45,8 +45,7 @@ public:\n \n \tint configure(libcamera::StreamConfiguration *streamConfigOut,\n \t\t      const libcamera::Size &size,\n-\t\t      const libcamera::PixelFormat &pixelformat,\n-\t\t      unsigned int bufferCount);\n+\t\t      const libcamera::PixelFormat &pixelformat);\n \tint validateConfiguration(const libcamera::PixelFormat &pixelformat,\n \t\t\t\t  const libcamera::Size &size,\n \t\t\t\t  libcamera::StreamConfiguration *streamConfigOut);\n@@ -68,6 +67,8 @@ public:\n \n \tbool isRunning();\n \n+\tunsigned int minimumRequests();\n+\n private:\n \tvoid requestComplete(libcamera::Request *request)\n \t\tLIBCAMERA_TSA_EXCLUDES(bufferLock_);\ndiff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp\nindex 559ffc61..b12a59a0 100644\n--- a/src/v4l2/v4l2_camera_proxy.cpp\n+++ b/src/v4l2/v4l2_camera_proxy.cpp\n@@ -392,8 +392,7 @@ int V4L2CameraProxy::vidioc_s_fmt(V4L2CameraFile *file, struct v4l2_format *arg)\n \n \tSize size(arg->fmt.pix.width, arg->fmt.pix.height);\n \tV4L2PixelFormat v4l2Format = V4L2PixelFormat(arg->fmt.pix.pixelformat);\n-\tret = vcam_->configure(&streamConfig_, size, v4l2Format.toPixelFormat(),\n-\t\t\t       bufferCount_);\n+\tret = vcam_->configure(&streamConfig_, size, v4l2Format.toPixelFormat());\n \tif (ret < 0)\n \t\treturn -EINVAL;\n \n@@ -539,14 +538,13 @@ int V4L2CameraProxy::vidioc_reqbufs(V4L2CameraFile *file, struct v4l2_requestbuf\n \tSize size(v4l2PixFormat_.width, v4l2PixFormat_.height);\n \tV4L2PixelFormat v4l2Format = V4L2PixelFormat(v4l2PixFormat_.pixelformat);\n \tint ret = vcam_->configure(&streamConfig_, size,\n-\t\t\t\t   v4l2Format.toPixelFormat(), arg->count);\n+\t\t\t\t   v4l2Format.toPixelFormat());\n \tif (ret < 0)\n \t\treturn -EINVAL;\n \n \tsetFmtFromConfig(streamConfig_);\n \n-\targ->count = streamConfig_.bufferCount;\n-\tbufferCount_ = arg->count;\n+\targ->count = std::max(arg->count, vcam_->minimumRequests());\n \n \tret = vcam_->allocBuffers(arg->count);\n \tif (ret < 0) {\n@@ -554,6 +552,8 @@ int V4L2CameraProxy::vidioc_reqbufs(V4L2CameraFile *file, struct v4l2_requestbuf\n \t\treturn ret;\n \t}\n \n+\tbufferCount_ = arg->count = ret;\n+\n \tbuffers_.resize(arg->count);\n \tfor (unsigned int i = 0; i < arg->count; i++) {\n \t\tstruct v4l2_buffer buf = {};\n","prefixes":["v11","10/19"]}