[libcamera-devel] [PATCH v3 1/9] libcamera: framebuffer: Add offset to FrameBuffer::Plane

Hirokazu Honda hiroh at chromium.org
Thu Aug 26 13:25:31 CEST 2021


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 <hiroh at chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 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<FileDescriptor>::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<FrameBuffer::Plane>::serialize(const FrameBuffer::Plane &data,
 	dataVec.insert(dataVec.end(), fdBuf.begin(), fdBuf.end());
 	fdsVec.insert(fdsVec.end(), fdFds.begin(), fdFds.end());
 
+	appendPOD<uint32_t>(dataVec, data.offset);
 	appendPOD<uint32_t>(dataVec, data.length);
 
 	return { dataVec, fdsVec };
@@ -603,7 +605,8 @@ IPADataSerializer<FrameBuffer::Plane>::deserialize(std::vector<uint8_t>::const_i
 
 	ret.fd = IPADataSerializer<FileDescriptor>::deserialize(dataBegin, dataBegin + 4,
 								fdsBegin, fdsBegin + 1);
-	ret.length = readPOD<uint32_t>(dataBegin, 4, dataEnd);
+	ret.offset = readPOD<uint32_t>(dataBegin, 4, dataEnd);
+	ret.length = readPOD<uint32_t>(dataBegin, 8, dataEnd);
 
 	return ret;
 }
-- 
2.33.0.rc2.250.ged5fa647cd-goog



More information about the libcamera-devel mailing list