[libcamera-devel,RFC,2/5] cam: file_sink: Fix wrong mapping planes
diff mbox series

Message ID 20210811124015.2116188-3-hiroh@chromium.org
State Superseded
Headers show
Series
  • MappedFrameBuffer::maps() returns the plane address
Related show

Commit Message

Hirokazu Honda Aug. 11, 2021, 12:40 p.m. UTC
FileSink maps FrameBuffer in a wrong way that the mapped data points
the address of a buffer, not plane. This fixes it.

Signed-off-by: Hirokazu Honda <hiroh@chromium.org>
---
 src/cam/file_sink.cpp | 30 +++++++++++++++++++++++++-----
 src/cam/file_sink.h   |  1 +
 2 files changed, 26 insertions(+), 5 deletions(-)

Patch
diff mbox series

diff --git a/src/cam/file_sink.cpp b/src/cam/file_sink.cpp
index 2d30694a..267f7ea2 100644
--- a/src/cam/file_sink.cpp
+++ b/src/cam/file_sink.cpp
@@ -51,12 +51,32 @@  int FileSink::configure(const libcamera::CameraConfiguration &config)
 
 void FileSink::mapBuffer(FrameBuffer *buffer)
 {
+	/* \todo Use MappedFrameBuffer. */
+	size_t offset = 0;
+	int prevFd = -1;
 	for (const FrameBuffer::Plane &plane : buffer->planes()) {
-		void *memory = mmap(NULL, plane.length, PROT_READ, MAP_SHARED,
-				    plane.fd.fd(), 0);
+		const int fd = plane.fd.fd();
+		if (prevFd != fd) {
+			const size_t length = lseek(fd, 0, SEEK_END);
+			void *address = mmap(nullptr, length, PROT_READ,
+					     MAP_SHARED, fd, 0);
+			if (address == MAP_FAILED) {
+				std::cerr << "Failed to mmap plane: "
+					  << strerror(errno) << std::endl;
+				return;
+			}
+			mappedBuffers_[fd] = std::make_pair(address, length);
+			prevFd = fd;
+		}
 
-		mappedBuffers_[plane.fd.fd()] =
-			std::make_pair(memory, plane.length);
+		uint8_t *buf = static_cast<uint8_t *>(mappedBuffers_[fd].first);
+		/*
+		 * This offset calculation assumes planes are consecutive.
+		 * \todo remove this assumption once offset is introduced to
+		 * FrameBuffer::Plane.
+		 */
+		planeData_[fd] = static_cast<void *>(buf + offset);
+		offset += plane.length;
 	}
 }
 
@@ -102,7 +122,7 @@  void FileSink::writeBuffer(const Stream *stream, FrameBuffer *buffer)
 		const FrameBuffer::Plane &plane = buffer->planes()[i];
 		const FrameMetadata::Plane &meta = buffer->metadata().planes[i];
 
-		void *data = mappedBuffers_[plane.fd.fd()].first;
+		void *data = planeData_[plane.fd.fd()];
 		unsigned int length = std::min(meta.bytesused, plane.length);
 
 		if (meta.bytesused > plane.length)
diff --git a/src/cam/file_sink.h b/src/cam/file_sink.h
index c3eb230a..d236d6d8 100644
--- a/src/cam/file_sink.h
+++ b/src/cam/file_sink.h
@@ -33,6 +33,7 @@  private:
 	std::map<const libcamera::Stream *, std::string> streamNames_;
 	std::string pattern_;
 	std::map<int, std::pair<void *, unsigned int>> mappedBuffers_;
+	std::map<int, void *> planeData_;
 };
 
 #endif /* __CAM_FILE_SINK_H__ */