summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKieran Bingham <kieran.bingham@ideasonboard.com>2021-10-15 15:16:56 +0100
committerKieran Bingham <kieran.bingham@ideasonboard.com>2021-10-18 09:53:59 +0100
commitf4999536b4f75eef1a489936b0c9795fdc234574 (patch)
tree85341cd5a8869f108ac5306b0ae4f5f3e747a6d7
parent2c8c967d725f56940a6c8f7e23930fed58ccf083 (diff)
libcamera-helpers: Integrate latest MappedFrameBuffer
The MappedFrameBuffer helper class has been updated in the libcamera source code. This makes use of the new enum MapFlags type, and corrects the mapping changes that were made during 8708904fad6f ("libcamera: mapped_framebuffer: Return plane begin address by MappedBuffer::maps()") This update also brings back isolated IPA functionality to this external IPA, which is otherwise broken due to the offset/plane changes. The files are renamed to mapped_framebuffer to match the naming in libcamera, but are kept within the 'libcamera-helper' hierarchy of the IPA. Also, a minor todo is added to IPAIPU3::mapBuffers, to highlight that we could potentially map Statistics buffers as read only rather than read/write if we could correctly identify them. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--include/libcamera-helpers/mapped_buffer.h53
-rw-r--r--include/libcamera-helpers/mapped_framebuffer.h65
-rw-r--r--ipu3.cpp8
-rw-r--r--src/libcamera-helpers/mapped_framebuffer.cpp (renamed from src/libcamera-helpers/mapped_buffer.cpp)110
-rw-r--r--src/libcamera-helpers/meson.build2
5 files changed, 163 insertions, 75 deletions
diff --git a/include/libcamera-helpers/mapped_buffer.h b/include/libcamera-helpers/mapped_buffer.h
deleted file mode 100644
index 6cfc572..0000000
--- a/include/libcamera-helpers/mapped_buffer.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-/*
- * Copyright (C) 2020, Google Inc.
- *
- * buffer.h - Internal buffer handling
- */
-#ifndef __LIBCAMERA_MAPPED_BUFFER_H__
-#define __LIBCAMERA_MAPPED_BUFFER_H__
-
-#include <sys/mman.h>
-#include <vector>
-
-#include <libcamera/base/class.h>
-#include <libcamera/base/span.h>
-
-#include <libcamera/framebuffer.h>
-
-namespace libcamera {
-
-class MappedBuffer
-{
-public:
- using Plane = Span<uint8_t>;
-
- ~MappedBuffer();
-
- MappedBuffer(MappedBuffer &&other);
- MappedBuffer &operator=(MappedBuffer &&other);
-
- bool isValid() const { return error_ == 0; }
- int error() const { return error_; }
- const std::vector<Plane> &maps() const { return maps_; }
-
-protected:
- MappedBuffer();
-
- int error_;
- std::vector<Plane> maps_;
-
-private:
- LIBCAMERA_DISABLE_COPY(MappedBuffer)
-};
-
-class MappedFrameBuffer : public MappedBuffer
-{
-public:
- MappedFrameBuffer(const FrameBuffer *buffer, int flags);
-};
-
-} /* namespace libcamera */
-
-#endif /* __LIBCAMERA_MAPPED_BUFFER_H__ */
-
diff --git a/include/libcamera-helpers/mapped_framebuffer.h b/include/libcamera-helpers/mapped_framebuffer.h
new file mode 100644
index 0000000..4215527
--- /dev/null
+++ b/include/libcamera-helpers/mapped_framebuffer.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021, Google Inc.
+ *
+ * mapped_framebuffer.h - Frame buffer memory mapping support
+ */
+#ifndef __LIBCAMERA_HELPER_MAPPED_FRAMEBUFFER_H__
+#define __LIBCAMERA_HELPER_MAPPED_FRAMEBUFFER_H__
+
+#include <stdint.h>
+#include <vector>
+
+#include <libcamera/base/class.h>
+#include <libcamera/base/flags.h>
+#include <libcamera/base/span.h>
+
+#include <libcamera/framebuffer.h>
+
+namespace libcamera {
+
+class MappedBuffer
+{
+public:
+ using Plane = Span<uint8_t>;
+
+ ~MappedBuffer();
+
+ MappedBuffer(MappedBuffer &&other);
+ MappedBuffer &operator=(MappedBuffer &&other);
+
+ bool isValid() const { return error_ == 0; }
+ int error() const { return error_; }
+ /* \todo rename to planes(). */
+ const std::vector<Plane> &maps() const { return planes_; }
+
+protected:
+ MappedBuffer();
+
+ int error_;
+ std::vector<Plane> planes_;
+ std::vector<Plane> maps_;
+
+private:
+ LIBCAMERA_DISABLE_COPY(MappedBuffer)
+};
+
+class MappedFrameBuffer : public MappedBuffer
+{
+public:
+ enum class MapFlag {
+ Read = 1 << 0,
+ Write = 1 << 1,
+ ReadWrite = Read | Write,
+ };
+
+ using MapFlags = Flags<MapFlag>;
+
+ MappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags);
+};
+
+LIBCAMERA_FLAGS_ENABLE_OPERATORS(MappedFrameBuffer::MapFlag)
+
+} /* namespace libcamera */
+
+#endif /* __LIBCAMERA_HELPER_MAPPED_FRAMEBUFFER_H__ */
diff --git a/ipu3.cpp b/ipu3.cpp
index b60c58c..7589eec 100644
--- a/ipu3.cpp
+++ b/ipu3.cpp
@@ -20,7 +20,7 @@
#include <libcamera/base/log.h>
-#include "libcamera-helpers/mapped_buffer.h"
+#include "libcamera-helpers/mapped_framebuffer.h"
/* IA AIQ Wrapper API */
#include "aic/aic.h"
@@ -258,10 +258,14 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo)
void IPAIPU3::mapBuffers(const std::vector<IPABuffer> &buffers)
{
+ /*
+ * todo: Statistics buffers could be mapped read-only if they
+ * could be easily identified.
+ */
for (const IPABuffer &buffer : buffers) {
const FrameBuffer fb(buffer.planes);
buffers_.emplace(buffer.id,
- MappedFrameBuffer(&fb, PROT_READ | PROT_WRITE));
+ MappedFrameBuffer(&fb, MappedFrameBuffer::MapFlag::ReadWrite));
}
}
diff --git a/src/libcamera-helpers/mapped_buffer.cpp b/src/libcamera-helpers/mapped_framebuffer.cpp
index 6f3248e..a657408 100644
--- a/src/libcamera-helpers/mapped_buffer.cpp
+++ b/src/libcamera-helpers/mapped_framebuffer.cpp
@@ -2,26 +2,27 @@
/*
* Copyright (C) 2021, Google Inc.
*
- * mapped_buffer.cpp - Mapped Buffer handling
+ * mapped_framebuffer.cpp - Mapped Framebuffer support
*/
-#include "libcamera-helpers/mapped_buffer.h"
+#include "libcamera-helpers/mapped_framebuffer.h"
+#include <algorithm>
#include <errno.h>
-#include <string.h>
+#include <map>
#include <sys/mman.h>
#include <unistd.h>
#include <libcamera/base/log.h>
/**
- * \file libcamera-helpers/mapped_buffer.h
- * \brief Mapped Buffer handling
+ * \file libcamera-helpers/mapped_framebuffer.h
+ * \brief Frame buffer memory mapping support
*/
namespace libcamera {
-LOG_DEFINE_CATEGORY(MappedBuffer)
+LOG_DECLARE_CATEGORY(Buffer)
/**
* \class MappedBuffer
@@ -81,6 +82,7 @@ MappedBuffer::MappedBuffer(MappedBuffer &&other)
MappedBuffer &MappedBuffer::operator=(MappedBuffer &&other)
{
error_ = other.error_;
+ planes_ = std::move(other.planes_);
maps_ = std::move(other.maps_);
other.error_ = -ENOENT;
@@ -129,10 +131,18 @@ MappedBuffer::~MappedBuffer()
*/
/**
- * \var MappedBuffer::maps_
+ * \var MappedBuffer::planes_
* \brief Stores the internal mapped planes
*
* MappedBuffer derived classes shall store the mappings they create in this
+ * vector which points the beginning of mapped plane addresses.
+ */
+
+/**
+ * \var MappedBuffer::maps_
+ * \brief Stores the mapped buffer
+ *
+ * MappedBuffer derived classes shall store the mappings they create in this
* vector which is parsed during destruct to unmap any memory mappings which
* completed successfully.
*/
@@ -143,28 +153,90 @@ MappedBuffer::~MappedBuffer()
*/
/**
+ * \enum MappedFrameBuffer::MapFlag
+ * \brief Specify the mapping mode for the FrameBuffer
+ * \var MappedFrameBuffer::Read
+ * \brief Create a read-only mapping
+ * \var MappedFrameBuffer::Write
+ * \brief Create a write-only mapping
+ * \var MappedFrameBuffer::ReadWrite
+ * \brief Create a mapping that can be both read and written
+ */
+
+/**
+ * \typedef MappedFrameBuffer::MapFlags
+ * \brief A bitwise combination of MappedFrameBuffer::MapFlag values
+ */
+
+/**
* \brief Map all planes of a FrameBuffer
* \param[in] buffer FrameBuffer to be mapped
* \param[in] flags Protection flags to apply to map
*
- * Construct an object to map a frame buffer for CPU access.
- * The flags are passed directly to mmap and should be either PROT_READ,
- * PROT_WRITE, or a bitwise-or combination of both.
+ * Construct an object to map a frame buffer for CPU access. The mapping can be
+ * made as Read only, Write only or support Read and Write operations by setting
+ * the MapFlag flags accordingly.
*/
-MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, int flags)
+MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags)
{
- maps_.reserve(buffer->planes().size());
+ ASSERT(!buffer->planes().empty());
+ planes_.reserve(buffer->planes().size());
+
+ int mmapFlags = 0;
+
+ if (flags & MapFlag::Read)
+ mmapFlags |= PROT_READ;
+
+ if (flags & MapFlag::Write)
+ mmapFlags |= PROT_WRITE;
+
+ struct MappedBufferInfo {
+ uint8_t *address = nullptr;
+ size_t mapLength = 0;
+ size_t dmabufLength = 0;
+ };
+ std::map<int, MappedBufferInfo> mappedBuffers;
+
+ for (const FrameBuffer::Plane &plane : buffer->planes()) {
+ const int fd = plane.fd.fd();
+ if (mappedBuffers.find(fd) == mappedBuffers.end()) {
+ const size_t length = lseek(fd, 0, SEEK_END);
+ mappedBuffers[fd] = MappedBufferInfo{ nullptr, 0, length };
+ }
+
+ const size_t length = mappedBuffers[fd].dmabufLength;
+
+ if (plane.offset > length ||
+ plane.offset + plane.length > length) {
+ LOG(Buffer, Fatal) << "plane is out of buffer: "
+ << "buffer length=" << length
+ << ", plane offset=" << plane.offset
+ << ", plane length=" << plane.length;
+ return;
+ }
+ size_t &mapLength = mappedBuffers[fd].mapLength;
+ mapLength = std::max(mapLength,
+ static_cast<size_t>(plane.offset + plane.length));
+ }
for (const FrameBuffer::Plane &plane : buffer->planes()) {
- void *address = mmap(nullptr, plane.length, flags,
- MAP_SHARED, plane.fd.fd(), 0);
- if (address == MAP_FAILED) {
- error_ = -errno;
- LOG(MappedBuffer, Error) << "Failed to mmap plane";
- break;
+ const int fd = plane.fd.fd();
+ auto &info = mappedBuffers[fd];
+ if (!info.address) {
+ void *address = mmap(nullptr, info.mapLength, mmapFlags,
+ MAP_SHARED, fd, 0);
+ if (address == MAP_FAILED) {
+ error_ = -errno;
+ LOG(Buffer, Error) << "Failed to mmap plane: "
+ << strerror(-error_);
+ return;
+ }
+
+ info.address = static_cast<uint8_t *>(address);
+ maps_.emplace_back(info.address, info.mapLength);
}
- maps_.emplace_back(static_cast<uint8_t *>(address), plane.length);
+ planes_.emplace_back(info.address + plane.offset, plane.length);
}
}
diff --git a/src/libcamera-helpers/meson.build b/src/libcamera-helpers/meson.build
index 444f212..084bf65 100644
--- a/src/libcamera-helpers/meson.build
+++ b/src/libcamera-helpers/meson.build
@@ -2,5 +2,5 @@
# Implementation of internal libcamera internals
libcamera_helpers = files([
- 'mapped_buffer.cpp',
+ 'mapped_framebuffer.cpp',
])