[libcamera-devel] [PATCH v9 09/18] v4l2: Allocate buffers based on requested count and MinimumRequests

Paul Elder paul.elder at ideasonboard.com
Fri Dec 16 13:29:30 CET 2022


From: Nícolas F. R. A. Prado <nfraprado at collabora.com>

Currently the number of buffers allocated is based on bufferCount, which
is hardcoded to 1. Instead allocate buffers based on the requested count
and on the MinimumRequests property for the camera, which is accessed
through a newly added getter.

This allows the removal of bufferCount.

While at it, fix a typo: s/interval/internal/.

Signed-off-by: Nícolas F. R. A. Prado <nfraprado at collabora.com>
Reviewed-by: Paul Elder <paul.elder at ideasonboard.com>
Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>

---
Changes in v9:
- rebased

Changes in v8:
- New
- Fixed typo: s/interval/internal/
---
 src/v4l2/v4l2_camera.cpp       | 20 +++++++++++++-------
 src/v4l2/v4l2_camera.h         |  5 +++--
 src/v4l2/v4l2_camera_proxy.cpp | 10 +++++-----
 3 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp
index 1c5fab64..eb0fd239 100644
--- a/src/v4l2/v4l2_camera.cpp
+++ b/src/v4l2/v4l2_camera.cpp
@@ -12,6 +12,8 @@
 
 #include <libcamera/base/log.h>
 
+#include <libcamera/property_ids.h>
+
 using namespace libcamera;
 
 LOG_DECLARE_CATEGORY(V4L2Compat)
@@ -106,15 +108,13 @@ void V4L2Camera::requestComplete(Request *request)
 }
 
 int V4L2Camera::configure(StreamConfiguration *streamConfigOut,
-			  const Size &size, const PixelFormat &pixelformat,
-			  unsigned int bufferCount)
+			  const Size &size, const PixelFormat &pixelformat)
 {
 	StreamConfiguration &streamConfig = config_->at(0);
 	streamConfig.size.width = size.width;
 	streamConfig.size.height = size.height;
 	streamConfig.pixelFormat = pixelformat;
-	streamConfig.bufferCount = bufferCount;
-	/* \todo memoryType (interval vs external) */
+	/* \todo memoryType (internal vs external) */
 
 	CameraConfiguration::Status validation = config_->validate();
 	if (validation == CameraConfiguration::Invalid) {
@@ -145,7 +145,6 @@ int V4L2Camera::validateConfiguration(const PixelFormat &pixelFormat,
 	StreamConfiguration &cfg = config->at(0);
 	cfg.size = size;
 	cfg.pixelFormat = pixelFormat;
-	cfg.bufferCount = 1;
 
 	CameraConfiguration::Status validation = config->validate();
 	if (validation == CameraConfiguration::Invalid)
@@ -164,7 +163,9 @@ int V4L2Camera::allocBuffers(unsigned int count)
 	if (ret < 0)
 		return ret;
 
-	for (unsigned int i = 0; i < count; i++) {
+	unsigned int allocatedCount = ret;
+
+	for (unsigned int i = 0; i < allocatedCount; i++) {
 		std::unique_ptr<Request> request = camera_->createRequest(i);
 		if (!request) {
 			requestPool_.clear();
@@ -173,7 +174,7 @@ int V4L2Camera::allocBuffers(unsigned int count)
 		requestPool_.push_back(std::move(request));
 	}
 
-	return ret;
+	return allocatedCount;
 }
 
 void V4L2Camera::freeBuffers()
@@ -298,3 +299,8 @@ bool V4L2Camera::isRunning()
 {
 	return isRunning_;
 }
+
+unsigned int V4L2Camera::minimumRequests()
+{
+	return camera_->properties().get(properties::MinimumRequests).value();
+}
diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h
index d3483444..ada66421 100644
--- a/src/v4l2/v4l2_camera.h
+++ b/src/v4l2/v4l2_camera.h
@@ -43,8 +43,7 @@ public:
 
 	int configure(libcamera::StreamConfiguration *streamConfigOut,
 		      const libcamera::Size &size,
-		      const libcamera::PixelFormat &pixelformat,
-		      unsigned int bufferCount);
+		      const libcamera::PixelFormat &pixelformat);
 	int validateConfiguration(const libcamera::PixelFormat &pixelformat,
 				  const libcamera::Size &size,
 				  libcamera::StreamConfiguration *streamConfigOut);
@@ -63,6 +62,8 @@ public:
 
 	bool isRunning();
 
+	unsigned int minimumRequests();
+
 private:
 	void requestComplete(libcamera::Request *request)
 		LIBCAMERA_TSA_EXCLUDES(bufferLock_);
diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
index 55ff62cd..bcf9c2ab 100644
--- a/src/v4l2/v4l2_camera_proxy.cpp
+++ b/src/v4l2/v4l2_camera_proxy.cpp
@@ -367,8 +367,7 @@ int V4L2CameraProxy::vidioc_s_fmt(V4L2CameraFile *file, struct v4l2_format *arg)
 
 	Size size(arg->fmt.pix.width, arg->fmt.pix.height);
 	V4L2PixelFormat v4l2Format = V4L2PixelFormat(arg->fmt.pix.pixelformat);
-	ret = vcam_->configure(&streamConfig_, size, v4l2Format.toPixelFormat(),
-			       bufferCount_);
+	ret = vcam_->configure(&streamConfig_, size, v4l2Format.toPixelFormat());
 	if (ret < 0)
 		return -EINVAL;
 
@@ -514,14 +513,13 @@ int V4L2CameraProxy::vidioc_reqbufs(V4L2CameraFile *file, struct v4l2_requestbuf
 	Size size(v4l2PixFormat_.width, v4l2PixFormat_.height);
 	V4L2PixelFormat v4l2Format = V4L2PixelFormat(v4l2PixFormat_.pixelformat);
 	int ret = vcam_->configure(&streamConfig_, size,
-				   v4l2Format.toPixelFormat(), arg->count);
+				   v4l2Format.toPixelFormat());
 	if (ret < 0)
 		return -EINVAL;
 
 	setFmtFromConfig(streamConfig_);
 
-	arg->count = streamConfig_.bufferCount;
-	bufferCount_ = arg->count;
+	arg->count = std::max(arg->count, vcam_->minimumRequests());
 
 	ret = vcam_->allocBuffers(arg->count);
 	if (ret < 0) {
@@ -529,6 +527,8 @@ int V4L2CameraProxy::vidioc_reqbufs(V4L2CameraFile *file, struct v4l2_requestbuf
 		return ret;
 	}
 
+	bufferCount_ = arg->count = ret;
+
 	buffers_.resize(arg->count);
 	for (unsigned int i = 0; i < arg->count; i++) {
 		struct v4l2_buffer buf = {};
-- 
2.35.1



More information about the libcamera-devel mailing list