[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