diff options
Diffstat (limited to 'src/v4l2')
-rw-r--r-- | src/v4l2/v4l2_camera.cpp | 60 | ||||
-rw-r--r-- | src/v4l2/v4l2_camera.h | 39 | ||||
-rw-r--r-- | src/v4l2/v4l2_camera_proxy.cpp | 17 |
3 files changed, 55 insertions, 61 deletions
diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp index e4a03c41..10db15d6 100644 --- a/src/v4l2/v4l2_camera.cpp +++ b/src/v4l2/v4l2_camera.cpp @@ -16,24 +16,15 @@ using namespace libcamera; LOG_DECLARE_CATEGORY(V4L2Compat); -V4L2FrameMetadata::V4L2FrameMetadata(Buffer *buffer) - : index_(buffer->index()), - bytesused_(buffer->metadata().planes[0].bytesused), - timestamp_(buffer->metadata().timestamp), - sequence_(buffer->metadata().sequence), - status_(buffer->metadata().status) -{ -} - V4L2Camera::V4L2Camera(std::shared_ptr<Camera> camera) - : camera_(camera), isRunning_(false) + : camera_(camera), isRunning_(false), bufferAllocator_(nullptr) { camera_->requestCompleted.connect(this, &V4L2Camera::requestComplete); } V4L2Camera::~V4L2Camera() { - camera_->release(); + close(); } int V4L2Camera::open() @@ -50,11 +41,16 @@ int V4L2Camera::open() return -EINVAL; } + bufferAllocator_ = FrameBufferAllocator::create(camera_); + return 0; } void V4L2Camera::close() { + delete bufferAllocator_; + bufferAllocator_ = nullptr; + camera_->release(); } @@ -63,12 +59,12 @@ void V4L2Camera::getStreamConfig(StreamConfiguration *streamConfig) *streamConfig = config_->at(0); } -std::vector<V4L2FrameMetadata> V4L2Camera::completedBuffers() +std::vector<V4L2Camera::Buffer> V4L2Camera::completedBuffers() { - std::vector<V4L2FrameMetadata> v; + std::vector<Buffer> v; bufferLock_.lock(); - for (std::unique_ptr<V4L2FrameMetadata> &metadata : completedBuffers_) + for (std::unique_ptr<Buffer> &metadata : completedBuffers_) v.push_back(*metadata.get()); completedBuffers_.clear(); bufferLock_.unlock(); @@ -83,9 +79,9 @@ void V4L2Camera::requestComplete(Request *request) /* We only have one stream at the moment. */ bufferLock_.lock(); - Buffer *buffer = request->buffers().begin()->second; - std::unique_ptr<V4L2FrameMetadata> metadata = - utils::make_unique<V4L2FrameMetadata>(buffer); + FrameBuffer *buffer = request->buffers().begin()->second; + std::unique_ptr<Buffer> metadata = + utils::make_unique<Buffer>(request->cookie(), buffer->metadata()); completedBuffers_.push_back(std::move(metadata)); bufferLock_.unlock(); @@ -126,18 +122,31 @@ int V4L2Camera::configure(StreamConfiguration *streamConfigOut, int V4L2Camera::allocBuffers(unsigned int count) { int ret = camera_->allocateBuffers(); - return ret == -EACCES ? -EBUSY : ret; + if (ret) + return ret == -EACCES ? -EBUSY : ret; + + Stream *stream = *camera_->streams().begin(); + + return bufferAllocator_->allocate(stream); } void V4L2Camera::freeBuffers() { + Stream *stream = *camera_->streams().begin(); + bufferAllocator_->free(stream); camera_->freeBuffers(); } FileDescriptor V4L2Camera::getBufferFd(unsigned int index) { Stream *stream = *camera_->streams().begin(); - return stream->buffers()[index].planes()[0].fd; + const std::vector<std::unique_ptr<FrameBuffer>> &buffers = + bufferAllocator_->buffers(stream); + + if (buffers.size() <= index) + return FileDescriptor(); + + return buffers[index]->planes()[0].fd; } int V4L2Camera::streamOn() @@ -180,21 +189,16 @@ int V4L2Camera::streamOff() int V4L2Camera::qbuf(unsigned int index) { - Stream *stream = config_->at(0).stream(); - std::unique_ptr<Buffer> buffer = stream->createBuffer(index); - if (!buffer) { - LOG(V4L2Compat, Error) << "Can't create buffer"; - return -ENOMEM; - } - std::unique_ptr<Request> request = - std::unique_ptr<Request>(camera_->createRequest()); + std::unique_ptr<Request>(camera_->createRequest(index)); if (!request) { LOG(V4L2Compat, Error) << "Can't create request"; return -ENOMEM; } - int ret = request->addBuffer(stream, std::move(buffer)); + Stream *stream = config_->at(0).stream(); + FrameBuffer *buffer = bufferAllocator_->buffers(stream)[index].get(); + int ret = request->addBuffer(stream, buffer); if (ret < 0) { LOG(V4L2Compat, Error) << "Can't set buffer for request"; return -ENOMEM; diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h index 06eab0e1..f1f04d9e 100644 --- a/src/v4l2/v4l2_camera.h +++ b/src/v4l2/v4l2_camera.h @@ -9,50 +9,38 @@ #define __V4L2_CAMERA_H__ #include <deque> -#include <linux/videodev2.h> #include <mutex> +#include <utility> #include <libcamera/buffer.h> #include <libcamera/camera.h> #include <libcamera/file_descriptor.h> +#include <libcamera/framebuffer_allocator.h> #include "semaphore.h" using namespace libcamera; -class V4L2FrameMetadata +class V4L2Camera : public Object { public: - V4L2FrameMetadata(Buffer *buffer); - - int index() const { return index_; } - - unsigned int bytesused() const { return bytesused_; } - uint64_t timestamp() const { return timestamp_; } - unsigned int sequence() const { return sequence_; } - - FrameMetadata::Status status() const { return status_; } - -private: - int index_; + struct Buffer { + Buffer(unsigned int index, const FrameMetadata &data) + : index(index), data(data) + { + } - unsigned int bytesused_; - uint64_t timestamp_; - unsigned int sequence_; + unsigned int index; + FrameMetadata data; + }; - FrameMetadata::Status status_; -}; - -class V4L2Camera : public Object -{ -public: V4L2Camera(std::shared_ptr<Camera> camera); ~V4L2Camera(); int open(); void close(); void getStreamConfig(StreamConfiguration *streamConfig); - std::vector<V4L2FrameMetadata> completedBuffers(); + std::vector<Buffer> completedBuffers(); int configure(StreamConfiguration *streamConfigOut, const Size &size, PixelFormat pixelformat, @@ -78,9 +66,10 @@ private: bool isRunning_; std::mutex bufferLock_; + FrameBufferAllocator *bufferAllocator_; std::deque<std::unique_ptr<Request>> pendingRequests_; - std::deque<std::unique_ptr<V4L2FrameMetadata>> completedBuffers_; + std::deque<std::unique_ptr<Buffer>> completedBuffers_; }; #endif /* __V4L2_CAMERA_H__ */ diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp index 5158eac4..28e58722 100644 --- a/src/v4l2/v4l2_camera_proxy.cpp +++ b/src/v4l2/v4l2_camera_proxy.cpp @@ -187,17 +187,18 @@ void V4L2CameraProxy::querycap(std::shared_ptr<Camera> camera) void V4L2CameraProxy::updateBuffers() { - std::vector<V4L2FrameMetadata> completedBuffers = vcam_->completedBuffers(); - for (V4L2FrameMetadata &fmd : completedBuffers) { - struct v4l2_buffer &buf = buffers_[fmd.index()]; + 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]; - switch (fmd.status()) { + switch (fmd.status) { case FrameMetadata::FrameSuccess: - buf.bytesused = fmd.bytesused(); + buf.bytesused = fmd.planes[0].bytesused; buf.field = V4L2_FIELD_NONE; - buf.timestamp.tv_sec = fmd.timestamp() / 1000000000; - buf.timestamp.tv_usec = fmd.timestamp() % 1000000; - buf.sequence = fmd.sequence(); + buf.timestamp.tv_sec = fmd.timestamp / 1000000000; + buf.timestamp.tv_usec = fmd.timestamp % 1000000; + buf.sequence = fmd.sequence; buf.flags |= V4L2_BUF_FLAG_DONE; break; |