From 86a47fdcd97350bd979a4d6b00124330a3b02441 Mon Sep 17 00:00:00 2001 From: Hirokazu Honda Date: Thu, 26 Aug 2021 20:25:31 +0900 Subject: libcamera: framebuffer: Add offset to FrameBuffer::Plane This adds offset to FrameBuffer::Plane. It enables representing frame buffers that store planes in the same dmabuf at different offsets, as for instance required by the V4L2 NV12 pixel format. Signed-off-by: Hirokazu Honda Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart --- include/libcamera/framebuffer.h | 1 + src/libcamera/framebuffer.cpp | 24 +++++++++++++++++------- src/libcamera/ipa_data_serializer.cpp | 5 ++++- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/include/libcamera/framebuffer.h b/include/libcamera/framebuffer.h index 28307890..5de3c744 100644 --- a/include/libcamera/framebuffer.h +++ b/include/libcamera/framebuffer.h @@ -42,6 +42,7 @@ class FrameBuffer final : public Extensible public: struct Plane { FileDescriptor fd; + unsigned int offset; unsigned int length; }; diff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp index b401c50e..bf7a52ad 100644 --- a/src/libcamera/framebuffer.cpp +++ b/src/libcamera/framebuffer.cpp @@ -131,7 +131,7 @@ FrameBuffer::Private::Private() * * The static information describes the memory planes that make a frame. The * planes are specified when creating the FrameBuffer and are expressed as a set - * of dmabuf file descriptors and length. + * of dmabuf file descriptors, offset and length. * * The dynamic information is grouped in a FrameMetadata instance. It is updated * during the processing of a queued capture request, and is valid from the @@ -151,18 +151,23 @@ FrameBuffer::Private::Private() * * Planar pixel formats use multiple memory regions to store the different * colour components of a frame. The Plane structure describes such a memory - * region by a dmabuf file descriptor and a length. A FrameBuffer then - * contains one or multiple planes, depending on the pixel format of the - * frames it is meant to store. + * region by a dmabuf file descriptor, an offset within the dmabuf and a length. + * A FrameBuffer then contains one or multiple planes, depending on the pixel + * format of the frames it is meant to store. + * + * The offset identifies the location of the plane data from the start of the + * memory referenced by the dmabuf file descriptor. Multiple planes may be + * stored in the same dmabuf, in which case they will reference the same dmabuf + * and different offsets. No two planes may overlap, as specified by their + * offset and length. * * To support DMA access, planes are associated with dmabuf objects represented * by FileDescriptor handles. The Plane class doesn't handle mapping of the * memory to the CPU, but applications and IPAs may use the dmabuf file * descriptors to map the plane memory with mmap() and access its contents. * - * \todo Once we have a Kernel API which can express offsets within a plane - * this structure shall be extended to contain this information. See commit - * 83148ce8be55e for initial documentation of this feature. + * \todo Specify how an application shall decide whether to use a single or + * multiple dmabufs, based on the camera requirements. */ /** @@ -170,6 +175,11 @@ FrameBuffer::Private::Private() * \brief The dmabuf file descriptor */ +/** + * \var FrameBuffer::Plane::offset + * \brief The plane offset in bytes +*/ + /** * \var FrameBuffer::Plane::length * \brief The plane length in bytes diff --git a/src/libcamera/ipa_data_serializer.cpp b/src/libcamera/ipa_data_serializer.cpp index 5b183c70..82ec9b20 100644 --- a/src/libcamera/ipa_data_serializer.cpp +++ b/src/libcamera/ipa_data_serializer.cpp @@ -569,6 +569,7 @@ FileDescriptor IPADataSerializer::deserialize(const std::vector< * FrameBuffer::Plane is serialized as: * * 4 byte - FileDescriptor + * 4 bytes - uint32_t Offset * 4 bytes - uint32_t Length */ template<> @@ -586,6 +587,7 @@ IPADataSerializer::serialize(const FrameBuffer::Plane &data, dataVec.insert(dataVec.end(), fdBuf.begin(), fdBuf.end()); fdsVec.insert(fdsVec.end(), fdFds.begin(), fdFds.end()); + appendPOD(dataVec, data.offset); appendPOD(dataVec, data.length); return { dataVec, fdsVec }; @@ -603,7 +605,8 @@ IPADataSerializer::deserialize(std::vector::const_i ret.fd = IPADataSerializer::deserialize(dataBegin, dataBegin + 4, fdsBegin, fdsBegin + 1); - ret.length = readPOD(dataBegin, 4, dataEnd); + ret.offset = readPOD(dataBegin, 4, dataEnd); + ret.length = readPOD(dataBegin, 8, dataEnd); return ret; } -- cgit v1.2.1