libcamera: buffer: Create a MappedBuffer
Provide a MappedFrameBuffer helper class which will map all of the Planes within a FrameBuffer and provide CPU addressable pointers for those planes. The MappedFrameBuffer implements the interface of the MappedBuffer allowing other buffer types to be constructed of the same form, with a common interface and cleanup. This allows MappedBuffer instances to be created from Camera3Buffer types. Mappings are removed upon destruction. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
38ca814e97
commit
b3383da79f
2 changed files with 197 additions and 1 deletions
47
include/libcamera/internal/buffer.h
Normal file
47
include/libcamera/internal/buffer.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
/*
|
||||
* Copyright (C) 2020, Google Inc.
|
||||
*
|
||||
* buffer.h - Internal buffer handling
|
||||
*/
|
||||
#ifndef __LIBCAMERA_INTERNAL_BUFFER_H__
|
||||
#define __LIBCAMERA_INTERNAL_BUFFER_H__
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <vector>
|
||||
|
||||
#include <libcamera/buffer.h>
|
||||
#include <libcamera/span.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_;
|
||||
};
|
||||
|
||||
class MappedFrameBuffer : public MappedBuffer
|
||||
{
|
||||
public:
|
||||
MappedFrameBuffer(const FrameBuffer *buffer, int flags);
|
||||
};
|
||||
|
||||
} /* namespace libcamera */
|
||||
|
||||
#endif /* __LIBCAMERA_INTERNAL_BUFFER_H__ */
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include <libcamera/buffer.h>
|
||||
#include "libcamera/internal/buffer.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
@ -15,8 +16,11 @@
|
|||
#include "libcamera/internal/log.h"
|
||||
|
||||
/**
|
||||
* \file buffer.h
|
||||
* \file libcamera/buffer.h
|
||||
* \brief Buffer handling
|
||||
*
|
||||
* \file libcamera/internal/buffer.h
|
||||
* \brief Internal buffer handling support
|
||||
*/
|
||||
|
||||
namespace libcamera {
|
||||
|
@ -290,4 +294,149 @@ int FrameBuffer::copyFrom(const FrameBuffer *src)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \class MappedBuffer
|
||||
* \brief Provide an interface to support managing memory mapped buffers
|
||||
*
|
||||
* The MappedBuffer interface provides access to a set of MappedPlanes which
|
||||
* are available for access by the CPU.
|
||||
*
|
||||
* This class is not meant to be constructed directly, but instead derived
|
||||
* classes should be used to implement the correct mapping of a source buffer.
|
||||
*
|
||||
* This allows treating CPU accessible memory through a generic interface
|
||||
* regardless of whether it originates from a libcamera FrameBuffer or other
|
||||
* source.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \typedef MappedBuffer::Plane
|
||||
* \brief A mapped region of memory accessible to the CPU
|
||||
*
|
||||
* The MappedBuffer::Plane uses the Span interface to describe the mapped memory
|
||||
* region.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Construct an empty MappedBuffer
|
||||
*/
|
||||
MappedBuffer::MappedBuffer()
|
||||
: error_(0)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Move constructor, construct the MappedBuffer with the contents of \a
|
||||
* other using move semantics
|
||||
* \param[in] other The other MappedBuffer
|
||||
*
|
||||
* Moving a MappedBuffer moves the mappings contained in the \a other to the new
|
||||
* MappedBuffer and invalidates the \a other.
|
||||
*
|
||||
* No mappings are unmapped or destroyed in this process.
|
||||
*/
|
||||
MappedBuffer::MappedBuffer(MappedBuffer &&other)
|
||||
{
|
||||
*this = std::move(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Move assignment operator, replace the mappings with those of \a other
|
||||
* \param[in] other The other MappedBuffer
|
||||
*
|
||||
* Moving a MappedBuffer moves the mappings contained in the \a other to the new
|
||||
* MappedBuffer and invalidates the \a other.
|
||||
*
|
||||
* No mappings are unmapped or destroyed in this process.
|
||||
*/
|
||||
MappedBuffer &MappedBuffer::operator=(MappedBuffer &&other)
|
||||
{
|
||||
error_ = other.error_;
|
||||
maps_ = std::move(other.maps_);
|
||||
other.error_ = -ENOENT;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
MappedBuffer::~MappedBuffer()
|
||||
{
|
||||
for (Plane &map : maps_)
|
||||
munmap(map.data(), map.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* \fn MappedBuffer::isValid()
|
||||
* \brief Check if the MappedBuffer instance is valid
|
||||
* \return True if the MappedBuffer has valid mappings, false otherwise
|
||||
*/
|
||||
|
||||
/**
|
||||
* \fn MappedBuffer::error()
|
||||
* \brief Retrieve the map error status
|
||||
*
|
||||
* This function retrieves the error status from the MappedBuffer.
|
||||
* The error status is a negative number as defined by errno.h. If
|
||||
* no error occurred, this function returns 0.
|
||||
*
|
||||
* \return The map error code
|
||||
*/
|
||||
|
||||
/**
|
||||
* \fn MappedBuffer::maps()
|
||||
* \brief Retrieve the mapped planes
|
||||
*
|
||||
* This function retrieves the successfully mapped planes stored as a vector
|
||||
* of Span<uint8_t> to provide access to the mapped memory.
|
||||
*
|
||||
* \return A vector of the mapped planes
|
||||
*/
|
||||
|
||||
/**
|
||||
* \var MappedBuffer::error_
|
||||
* \brief Stores the error value if present
|
||||
*
|
||||
* MappedBuffer derived classes shall set this to a negative value as defined
|
||||
* by errno.h if an error occured during the mapping process.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \var MappedBuffer::maps_
|
||||
* \brief Stores the internal
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \class MappedFrameBuffer
|
||||
* \brief Map a FrameBuffer using the MappedBuffer interface
|
||||
*/
|
||||
|
||||
/**
|
||||
* \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.
|
||||
*/
|
||||
MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, int flags)
|
||||
{
|
||||
maps_.reserve(buffer->planes().size());
|
||||
|
||||
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(Buffer, Error) << "Failed to mmap plane";
|
||||
break;
|
||||
}
|
||||
|
||||
maps_.emplace_back(static_cast<uint8_t *>(address), plane.length);
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace libcamera */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue