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 <hiroh@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
Hirokazu Honda 2021-08-26 20:25:31 +09:00 committed by Laurent Pinchart
parent a000a1f6e3
commit 86a47fdcd9
3 changed files with 22 additions and 8 deletions

View file

@ -42,6 +42,7 @@ class FrameBuffer final : public Extensible
public:
struct Plane {
FileDescriptor fd;
unsigned int offset;
unsigned int length;
};

View file

@ -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

View file

@ -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;
}