[PATCH v11 02/19] libcamera: framebuffer_allocator: Make allocate() require count
Sven Püschel
s.pueschel at pengutronix.de
Mon Apr 28 11:02:27 CEST 2025
From: Nícolas F. R. A. Prado <nfraprado at collabora.com>
Make FrameBufferAllocator::allocate() require a 'count' argument for the
number of buffers to be allocated.
Signed-off-by: Nícolas F. R. A. Prado <nfraprado at collabora.com>
Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder at ideasonboard.com>
Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo at jmondi.org>
Signed-off-by: Sven Püschel <s.pueschel at pengutronix.de>
---
Changes in v11:
- add mali-c55 and virtual
- adapt python binding
Changes in v10:
- add imx8-isi
Changes in v9:
- rebased
- notably, ControlList::get() returns a std::optional, and since the
MinimumRequests property is a required property, we can simply
get it via .value()
- this will be enforced by lc-compliance in a later patch
Changes in v8:
- Updated application-developer and pipeline-handler guides with new allocate()
API and MinimumRequests property
- Added handling for when allocate() returns less buffers than needed in cam and
the capture unit test
- Improved FrameBufferAllocator::allocate() description
Changes in v6:
- Changed static_cast to convert 'count' to unsigned int instead of
'bufferCount' to int when comparing
Changes in v5:
- Made sure that qcam allocates at least 2 buffers
---
Documentation/guides/application-developer.rst | 9 +++++++--
Documentation/guides/pipeline-handler.rst | 3 +--
include/libcamera/camera.h | 2 +-
include/libcamera/framebuffer_allocator.h | 2 +-
include/libcamera/internal/pipeline_handler.h | 2 +-
src/apps/cam/camera_session.cpp | 13 +++++++++----
src/apps/lc-compliance/helpers/capture.cpp | 5 +++--
src/apps/qcam/main_window.cpp | 10 +++++++++-
src/gstreamer/gstlibcameraallocator.cpp | 6 +++++-
src/libcamera/camera.cpp | 4 ++--
src/libcamera/framebuffer_allocator.cpp | 9 +++++++--
src/libcamera/pipeline/imx8-isi/imx8-isi.cpp | 5 ++---
src/libcamera/pipeline/ipu3/ipu3.cpp | 4 ++--
src/libcamera/pipeline/mali-c55/mali-c55.cpp | 3 ++-
src/libcamera/pipeline/rkisp1/rkisp1.cpp | 4 ++--
src/libcamera/pipeline/rpi/common/pipeline_base.cpp | 2 +-
src/libcamera/pipeline/rpi/common/pipeline_base.h | 2 +-
src/libcamera/pipeline/simple/simple.cpp | 4 ++--
src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 7 ++++---
src/libcamera/pipeline/vimc/vimc.cpp | 7 ++++---
src/libcamera/pipeline/virtual/virtual.cpp | 5 +++--
src/libcamera/pipeline_handler.cpp | 1 +
src/py/libcamera/py_main.cpp | 4 ++--
src/v4l2/v4l2_camera.cpp | 2 +-
test/camera/camera_reconfigure.cpp | 5 ++++-
test/camera/capture.cpp | 11 +++++++----
test/camera/statemachine.cpp | 5 ++++-
test/fence.cpp | 6 +++++-
test/mapped-buffer.cpp | 5 ++++-
29 files changed, 97 insertions(+), 50 deletions(-)
diff --git a/Documentation/guides/application-developer.rst b/Documentation/guides/application-developer.rst
index f3798d17..dbd2bfc6 100644
--- a/Documentation/guides/application-developer.rst
+++ b/Documentation/guides/application-developer.rst
@@ -32,6 +32,7 @@ defined names and types without the need of prefixing them.
#include <thread>
#include <libcamera/libcamera.h>
+ #include <libcamera/property_ids.h>
using namespace libcamera;
using namespace std::chrono_literals;
@@ -276,7 +277,10 @@ Using the libcamera ``FrameBufferAllocator``
Applications create a ``FrameBufferAllocator`` for a Camera and use it
to allocate buffers for streams of a ``CameraConfiguration`` with the
-``allocate()`` function.
+``allocate()`` function. The number of buffers to be allocated needs to be
+specified, and should be at least equal to the value of the ``MinimumRequests``
+property in order for the pipeline to have enough requests to be able to
+capture without frame drops.
The list of allocated buffers can be retrieved using the ``Stream`` instance
as the parameter of the ``FrameBufferAllocator::buffers()`` function.
@@ -284,9 +288,10 @@ as the parameter of the ``FrameBufferAllocator::buffers()`` function.
.. code:: cpp
FrameBufferAllocator *allocator = new FrameBufferAllocator(camera);
+ unsigned int bufferCount = camera->properties().get(properties::MinimumRequests);
for (StreamConfiguration &cfg : *config) {
- int ret = allocator->allocate(cfg.stream());
+ int ret = allocator->allocate(cfg.stream(), bufferCount);
if (ret < 0) {
std::cerr << "Can't allocate buffers" << std::endl;
return -ENOMEM;
diff --git a/Documentation/guides/pipeline-handler.rst b/Documentation/guides/pipeline-handler.rst
index 1079d998..2e9825dc 100644
--- a/Documentation/guides/pipeline-handler.rst
+++ b/Documentation/guides/pipeline-handler.rst
@@ -209,7 +209,7 @@ implementations for the overridden class members.
Span<const StreamRole> roles) override;
int configure(Camera *camera, CameraConfiguration *config) override;
- int exportFrameBuffers(Camera *camera, Stream *stream,
+ int exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;
int start(Camera *camera, const ControlList *controls) override;
@@ -1242,7 +1242,6 @@ handle this:
.. code-block:: cpp
- unsigned int count = stream->configuration().bufferCount;
VividCameraData *data = cameraData(camera);
return data->video_->exportBuffers(count, buffers);
diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h
index 94cee7bd..ce9d8812 100644
--- a/include/libcamera/camera.h
+++ b/include/libcamera/camera.h
@@ -163,7 +163,7 @@ private:
void requestComplete(Request *request);
friend class FrameBufferAllocator;
- int exportFrameBuffers(Stream *stream,
+ int exportFrameBuffers(Stream *stream, unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers);
};
diff --git a/include/libcamera/framebuffer_allocator.h b/include/libcamera/framebuffer_allocator.h
index f3896bf2..1568c55d 100644
--- a/include/libcamera/framebuffer_allocator.h
+++ b/include/libcamera/framebuffer_allocator.h
@@ -25,7 +25,7 @@ public:
FrameBufferAllocator(std::shared_ptr<Camera> camera);
~FrameBufferAllocator();
- int allocate(Stream *stream);
+ int allocate(Stream *stream, unsigned int count);
int free(Stream *stream);
bool allocated() const { return !buffers_.empty(); }
diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h
index 972a2fa6..0e9fe23e 100644
--- a/include/libcamera/internal/pipeline_handler.h
+++ b/include/libcamera/internal/pipeline_handler.h
@@ -48,7 +48,7 @@ public:
Span<const StreamRole> roles) = 0;
virtual int configure(Camera *camera, CameraConfiguration *config) = 0;
- virtual int exportFrameBuffers(Camera *camera, Stream *stream,
+ virtual int exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) = 0;
virtual int start(Camera *camera, const ControlList *controls) = 0;
diff --git a/src/apps/cam/camera_session.cpp b/src/apps/cam/camera_session.cpp
index 97c1ae44..f50108f3 100644
--- a/src/apps/cam/camera_session.cpp
+++ b/src/apps/cam/camera_session.cpp
@@ -326,17 +326,22 @@ int CameraSession::startCapture()
{
int ret;
- /* Identify the stream with the least number of buffers. */
- unsigned int nbuffers = UINT_MAX;
+ unsigned int nbuffers =
+ camera_->properties().get(properties::MinimumRequests).value();
+
for (StreamConfiguration &cfg : *config_) {
- ret = allocator_->allocate(cfg.stream());
+ ret = allocator_->allocate(cfg.stream(), nbuffers);
if (ret < 0) {
std::cerr << "Can't allocate buffers" << std::endl;
return -ENOMEM;
}
unsigned int allocated = allocator_->buffers(cfg.stream()).size();
- nbuffers = std::min(nbuffers, allocated);
+ if (allocated < nbuffers) {
+ std::cerr << "Unable to allocate enough buffers"
+ << std::endl;
+ return -ENOMEM;
+ }
}
/*
diff --git a/src/apps/lc-compliance/helpers/capture.cpp b/src/apps/lc-compliance/helpers/capture.cpp
index 2a3fa3b6..690de005 100644
--- a/src/apps/lc-compliance/helpers/capture.cpp
+++ b/src/apps/lc-compliance/helpers/capture.cpp
@@ -120,7 +120,8 @@ void Capture::start()
assert(!allocator_.allocated());
assert(requests_.empty());
- const auto bufferCount = config_->at(0).bufferCount;
+ unsigned int bufferCount =
+ camera_->properties().get(properties::MinimumRequests).value();
/* No point in testing less requests then the camera depth. */
if (queueLimit_ && *queueLimit_ < bufferCount) {
@@ -137,7 +138,7 @@ void Capture::start()
for (const auto &cfg : *config_) {
Stream *stream = cfg.stream();
- int count = allocator_.allocate(stream);
+ int count = allocator_.allocate(stream, bufferCount);
ASSERT_GE(count, 0) << "Failed to allocate buffers";
const auto &buffers = allocator_.buffers(stream);
diff --git a/src/apps/qcam/main_window.cpp b/src/apps/qcam/main_window.cpp
index d2ccbd23..9a9b7fa9 100644
--- a/src/apps/qcam/main_window.cpp
+++ b/src/apps/qcam/main_window.cpp
@@ -12,6 +12,7 @@
#include <string>
#include <libcamera/camera_manager.h>
+#include <libcamera/property_ids.h>
#include <libcamera/version.h>
#include <QCoreApplication>
@@ -447,7 +448,14 @@ int MainWindow::startCapture()
for (StreamConfiguration &config : *config_) {
Stream *stream = config.stream();
- ret = allocator_->allocate(stream);
+ /*
+ * We hold on to a buffer for display, so need one extra from
+ * the minimum required for capture.
+ */
+ unsigned int bufferCount =
+ camera_->properties().get(properties::MinimumRequests).value() + 1;
+
+ ret = allocator_->allocate(stream, bufferCount);
if (ret < 0) {
qWarning() << "Failed to allocate capture buffers";
goto error;
diff --git a/src/gstreamer/gstlibcameraallocator.cpp b/src/gstreamer/gstlibcameraallocator.cpp
index d4492d99..0d8e4c40 100644
--- a/src/gstreamer/gstlibcameraallocator.cpp
+++ b/src/gstreamer/gstlibcameraallocator.cpp
@@ -12,6 +12,7 @@
#include <libcamera/camera.h>
#include <libcamera/framebuffer_allocator.h>
+#include <libcamera/property_ids.h>
#include <libcamera/stream.h>
#include "gstlibcamera-utils.h"
@@ -209,11 +210,14 @@ gst_libcamera_allocator_new(std::shared_ptr<Camera> camera,
if (ret)
return nullptr;
+ unsigned int bufferCount =
+ camera->properties().get(properties::MinimumRequests).value();
+
self->fb_allocator = new FrameBufferAllocator(camera);
for (StreamConfiguration &streamCfg : *config_) {
Stream *stream = streamCfg.stream();
- ret = self->fb_allocator->allocate(stream);
+ ret = self->fb_allocator->allocate(stream, bufferCount);
if (ret <= 0)
return nullptr;
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index c180a5fd..33e928b9 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -950,7 +950,7 @@ void Camera::disconnect()
disconnected.emit();
}
-int Camera::exportFrameBuffers(Stream *stream,
+int Camera::exportFrameBuffers(Stream *stream, unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers)
{
Private *const d = _d();
@@ -967,7 +967,7 @@ int Camera::exportFrameBuffers(Stream *stream,
return d->pipe_->invokeMethod(&PipelineHandler::exportFrameBuffers,
ConnectionTypeBlocking, this, stream,
- buffers);
+ count, buffers);
}
/**
diff --git a/src/libcamera/framebuffer_allocator.cpp b/src/libcamera/framebuffer_allocator.cpp
index 3d53bde2..c522f479 100644
--- a/src/libcamera/framebuffer_allocator.cpp
+++ b/src/libcamera/framebuffer_allocator.cpp
@@ -68,6 +68,7 @@ FrameBufferAllocator::~FrameBufferAllocator() = default;
/**
* \brief Allocate buffers for a configured stream
* \param[in] stream The stream to allocate buffers for
+ * \param[in] count The number of buffers to allocate
*
* Allocate buffers suitable for capturing frames from the \a stream. The Camera
* shall have been previously configured with Camera::configure() and shall be
@@ -76,6 +77,10 @@ FrameBufferAllocator::~FrameBufferAllocator() = default;
* Upon successful allocation, the allocated buffers can be retrieved with the
* buffers() function.
*
+ * This function may allocate less buffers than requested, due to memory and
+ * other system constraints. The caller shall always check the return value to
+ * verify if the number of allocate buffers matches its needs.
+ *
* \return The number of allocated buffers on success or a negative error code
* otherwise
* \retval -EACCES The camera is not in a state where buffers can be allocated
@@ -83,7 +88,7 @@ FrameBufferAllocator::~FrameBufferAllocator() = default;
* not part of the active camera configuration
* \retval -EBUSY Buffers are already allocated for the \a stream
*/
-int FrameBufferAllocator::allocate(Stream *stream)
+int FrameBufferAllocator::allocate(Stream *stream, unsigned int count)
{
const auto &[it, inserted] = buffers_.try_emplace(stream);
@@ -92,7 +97,7 @@ int FrameBufferAllocator::allocate(Stream *stream)
return -EBUSY;
}
- int ret = camera_->exportFrameBuffers(stream, &it->second);
+ int ret = camera_->exportFrameBuffers(stream, count, &it->second);
if (ret == -EINVAL)
LOG(Allocator, Error)
<< "Stream is not part of " << camera_->id()
diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp
index 2b8a583e..21f44424 100644
--- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp
+++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp
@@ -108,7 +108,7 @@ public:
generateConfiguration(Camera *camera, Span<const StreamRole> roles) override;
int configure(Camera *camera, CameraConfiguration *config) override;
- int exportFrameBuffers(Camera *camera, Stream *stream,
+ int exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;
int start(Camera *camera, const ControlList *controls) override;
@@ -908,10 +908,9 @@ int PipelineHandlerISI::configure(Camera *camera, CameraConfiguration *c)
return 0;
}
-int PipelineHandlerISI::exportFrameBuffers(Camera *camera, Stream *stream,
+int PipelineHandlerISI::exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers)
{
- unsigned int count = stream->configuration().bufferCount;
Pipe *pipe = pipeFromStream(camera, stream);
return pipe->capture->exportBuffers(count, buffers);
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 356ca2e1..30b74d4e 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -139,7 +139,7 @@ public:
Span<const StreamRole> roles) override;
int configure(Camera *camera, CameraConfiguration *config) override;
- int exportFrameBuffers(Camera *camera, Stream *stream,
+ int exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;
int start(Camera *camera, const ControlList *controls) override;
@@ -637,10 +637,10 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)
}
int PipelineHandlerIPU3::exportFrameBuffers(Camera *camera, Stream *stream,
+ unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers)
{
IPU3CameraData *data = cameraData(camera);
- unsigned int count = stream->configuration().bufferCount;
if (stream == &data->outStream_)
return data->imgu_->output_->exportBuffers(count, buffers);
diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp
index f0ab3d2e..9df1622e 100644
--- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp
+++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp
@@ -608,6 +608,7 @@ public:
int configure(Camera *camera, CameraConfiguration *config) override;
int exportFrameBuffers(Camera *camera, Stream *stream,
+ unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;
int allocateBuffers(Camera *camera);
void freeBuffers(Camera *camera);
@@ -1087,10 +1088,10 @@ int PipelineHandlerMaliC55::configure(Camera *camera,
}
int PipelineHandlerMaliC55::exportFrameBuffers(Camera *camera, Stream *stream,
+ unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers)
{
MaliC55Pipe *pipe = pipeFromStream(cameraData(camera), stream);
- unsigned int count = stream->configuration().bufferCount;
return pipe->cap->exportBuffers(count, buffers);
}
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index 5e3a4dba..4e8eff70 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -158,7 +158,7 @@ public:
Span<const StreamRole> roles) override;
int configure(Camera *camera, CameraConfiguration *config) override;
- int exportFrameBuffers(Camera *camera, Stream *stream,
+ int exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;
int start(Camera *camera, const ControlList *controls) override;
@@ -953,10 +953,10 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
}
int PipelineHandlerRkISP1::exportFrameBuffers([[maybe_unused]] Camera *camera, Stream *stream,
+ unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers)
{
RkISP1CameraData *data = cameraData(camera);
- unsigned int count = stream->configuration().bufferCount;
if (stream == &data->mainPathStream_) {
/*
diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
index ef51d530..dc1e0a2e 100644
--- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
+++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
@@ -630,10 +630,10 @@ int PipelineHandlerBase::configure(Camera *camera, CameraConfiguration *config)
}
int PipelineHandlerBase::exportFrameBuffers([[maybe_unused]] Camera *camera, libcamera::Stream *stream,
+ unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers)
{
RPi::Stream *s = static_cast<RPi::Stream *>(stream);
- unsigned int count = stream->configuration().bufferCount;
int ret = s->dev()->exportBuffers(count, buffers);
s->setExportedBuffers(buffers);
diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h b/src/libcamera/pipeline/rpi/common/pipeline_base.h
index aae0c2f3..e73d6f18 100644
--- a/src/libcamera/pipeline/rpi/common/pipeline_base.h
+++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h
@@ -218,7 +218,7 @@ public:
generateConfiguration(Camera *camera, Span<const StreamRole> roles) override;
int configure(Camera *camera, CameraConfiguration *config) override;
- int exportFrameBuffers(Camera *camera, libcamera::Stream *stream,
+ int exportFrameBuffers(Camera *camera, libcamera::Stream *stream, unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;
int start(Camera *camera, const ControlList *controls) override;
diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index 7abf0fc9..1e77ccdc 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -404,7 +404,7 @@ public:
Span<const StreamRole> roles) override;
int configure(Camera *camera, CameraConfiguration *config) override;
- int exportFrameBuffers(Camera *camera, Stream *stream,
+ int exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;
int start(Camera *camera, const ControlList *controls) override;
@@ -1434,10 +1434,10 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c)
}
int SimplePipelineHandler::exportFrameBuffers(Camera *camera, Stream *stream,
+ unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers)
{
SimpleCameraData *data = cameraData(camera);
- unsigned int count = stream->configuration().bufferCount;
/*
* Export buffers on the converter or capture video node, depending on
diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
index 31951a12..60c82364 100644
--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
@@ -87,7 +87,7 @@ public:
Span<const StreamRole> roles) override;
int configure(Camera *camera, CameraConfiguration *config) override;
- int exportFrameBuffers(Camera *camera, Stream *stream,
+ int exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;
int start(Camera *camera, const ControlList *controls) override;
@@ -278,11 +278,12 @@ int PipelineHandlerUVC::configure(Camera *camera, CameraConfiguration *config)
return 0;
}
-int PipelineHandlerUVC::exportFrameBuffers(Camera *camera, Stream *stream,
+int PipelineHandlerUVC::exportFrameBuffers(Camera *camera,
+ [[maybe_unused]] Stream *stream,
+ unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers)
{
UVCCameraData *data = cameraData(camera);
- unsigned int count = stream->configuration().bufferCount;
return data->video_->exportBuffers(count, buffers);
}
diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp
index 01685a64..8833647a 100644
--- a/src/libcamera/pipeline/vimc/vimc.cpp
+++ b/src/libcamera/pipeline/vimc/vimc.cpp
@@ -92,7 +92,7 @@ public:
Span<const StreamRole> roles) override;
int configure(Camera *camera, CameraConfiguration *config) override;
- int exportFrameBuffers(Camera *camera, Stream *stream,
+ int exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;
int start(Camera *camera, const ControlList *controls) override;
@@ -343,11 +343,12 @@ int PipelineHandlerVimc::configure(Camera *camera, CameraConfiguration *config)
return 0;
}
-int PipelineHandlerVimc::exportFrameBuffers(Camera *camera, Stream *stream,
+int PipelineHandlerVimc::exportFrameBuffers(Camera *camera,
+ [[maybe_unused]] Stream *stream,
+ unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers)
{
VimcCameraData *data = cameraData(camera);
- unsigned int count = stream->configuration().bufferCount;
return data->video_->exportBuffers(count, buffers);
}
diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp
index c33f1a5e..ad2bdb57 100644
--- a/src/libcamera/pipeline/virtual/virtual.cpp
+++ b/src/libcamera/pipeline/virtual/virtual.cpp
@@ -87,7 +87,7 @@ public:
Span<const StreamRole> roles) override;
int configure(Camera *camera, CameraConfiguration *config) override;
- int exportFrameBuffers(Camera *camera, Stream *stream,
+ int exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;
int start(Camera *camera, const ControlList *controls) override;
@@ -269,6 +269,7 @@ int PipelineHandlerVirtual::configure(Camera *camera,
int PipelineHandlerVirtual::exportFrameBuffers([[maybe_unused]] Camera *camera,
Stream *stream,
+ unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers)
{
if (!dmaBufAllocator_.isValid())
@@ -281,7 +282,7 @@ int PipelineHandlerVirtual::exportFrameBuffers([[maybe_unused]] Camera *camera,
for (size_t i = 0; i < info.numPlanes(); ++i)
planeSizes.push_back(info.planeSize(config.size, i));
- return dmaBufAllocator_.exportBuffers(config.bufferCount, planeSizes, buffers);
+ return dmaBufAllocator_.exportBuffers(count, planeSizes, buffers);
}
int PipelineHandlerVirtual::start([[maybe_unused]] Camera *camera,
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index d84dff3c..3211256c 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -314,6 +314,7 @@ void PipelineHandler::unlockMediaDevices()
* \brief Allocate and export buffers for \a stream
* \param[in] camera The camera
* \param[in] stream The stream to allocate buffers for
+ * \param[in] count The number of buffers to allocate
* \param[out] buffers Array of buffers successfully allocated
*
* This function allocates buffers for the \a stream from the devices associated
diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp
index 441a70ab..f75450ee 100644
--- a/src/py/libcamera/py_main.cpp
+++ b/src/py/libcamera/py_main.cpp
@@ -349,8 +349,8 @@ PYBIND11_MODULE(_libcamera, m)
pyFrameBufferAllocator
.def(py::init<PyCameraSmartPtr<Camera>>(), py::keep_alive<1, 2>())
- .def("allocate", [](FrameBufferAllocator &self, Stream *stream) {
- int ret = self.allocate(stream);
+ .def("allocate", [](FrameBufferAllocator &self, Stream *stream, unsigned int count) {
+ int ret = self.allocate(stream, count);
if (ret < 0)
throw std::system_error(-ret, std::generic_category(),
"Failed to allocate buffers");
diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp
index 94d138cd..a4b0e562 100644
--- a/src/v4l2/v4l2_camera.cpp
+++ b/src/v4l2/v4l2_camera.cpp
@@ -162,7 +162,7 @@ int V4L2Camera::allocBuffers(unsigned int count)
{
Stream *stream = config_->at(0).stream();
- int ret = bufferAllocator_->allocate(stream);
+ int ret = bufferAllocator_->allocate(stream, count);
if (ret < 0)
return ret;
diff --git a/test/camera/camera_reconfigure.cpp b/test/camera/camera_reconfigure.cpp
index 06c87730..63a97863 100644
--- a/test/camera/camera_reconfigure.cpp
+++ b/test/camera/camera_reconfigure.cpp
@@ -17,6 +17,7 @@
#include <libcamera/base/timer.h>
#include <libcamera/framebuffer_allocator.h>
+#include <libcamera/property_ids.h>
#include "camera_test.h"
#include "test.h"
@@ -78,7 +79,9 @@ private:
* same buffer allocation for each run.
*/
if (!allocated_) {
- int ret = allocator_->allocate(stream);
+ unsigned int bufferCount =
+ camera_->properties().get(properties::MinimumRequests).value();
+ int ret = allocator_->allocate(stream, bufferCount);
if (ret < 0) {
cerr << "Failed to allocate buffers" << endl;
return TestFail;
diff --git a/test/camera/capture.cpp b/test/camera/capture.cpp
index 8766fb19..05f4a1e3 100644
--- a/test/camera/capture.cpp
+++ b/test/camera/capture.cpp
@@ -7,12 +7,13 @@
#include <iostream>
-#include <libcamera/framebuffer_allocator.h>
-
#include <libcamera/base/event_dispatcher.h>
#include <libcamera/base/thread.h>
#include <libcamera/base/timer.h>
+#include <libcamera/framebuffer_allocator.h>
+#include <libcamera/property_ids.h>
+
#include "camera_test.h"
#include "test.h"
@@ -101,8 +102,10 @@ protected:
Stream *stream = cfg.stream();
- int ret = allocator_->allocate(stream);
- if (ret < 0)
+ unsigned int bufferCount =
+ camera_->properties().get(properties::MinimumRequests).value();
+ int ret = allocator_->allocate(stream, bufferCount);
+ if (ret < static_cast<int>(bufferCount))
return TestFail;
for (const std::unique_ptr<FrameBuffer> &buffer : allocator_->buffers(stream)) {
diff --git a/test/camera/statemachine.cpp b/test/camera/statemachine.cpp
index 9c2b0c6a..a9ddb323 100644
--- a/test/camera/statemachine.cpp
+++ b/test/camera/statemachine.cpp
@@ -8,6 +8,7 @@
#include <iostream>
#include <libcamera/framebuffer_allocator.h>
+#include <libcamera/property_ids.h>
#include "camera_test.h"
#include "test.h"
@@ -120,7 +121,9 @@ protected:
/* Use internally allocated buffers. */
allocator_ = new FrameBufferAllocator(camera_);
Stream *stream = *camera_->streams().begin();
- if (allocator_->allocate(stream) < 0)
+ unsigned int bufferCount =
+ camera_->properties().get(properties::MinimumRequests).value();
+ if (allocator_->allocate(stream, bufferCount) < 0)
return TestFail;
if (camera_->start())
diff --git a/test/fence.cpp b/test/fence.cpp
index 8095b228..eb6c8b54 100644
--- a/test/fence.cpp
+++ b/test/fence.cpp
@@ -18,6 +18,7 @@
#include <libcamera/fence.h>
#include <libcamera/framebuffer_allocator.h>
+#include <libcamera/property_ids.h>
#include "camera_test.h"
#include "test.h"
@@ -119,8 +120,11 @@ int FenceTest::init()
StreamConfiguration &cfg = config_->at(0);
stream_ = cfg.stream();
+ unsigned int bufferCount =
+ camera_->properties().get(properties::MinimumRequests).value();
+
allocator_ = std::make_unique<FrameBufferAllocator>(camera_);
- if (allocator_->allocate(stream_) < 0)
+ if (allocator_->allocate(stream_, bufferCount) < 0)
return TestFail;
nbuffers_ = allocator_->buffers(stream_).size();
diff --git a/test/mapped-buffer.cpp b/test/mapped-buffer.cpp
index b4422f7d..1b98feea 100644
--- a/test/mapped-buffer.cpp
+++ b/test/mapped-buffer.cpp
@@ -8,6 +8,7 @@
#include <iostream>
#include <libcamera/framebuffer_allocator.h>
+#include <libcamera/property_ids.h>
#include "libcamera/internal/mapped_framebuffer.h"
@@ -55,7 +56,9 @@ protected:
stream_ = cfg.stream();
- int ret = allocator_->allocate(stream_);
+ unsigned int bufferCount =
+ camera_->properties().get(properties::MinimumRequests).value();
+ int ret = allocator_->allocate(stream_, bufferCount);
if (ret < 0)
return TestFail;
--
2.49.0
More information about the libcamera-devel
mailing list