[libcamera-devel] [PATCH v2 12/16] libcamera: buffer: Add dmabuf file descriptors
Jacopo Mondi
jacopo at jmondi.org
Sun Jul 14 09:22:31 CEST 2019
Hi Laurent,
thanks for the update
On Sat, Jul 13, 2019 at 08:23:47PM +0300, Laurent Pinchart wrote:
> From: Jacopo Mondi <jacopo at jmondi.org>
>
> In addition to referencing buffer memory by index, add support to
> referencing it using dmabuf file descriptors. This will be used to
> reference buffer memory allocated outside of libcamera and import it.
>
> The dmabuf file descriptors are stored in an array in the Buffer class,
> and a new Stream::createBuffer() overload is added to construct a buffer
> from dmabuf file descriptor.
>
> Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
> include/libcamera/buffer.h | 3 +++
> include/libcamera/stream.h | 1 +
> src/libcamera/buffer.cpp | 13 ++++++++++-
> src/libcamera/request.cpp | 5 ++++
> src/libcamera/stream.cpp | 47 +++++++++++++++++++++++++++++++++++++-
> 5 files changed, 67 insertions(+), 2 deletions(-)
>
> diff --git a/include/libcamera/buffer.h b/include/libcamera/buffer.h
> index f5ba6207bcef..f8569a6b67f3 100644
> --- a/include/libcamera/buffer.h
> +++ b/include/libcamera/buffer.h
> @@ -7,6 +7,7 @@
> #ifndef __LIBCAMERA_BUFFER_H__
> #define __LIBCAMERA_BUFFER_H__
>
> +#include <array>
> #include <stdint.h>
> #include <vector>
>
> @@ -75,6 +76,7 @@ public:
> Buffer &operator=(const Buffer &) = delete;
>
> unsigned int index() const { return index_; }
> + const std::array<int, 3> &dmabufs() const { return dmabuf_; }
>
> unsigned int bytesused() const { return bytesused_; }
> uint64_t timestamp() const { return timestamp_; }
> @@ -95,6 +97,7 @@ private:
> void setRequest(Request *request) { request_ = request; }
>
> unsigned int index_;
> + std::array<int, 3> dmabuf_;
>
> unsigned int bytesused_;
> uint64_t timestamp_;
> diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h
> index 08eb8cc7d5c7..1883d9e9b9c5 100644
> --- a/include/libcamera/stream.h
> +++ b/include/libcamera/stream.h
> @@ -75,6 +75,7 @@ public:
> Stream();
>
> std::unique_ptr<Buffer> createBuffer(unsigned int index);
> + std::unique_ptr<Buffer> createBuffer(const std::array<int, 3> &fds);
>
> BufferPool &bufferPool() { return bufferPool_; }
> std::vector<BufferMemory> &buffers() { return bufferPool_.buffers(); }
> diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp
> index ecbf25246a55..99358633a088 100644
> --- a/src/libcamera/buffer.cpp
> +++ b/src/libcamera/buffer.cpp
> @@ -269,7 +269,8 @@ void BufferPool::destroyBuffers()
> * for a stream with Stream::createBuffer().
> */
> Buffer::Buffer(unsigned int index, const Buffer *metadata)
> - : index_(index), status_(Buffer::BufferSuccess), request_(nullptr),
> + : index_(index), dmabuf_({ -1, -1, -1 }),
> + status_(Buffer::BufferSuccess), request_(nullptr),
> stream_(nullptr)
> {
> if (metadata) {
> @@ -289,6 +290,16 @@ Buffer::Buffer(unsigned int index, const Buffer *metadata)
> * \return The buffer index
> */
>
> +/**
> + * \fn Buffer::dmabufs()
> + * \brief Retrieve the dmabuf file descriptors for all buffer planes
> + *
> + * The dmabufs array contains one dmabuf file descriptor per plane. Unused
> + * entries are set to -1.
> + *
> + * \return The dmabuf file descriptors
> + */
> +
> /**
> * \fn Buffer::bytesused()
> * \brief Retrieve the number of bytes occupied by the data in the buffer
> diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp
> index 19131472710b..ee2158fc7a9c 100644
> --- a/src/libcamera/request.cpp
> +++ b/src/libcamera/request.cpp
> @@ -106,10 +106,15 @@ Request::~Request()
> *
> * \return 0 on success or a negative error code otherwise
> * \retval -EEXIST The request already contains a buffer for the stream
> + * \retval -EINVAL The buffer does not reference a valid Stream
> */
> int Request::addBuffer(std::unique_ptr<Buffer> buffer)
> {
> Stream *stream = buffer->stream();
> + if (!stream) {
> + LOG(Request, Error) << "Invalid stream reference";
> + return -EINVAL;
> + }
>
> auto it = bufferMap_.find(stream);
> if (it != bufferMap_.end()) {
> diff --git a/src/libcamera/stream.cpp b/src/libcamera/stream.cpp
> index 94aa4810f6b9..e6aa1b643a37 100644
> --- a/src/libcamera/stream.cpp
> +++ b/src/libcamera/stream.cpp
> @@ -424,17 +424,26 @@ Stream::Stream()
> }
>
> /**
> - * \brief Create a Buffer instance
> + * \brief Create a Buffer instance referencing the memory buffer \a index
> * \param[in] index The desired buffer index
> *
> * This method creates a Buffer instance that references a BufferMemory from
> * the stream's buffers pool by its \a index. The index shall be lower than the
> * number of buffers in the pool.
> *
> + * This method is only valid for streams that use the InternalMemory type. It
> + * will return a null pointer when called on streams using the ExternalMemory
> + * type.
> + *
> * \return A newly created Buffer on success or nullptr otherwise
> */
> std::unique_ptr<Buffer> Stream::createBuffer(unsigned int index)
> {
> + if (memoryType_ != InternalMemory) {
> + LOG(Stream, Error) << "Invalid stream memory type";
> + return nullptr;
> + }
> +
> if (index >= bufferPool_.count()) {
> LOG(Stream, Error) << "Invalid buffer index " << index;
> return nullptr;
> @@ -447,6 +456,42 @@ std::unique_ptr<Buffer> Stream::createBuffer(unsigned int index)
> return std::unique_ptr<Buffer>(buffer);
> }
>
> +/**
> + * \brief Create a Buffer instance that represents a memory area identified by
> + * dmabuf file descriptors
> + * \param[in] fds The dmabuf file descriptors for each plane
> + *
> + * This method creates a Buffer instance that references buffer memory
> + * allocated outside of libcamera through dmabuf file descriptors. The \a
> + * dmabuf array shall contain a file descriptor for each plane in the buffer,
> + * and unused entries shall be set to -1.
> + *
> + * The buffer is created without a valid index, as it does not yet map to any of
> + * the stream's BufferMemory instances. An index will be assigned at the time
> + * the buffer is queued to the camera in a request. Applications may thus
> + * create any number of Buffer instances, providing that no more than the
> + * number of buffers allocated for the stream are queued at any given time.
> + *
> + * This method is only valid for streams that use the InternalMemory type. It
> + * will return a null pointer when called on streams using the ExternalMemory
> + * type.
It's actually the other way around!
Thanks
j
> + *
> + * \return A newly created Buffer on success or nullptr otherwise
> + */
> +std::unique_ptr<Buffer> Stream::createBuffer(const std::array<int, 3> &fds)
> +{
> + if (memoryType_ != ExternalMemory) {
> + LOG(Stream, Error) << "Invalid stream memory type";
> + return nullptr;
> + }
> +
> + Buffer *buffer = new Buffer();
> + buffer->dmabuf_ = fds;
> + buffer->stream_ = this;
> +
> + return std::unique_ptr<Buffer>(buffer);
> +}
> +
> /**
> * \fn Stream::bufferPool()
> * \brief Retrieve the buffer pool for the stream
> --
> Regards,
>
> Laurent Pinchart
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel at lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://lists.libcamera.org/pipermail/libcamera-devel/attachments/20190714/828c8738/attachment.sig>
More information about the libcamera-devel
mailing list