[libcamera-devel] [RFC PATCH 1/8] libcamera: buffer: Create a MappedFrameBuffer

Kieran Bingham kieran.bingham at ideasonboard.com
Tue Jul 21 00:42:25 CEST 2020


Provide a MappedFrameBuffer helper class which will map
all of the Planes within a FrameBuffer and provide CPU addressable
pointers for those planes.

Mappings are removed upon destruction.

Signed-off-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
---

This introduces an automatically mapping/unmapping MappedFrameBuffer
object, with a move constructor (essential to prevent un-desirable
unmapping).



 include/libcamera/buffer.h | 23 ++++++++++++++++++++
 src/libcamera/buffer.cpp   | 43 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/include/libcamera/buffer.h b/include/libcamera/buffer.h
index 6bb2e4f8558f..881d736da2db 100644
--- a/include/libcamera/buffer.h
+++ b/include/libcamera/buffer.h
@@ -71,6 +71,29 @@ private:
 	unsigned int cookie_;
 };
 
+class MappedFrameBuffer {
+public:
+	MappedFrameBuffer(const FrameBuffer *buffer, int flags);
+	~MappedFrameBuffer();
+
+	/* Move constructor only, copying is not permitted. */
+	MappedFrameBuffer(MappedFrameBuffer &&rhs);
+
+	struct MappedPlane {
+		void *address;
+		size_t length;
+	};
+
+	bool isValid() const { return valid_; }
+	int error() const { return error_; }
+	const std::vector<MappedPlane> &maps() const { return maps_; }
+
+private:
+	int error_;
+	bool valid_;
+	std::vector<MappedPlane> maps_;
+};
+
 } /* namespace libcamera */
 
 #endif /* __LIBCAMERA_BUFFER_H__ */
diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp
index 1a1d4bac7aed..28b43d937f57 100644
--- a/src/libcamera/buffer.cpp
+++ b/src/libcamera/buffer.cpp
@@ -290,4 +290,47 @@ int FrameBuffer::copyFrom(const FrameBuffer *src)
 	return 0;
 }
 
+/**
+ * \brief Map all planes of a FrameBuffer
+ * \param[in] src Buffer to be mapped
+ * \param[in] flags Protection flags to apply to map
+ *
+ * Construct an object to map a frame buffer for CPU access.
+ * The flags are passed directly to mmap and should be either PROT_READ,
+ * PROT_WRITE, or a bitwise-or combination of both.
+ */
+MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, int flags)
+	: error_(0)
+{
+	maps_.reserve(buffer->planes().size());
+
+	for (const FrameBuffer::Plane &plane : buffer->planes()) {
+		void *address = mmap(nullptr, plane.length, flags,
+				     MAP_SHARED, plane.fd.fd(), 0);
+
+		if (address == MAP_FAILED) {
+			error_ = -errno;
+			LOG(Buffer, Error) << "Failed to mmap plane";
+			continue;
+		}
+
+		maps_.push_back({address, plane.length});
+	}
+
+	valid_ = buffer->planes().size() == maps_.size();
+}
+
+MappedFrameBuffer::~MappedFrameBuffer()
+{
+	for (MappedPlane map : maps_)
+		munmap(map.address, map.length);
+}
+
+MappedFrameBuffer::MappedFrameBuffer(MappedFrameBuffer &&rhs)
+{
+	error_ = rhs.error_;
+	valid_ = rhs.valid_;
+	maps_ = std::move(rhs.maps_);
+}
+
 } /* namespace libcamera */
-- 
2.25.1



More information about the libcamera-devel mailing list