Patch Detail
Show a patch.
GET /api/1.1/patches/18017/?format=api
{ "id": 18017, "url": "https://patchwork.libcamera.org/api/1.1/patches/18017/?format=api", "web_url": "https://patchwork.libcamera.org/patch/18017/", "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": "<20221216122939.256534-4-paul.elder@ideasonboard.com>", "date": "2022-12-16T12:29:24", "name": "[libcamera-devel,v9,03/18] libcamera: framebuffer_allocator: Make allocate() require count", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "3b42b6ad8fa0a1c9f563713ddcfa7ea2acc9abd7", "submitter": { "id": 17, "url": "https://patchwork.libcamera.org/api/1.1/people/17/?format=api", "name": "Paul Elder", "email": "paul.elder@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/18017/mbox/", "series": [ { "id": 3675, "url": "https://patchwork.libcamera.org/api/1.1/series/3675/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=3675", "date": "2022-12-16T12:29:21", "name": "lc-compliance: Add test to queue more requests than hardware depth", "version": 9, "mbox": "https://patchwork.libcamera.org/series/3675/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/18017/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/18017/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 7CB1EC31E9\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 16 Dec 2022 12:30:09 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 33E1E633A4;\n\tFri, 16 Dec 2022 13:30:09 +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 45AA4633A2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 16 Dec 2022 13:30:07 +0100 (CET)", "from pyrite.tail37cf.ts.net (h175-177-042-159.catv02.itscom.jp\n\t[175.177.42.159])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 20F50128D;\n\tFri, 16 Dec 2022 13:30:04 +0100 (CET)" ], "DKIM-Signature": [ "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1671193809;\n\tbh=C1lOOwQ/7O2Co/57KOtHQ6+8s9cqLHzcW8b4zm1YOVE=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=3iWI+9H2/oZcMk0JV62y+gjB+HAyJV3UMH9XqxF0uDQyU5Z8c70xUxbVS/DJRzhbX\n\tQIcSJsdS5rvTvmaBpL3tgnJWo4nXVdkShVo3pea86n0T0Uurs5RMmE5juqzoNAoPTu\n\t3q0KK8yRx+O4BajNhvByw4ZRDLjt9MXETStdcWmuUtZhixflWpbK1EmB8+J3lRYPpv\n\t1L1Ihhnul+ZOVRhz6C7v004Td9wbHNkJiXZH1h2XgXveL4uoBeaaKDgopw2JBjoyas\n\trN/jisWA29rxKtVE6CsyiTt1HNFKJHt82HzZA0Oo+55imKCwxhdltN/j6xb6BQ/erv\n\tafu4uXW6XPbAA==", "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1671193807;\n\tbh=C1lOOwQ/7O2Co/57KOtHQ6+8s9cqLHzcW8b4zm1YOVE=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=f/xdFFMp3YckcXhwCed3SIwDK/DteUZeFdqBjPvB7w1O/zXwJcQiO/QmCZFazxZUN\n\tcAuvfyKqiuX7QB8iw+QbMXw9G9vAmBHgLWCZ3EJ0qXd6BF219PnHH5m87BxCLGgWL4\n\tkzz1Q1pev8KWgkDEiNSkK478w3Rh/EmRX2SftcBE=" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"f/xdFFMp\"; dkim-atps=neutral", "To": "libcamera-devel@lists.libcamera.org", "Date": "Fri, 16 Dec 2022 21:29:24 +0900", "Message-Id": "<20221216122939.256534-4-paul.elder@ideasonboard.com>", "X-Mailer": "git-send-email 2.35.1", "In-Reply-To": "<20221216122939.256534-1-paul.elder@ideasonboard.com>", "References": "<20221216122939.256534-1-paul.elder@ideasonboard.com>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH v9 03/18] libcamera:\n\tframebuffer_allocator: Make allocate() require count", "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>", "From": "Paul Elder via libcamera-devel <libcamera-devel@lists.libcamera.org>", "Reply-To": "Paul Elder <paul.elder@ideasonboard.com>", "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\nMake FrameBufferAllocator::allocate() require a 'count' argument for the\nnumber of buffers to be allocated.\n\nSigned-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\nReviewed-by: Paul Elder <paul.elder@ideasonboard.com>\nSigned-off-by: Paul Elder <paul.elder@ideasonboard.com>\n\n---\nChanges in v9:\n- rebased\n- notably, ControlList::get() returns a std::optional, and since the\n MinimumRequests property is a required property, we can simply\n get it via .value()\n - this will be enforced by lc-compliance in a later patch\n\nChanges in v8:\n- Updated application-developer and pipeline-handler guides with new allocate()\n API and MinimumRequests property\n- Added handling for when allocate() returns less buffers than needed in cam and\n the capture unit test\n- Improved FrameBufferAllocator::allocate() description\n\nChanges in v6:\n- Changed static_cast to convert 'count' to unsigned int instead of\n 'bufferCount' to int when comparing\n\nChanges in v5:\n- Made sure that qcam allocates at least 2 buffers\n---\n Documentation/guides/application-developer.rst | 9 +++++++--\n Documentation/guides/pipeline-handler.rst | 3 +--\n include/libcamera/camera.h | 2 +-\n include/libcamera/framebuffer_allocator.h | 2 +-\n include/libcamera/internal/pipeline_handler.h | 2 +-\n src/apps/cam/camera_session.cpp | 13 +++++++++----\n src/apps/lc-compliance/simple_capture.cpp | 8 ++++++--\n src/apps/qcam/main_window.cpp | 10 +++++++++-\n src/gstreamer/gstlibcameraallocator.cpp | 5 ++++-\n src/libcamera/camera.cpp | 4 ++--\n src/libcamera/framebuffer_allocator.cpp | 9 +++++++--\n src/libcamera/pipeline/ipu3/ipu3.cpp | 4 ++--\n src/libcamera/pipeline/raspberrypi/raspberrypi.cpp | 4 ++--\n src/libcamera/pipeline/rkisp1/rkisp1.cpp | 4 ++--\n src/libcamera/pipeline/simple/simple.cpp | 4 ++--\n src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 7 ++++---\n src/libcamera/pipeline/vimc/vimc.cpp | 7 ++++---\n src/libcamera/pipeline_handler.cpp | 1 +\n src/v4l2/v4l2_camera.cpp | 2 +-\n test/camera/camera_reconfigure.cpp | 5 ++++-\n test/camera/capture.cpp | 11 +++++++----\n test/camera/statemachine.cpp | 5 ++++-\n test/fence.cpp | 6 +++++-\n test/mapped-buffer.cpp | 5 ++++-\n 24 files changed, 90 insertions(+), 42 deletions(-)", "diff": "diff --git a/Documentation/guides/application-developer.rst b/Documentation/guides/application-developer.rst\nindex 1b2d7727..40bcf67a 100644\n--- a/Documentation/guides/application-developer.rst\n+++ b/Documentation/guides/application-developer.rst\n@@ -30,6 +30,7 @@ defined names and types without the need of prefixing them.\n #include <thread>\n \n #include <libcamera/libcamera.h>\n+ #include <libcamera/property_ids.h>\n \n using namespace libcamera;\n using namespace std::chrono_literals;\n@@ -272,7 +273,10 @@ Using the libcamera ``FrameBufferAllocator``\n \n Applications create a ``FrameBufferAllocator`` for a Camera and use it\n to allocate buffers for streams of a ``CameraConfiguration`` with the\n-``allocate()`` function.\n+``allocate()`` function. The number of buffers to be allocated needs to be\n+specified, and should be at least equal to the value of the ``MinimumRequests``\n+property in order for the pipeline to have enough requests to be able to\n+capture without frame drops.\n \n The list of allocated buffers can be retrieved using the ``Stream`` instance\n as the parameter of the ``FrameBufferAllocator::buffers()`` function.\n@@ -280,9 +284,10 @@ as the parameter of the ``FrameBufferAllocator::buffers()`` function.\n .. code:: cpp\n \n FrameBufferAllocator *allocator = new FrameBufferAllocator(camera);\n+ unsigned int bufferCount = camera->properties().get(properties::MinimumRequests);\n \n for (StreamConfiguration &cfg : *config) {\n- int ret = allocator->allocate(cfg.stream());\n+ int ret = allocator->allocate(cfg.stream(), bufferCount);\n if (ret < 0) {\n std::cerr << \"Can't allocate buffers\" << std::endl;\n return -ENOMEM;\ndiff --git a/Documentation/guides/pipeline-handler.rst b/Documentation/guides/pipeline-handler.rst\nindex a7356e4a..70de82af 100644\n--- a/Documentation/guides/pipeline-handler.rst\n+++ b/Documentation/guides/pipeline-handler.rst\n@@ -206,7 +206,7 @@ implementations for the overridden class members.\n const StreamRoles &roles) override;\n int configure(Camera *camera, CameraConfiguration *config) override;\n \n- int exportFrameBuffers(Camera *camera, Stream *stream,\n+ int exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count,\n std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;\n \n int start(Camera *camera, const ControlList *controls) override;\n@@ -1187,7 +1187,6 @@ handle this:\n \n .. code-block:: cpp\n \n- unsigned int count = stream->configuration().bufferCount;\n VividCameraData *data = cameraData(camera);\n \n return data->video_->exportBuffers(count, buffers);\ndiff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\nindex 5bb06584..4d32d16b 100644\n--- a/include/libcamera/camera.h\n+++ b/include/libcamera/camera.h\n@@ -126,7 +126,7 @@ private:\n \tvoid requestComplete(Request *request);\n \n \tfriend class FrameBufferAllocator;\n-\tint exportFrameBuffers(Stream *stream,\n+\tint exportFrameBuffers(Stream *stream, unsigned int count,\n \t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers);\n };\n \ndiff --git a/include/libcamera/framebuffer_allocator.h b/include/libcamera/framebuffer_allocator.h\nindex 45ff232b..7a0bf1a0 100644\n--- a/include/libcamera/framebuffer_allocator.h\n+++ b/include/libcamera/framebuffer_allocator.h\n@@ -25,7 +25,7 @@ public:\n \tFrameBufferAllocator(std::shared_ptr<Camera> camera);\n \t~FrameBufferAllocator();\n \n-\tint allocate(Stream *stream);\n+\tint allocate(Stream *stream, unsigned int count);\n \tint free(Stream *stream);\n \n \tbool allocated() const { return !buffers_.empty(); }\ndiff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h\nindex ec4f662d..8af165a3 100644\n--- a/include/libcamera/internal/pipeline_handler.h\n+++ b/include/libcamera/internal/pipeline_handler.h\n@@ -52,7 +52,7 @@ public:\n \t\tconst StreamRoles &roles) = 0;\n \tvirtual int configure(Camera *camera, CameraConfiguration *config) = 0;\n \n-\tvirtual int exportFrameBuffers(Camera *camera, Stream *stream,\n+\tvirtual int exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count,\n \t\t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers) = 0;\n \n \tvirtual int start(Camera *camera, const ControlList *controls) = 0;\ndiff --git a/src/apps/cam/camera_session.cpp b/src/apps/cam/camera_session.cpp\nindex 8fcec630..b2f64e39 100644\n--- a/src/apps/cam/camera_session.cpp\n+++ b/src/apps/cam/camera_session.cpp\n@@ -253,17 +253,22 @@ int CameraSession::startCapture()\n {\n \tint ret;\n \n-\t/* Identify the stream with the least number of buffers. */\n-\tunsigned int nbuffers = UINT_MAX;\n+\tunsigned int nbuffers =\n+\t\tcamera_->properties().get(properties::MinimumRequests).value();\n+\n \tfor (StreamConfiguration &cfg : *config_) {\n-\t\tret = allocator_->allocate(cfg.stream());\n+\t\tret = allocator_->allocate(cfg.stream(), nbuffers);\n \t\tif (ret < 0) {\n \t\t\tstd::cerr << \"Can't allocate buffers\" << std::endl;\n \t\t\treturn -ENOMEM;\n \t\t}\n \n \t\tunsigned int allocated = allocator_->buffers(cfg.stream()).size();\n-\t\tnbuffers = std::min(nbuffers, allocated);\n+\t\tif (allocated < nbuffers) {\n+\t\t\tstd::cerr << \"Unable to allocate enough buffers\"\n+\t\t\t\t << std::endl;\n+\t\t\treturn -ENOMEM;\n+\t\t}\n \t}\n \n \t/*\ndiff --git a/src/apps/lc-compliance/simple_capture.cpp b/src/apps/lc-compliance/simple_capture.cpp\nindex cf4d7cf3..be495986 100644\n--- a/src/apps/lc-compliance/simple_capture.cpp\n+++ b/src/apps/lc-compliance/simple_capture.cpp\n@@ -7,6 +7,8 @@\n \n #include <gtest/gtest.h>\n \n+#include <libcamera/property_ids.h>\n+\n #include \"simple_capture.h\"\n \n using namespace libcamera;\n@@ -44,11 +46,13 @@ void SimpleCapture::configure(StreamRole role)\n \n void SimpleCapture::start()\n {\n+\tunsigned int bufferCount =\n+\t\tcamera_->properties().get(properties::MinimumRequests).value();\n \tStream *stream = config_->at(0).stream();\n-\tint count = allocator_->allocate(stream);\n+\tint count = allocator_->allocate(stream, bufferCount);\n \n \tASSERT_GE(count, 0) << \"Failed to allocate buffers\";\n-\tEXPECT_EQ(count, config_->at(0).bufferCount) << \"Allocated less buffers than expected\";\n+\tEXPECT_EQ(count, bufferCount) << \"Allocated less buffers than expected\";\n \n \tcamera_->requestCompleted.connect(this, &SimpleCapture::requestComplete);\n \ndiff --git a/src/apps/qcam/main_window.cpp b/src/apps/qcam/main_window.cpp\nindex fb2db4aa..85b696fe 100644\n--- a/src/apps/qcam/main_window.cpp\n+++ b/src/apps/qcam/main_window.cpp\n@@ -12,6 +12,7 @@\n #include <string>\n \n #include <libcamera/camera_manager.h>\n+#include <libcamera/property_ids.h>\n #include <libcamera/version.h>\n \n #include <QCoreApplication>\n@@ -464,7 +465,14 @@ int MainWindow::startCapture()\n \tfor (StreamConfiguration &config : *config_) {\n \t\tStream *stream = config.stream();\n \n-\t\tret = allocator_->allocate(stream);\n+\t\t/*\n+\t\t * We hold on to a buffer for display, so need one extra from\n+\t\t * the minimum required for capture.\n+\t\t */\n+\t\tunsigned int bufferCount =\n+\t\t\tcamera_->properties().get(properties::MinimumRequests).value() + 1;\n+\n+\t\tret = allocator_->allocate(stream, bufferCount);\n \t\tif (ret < 0) {\n \t\t\tqWarning() << \"Failed to allocate capture buffers\";\n \t\t\tgoto error;\ndiff --git a/src/gstreamer/gstlibcameraallocator.cpp b/src/gstreamer/gstlibcameraallocator.cpp\nindex c740b8fc..5f9b96ad 100644\n--- a/src/gstreamer/gstlibcameraallocator.cpp\n+++ b/src/gstreamer/gstlibcameraallocator.cpp\n@@ -10,6 +10,7 @@\n \n #include <libcamera/camera.h>\n #include <libcamera/framebuffer_allocator.h>\n+#include <libcamera/property_ids.h>\n #include <libcamera/stream.h>\n \n #include \"gstlibcamera-utils.h\"\n@@ -193,13 +194,15 @@ gst_libcamera_allocator_new(std::shared_ptr<Camera> camera,\n {\n \tauto *self = GST_LIBCAMERA_ALLOCATOR(g_object_new(GST_TYPE_LIBCAMERA_ALLOCATOR,\n \t\t\t\t\t\t\t nullptr));\n+\tunsigned int bufferCount =\n+\t\tcamera->properties().get(properties::MinimumRequests).value();\n \n \tself->fb_allocator = new FrameBufferAllocator(camera);\n \tfor (StreamConfiguration &streamCfg : *config_) {\n \t\tStream *stream = streamCfg.stream();\n \t\tgint ret;\n \n-\t\tret = self->fb_allocator->allocate(stream);\n+\t\tret = self->fb_allocator->allocate(stream, bufferCount);\n \t\tif (ret == 0)\n \t\t\treturn nullptr;\n \ndiff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\nindex 2d947a44..ad289b28 100644\n--- a/src/libcamera/camera.cpp\n+++ b/src/libcamera/camera.cpp\n@@ -779,7 +779,7 @@ void Camera::disconnect()\n \tdisconnected.emit();\n }\n \n-int Camera::exportFrameBuffers(Stream *stream,\n+int Camera::exportFrameBuffers(Stream *stream, unsigned int count,\n \t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n {\n \tPrivate *const d = _d();\n@@ -796,7 +796,7 @@ int Camera::exportFrameBuffers(Stream *stream,\n \n \treturn d->pipe_->invokeMethod(&PipelineHandler::exportFrameBuffers,\n \t\t\t\t ConnectionTypeBlocking, this, stream,\n-\t\t\t\t buffers);\n+\t\t\t\t count, buffers);\n }\n \n /**\ndiff --git a/src/libcamera/framebuffer_allocator.cpp b/src/libcamera/framebuffer_allocator.cpp\nindex dabd9219..6a0bb8df 100644\n--- a/src/libcamera/framebuffer_allocator.cpp\n+++ b/src/libcamera/framebuffer_allocator.cpp\n@@ -71,6 +71,7 @@ FrameBufferAllocator::~FrameBufferAllocator()\n /**\n * \\brief Allocate buffers for a configured stream\n * \\param[in] stream The stream to allocate buffers for\n+ * \\param[in] count The number of buffers to allocate\n *\n * Allocate buffers suitable for capturing frames from the \\a stream. The Camera\n * shall have been previously configured with Camera::configure() and shall be\n@@ -79,6 +80,10 @@ FrameBufferAllocator::~FrameBufferAllocator()\n * Upon successful allocation, the allocated buffers can be retrieved with the\n * buffers() function.\n *\n+ * This function may allocate less buffers than requested, due to memory and\n+ * other system constraints. The caller shall always check the return value to\n+ * verify if the number of allocate buffers matches its needs.\n+ *\n * \\return The number of allocated buffers on success or a negative error code\n * otherwise\n * \\retval -EACCES The camera is not in a state where buffers can be allocated\n@@ -86,7 +91,7 @@ FrameBufferAllocator::~FrameBufferAllocator()\n * not part of the active camera configuration\n * \\retval -EBUSY Buffers are already allocated for the \\a stream\n */\n-int FrameBufferAllocator::allocate(Stream *stream)\n+int FrameBufferAllocator::allocate(Stream *stream, unsigned int count)\n {\n \tconst auto &[it, inserted] = buffers_.try_emplace(stream);\n \n@@ -95,7 +100,7 @@ int FrameBufferAllocator::allocate(Stream *stream)\n \t\treturn -EBUSY;\n \t}\n \n-\tint ret = camera_->exportFrameBuffers(stream, &it->second);\n+\tint ret = camera_->exportFrameBuffers(stream, count, &it->second);\n \tif (ret == -EINVAL)\n \t\tLOG(Allocator, Error)\n \t\t\t<< \"Stream is not part of \" << camera_->id()\ndiff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\nindex 98a4a3e5..bab2db65 100644\n--- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n@@ -140,7 +140,7 @@ public:\n \t\tconst StreamRoles &roles) override;\n \tint configure(Camera *camera, CameraConfiguration *config) override;\n \n-\tint exportFrameBuffers(Camera *camera, Stream *stream,\n+\tint exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count,\n \t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;\n \n \tint start(Camera *camera, const ControlList *controls) override;\n@@ -687,10 +687,10 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)\n }\n \n int PipelineHandlerIPU3::exportFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t\t\t unsigned int count,\n \t\t\t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n {\n \tIPU3CameraData *data = cameraData(camera);\n-\tunsigned int count = stream->configuration().bufferCount;\n \n \tif (stream == &data->outStream_)\n \t\treturn data->imgu_->output_->exportBuffers(count, buffers);\ndiff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\nindex 4a08d01e..4641c76f 100644\n--- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n+++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n@@ -328,7 +328,7 @@ public:\n \t\tconst StreamRoles &roles) override;\n \tint configure(Camera *camera, CameraConfiguration *config) override;\n \n-\tint exportFrameBuffers(Camera *camera, Stream *stream,\n+\tint exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count,\n \t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;\n \n \tint start(Camera *camera, const ControlList *controls) override;\n@@ -1005,10 +1005,10 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config)\n }\n \n int PipelineHandlerRPi::exportFrameBuffers([[maybe_unused]] Camera *camera, Stream *stream,\n+\t\t\t\t\t unsigned int count,\n \t\t\t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n {\n \tRPi::Stream *s = static_cast<RPi::Stream *>(stream);\n-\tunsigned int count = stream->configuration().bufferCount;\n \tint ret = s->dev()->exportBuffers(count, buffers);\n \n \ts->setExportedBuffers(buffers);\ndiff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\nindex 45b6beaf..8fe37c4f 100644\n--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n@@ -148,7 +148,7 @@ public:\n \t\tconst StreamRoles &roles) override;\n \tint configure(Camera *camera, CameraConfiguration *config) override;\n \n-\tint exportFrameBuffers(Camera *camera, Stream *stream,\n+\tint exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count,\n \t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;\n \n \tint start(Camera *camera, const ControlList *controls) override;\n@@ -816,10 +816,10 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)\n }\n \n int PipelineHandlerRkISP1::exportFrameBuffers([[maybe_unused]] Camera *camera, Stream *stream,\n+\t\t\t\t\t unsigned int count,\n \t\t\t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n {\n \tRkISP1CameraData *data = cameraData(camera);\n-\tunsigned int count = stream->configuration().bufferCount;\n \n \tif (stream == &data->mainPathStream_)\n \t\treturn mainPath_.exportBuffers(count, buffers);\ndiff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\nindex 8ed983fe..6b7c6d5c 100644\n--- a/src/libcamera/pipeline/simple/simple.cpp\n+++ b/src/libcamera/pipeline/simple/simple.cpp\n@@ -322,7 +322,7 @@ public:\n \t\tconst StreamRoles &roles) override;\n \tint configure(Camera *camera, CameraConfiguration *config) override;\n \n-\tint exportFrameBuffers(Camera *camera, Stream *stream,\n+\tint exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count,\n \t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;\n \n \tint start(Camera *camera, const ControlList *controls) override;\n@@ -1202,10 +1202,10 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c)\n }\n \n int SimplePipelineHandler::exportFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t\t\t unsigned int count,\n \t\t\t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n {\n \tSimpleCameraData *data = cameraData(camera);\n-\tunsigned int count = stream->configuration().bufferCount;\n \n \t/*\n \t * Export buffers on the converter or capture video node, depending on\ndiff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\nindex 7f580955..4ce240a4 100644\n--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n@@ -78,7 +78,7 @@ public:\n \t\tconst StreamRoles &roles) override;\n \tint configure(Camera *camera, CameraConfiguration *config) override;\n \n-\tint exportFrameBuffers(Camera *camera, Stream *stream,\n+\tint exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count,\n \t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;\n \n \tint start(Camera *camera, const ControlList *controls) override;\n@@ -226,11 +226,12 @@ int PipelineHandlerUVC::configure(Camera *camera, CameraConfiguration *config)\n \treturn 0;\n }\n \n-int PipelineHandlerUVC::exportFrameBuffers(Camera *camera, Stream *stream,\n+int PipelineHandlerUVC::exportFrameBuffers(Camera *camera,\n+\t\t\t\t\t [[maybe_unused]] Stream *stream,\n+\t\t\t\t\t unsigned int count,\n \t\t\t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n {\n \tUVCCameraData *data = cameraData(camera);\n-\tunsigned int count = stream->configuration().bufferCount;\n \n \treturn data->video_->exportBuffers(count, buffers);\n }\ndiff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp\nindex d2633be4..e58caf99 100644\n--- a/src/libcamera/pipeline/vimc/vimc.cpp\n+++ b/src/libcamera/pipeline/vimc/vimc.cpp\n@@ -89,7 +89,7 @@ public:\n \t\tconst StreamRoles &roles) override;\n \tint configure(Camera *camera, CameraConfiguration *config) override;\n \n-\tint exportFrameBuffers(Camera *camera, Stream *stream,\n+\tint exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count,\n \t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;\n \n \tint start(Camera *camera, const ControlList *controls) override;\n@@ -321,11 +321,12 @@ int PipelineHandlerVimc::configure(Camera *camera, CameraConfiguration *config)\n \treturn 0;\n }\n \n-int PipelineHandlerVimc::exportFrameBuffers(Camera *camera, Stream *stream,\n+int PipelineHandlerVimc::exportFrameBuffers(Camera *camera,\n+\t\t\t\t\t [[maybe_unused]] Stream *stream,\n+\t\t\t\t\t unsigned int count,\n \t\t\t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n {\n \tVimcCameraData *data = cameraData(camera);\n-\tunsigned int count = stream->configuration().bufferCount;\n \n \treturn data->video_->exportBuffers(count, buffers);\n }\ndiff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp\nindex cfade490..fffbd51b 100644\n--- a/src/libcamera/pipeline_handler.cpp\n+++ b/src/libcamera/pipeline_handler.cpp\n@@ -280,6 +280,7 @@ void PipelineHandler::unlockMediaDevices()\n * \\brief Allocate and export buffers for \\a stream\n * \\param[in] camera The camera\n * \\param[in] stream The stream to allocate buffers for\n+ * \\param[in] count The number of buffers to allocate\n * \\param[out] buffers Array of buffers successfully allocated\n *\n * This function allocates buffers for the \\a stream from the devices associated\ndiff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp\nindex 7b97c2d5..1c5fab64 100644\n--- a/src/v4l2/v4l2_camera.cpp\n+++ b/src/v4l2/v4l2_camera.cpp\n@@ -160,7 +160,7 @@ int V4L2Camera::allocBuffers(unsigned int count)\n {\n \tStream *stream = config_->at(0).stream();\n \n-\tint ret = bufferAllocator_->allocate(stream);\n+\tint ret = bufferAllocator_->allocate(stream, count);\n \tif (ret < 0)\n \t\treturn ret;\n \ndiff --git a/test/camera/camera_reconfigure.cpp b/test/camera/camera_reconfigure.cpp\nindex 06c87730..63a97863 100644\n--- a/test/camera/camera_reconfigure.cpp\n+++ b/test/camera/camera_reconfigure.cpp\n@@ -17,6 +17,7 @@\n #include <libcamera/base/timer.h>\n \n #include <libcamera/framebuffer_allocator.h>\n+#include <libcamera/property_ids.h>\n \n #include \"camera_test.h\"\n #include \"test.h\"\n@@ -78,7 +79,9 @@ private:\n \t\t * same buffer allocation for each run.\n \t\t */\n \t\tif (!allocated_) {\n-\t\t\tint ret = allocator_->allocate(stream);\n+\t\t\tunsigned int bufferCount =\n+\t\t\t\tcamera_->properties().get(properties::MinimumRequests).value();\n+\t\t\tint ret = allocator_->allocate(stream, bufferCount);\n \t\t\tif (ret < 0) {\n \t\t\t\tcerr << \"Failed to allocate buffers\" << endl;\n \t\t\t\treturn TestFail;\ndiff --git a/test/camera/capture.cpp b/test/camera/capture.cpp\nindex de824083..64d3a8e7 100644\n--- a/test/camera/capture.cpp\n+++ b/test/camera/capture.cpp\n@@ -7,12 +7,13 @@\n \n #include <iostream>\n \n-#include <libcamera/framebuffer_allocator.h>\n-\n #include <libcamera/base/event_dispatcher.h>\n #include <libcamera/base/thread.h>\n #include <libcamera/base/timer.h>\n \n+#include <libcamera/framebuffer_allocator.h>\n+#include <libcamera/property_ids.h>\n+\n #include \"camera_test.h\"\n #include \"test.h\"\n \n@@ -98,8 +99,10 @@ protected:\n \n \t\tStream *stream = cfg.stream();\n \n-\t\tint ret = allocator_->allocate(stream);\n-\t\tif (ret < 0)\n+\t\tunsigned int bufferCount =\n+\t\t\tcamera_->properties().get(properties::MinimumRequests).value();\n+\t\tint ret = allocator_->allocate(stream, bufferCount);\n+\t\tif (ret < static_cast<int>(bufferCount))\n \t\t\treturn TestFail;\n \n \t\tfor (const std::unique_ptr<FrameBuffer> &buffer : allocator_->buffers(stream)) {\ndiff --git a/test/camera/statemachine.cpp b/test/camera/statemachine.cpp\nindex 9c2b0c6a..a9ddb323 100644\n--- a/test/camera/statemachine.cpp\n+++ b/test/camera/statemachine.cpp\n@@ -8,6 +8,7 @@\n #include <iostream>\n \n #include <libcamera/framebuffer_allocator.h>\n+#include <libcamera/property_ids.h>\n \n #include \"camera_test.h\"\n #include \"test.h\"\n@@ -120,7 +121,9 @@ protected:\n \t\t/* Use internally allocated buffers. */\n \t\tallocator_ = new FrameBufferAllocator(camera_);\n \t\tStream *stream = *camera_->streams().begin();\n-\t\tif (allocator_->allocate(stream) < 0)\n+\t\tunsigned int bufferCount =\n+\t\t\tcamera_->properties().get(properties::MinimumRequests).value();\n+\t\tif (allocator_->allocate(stream, bufferCount) < 0)\n \t\t\treturn TestFail;\n \n \t\tif (camera_->start())\ndiff --git a/test/fence.cpp b/test/fence.cpp\nindex 1e38bc2f..88ce2857 100644\n--- a/test/fence.cpp\n+++ b/test/fence.cpp\n@@ -18,6 +18,7 @@\n \n #include <libcamera/fence.h>\n #include <libcamera/framebuffer_allocator.h>\n+#include <libcamera/property_ids.h>\n \n #include \"camera_test.h\"\n #include \"test.h\"\n@@ -117,8 +118,11 @@ int FenceTest::init()\n \tStreamConfiguration &cfg = config_->at(0);\n \tstream_ = cfg.stream();\n \n+\tunsigned int bufferCount =\n+\t\tcamera_->properties().get(properties::MinimumRequests).value();\n+\n \tallocator_ = std::make_unique<FrameBufferAllocator>(camera_);\n-\tif (allocator_->allocate(stream_) < 0)\n+\tif (allocator_->allocate(stream_, bufferCount) < 0)\n \t\treturn TestFail;\n \n \tnbuffers_ = allocator_->buffers(stream_).size();\ndiff --git a/test/mapped-buffer.cpp b/test/mapped-buffer.cpp\nindex b4422f7d..1b98feea 100644\n--- a/test/mapped-buffer.cpp\n+++ b/test/mapped-buffer.cpp\n@@ -8,6 +8,7 @@\n #include <iostream>\n \n #include <libcamera/framebuffer_allocator.h>\n+#include <libcamera/property_ids.h>\n \n #include \"libcamera/internal/mapped_framebuffer.h\"\n \n@@ -55,7 +56,9 @@ protected:\n \n \t\tstream_ = cfg.stream();\n \n-\t\tint ret = allocator_->allocate(stream_);\n+\t\tunsigned int bufferCount =\n+\t\t\tcamera_->properties().get(properties::MinimumRequests).value();\n+\t\tint ret = allocator_->allocate(stream_, bufferCount);\n \t\tif (ret < 0)\n \t\t\treturn TestFail;\n \n", "prefixes": [ "libcamera-devel", "v9", "03/18" ] }