@@ -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)
@@ -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__ */
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(-)