[libcamera-devel] [PATCH v3 08/33] libcamera: buffer: Add FrameBuffer interface

Niklas Söderlund niklas.soderlund at ragnatech.se
Fri Jan 10 20:37:43 CET 2020


Add a new FrameBuffer class to describe memory used to store frames.
This change just adds the new interface, future patches will migrate all
parts of libcamera to use this and replace the old Buffer interface.

This change needs to specify the const keyword for Plane::length() as to
not get Doxygen confused with FrameBuffer::Plane::length added in this
change.

Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
---
* Changes since v2
- Drop default value for planes argument for FrameBuffer::FrameBuffer(planes, cookie).
- Deleted FrameBuffer copy constructor and assignment operator.
- Add a Move constructor for FrameBuffer.
- Update documentation.

Changes since v1:
- Rename FrameBuffer::info() to FrameBuffer::metadata()
- Fixup commit message
- Reorder method order
- Rewrite documentation
- Add operator==() and operator=!() for FrameBuffer::Plane
---
 include/libcamera/buffer.h |  36 ++++++++++
 src/libcamera/buffer.cpp   | 130 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 165 insertions(+), 1 deletion(-)

diff --git a/include/libcamera/buffer.h b/include/libcamera/buffer.h
index 0b95e41a2dd205b2..f5522edaf68bbf61 100644
--- a/include/libcamera/buffer.h
+++ b/include/libcamera/buffer.h
@@ -11,6 +11,8 @@
 #include <stdint.h>
 #include <vector>
 
+#include <libcamera/file_descriptor.h>
+
 namespace libcamera {
 
 class Request;
@@ -33,6 +35,40 @@ struct FrameMetadata {
 	std::vector<Plane> planes;
 };
 
+class FrameBuffer final
+{
+public:
+	struct Plane {
+		FileDescriptor fd;
+		unsigned int length;
+	};
+
+	FrameBuffer(const std::vector<Plane> &planes, unsigned int cookie = 0);
+	FrameBuffer(FrameBuffer &&other);
+
+	FrameBuffer(const FrameBuffer &other) = delete;
+	FrameBuffer &operator=(const FrameBuffer &) = delete;
+
+	const std::vector<Plane> &planes() const { return planes_; }
+
+	Request *request() const { return request_; }
+	const FrameMetadata &metadata() const { return metadata_; };
+
+	unsigned int cookie() const { return cookie_; }
+	void setCookie(unsigned int cookie) { cookie_ = cookie; }
+
+private:
+	friend class Request; /* Needed to update request_. */
+	friend class V4L2VideoDevice; /* Needed to update metadata_. */
+
+	std::vector<Plane> planes_;
+
+	Request *request_;
+	FrameMetadata metadata_;
+
+	unsigned int cookie_;
+};
+
 class Plane final
 {
 public:
diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp
index b7bc948c80748b18..3e2cc9b94595795e 100644
--- a/src/libcamera/buffer.cpp
+++ b/src/libcamera/buffer.cpp
@@ -240,7 +240,7 @@ void *Plane::mem()
 }
 
 /**
- * \fn Plane::length()
+ * \fn Plane::length() const
  * \brief Retrieve the length of the memory region
  * \return The length of the memory region
  */
@@ -473,4 +473,132 @@ void Buffer::cancel()
  * The intended callers are Request::prepare() and Request::completeBuffer().
  */
 
+/**
+ * \class FrameBuffer
+ * \brief Frame buffer data and its associated dynamic metadata
+ *
+ * The FrameBuffer class is the primary interface for applications, IPAs and
+ * pipelines to interact with frame memory. It contains all the static and
+ * dynamic information to manage the whole life cycle of a frame capture, from
+ * buffer creation to consumption.
+ *
+ * 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.
+ *
+ * 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
+ * completion of the buffer as signaled by Camera::bufferComplete() until the
+ * FrameBuffer is either reused in a new request or deleted.
+ *
+ * The creator of a FrameBuffer (application, IPA or pipeline) may associate
+ * to it an integer cookie for any private purpose. The cookie may be set when
+ * creating the FrameBuffer, and updated at any time with setCookie(). The
+ * cookie is transparent to the libcamera core and shall only be set by the
+ * creator of the FrameBuffer. This mechanism supplements the Request cookie.
+ */
+
+/**
+ * \struct FrameBuffer::Plane
+ * \brief A memory region to store a single plane of a frame
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+/**
+ * \var FrameBuffer::Plane::fd
+ * \brief The dmabuf file descriptor
+ */
+
+/**
+ * \var FrameBuffer::Plane::length
+ * \brief The plane length in bytes
+ */
+
+/**
+ * \brief Construct a FrameBuffer with an array of planes
+ * \param[in] planes The frame memory planes
+ * \param[in] cookie Cookie
+ *
+ * The file descriptors associated with each plane are duplicated and can be
+ * closed by the caller after the FrameBuffer has been constructed.
+ */
+FrameBuffer::FrameBuffer(const std::vector<Plane> &planes, unsigned int cookie)
+	: planes_(planes), request_(nullptr), cookie_(cookie)
+{
+}
+
+/**
+ * \brief Move constructor, create a FrameBuffer by taking over \a other
+ * \param[in] other The other FrameBuffer
+ *
+ * The \a other FrameBuffer will be invalidated.
+ */
+FrameBuffer::FrameBuffer(FrameBuffer &&other)
+	: planes_(std::move(other.planes_)),
+	  request_(utils::exchange(other.request_, nullptr)),
+	  metadata_(std::move(other.metadata_)),
+	  cookie_(utils::exchange(other.cookie_, 0))
+{
+}
+
+/**
+ * \fn FrameBuffer::planes()
+ * \brief Retrieve the static plane descriptors
+ * \return Array of plane descriptors
+ */
+
+/**
+ * \fn FrameBuffer::request()
+ * \brief Retrieve the request this buffer belongs to
+ *
+ * The intended callers of this method are buffer completion handlers that
+ * need to associate a buffer to the request it belongs to.
+ *
+ * \return The Request the Buffer belongs to, or nullptr if the buffer is
+ * not associated with a request
+ */
+
+/**
+ * \fn FrameBuffer::metadata()
+ * \brief Retrieve the dynamic metadata
+ * \return Dynamic metadata for the frame contained in the buffer
+ */
+
+/**
+ * \fn FrameBuffer::cookie()
+ * \brief Retrieve the cookie
+ *
+ * The cookie belongs to the creator of the FrameBuffer, which controls its
+ * lifetime and value.
+ *
+ * \sa setCookie()
+ *
+ * \return The cookie
+ */
+
+/**
+ * \fn FrameBuffer::setCookie()
+ * \brief Set the cookie
+ * \param[in] cookie Cookie to set
+ *
+ * The cookie belongs to the creator of the FrameBuffer. Its value may be
+ * modified at any time with this method. Applications and IPAs shall not modify
+ * the cookie value of buffers they haven't created themselves. The libcamera
+ * core never modifies the buffer cookie.
+ */
+
 } /* namespace libcamera */
-- 
2.24.1



More information about the libcamera-devel mailing list