diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp
index 8666f1992a77..a2b66dc86129 100644
--- a/src/libcamera/buffer.cpp
+++ b/src/libcamera/buffer.cpp
@@ -259,32 +259,23 @@ int FrameBuffer::copyFrom(const FrameBuffer *src)
 		}
 	}
 
-	for (unsigned int i = 0; i < planes_.size(); i++) {
-		void *dstmem = mmap(nullptr, planes_[i].length, PROT_WRITE,
-				    MAP_SHARED, planes_[i].fd.fd(), 0);
+	MappedFrameBuffer source(src, PROT_READ);
+	MappedFrameBuffer destination(this, PROT_WRITE);
 
-		if (dstmem == MAP_FAILED) {
-			LOG(Buffer, Error)
-				<< "Failed to map destination plane " << i;
-			metadata_.status = FrameMetadata::FrameError;
-			return -EINVAL;
-		}
-
-		void *srcmem = mmap(nullptr, src->planes_[i].length, PROT_READ,
-				    MAP_SHARED, src->planes_[i].fd.fd(), 0);
-
-		if (srcmem == MAP_FAILED) {
-			munmap(dstmem, planes_[i].length);
-			LOG(Buffer, Error)
-				<< "Failed to map source plane " << i;
-			metadata_.status = FrameMetadata::FrameError;
-			return -EINVAL;
-		}
+	if (!source.isValid()) {
+		LOG(Buffer, Error) << "Failed to map source planes";
+		return -EINVAL;
+	}
 
-		memcpy(dstmem, srcmem, src->planes_[i].length);
+	if (!destination.isValid()) {
+		LOG(Buffer, Error) << "Failed to map destination planes";
+		return -EINVAL;
+	}
 
-		munmap(srcmem, src->planes_[i].length);
-		munmap(dstmem, planes_[i].length);
+	for (unsigned int i = 0; i < planes_.size(); i++) {
+		memcpy(destination.maps()[i].data(),
+		       source.maps()[i].data(),
+		       source.maps()[i].size());
 	}
 
 	metadata_ = src->metadata_;
