From patchwork Tue Nov 26 23:35:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 2354 Return-Path: Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8E3EF61C59 for ; Wed, 27 Nov 2019 00:39:29 +0100 (CET) X-Halon-ID: fc4de60d-10a5-11ea-a0b9-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac5865.dip0.t-ipconnect.de [84.172.88.101]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id fc4de60d-10a5-11ea-a0b9-005056917f90; Wed, 27 Nov 2019 00:39:27 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 27 Nov 2019 00:35:56 +0100 Message-Id: <20191126233620.1695316-7-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191126233620.1695316-1-niklas.soderlund@ragnatech.se> References: <20191126233620.1695316-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 06/30] libcamera: buffer: Add FrameBuffer interface X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 Nov 2019 23:39:29 -0000 Add the FrameBuffer interface buffer implementation. 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 clarify the const for Plane::length() as to not get Doxygen confused with FrameBuffer::Plane::length added in this chance. Signed-off-by: Niklas Söderlund --- include/libcamera/buffer.h | 33 ++++++++++ src/libcamera/buffer.cpp | 130 ++++++++++++++++++++++++++++++++++++- 2 files changed, 162 insertions(+), 1 deletion(-) diff --git a/include/libcamera/buffer.h b/include/libcamera/buffer.h index 3c430afbfe8e9a05..fe5195327b540f5c 100644 --- a/include/libcamera/buffer.h +++ b/include/libcamera/buffer.h @@ -171,6 +171,39 @@ private: Stream *stream_; }; +class FrameBuffer final +{ +public: + struct Plane { + int fd; + unsigned int length; + }; + + FrameBuffer(std::vector planes, unsigned int cookie = 0); + ~FrameBuffer(); + + Request *request() const { return request_; } + const BufferInfo &info() const { return info_; }; + const std::vector &dmabufs() { return dmabufs_; } + + const std::vector &planes() const { return planes_; } + + 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 info_. */ + + Request *request_; + BufferInfo info_; + std::vector dmabufs_; + + std::vector planes_; + + unsigned int cookie_; +}; + } /* namespace libcamera */ #endif /* __LIBCAMERA_BUFFER_H__ */ diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp index 5516055b2ea885c2..07647124a2cd9c62 100644 --- a/src/libcamera/buffer.cpp +++ b/src/libcamera/buffer.cpp @@ -412,7 +412,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 */ @@ -645,4 +645,132 @@ void Buffer::cancel() * The intended callers are Request::prepare() and Request::completeBuffer(). */ +/** + * \class FrameBuffer + * \brief A buffer handle and dynamic metadata + * + * The FrameBuffer class references a buffer memory and associates dynamic + * metadata related to the frame contained in the buffer. It allows referencing + * buffer memory. + * + * A FrameBuffer object can be created from both internal and externally + * allocated dmabuf. + */ + +/** + * \struct FrameBuffer::Plane + * \brief Describe a DMA buffer using low level data + * + * The plane description contains a file descriptor and a length, together + * they represent a dmabuf. + */ + +/** + * \var FrameBuffer::Plane::fd + * \brief The dmabuf file handle + */ + +/** + * \var FrameBuffer::Plane::length + * \brief The dmabuf length + */ + +/** + * \brief Create a libcamera FrameBuffer object from an array of dmabufs + * \param[in] planes dmabufs described as planes + * \param[in] cookie Opaque cookie for application use + * + * Buffers used by libcamera might be allocated externally or internally to + * libcamera, the FrameBuffer object handles both cases. + * + * The \a cookie is stored in the buffer and is accessible through the + * cookie() method at any time. It is typically used by user to map the + * buffer to an external resource, and is completely opaque to the FrameBuffer + * object. + */ +FrameBuffer::FrameBuffer(std::vector planes, unsigned int cookie) + : request_(nullptr), cookie_(cookie) +{ + /* Clone all file descriptors and create dmabufs. */ + for (Plane plane : planes) + dmabufs_.push_back(new Dmabuf(plane.fd, plane.length)); + + /* Cache the new plane description for this frame buffer. */ + for (const Dmabuf *dmabuf : dmabufs_) { + Plane plane = { + .fd = dmabuf->fd(), + .length = dmabuf->length() + }; + + planes_.emplace_back(plane); + } +} + +FrameBuffer::~FrameBuffer() +{ + for (Dmabuf *dmabuf : dmabufs_) + delete dmabuf; +} + +/** + * \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. + * + * A Buffer is associated to a request by Request::prepare() and the + * association is valid until the buffer completes. The returned request + * pointer is valid only during that interval. + * + * \return The Request the Buffer belongs to, or nullptr if the buffer is + * either completed or not associated with a request + */ + +/** + * \fn FrameBuffer::info() + * \brief Retrieve the buffer metadata information + * + * The buffer metadata information is update every time the buffer contained + * are changed, for example when it is dequeued from hardware. + * + * \return Metadata of the buffer + */ + +/** + * \fn FrameBuffer::dmabufs() + * \brief Retrieve the Dmabuf(s) from the buffer + * + * This is intended for applications who wish to access the frame buffer + * content. The array returned is one item for each plane in the frame buffer. + * + * \return Array of Dmabuf(s) + */ + +/** + * \fn FrameBuffer::planes() + * \brief Retrieve the Dmabuf(s) as plane descriptions + * + * This is intended for internal libcamera use-cases where a frame buffer needs + * to be sent over an IPC barrier. Since IPC may be in the hot-path of capture + * a dedicated cached method is provided, the result might otherwise be + * constructed from information retrieved from dmabuf(). + * + * The array returned is one item for each plane in the frame buffer. + * + * \return Array of Dmabuf(s) as plane descriptions + */ + +/** + * \fn FrameBuffer::cookie() + * \brief Retrieve the cookie associated with the buffer + * \return The cookie + */ + +/** + * \fn FrameBuffer::setCookie() + * \brief Set the cookie associated with the buffer + * \param[in] cookie The cookie to set on the request + */ + } /* namespace libcamera */