diff --git a/include/libcamera/internal/mapped_framebuffer.h b/include/libcamera/internal/mapped_framebuffer.h
index 70ffbcbe..7deecded 100644
--- a/include/libcamera/internal/mapped_framebuffer.h
+++ b/include/libcamera/internal/mapped_framebuffer.h
@@ -59,6 +59,15 @@ public:
 
 LIBCAMERA_FLAGS_ENABLE_OPERATORS(MappedFrameBuffer::MapFlag)
 
+class MappedVectorBuffer : public MappedBuffer
+{
+public:
+	MappedVectorBuffer(std::vector<std::vector<uint8_t>> &&planes);
+
+private:
+	std::vector<std::vector<uint8_t>> data_;
+};
+
 } /* namespace libcamera */
 
 #endif /* __LIBCAMERA_INTERNAL_MAPPED_FRAMEBUFFER_H__ */
diff --git a/src/libcamera/mapped_framebuffer.cpp b/src/libcamera/mapped_framebuffer.cpp
index 464d35fe..b09ad41a 100644
--- a/src/libcamera/mapped_framebuffer.cpp
+++ b/src/libcamera/mapped_framebuffer.cpp
@@ -240,4 +240,21 @@ MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags)
 	}
 }
 
+/**
+ * \class MappedVectorBuffer
+ * \brief Owns planes data in heap and provides the MappedBuffer interface
+ */
+
+/**
+ * \brief Takes the ownership of the passed \a planes
+ * \param[in] planes the plane data that shall be owned by MappedVectorBuffer
+ */
+MappedVectorBuffer::MappedVectorBuffer(std::vector<std::vector<uint8_t>> &&planes)
+	: data_(std::move(planes))
+{
+	planes_.reserve(data_.size());
+	for (auto &plane : data_)
+		planes_.emplace_back(plane.data(), plane.size());
+}
+
 } /* namespace libcamera */
