@@ -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();
+}
@@ -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_);
@@ -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 = {};