From patchwork Tue Jan 29 13:53:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 441 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2CEE260DB6 for ; Tue, 29 Jan 2019 14:54:02 +0100 (CET) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 9887185; Tue, 29 Jan 2019 14:54:01 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1548770041; bh=mpJhigK67X9Dl/OhAeAIAWF/WJ/ksRHJbPvIx1oPqMc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OjSxGv0bWICmo5gj2TG37zW9ePNc/XjPx+BPYsdaxUIdY8MyzPxnu+W3oA3Hg1c3r 9IJrM+FTu8sJBJe2rVZRMT8iq9DIqyLOk22CGSAmxMBwY88YlIrKE/N00+e/lg+d2t f3vMtupo3Wt6zCL31nEcDCMkfek/esiwfnkT4mHY= From: Kieran Bingham To: LibCamera Devel Date: Tue, 29 Jan 2019 13:53:54 +0000 Message-Id: <20190129135357.32339-2-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190129135357.32339-1-kieran.bingham@ideasonboard.com> References: <20190129135357.32339-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/4] libcamera: Add Buffer and BufferPool classes X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Jan 2019 13:54:02 -0000 From: Laurent Pinchart Provide classes that represent frame buffers and pools of frame buffers. Signed-off-by: Laurent Pinchart Signed-off-by: Kieran Bingham --- Kieran - Fix checkstyle.py diff --- include/libcamera/buffer.h | 55 ++++++++++++++++++ include/libcamera/libcamera.h | 1 + include/libcamera/meson.build | 1 + src/libcamera/buffer.cpp | 102 ++++++++++++++++++++++++++++++++++ src/libcamera/meson.build | 1 + 5 files changed, 160 insertions(+) create mode 100644 include/libcamera/buffer.h create mode 100644 src/libcamera/buffer.cpp diff --git a/include/libcamera/buffer.h b/include/libcamera/buffer.h new file mode 100644 index 000000000000..97c8025d9e77 --- /dev/null +++ b/include/libcamera/buffer.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018, Google Inc. + * + * buffer.h - Buffer handling + */ +#ifndef __LIBCAMERA_BUFFER_H__ +#define __LIBCAMERA_BUFFER_H__ + +#include + +namespace libcamera { + +class Buffer +{ +public: + Buffer(); + ~Buffer(); + + int dmabuf() const { return fd_; }; + int setDmabuf(int fd); + + int mmap(); + void munmap(); + +private: + int fd_; +}; + +class BufferPool +{ +public: + enum Memory { + Internal, + External, + }; + + BufferPool(Memory memory); + virtual ~BufferPool(); + + int allocate(unsigned int count); + void free(); + + unsigned int count() const { return buffers_.size(); }; + +private: + virtual int allocateMemory() = 0; + + BufferPool::Memory memory_; + std::vector buffers_; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_BUFFER_H__ */ diff --git a/include/libcamera/libcamera.h b/include/libcamera/libcamera.h index c0511cf6d662..6619e556ebbd 100644 --- a/include/libcamera/libcamera.h +++ b/include/libcamera/libcamera.h @@ -7,6 +7,7 @@ #ifndef __LIBCAMERA_LIBCAMERA_H__ #define __LIBCAMERA_LIBCAMERA_H__ +#include #include #include #include diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build index d7cb55ba4a49..8fcbbf7892ea 100644 --- a/include/libcamera/meson.build +++ b/include/libcamera/meson.build @@ -1,4 +1,5 @@ libcamera_api = files([ + 'buffer.h', 'camera.h', 'camera_manager.h', 'event_dispatcher.h', diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp new file mode 100644 index 000000000000..6dfebfc6bb28 --- /dev/null +++ b/src/libcamera/buffer.cpp @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018, Google Inc. + * + * buffer.cpp - Buffer handling + */ + +#include +#include + +#include + +/** + * \file buffer.h + * \brief Buffer handling + */ + +namespace libcamera { + +/** + * \class Buffer + * \brief A memory buffer to store a frame + * + * The Buffer class represents a memory buffer used to store a frame. + */ +Buffer::Buffer() + : fd_(-1) +{ +} + +Buffer::~Buffer() +{ + if (fd_ != -1) + close(fd_); +} + +/** + * \fn Buffer::dmabuf() + * \brief Get the dmabuf file handle backing the buffer + */ + +/** + * \brief Set the dmabuf file handle backing the buffer + * + * The \a fd dmabuf file handle is duplicated and stored. + */ +int Buffer::setDmabuf(int fd) +{ + if (fd_ != -1) { + close(fd_); + fd_ = -1; + } + + if (fd != -1) + return 0; + + fd_ = dup(fd); + if (fd_ == -1) + return -errno; + + return 0; +} + +/** + * \class BufferPool + * \brief A pool of buffers + */ +BufferPool::BufferPool(BufferPool::Memory memory) + : memory_(memory) +{ +} + +BufferPool::~BufferPool() +{ + free(); +} + +int BufferPool::allocate(unsigned int count) +{ + for (unsigned int i = 0; i < count; ++i) { + Buffer *buffer = new Buffer(); + buffers_.push_back(buffer); + } + + if (memory_ == Memory::Internal) { + int ret = allocateMemory(); + if (ret < 0) + return ret; + } + + return 0; +} + +void BufferPool::free() +{ + for (Buffer *buffer : buffers_) + delete buffer; + + buffers_.clear(); +} + +} /* namespace libcamera */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index f9f25c0ecf15..b5b25965fd12 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -1,4 +1,5 @@ libcamera_sources = files([ + 'buffer.cpp', 'camera.cpp', 'camera_manager.cpp', 'device_enumerator.cpp', From patchwork Tue Jan 29 13:53:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 442 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 60E2260DB9 for ; Tue, 29 Jan 2019 14:54:02 +0100 (CET) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id ECA8E2F5; Tue, 29 Jan 2019 14:54:01 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1548770042; bh=tWyZl+2uCZsk1WDXmI44TZGPn6aXbCqwQIT7f9XvXOY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tL5bEWQybWSAX2mRAi45p6hPl7CGOEo7tvB2OGG8E27hO1l+kDf0JG/4QV1DmJetw iJc7mdIJeB+jEfgQlSIMUoaVSS8OeGksJrt0S/4M1Dh9bfyT17E+85ZCbypZFc/uO6 AItP70Jr3w2QSuFWat6akAzuxXhaT0gz5ngH1yFM= From: Kieran Bingham To: LibCamera Devel Date: Tue, 29 Jan 2019 13:53:55 +0000 Message-Id: <20190129135357.32339-3-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190129135357.32339-1-kieran.bingham@ideasonboard.com> References: <20190129135357.32339-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/4] libcamera: buffer: Document the BufferPool X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Jan 2019 13:54:02 -0000 Add Doxygen documentation for the existing code in the BufferPool class. Signed-off-by: Kieran Bingham --- src/libcamera/buffer.cpp | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp index 6dfebfc6bb28..5c580b540a67 100644 --- a/src/libcamera/buffer.cpp +++ b/src/libcamera/buffer.cpp @@ -64,6 +64,37 @@ int Buffer::setDmabuf(int fd) /** * \class BufferPool * \brief A pool of buffers + * + * The BufferPool class groups together a collection of Buffers for passing + * between devices. The buffers must be exported by a device before they can be + * imported into another device for further use. + */ + +/** + * \enum BufferPool::Memory + * \brief Identify the memory type used in the BufferPool + */ + +/** + * \var BufferPool::Internal + * \brief The memory for the Buffers in this pool is allocated internally by the + * device associated with the pool + */ + +/** + * \var BufferPool::External + * \brief The memory for the Buffers in this pool is allocated externally by + * another device and can be imported for use by other devices. + * + * The buffers in the pool have been exported to make them available for sharing + * with other devices, and can be managed using their own file descriptors. + */ + +/** + * \brief Construct a buffer pool. The \a memory argument declares the intent of + * the pool to be either internal or external to a device. + * + * \sa BufferPool::Memory */ BufferPool::BufferPool(BufferPool::Memory memory) : memory_(memory) @@ -75,6 +106,9 @@ BufferPool::~BufferPool() free(); } +/** + * \brief Allocate buffers in a pool + */ int BufferPool::allocate(unsigned int count) { for (unsigned int i = 0; i < count; ++i) { @@ -91,6 +125,9 @@ int BufferPool::allocate(unsigned int count) return 0; } +/** + * \brief Release all buffers from pool. + */ void BufferPool::free() { for (Buffer *buffer : buffers_) @@ -99,4 +136,9 @@ void BufferPool::free() buffers_.clear(); } +/** + * \fn BufferPool::count() + * \brief Get the number of Buffers contained within this pool + */ + } /* namespace libcamera */ From patchwork Tue Jan 29 13:53:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 443 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9E7B260DB9 for ; Tue, 29 Jan 2019 14:54:02 +0100 (CET) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 409AB41; Tue, 29 Jan 2019 14:54:02 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1548770042; bh=khPrAXSUDdvHG6oC9UX0l6d1zbgeRJ1DZZlS0YUpEvU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=D3HtYr/OgjugldA0fpAQ2lbEd/f2grgndEmAFV/GRJOTGnugokIAjvAt3MYVNgQlk TeIq1wnbLcz8pFh4kH9RbM4Bfsm0GtyyWVibljmlG834QdKpVJoerIKsAHDlC6vSpk A9lsoXVfw3csEQmFOl/kfN7N6b23/4ChaehGXqjs= From: Kieran Bingham To: LibCamera Devel Date: Tue, 29 Jan 2019 13:53:56 +0000 Message-Id: <20190129135357.32339-4-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190129135357.32339-1-kieran.bingham@ideasonboard.com> References: <20190129135357.32339-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/4] libcamera: buffer: Provide access to the Buffer vector X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Jan 2019 13:54:02 -0000 Extend the BufferPool to support retrieving Buffers by receiving a reference to the buffer vector. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- include/libcamera/buffer.h | 1 + src/libcamera/buffer.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/include/libcamera/buffer.h b/include/libcamera/buffer.h index 97c8025d9e77..dda5075f2879 100644 --- a/include/libcamera/buffer.h +++ b/include/libcamera/buffer.h @@ -42,6 +42,7 @@ public: void free(); unsigned int count() const { return buffers_.size(); }; + const std::vector &buffers() { return buffers_; }; private: virtual int allocateMemory() = 0; diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp index 5c580b540a67..4a870df77e92 100644 --- a/src/libcamera/buffer.cpp +++ b/src/libcamera/buffer.cpp @@ -141,4 +141,9 @@ void BufferPool::free() * \brief Get the number of Buffers contained within this pool */ +/** + * \fn BufferPool::buffers() + * \brief Return a reference to the vector holding all buffers within the pool + */ + } /* namespace libcamera */ From patchwork Tue Jan 29 13:53:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 444 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EACD260DB9 for ; Tue, 29 Jan 2019 14:54:02 +0100 (CET) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 8835885; Tue, 29 Jan 2019 14:54:02 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1548770042; bh=sIZk/gpukKuccbysgUiSbY0jibrHL3/r1lTLI6PakHM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SinKuUWP1r3SwleqHDdeukevpuNPm+VtTjR74gcjTiIE9s3fstTfrNjGWapKwOe1/ ejZPRRtfXxrI+lJKfitPPIRutq137rySnUAYWq9jl+fF4ZEJh+afQjdWwDl+46aR7i liKw5oPZrAP4YpgYSCvRXd2RvbpuaeDOYjJzlnzg= From: Kieran Bingham To: LibCamera Devel Date: Tue, 29 Jan 2019 13:53:57 +0000 Message-Id: <20190129135357.32339-5-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190129135357.32339-1-kieran.bingham@ideasonboard.com> References: <20190129135357.32339-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 4/4] libcamera: buffer: Provide Buffer Planes X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Jan 2019 13:54:03 -0000 Extend the Buffer management to support multi-planar formats. An image within the system may use one or more Plane objects to track each plane in the case of multi-planar image formats. The Buffer class manages all of the data required to render or interpret the raw image data. Signed-off-by: Kieran Bingham --- include/libcamera/buffer.h | 38 +++++++- src/libcamera/buffer.cpp | 189 +++++++++++++++++++++++++++++++++++-- 2 files changed, 215 insertions(+), 12 deletions(-) diff --git a/include/libcamera/buffer.h b/include/libcamera/buffer.h index dda5075f2879..08a74fb70b88 100644 --- a/include/libcamera/buffer.h +++ b/include/libcamera/buffer.h @@ -11,20 +11,50 @@ namespace libcamera { -class Buffer +class Plane { public: - Buffer(); - ~Buffer(); + Plane(); + Plane(unsigned int length, unsigned int offset); + ~Plane(); int dmabuf() const { return fd_; }; int setDmabuf(int fd); + int mmap(int fd); int mmap(); - void munmap(); + int munmap(); + + unsigned int length() const { return length_; }; + void *mem() const { return mem_; }; private: int fd_; + unsigned int length_; + unsigned int offset_; + void *mem_; +}; + +class Buffer +{ +public: + Buffer(); + virtual ~Buffer(); + + int mmap(int fd); + int munmap(); + + unsigned int index() const { return index_; }; + const std::vector &planes() { return planes_; }; + +private: + unsigned int index_; + + unsigned int format_; + unsigned int width_; + unsigned int height_; + + std::vector planes_; }; class BufferPool diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp index 4a870df77e92..7b84a97dcd2b 100644 --- a/src/libcamera/buffer.cpp +++ b/src/libcamera/buffer.cpp @@ -6,10 +6,14 @@ */ #include +#include +#include #include #include +#include "log.h" + /** * \file buffer.h * \brief Buffer handling @@ -17,25 +21,46 @@ namespace libcamera { +LOG_DEFINE_CATEGORY(Buffer) + /** - * \class Buffer - * \brief A memory buffer to store a frame + * \class Plane + * \brief A memory buffer to store a single plane of a frame * - * The Buffer class represents a memory buffer used to store a frame. + * The Plane class represents a memory region used to store a single plane. It + * may be backed by it's own dmaBuf handle, and represents a single plane from a + * Buffer. In the case of multi-planar image formats, multiple Plane objects are + * attached to a Buffer to manage the whole picture. */ -Buffer::Buffer() - : fd_(-1) + +Plane::Plane() + : fd_(-1), length_(0), offset_(0), mem_(0) { } -Buffer::~Buffer() +/** + * \brief Construct a Plane memory region for CPU mappings + * \param[in] length The size of the memory region which should be mapped + * \param[in] offset The offset into the file descriptor base at which the + * buffer commences + * + * \sa mmap(int fd) + */ +Plane::Plane(unsigned int length, unsigned int offset) + : fd_(-1), length_(length), offset_(offset), mem_(0) +{ +} + +Plane::~Plane() { + munmap(); + if (fd_ != -1) close(fd_); } /** - * \fn Buffer::dmabuf() + * \fn Plane::dmabuf() * \brief Get the dmabuf file handle backing the buffer */ @@ -44,7 +69,7 @@ Buffer::~Buffer() * * The \a fd dmabuf file handle is duplicated and stored. */ -int Buffer::setDmabuf(int fd) +int Plane::setDmabuf(int fd) { if (fd_ != -1) { close(fd_); @@ -61,6 +86,154 @@ int Buffer::setDmabuf(int fd) return 0; } +/** + * \brief Map the plane memory data to a CPU accessible address + * + * The \a fd specifies the file descriptor to map the memory from. + * + * \return 0 on success or a negative error value otherwise. + */ +int Plane::mmap(int fd) +{ + void *map; + + map = ::mmap(NULL, length_, PROT_READ | PROT_WRITE, MAP_SHARED, fd, + offset_); + if (map == reinterpret_cast(-1)) { + int ret = -errno; + LOG(Buffer, Error) + << "Failed to mmap buffer: " << strerror(ret); + return ret; + } + + mem_ = map; + + return 0; +} + +/** + * \brief Map the plane memory data to a CPU accessible address + * + * The file descriptor to map the memory from must be set by a call to + * setDmaBuf before calling this function. + * + * \sa setDmaBuf + * + * \return 0 on success or a negative error value otherwise. + */ +int Plane::mmap() +{ + return mmap(fd_); +} + +/** + * \brief Unmap any existing CPU accessible mapping + * + * Unmap the memory mapped by an earlier call to mmap. + * + * \return 0 on success or a negative error value otherwise. + */ +int Plane::munmap() +{ + int ret = 0; + + if (mem_) + ret = ::munmap(mem_, length_); + + if (ret) { + ret = -errno; + LOG(Buffer, Warning) + << "Failed to unmap buffer: " << strerror(ret); + } else { + mem_ = 0; + } + + return ret; +} + +/** + * \fn Plane::length() + * \brief Get the length of the memory buffer + */ + +/** + * \fn Plane::mem() + * \brief Get the CPU accessible memory address if mapped + */ + +/** + * \class Buffer + * \brief A memory buffer to store an image + * + * The Buffer class represents the memory buffers used to store a + * full frame image, which may contain multiple separate memory Plane + * objects if the image format is multi-planar. + */ + +Buffer::Buffer() + : index_(-1), format_(0), width_(0), height_(0) +{ +} + +Buffer::~Buffer() +{ + for (Plane *plane : planes_) + delete plane; + + planes_.clear(); +} + +/** + * \brief Map each buffer plane to a CPU accessible address + * + * Utilise the \a fd file descriptor to map each of the Buffer's planes to a CPU + * accessible address. + * + * \return 0 on success or a negative error value otherwise. + */ +int Buffer::mmap(int fd) +{ + int ret; + + for (Plane *plane : planes_) { + ret = plane->mmap(fd); + if (ret) + return ret; + } + + return 0; +} + +/** + * \brief Unmap any existing CPU accessible mapping for each plane + * + * Unmap the memory mapped by an earlier call to mmap. + * + * \return 0 on success or a negative error value otherwise. + */ +int Buffer::munmap() +{ + int ret; + + for (Plane *plane : planes_) { + ret = plane->munmap(); + if (ret) + return ret; + } + + return 0; +} + +/** + * \fn Buffer::index() + * \brief Get the Buffer index value + */ + +/** + * \fn Buffer::planes() + * \brief Return a reference to the vector holding all Planes within the buffer + */ + /** * \class BufferPool * \brief A pool of buffers