summaryrefslogtreecommitdiff
path: root/src/v4l2
diff options
context:
space:
mode:
Diffstat (limited to 'src/v4l2')
-rw-r--r--src/v4l2/meson.build9
-rw-r--r--src/v4l2/v4l2_camera.cpp48
-rw-r--r--src/v4l2/v4l2_camera.h16
-rw-r--r--src/v4l2/v4l2_camera_proxy.cpp13
-rw-r--r--src/v4l2/v4l2_compat_manager.cpp15
5 files changed, 65 insertions, 36 deletions
diff --git a/src/v4l2/meson.build b/src/v4l2/meson.build
index e3838f0b..f78497b6 100644
--- a/src/v4l2/meson.build
+++ b/src/v4l2/meson.build
@@ -1,5 +1,12 @@
# SPDX-License-Identifier: CC0-1.0
+if not get_option('v4l2')
+ v4l2_enabled = false
+ subdir_done()
+endif
+
+v4l2_enabled = true
+
v4l2_compat_sources = files([
'v4l2_camera.cpp',
'v4l2_camera_file.cpp',
@@ -24,5 +31,5 @@ v4l2_compat = shared_library('v4l2-compat',
v4l2_compat_sources,
name_prefix : '',
install : true,
- dependencies : [ libcamera_dep, libdl ],
+ dependencies : [libcamera_private, libdl],
cpp_args : v4l2_compat_cpp_args)
diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp
index 3565f369..157ab94e 100644
--- a/src/v4l2/v4l2_camera.cpp
+++ b/src/v4l2/v4l2_camera.cpp
@@ -10,11 +10,11 @@
#include <errno.h>
#include <unistd.h>
-#include "libcamera/internal/log.h"
+#include <libcamera/base/log.h>
using namespace libcamera;
-LOG_DECLARE_CATEGORY(V4L2Compat);
+LOG_DECLARE_CATEGORY(V4L2Compat)
V4L2Camera::V4L2Camera(std::shared_ptr<Camera> camera)
: camera_(camera), isRunning_(false), bufferAllocator_(nullptr),
@@ -49,6 +49,8 @@ int V4L2Camera::open(StreamConfiguration *streamConfig)
void V4L2Camera::close()
{
+ requestPool_.clear();
+
delete bufferAllocator_;
bufferAllocator_ = nullptr;
@@ -96,6 +98,7 @@ void V4L2Camera::requestComplete(Request *request)
if (ret != sizeof(data))
LOG(V4L2Compat, Error) << "Failed to signal eventfd POLLIN";
+ request->reuse();
{
MutexLocker locker(bufferMutex_);
bufferAvailableCount_++;
@@ -154,16 +157,30 @@ int V4L2Camera::validateConfiguration(const PixelFormat &pixelFormat,
return 0;
}
-int V4L2Camera::allocBuffers([[maybe_unused]] unsigned int count)
+int V4L2Camera::allocBuffers(unsigned int count)
{
Stream *stream = config_->at(0).stream();
- return bufferAllocator_->allocate(stream);
+ int ret = bufferAllocator_->allocate(stream);
+ if (ret < 0)
+ return ret;
+
+ for (unsigned int i = 0; i < count; i++) {
+ std::unique_ptr<Request> request = camera_->createRequest(i);
+ if (!request) {
+ requestPool_.clear();
+ return -ENOMEM;
+ }
+ requestPool_.push_back(std::move(request));
+ }
+
+ return ret;
}
void V4L2Camera::freeBuffers()
{
pendingRequests_.clear();
+ requestPool_.clear();
Stream *stream = config_->at(0).stream();
bufferAllocator_->free(stream);
@@ -192,9 +209,9 @@ int V4L2Camera::streamOn()
isRunning_ = true;
- for (std::unique_ptr<Request> &req : pendingRequests_) {
+ for (Request *req : pendingRequests_) {
/* \todo What should we do if this returns -EINVAL? */
- ret = camera_->queueRequest(req.release());
+ ret = camera_->queueRequest(req);
if (ret < 0)
return ret == -EACCES ? -EBUSY : ret;
}
@@ -206,8 +223,12 @@ int V4L2Camera::streamOn()
int V4L2Camera::streamOff()
{
- if (!isRunning_)
+ if (!isRunning_) {
+ for (std::unique_ptr<Request> &req : requestPool_)
+ req->reuse();
+
return 0;
+ }
pendingRequests_.clear();
@@ -226,12 +247,11 @@ int V4L2Camera::streamOff()
int V4L2Camera::qbuf(unsigned int index)
{
- std::unique_ptr<Request> request =
- std::unique_ptr<Request>(camera_->createRequest(index));
- if (!request) {
- LOG(V4L2Compat, Error) << "Can't create request";
- return -ENOMEM;
+ if (index >= requestPool_.size()) {
+ LOG(V4L2Compat, Error) << "Invalid index";
+ return -EINVAL;
}
+ Request *request = requestPool_[index].get();
Stream *stream = config_->at(0).stream();
FrameBuffer *buffer = bufferAllocator_->buffers(stream)[index].get();
@@ -242,11 +262,11 @@ int V4L2Camera::qbuf(unsigned int index)
}
if (!isRunning_) {
- pendingRequests_.push_back(std::move(request));
+ pendingRequests_.push_back(request);
return 0;
}
- ret = camera_->queueRequest(request.release());
+ ret = camera_->queueRequest(request);
if (ret < 0) {
LOG(V4L2Compat, Error) << "Can't queue request";
return ret == -EACCES ? -EBUSY : ret;
diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h
index 1fc5ebef..a095f4e2 100644
--- a/src/v4l2/v4l2_camera.h
+++ b/src/v4l2/v4l2_camera.h
@@ -12,13 +12,13 @@
#include <mutex>
#include <utility>
-#include <libcamera/buffer.h>
+#include <libcamera/base/semaphore.h>
+
#include <libcamera/camera.h>
#include <libcamera/file_descriptor.h>
+#include <libcamera/framebuffer.h>
#include <libcamera/framebuffer_allocator.h>
-#include "libcamera/internal/semaphore.h"
-
using namespace libcamera;
class V4L2Camera
@@ -26,12 +26,12 @@ class V4L2Camera
public:
struct Buffer {
Buffer(unsigned int index, const FrameMetadata &data)
- : index(index), data(data)
+ : index_(index), data_(data)
{
}
- unsigned int index;
- FrameMetadata data;
+ unsigned int index_;
+ FrameMetadata data_;
};
V4L2Camera(std::shared_ptr<Camera> camera);
@@ -76,7 +76,9 @@ private:
std::mutex bufferLock_;
FrameBufferAllocator *bufferAllocator_;
- std::deque<std::unique_ptr<Request>> pendingRequests_;
+ std::vector<std::unique_ptr<Request>> requestPool_;
+
+ std::deque<Request *> pendingRequests_;
std::deque<std::unique_ptr<Buffer>> completedBuffers_;
int efd_;
diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
index 8ff990f6..7682c4bd 100644
--- a/src/v4l2/v4l2_camera_proxy.cpp
+++ b/src/v4l2/v4l2_camera_proxy.cpp
@@ -18,11 +18,12 @@
#include <libcamera/camera.h>
#include <libcamera/formats.h>
-#include <libcamera/object.h>
+
+#include <libcamera/base/log.h>
+#include <libcamera/base/object.h>
+#include <libcamera/base/utils.h>
#include "libcamera/internal/formats.h"
-#include "libcamera/internal/log.h"
-#include "libcamera/internal/utils.h"
#include "v4l2_camera.h"
#include "v4l2_camera_file.h"
@@ -32,7 +33,7 @@
using namespace libcamera;
-LOG_DECLARE_CATEGORY(V4L2Compat);
+LOG_DECLARE_CATEGORY(V4L2Compat)
V4L2CameraProxy::V4L2CameraProxy(unsigned int index,
std::shared_ptr<Camera> camera)
@@ -206,8 +207,8 @@ void V4L2CameraProxy::updateBuffers()
{
std::vector<V4L2Camera::Buffer> completedBuffers = vcam_->completedBuffers();
for (const V4L2Camera::Buffer &buffer : completedBuffers) {
- const FrameMetadata &fmd = buffer.data;
- struct v4l2_buffer &buf = buffers_[buffer.index];
+ const FrameMetadata &fmd = buffer.data_;
+ struct v4l2_buffer &buf = buffers_[buffer.index_];
switch (fmd.status) {
case FrameMetadata::FrameSuccess:
diff --git a/src/v4l2/v4l2_compat_manager.cpp b/src/v4l2/v4l2_compat_manager.cpp
index 90c0f012..e566125a 100644
--- a/src/v4l2/v4l2_compat_manager.cpp
+++ b/src/v4l2/v4l2_compat_manager.cpp
@@ -19,11 +19,12 @@
#include <sys/types.h>
#include <unistd.h>
+#include <libcamera/base/log.h>
+#include <libcamera/base/utils.h>
+
#include <libcamera/camera.h>
#include <libcamera/camera_manager.h>
-#include "libcamera/internal/log.h"
-
#include "v4l2_camera_file.h"
using namespace libcamera;
@@ -81,11 +82,10 @@ int V4L2CompatManager::start()
* For each Camera registered in the system, a V4L2CameraProxy gets
* created here to wrap a camera device.
*/
- unsigned int index = 0;
- for (auto &camera : cm_->cameras()) {
+ auto cameras = cm_->cameras();
+ for (auto [index, camera] : utils::enumerate(cameras)) {
V4L2CameraProxy *proxy = new V4L2CameraProxy(index, camera);
proxies_.emplace_back(proxy);
- ++index;
}
return 0;
@@ -117,11 +117,10 @@ int V4L2CompatManager::getCameraIndex(int fd)
if (!target)
return -1;
- unsigned int index = 0;
- for (auto &camera : cm_->cameras()) {
+ auto cameras = cm_->cameras();
+ for (auto [index, camera] : utils::enumerate(cameras)) {
if (camera == target)
return index;
- ++index;
}
return -1;