summaryrefslogtreecommitdiff
path: root/src/libcamera/v4l2_videodevice.cpp
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2019-07-09 18:08:07 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2019-07-14 16:00:54 +0300
commita2bcf6feee5ae6077225cc787c3d1a25d9ef95e7 (patch)
treeb654f7e4a25852edba8ba1ecaff86779ccddb25e /src/libcamera/v4l2_videodevice.cpp
parent9bb36ec274da530e509fe2f4010b262c43e812f3 (diff)
libcamera: buffer: Split memory information to BufferMemory
The Buffer class is a large beast the stores information about the buffer memory, dynamic metadata related to the frame stored in the buffer, and buffer reference data (in the index). In order to implement buffer import we will need to extend this with dmabuf file descriptors, making usage of the class even more complex. Refactor the Buffer class by splitting the buffer memory information to a BufferMemory class, and repurposing the Buffer class to reference a buffer and to store dynamic metadata. The BufferMemory class becomes a long term storage, valid and stable from the time buffer memory is allocated to the time it is freed. The Buffer class, on the other hand, becomes transient, is created on demand when an application requires a buffer, is given to a request, and is deleted when the request completes. Buffer and BufferMemory don't need to be copied, so their copy constructor and assignment operators are deleted. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Diffstat (limited to 'src/libcamera/v4l2_videodevice.cpp')
-rw-r--r--src/libcamera/v4l2_videodevice.cpp40
1 files changed, 22 insertions, 18 deletions
diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
index 0ab92b3a..86e299c0 100644
--- a/src/libcamera/v4l2_videodevice.cpp
+++ b/src/libcamera/v4l2_videodevice.cpp
@@ -268,8 +268,7 @@ const std::string V4L2DeviceFormat::toString() const
* \param[in] deviceNode The file-system path to the video device node
*/
V4L2VideoDevice::V4L2VideoDevice(const std::string &deviceNode)
- : V4L2Device(deviceNode), bufferPool_(nullptr),
- queuedBuffersCount_(0), fdEvent_(nullptr)
+ : V4L2Device(deviceNode), bufferPool_(nullptr), fdEvent_(nullptr)
{
/*
* We default to an MMAP based CAPTURE video device, however this will
@@ -764,7 +763,7 @@ int V4L2VideoDevice::exportBuffers(BufferPool *pool)
for (i = 0; i < pool->count(); ++i) {
struct v4l2_plane planes[VIDEO_MAX_PLANES] = {};
struct v4l2_buffer buf = {};
- Buffer &buffer = pool->buffers()[i];
+ BufferMemory &buffer = pool->buffers()[i];
buf.index = i;
buf.type = bufferType_;
@@ -782,13 +781,13 @@ int V4L2VideoDevice::exportBuffers(BufferPool *pool)
if (V4L2_TYPE_IS_MULTIPLANAR(buf.type)) {
for (unsigned int p = 0; p < buf.length; ++p) {
- ret = createPlane(&buffer, p,
+ ret = createPlane(&buffer, i, p,
buf.m.planes[p].length);
if (ret)
break;
}
} else {
- ret = createPlane(&buffer, 0, buf.length);
+ ret = createPlane(&buffer, i, 0, buf.length);
}
if (ret) {
@@ -808,19 +807,19 @@ int V4L2VideoDevice::exportBuffers(BufferPool *pool)
return 0;
}
-int V4L2VideoDevice::createPlane(Buffer *buffer, unsigned int planeIndex,
- unsigned int length)
+int V4L2VideoDevice::createPlane(BufferMemory *buffer, unsigned int index,
+ unsigned int planeIndex, unsigned int length)
{
struct v4l2_exportbuffer expbuf = {};
int ret;
LOG(V4L2, Debug)
- << "Buffer " << buffer->index()
+ << "Buffer " << index
<< " plane " << planeIndex
<< ": length=" << length;
expbuf.type = bufferType_;
- expbuf.index = buffer->index();
+ expbuf.index = index;
expbuf.plane = planeIndex;
expbuf.flags = O_RDWR;
@@ -904,7 +903,8 @@ int V4L2VideoDevice::queueBuffer(Buffer *buffer)
buf.field = V4L2_FIELD_NONE;
bool multiPlanar = V4L2_TYPE_IS_MULTIPLANAR(buf.type);
- const std::vector<Plane> &planes = buffer->planes();
+ BufferMemory *mem = &bufferPool_->buffers()[buf.index];
+ const std::vector<Plane> &planes = mem->planes();
if (buf.memory == V4L2_MEMORY_DMABUF) {
if (multiPlanar) {
@@ -937,9 +937,11 @@ int V4L2VideoDevice::queueBuffer(Buffer *buffer)
return ret;
}
- if (queuedBuffersCount_++ == 0)
+ if (queuedBuffers_.empty())
fdEvent_->setEnabled(true);
+ queuedBuffers_[buf.index] = buffer;
+
return 0;
}
@@ -970,7 +972,7 @@ std::vector<std::unique_ptr<Buffer>> V4L2VideoDevice::queueAllBuffers()
{
int ret;
- if (queuedBuffersCount_)
+ if (!queuedBuffers_.empty())
return {};
if (V4L2_TYPE_IS_OUTPUT(bufferType_))
@@ -979,8 +981,7 @@ std::vector<std::unique_ptr<Buffer>> V4L2VideoDevice::queueAllBuffers()
std::vector<std::unique_ptr<Buffer>> buffers;
for (unsigned int i = 0; i < bufferPool_->count(); ++i) {
- Buffer *buffer = new Buffer();
- buffer->index_ = i;
+ Buffer *buffer = new Buffer(i);
buffers.emplace_back(buffer);
ret = queueBuffer(buffer);
if (ret)
@@ -1021,11 +1022,14 @@ Buffer *V4L2VideoDevice::dequeueBuffer()
ASSERT(buf.index < bufferPool_->count());
- if (--queuedBuffersCount_ == 0)
- fdEvent_->setEnabled(false);
+ auto it = queuedBuffers_.find(buf.index);
+ Buffer *buffer = it->second;
+ queuedBuffers_.erase(it);
- Buffer *buffer = &bufferPool_->buffers()[buf.index];
+ if (queuedBuffers_.empty())
+ fdEvent_->setEnabled(false);
+ buffer->index_ = buf.index;
buffer->bytesused_ = buf.bytesused;
buffer->timestamp_ = buf.timestamp.tv_sec * 1000000000ULL
+ buf.timestamp.tv_usec * 1000ULL;
@@ -1100,7 +1104,7 @@ int V4L2VideoDevice::streamOff()
return ret;
}
- queuedBuffersCount_ = 0;
+ queuedBuffers_.clear();
fdEvent_->setEnabled(false);
return 0;