[libcamera-devel] [RFC 4/6] libcamera: buffer: Add helper to memcopy a FrameBuffer

Niklas Söderlund niklas.soderlund at ragnatech.se
Mon Mar 16 03:41:44 CET 2020


This helper may be used to memory copy a while FrameBuffer content to
another buffer. The operation is not fast and should not be used without
grate care by pipelines.

The intended use-case is to have an option to copy out RAW buffers from
the middle of an pipeline.

Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
---
 include/libcamera/buffer.h |  1 +
 src/libcamera/buffer.cpp   | 43 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/include/libcamera/buffer.h b/include/libcamera/buffer.h
index 8e5ec699e3925eee..669d2591a90e5f37 100644
--- a/include/libcamera/buffer.h
+++ b/include/libcamera/buffer.h
@@ -60,6 +60,7 @@ public:
 private:
 	friend class Request; /* Needed to update request_. */
 	friend class V4L2VideoDevice; /* Needed to update metadata_. */
+	friend int FrameBufferMemCopy(FrameBuffer *destination, const FrameBuffer *source);
 
 	std::vector<Plane> planes_;
 
diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp
index 673a63d3d1658190..f680d1879b57a68b 100644
--- a/src/libcamera/buffer.cpp
+++ b/src/libcamera/buffer.cpp
@@ -211,4 +211,47 @@ FrameBuffer::FrameBuffer(const std::vector<Plane> &planes, unsigned int cookie)
  * core never modifies the buffer cookie.
  */
 
+int FrameBufferMemCopy(FrameBuffer *dst, const FrameBuffer *src)
+{
+	if (dst->planes_.size() != src->planes_.size()) {
+		LOG(Buffer, Error) << "Different number of planes";
+		return -EINVAL;
+	}
+
+	for (unsigned int i = 0; i < dst->planes_.size(); i++) {
+		if (dst->planes_[i].length < src->planes_[i].length) {
+			LOG(Buffer, Error) << "Plane " << i << " is too small";
+			return -EINVAL;
+		}
+	}
+
+	for (unsigned int i = 0; i < dst->planes_.size(); i++) {
+		void *out = mmap(NULL, dst->planes_[i].length, PROT_WRITE, MAP_SHARED,
+			   dst->planes_[i].fd.fd(), 0);
+
+		if (out == MAP_FAILED) {
+			LOG(Buffer, Error) << "Failed to map output plane " << i;
+			return -EINVAL;
+		}
+
+		void *in = mmap(NULL, src->planes_[i].length, PROT_READ, MAP_SHARED,
+			  src->planes_[i].fd.fd(), 0);
+
+		if (in == MAP_FAILED) {
+			munmap(out, dst->planes_[i].length);
+			LOG(Buffer, Error) << "Failed to map input plane " << i;
+			return -EINVAL;
+		}
+
+		memcpy(out, in, src->planes_[i].length);
+
+		munmap(in, src->planes_[i].length);
+		munmap(out, dst->planes_[i].length);
+	}
+
+	dst->metadata_ = src->metadata_;
+
+	return 0;
+}
+
 } /* namespace libcamera */
-- 
2.25.1



More information about the libcamera-devel mailing list