mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-23 16:45:07 +03:00
libcamera: Remove dead code after switch to FrameBuffer
Delete all dead code after switching to the FrameBuffer interface. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
66d4929c73
commit
164fbf17ff
5 changed files with 2 additions and 517 deletions
|
@ -7,7 +7,6 @@
|
||||||
#ifndef __LIBCAMERA_BUFFER_H__
|
#ifndef __LIBCAMERA_BUFFER_H__
|
||||||
#define __LIBCAMERA_BUFFER_H__
|
#define __LIBCAMERA_BUFFER_H__
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -16,7 +15,6 @@
|
||||||
namespace libcamera {
|
namespace libcamera {
|
||||||
|
|
||||||
class Request;
|
class Request;
|
||||||
class Stream;
|
|
||||||
|
|
||||||
struct FrameMetadata {
|
struct FrameMetadata {
|
||||||
enum Status {
|
enum Status {
|
||||||
|
@ -71,65 +69,6 @@ private:
|
||||||
unsigned int cookie_;
|
unsigned int cookie_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BufferMemory final
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
const std::vector<FrameBuffer::Plane> &planes() const { return planes_; }
|
|
||||||
std::vector<FrameBuffer::Plane> &planes() { return planes_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<FrameBuffer::Plane> planes_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BufferPool final
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~BufferPool();
|
|
||||||
|
|
||||||
void createBuffers(unsigned int count);
|
|
||||||
void destroyBuffers();
|
|
||||||
|
|
||||||
unsigned int count() const { return buffers_.size(); }
|
|
||||||
std::vector<BufferMemory> &buffers() { return buffers_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<BufferMemory> buffers_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Buffer final
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Buffer(unsigned int index = -1, const Buffer *metadata = nullptr);
|
|
||||||
Buffer(const Buffer &) = delete;
|
|
||||||
Buffer &operator=(const Buffer &) = delete;
|
|
||||||
|
|
||||||
unsigned int index() const { return index_; }
|
|
||||||
const std::array<int, 3> &dmabufs() const { return dmabuf_; }
|
|
||||||
BufferMemory *mem() { return mem_; }
|
|
||||||
|
|
||||||
const FrameMetadata &metadata() const { return metadata_; };
|
|
||||||
|
|
||||||
Request *request() const { return request_; }
|
|
||||||
Stream *stream() const { return stream_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class Camera;
|
|
||||||
friend class Request;
|
|
||||||
friend class Stream;
|
|
||||||
friend class V4L2VideoDevice;
|
|
||||||
|
|
||||||
void cancel();
|
|
||||||
|
|
||||||
unsigned int index_;
|
|
||||||
std::array<int, 3> dmabuf_;
|
|
||||||
BufferMemory *mem_;
|
|
||||||
|
|
||||||
FrameMetadata metadata_;
|
|
||||||
|
|
||||||
Request *request_;
|
|
||||||
Stream *stream_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
||||||
|
|
||||||
#endif /* __LIBCAMERA_BUFFER_H__ */
|
#endif /* __LIBCAMERA_BUFFER_H__ */
|
||||||
|
|
|
@ -36,11 +36,6 @@ private:
|
||||||
std::map<PixelFormat, std::vector<SizeRange>> formats_;
|
std::map<PixelFormat, std::vector<SizeRange>> formats_;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MemoryType {
|
|
||||||
InternalMemory,
|
|
||||||
ExternalMemory,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct StreamConfiguration {
|
struct StreamConfiguration {
|
||||||
StreamConfiguration();
|
StreamConfiguration();
|
||||||
StreamConfiguration(const StreamFormats &formats);
|
StreamConfiguration(const StreamFormats &formats);
|
||||||
|
@ -48,7 +43,6 @@ struct StreamConfiguration {
|
||||||
PixelFormat pixelFormat;
|
PixelFormat pixelFormat;
|
||||||
Size size;
|
Size size;
|
||||||
|
|
||||||
MemoryType memoryType;
|
|
||||||
unsigned int bufferCount;
|
unsigned int bufferCount;
|
||||||
|
|
||||||
Stream *stream() const { return stream_; }
|
Stream *stream() const { return stream_; }
|
||||||
|
@ -75,29 +69,12 @@ class Stream
|
||||||
public:
|
public:
|
||||||
Stream();
|
Stream();
|
||||||
|
|
||||||
std::unique_ptr<Buffer> createBuffer(unsigned int index);
|
|
||||||
std::unique_ptr<Buffer> createBuffer(const std::array<int, 3> &fds);
|
|
||||||
|
|
||||||
BufferPool &bufferPool() { return bufferPool_; }
|
|
||||||
std::vector<BufferMemory> &buffers() { return bufferPool_.buffers(); }
|
|
||||||
const StreamConfiguration &configuration() const { return configuration_; }
|
const StreamConfiguration &configuration() const { return configuration_; }
|
||||||
MemoryType memoryType() const { return memoryType_; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Camera;
|
friend class Camera;
|
||||||
|
|
||||||
int mapBuffer(const Buffer *buffer);
|
|
||||||
void unmapBuffer(const Buffer *buffer);
|
|
||||||
|
|
||||||
void createBuffers(MemoryType memory, unsigned int count);
|
|
||||||
void destroyBuffers();
|
|
||||||
|
|
||||||
BufferPool bufferPool_;
|
|
||||||
StreamConfiguration configuration_;
|
StreamConfiguration configuration_;
|
||||||
MemoryType memoryType_;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<std::pair<std::array<int, 3>, unsigned int>> bufferCache_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
||||||
|
|
|
@ -641,7 +641,6 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
|
||||||
StreamConfiguration *streamConfiguration = &config_->at(0);
|
StreamConfiguration *streamConfiguration = &config_->at(0);
|
||||||
streamConfiguration->size.width = camera3Stream->width;
|
streamConfiguration->size.width = camera3Stream->width;
|
||||||
streamConfiguration->size.height = camera3Stream->height;
|
streamConfiguration->size.height = camera3Stream->height;
|
||||||
streamConfiguration->memoryType = ExternalMemory;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* \todo We'll need to translate from Android defined pixel format codes
|
* \todo We'll need to translate from Android defined pixel format codes
|
||||||
|
|
|
@ -96,190 +96,6 @@ LOG_DEFINE_CATEGORY(Buffer)
|
||||||
* \brief Array of per-plane metadata
|
* \brief Array of per-plane metadata
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* \class BufferMemory
|
|
||||||
* \brief A memory buffer to store an image
|
|
||||||
*
|
|
||||||
* The BufferMemory class represents the memory buffers used to store full frame
|
|
||||||
* images, which may contain multiple separate memory Plane objects if the
|
|
||||||
* image format is multi-planar.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn BufferMemory::planes() const
|
|
||||||
* \brief Retrieve the planes within the buffer
|
|
||||||
* \return A const reference to a vector holding all planes within the buffer
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn BufferMemory::planes()
|
|
||||||
* \brief Retrieve the planes within the buffer
|
|
||||||
* \return A reference to a vector holding all planes within the buffer
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \class BufferPool
|
|
||||||
* \brief A pool of buffers
|
|
||||||
*
|
|
||||||
* The BufferPool class groups together a collection of Buffers to store frames.
|
|
||||||
* The buffers must be exported by a device before they can be imported into
|
|
||||||
* another device for further use.
|
|
||||||
*/
|
|
||||||
|
|
||||||
BufferPool::~BufferPool()
|
|
||||||
{
|
|
||||||
destroyBuffers();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Create buffers in the Pool
|
|
||||||
* \param[in] count The number of buffers to create
|
|
||||||
*/
|
|
||||||
void BufferPool::createBuffers(unsigned int count)
|
|
||||||
{
|
|
||||||
buffers_.resize(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Release all buffers from pool
|
|
||||||
*
|
|
||||||
* If no buffers have been created or if buffers have already been released no
|
|
||||||
* operation is performed.
|
|
||||||
*/
|
|
||||||
void BufferPool::destroyBuffers()
|
|
||||||
{
|
|
||||||
buffers_.resize(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn BufferPool::count()
|
|
||||||
* \brief Retrieve the number of buffers contained within the pool
|
|
||||||
* \return The number of buffers contained in the pool
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn BufferPool::buffers()
|
|
||||||
* \brief Retrieve all the buffers in the pool
|
|
||||||
* \return A vector containing all the buffers in the pool.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \class Buffer
|
|
||||||
* \brief A buffer handle and dynamic metadata
|
|
||||||
*
|
|
||||||
* The Buffer class references a buffer memory and associates dynamic metadata
|
|
||||||
* related to the frame contained in the buffer. It allows referencing buffer
|
|
||||||
* memory through a single interface regardless of whether the memory is
|
|
||||||
* allocated internally in libcamera or provided externally through dmabuf.
|
|
||||||
*
|
|
||||||
* Buffer instances are allocated dynamically for a stream through
|
|
||||||
* Stream::createBuffer(), added to a request with Request::addBuffer() and
|
|
||||||
* deleted automatically after the request complete handler returns.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Construct a buffer not associated with any stream
|
|
||||||
*
|
|
||||||
* This method constructs an orphaned buffer not associated with any stream. It
|
|
||||||
* is not meant to be called by applications, they should instead create buffers
|
|
||||||
* for a stream with Stream::createBuffer().
|
|
||||||
*/
|
|
||||||
Buffer::Buffer(unsigned int index, const Buffer *metadata)
|
|
||||||
: index_(index), dmabuf_({ -1, -1, -1 }), request_(nullptr),
|
|
||||||
stream_(nullptr)
|
|
||||||
{
|
|
||||||
if (metadata)
|
|
||||||
metadata_ = metadata->metadata();
|
|
||||||
else
|
|
||||||
metadata_ = {};
|
|
||||||
|
|
||||||
metadata_.status = FrameMetadata::FrameSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn Buffer::index()
|
|
||||||
* \brief Retrieve the Buffer index
|
|
||||||
* \return The buffer index
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn Buffer::dmabufs()
|
|
||||||
* \brief Retrieve the dmabuf file descriptors for all buffer planes
|
|
||||||
*
|
|
||||||
* The dmabufs array contains one dmabuf file descriptor per plane. Unused
|
|
||||||
* entries are set to -1.
|
|
||||||
*
|
|
||||||
* \return The dmabuf file descriptors
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn Buffer::mem()
|
|
||||||
* \brief Retrieve the BufferMemory this buffer is associated with
|
|
||||||
*
|
|
||||||
* The association between the buffer and a BufferMemory instance is valid from
|
|
||||||
* the time the request containing this buffer is queued to a camera to the end
|
|
||||||
* of that request's completion handler.
|
|
||||||
*
|
|
||||||
* \return The BufferMemory this buffer is associated with
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn Buffer::metadata()
|
|
||||||
* \brief Retrieve the buffer metadata
|
|
||||||
*
|
|
||||||
* The buffer metadata is updated when the buffer contents are modified, for
|
|
||||||
* example when a frame has been captured to the buffer by the hardware.
|
|
||||||
*
|
|
||||||
* \return Metadata for the buffer
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn Buffer::request()
|
|
||||||
* \brief Retrieve the request this buffer belongs to
|
|
||||||
*
|
|
||||||
* The intended callers of this method are buffer completion handlers that
|
|
||||||
* need to associate a buffer to the request it belongs to.
|
|
||||||
*
|
|
||||||
* A Buffer is associated to a request by Request::addBuffer() and the
|
|
||||||
* association is valid until the buffer completes. The returned request
|
|
||||||
* pointer is valid only during that interval.
|
|
||||||
*
|
|
||||||
* \return The Request the Buffer belongs to, or nullptr if the buffer is
|
|
||||||
* either completed or not associated with a request
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn Buffer::stream()
|
|
||||||
* \brief Retrieve the stream this buffer is associated with
|
|
||||||
*
|
|
||||||
* A Buffer is associated to the stream that created it with
|
|
||||||
* Stream::createBuffer() and the association is valid until the buffer is
|
|
||||||
* destroyed. Buffer instances that are created directly are not associated
|
|
||||||
* with any stream.
|
|
||||||
*
|
|
||||||
* \return The Stream the Buffer is associated with, or nullptr if the buffer
|
|
||||||
* is not associated with a stream
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Mark a buffer as cancel by setting its status to BufferCancelled
|
|
||||||
*/
|
|
||||||
void Buffer::cancel()
|
|
||||||
{
|
|
||||||
metadata_.status = FrameMetadata::FrameCancelled;
|
|
||||||
metadata_.sequence = 0;
|
|
||||||
metadata_.timestamp = 0;
|
|
||||||
metadata_.planes = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \var Buffer::request_
|
|
||||||
* \brief The request this buffer belongs to
|
|
||||||
*
|
|
||||||
* This member is intended to be set by Request::addBuffer() and
|
|
||||||
* Request::completeBuffer().
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \class FrameBuffer
|
* \class FrameBuffer
|
||||||
* \brief Frame buffer data and its associated dynamic metadata
|
* \brief Frame buffer data and its associated dynamic metadata
|
||||||
|
|
|
@ -266,17 +266,6 @@ SizeRange StreamFormats::range(PixelFormat pixelformat) const
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* \enum MemoryType
|
|
||||||
* \brief Define the memory type used by a Stream
|
|
||||||
* \var MemoryType::InternalMemory
|
|
||||||
* The Stream uses memory allocated internally by the library and exported to
|
|
||||||
* applications.
|
|
||||||
* \var MemoryType::ExternalMemory
|
|
||||||
* The Stream uses memory allocated externally by application and imported in
|
|
||||||
* the library.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \struct StreamConfiguration
|
* \struct StreamConfiguration
|
||||||
* \brief Configuration parameters for a stream
|
* \brief Configuration parameters for a stream
|
||||||
|
@ -290,7 +279,7 @@ SizeRange StreamFormats::range(PixelFormat pixelformat) const
|
||||||
* handlers provied StreamFormats.
|
* handlers provied StreamFormats.
|
||||||
*/
|
*/
|
||||||
StreamConfiguration::StreamConfiguration()
|
StreamConfiguration::StreamConfiguration()
|
||||||
: pixelFormat(0), memoryType(InternalMemory), stream_(nullptr)
|
: pixelFormat(0), stream_(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,8 +287,7 @@ StreamConfiguration::StreamConfiguration()
|
||||||
* \brief Construct a configuration with stream formats
|
* \brief Construct a configuration with stream formats
|
||||||
*/
|
*/
|
||||||
StreamConfiguration::StreamConfiguration(const StreamFormats &formats)
|
StreamConfiguration::StreamConfiguration(const StreamFormats &formats)
|
||||||
: pixelFormat(0), memoryType(InternalMemory), stream_(nullptr),
|
: pixelFormat(0), stream_(nullptr), formats_(formats)
|
||||||
formats_(formats)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,11 +301,6 @@ StreamConfiguration::StreamConfiguration(const StreamFormats &formats)
|
||||||
* \brief Stream pixel format
|
* \brief Stream pixel format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* \var StreamConfiguration::memoryType
|
|
||||||
* \brief The memory type the stream shall use
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \var StreamConfiguration::bufferCount
|
* \var StreamConfiguration::bufferCount
|
||||||
* \brief Requested number of buffers to allocate for the stream
|
* \brief Requested number of buffers to allocate for the stream
|
||||||
|
@ -420,236 +403,12 @@ Stream::Stream()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Create a Buffer instance referencing the memory buffer \a index
|
|
||||||
* \param[in] index The desired buffer index
|
|
||||||
*
|
|
||||||
* This method creates a Buffer instance that references a BufferMemory from
|
|
||||||
* the stream's buffers pool by its \a index. The index shall be lower than the
|
|
||||||
* number of buffers in the pool.
|
|
||||||
*
|
|
||||||
* This method is only valid for streams that use the InternalMemory type. It
|
|
||||||
* will return a null pointer when called on streams using the ExternalMemory
|
|
||||||
* type.
|
|
||||||
*
|
|
||||||
* \return A newly created Buffer on success or nullptr otherwise
|
|
||||||
*/
|
|
||||||
std::unique_ptr<Buffer> Stream::createBuffer(unsigned int index)
|
|
||||||
{
|
|
||||||
if (memoryType_ != InternalMemory) {
|
|
||||||
LOG(Stream, Error) << "Invalid stream memory type";
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index >= bufferPool_.count()) {
|
|
||||||
LOG(Stream, Error) << "Invalid buffer index " << index;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Buffer *buffer = new Buffer();
|
|
||||||
buffer->index_ = index;
|
|
||||||
buffer->stream_ = this;
|
|
||||||
|
|
||||||
return std::unique_ptr<Buffer>(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Create a Buffer instance that represents a memory area identified by
|
|
||||||
* dmabuf file descriptors
|
|
||||||
* \param[in] fds The dmabuf file descriptors for each plane
|
|
||||||
*
|
|
||||||
* This method creates a Buffer instance that references buffer memory
|
|
||||||
* allocated outside of libcamera through dmabuf file descriptors. The \a
|
|
||||||
* dmabuf array shall contain a file descriptor for each plane in the buffer,
|
|
||||||
* and unused entries shall be set to -1.
|
|
||||||
*
|
|
||||||
* The buffer is created without a valid index, as it does not yet map to any of
|
|
||||||
* the stream's BufferMemory instances. An index will be assigned at the time
|
|
||||||
* the buffer is queued to the camera in a request. Applications may thus
|
|
||||||
* create any number of Buffer instances, providing that no more than the
|
|
||||||
* number of buffers allocated for the stream are queued at any given time.
|
|
||||||
*
|
|
||||||
* This method is only valid for streams that use the ExternalMemory type. It
|
|
||||||
* will return a null pointer when called on streams using the InternalMemory
|
|
||||||
* type.
|
|
||||||
*
|
|
||||||
* \sa Stream::mapBuffer()
|
|
||||||
*
|
|
||||||
* \return A newly created Buffer on success or nullptr otherwise
|
|
||||||
*/
|
|
||||||
std::unique_ptr<Buffer> Stream::createBuffer(const std::array<int, 3> &fds)
|
|
||||||
{
|
|
||||||
if (memoryType_ != ExternalMemory) {
|
|
||||||
LOG(Stream, Error) << "Invalid stream memory type";
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Buffer *buffer = new Buffer();
|
|
||||||
buffer->dmabuf_ = fds;
|
|
||||||
buffer->stream_ = this;
|
|
||||||
|
|
||||||
return std::unique_ptr<Buffer>(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn Stream::bufferPool()
|
|
||||||
* \brief Retrieve the buffer pool for the stream
|
|
||||||
*
|
|
||||||
* The buffer pool handles the memory buffers used to store frames for the
|
|
||||||
* stream. It is initially created empty and shall be populated with
|
|
||||||
* buffers before being used.
|
|
||||||
*
|
|
||||||
* \return A reference to the buffer pool
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn Stream::buffers()
|
|
||||||
* \brief Retrieve the memory buffers in the Stream's buffer pool
|
|
||||||
* \return The list of stream's memory buffers
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \fn Stream::configuration()
|
* \fn Stream::configuration()
|
||||||
* \brief Retrieve the active configuration of the stream
|
* \brief Retrieve the active configuration of the stream
|
||||||
* \return The active configuration of the stream
|
* \return The active configuration of the stream
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn Stream::memoryType()
|
|
||||||
* \brief Retrieve the stream memory type
|
|
||||||
* \return The memory type used by the stream
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Map a Buffer to a buffer memory index
|
|
||||||
* \param[in] buffer The buffer to map to a buffer memory index
|
|
||||||
*
|
|
||||||
* Streams configured to use externally allocated memory need to maintain a
|
|
||||||
* best-effort association between the memory area the \a buffer represents
|
|
||||||
* and the associated buffer memory in the Stream's pool.
|
|
||||||
*
|
|
||||||
* The buffer memory to use, once the \a buffer reaches the video device,
|
|
||||||
* is selected using the index assigned to the \a buffer and to minimize
|
|
||||||
* relocations in the V4L2 back-end, this operation provides a best-effort
|
|
||||||
* caching mechanism that associates to the dmabuf file descriptors contained
|
|
||||||
* in the \a buffer the index of the buffer memory that was lastly queued with
|
|
||||||
* those file descriptors set.
|
|
||||||
*
|
|
||||||
* If the Stream uses internally allocated memory, the index of the memory
|
|
||||||
* buffer to use will match the one request at Stream::createBuffer(unsigned int)
|
|
||||||
* time, and no mapping is thus required.
|
|
||||||
*
|
|
||||||
* \return The buffer memory index for the buffer on success, or a negative
|
|
||||||
* error code otherwise
|
|
||||||
* \retval -ENOMEM No buffer memory was available to map the buffer
|
|
||||||
*/
|
|
||||||
int Stream::mapBuffer(const Buffer *buffer)
|
|
||||||
{
|
|
||||||
ASSERT(memoryType_ == ExternalMemory);
|
|
||||||
|
|
||||||
if (bufferCache_.empty())
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
const std::array<int, 3> &dmabufs = buffer->dmabufs();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Try to find a previously mapped buffer in the cache. If we miss, use
|
|
||||||
* the oldest entry in the cache.
|
|
||||||
*/
|
|
||||||
auto map = std::find_if(bufferCache_.begin(), bufferCache_.end(),
|
|
||||||
[&](std::pair<std::array<int, 3>, unsigned int> &entry) {
|
|
||||||
return entry.first == dmabufs;
|
|
||||||
});
|
|
||||||
if (map == bufferCache_.end())
|
|
||||||
map = bufferCache_.begin();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update the dmabuf file descriptors of the entry. We can't assume that
|
|
||||||
* identical file descriptor numbers refer to the same dmabuf object as
|
|
||||||
* it may have been closed and its file descriptor reused. We thus need
|
|
||||||
* to update the plane's internally cached mmap()ed memory.
|
|
||||||
*/
|
|
||||||
unsigned int index = map->second;
|
|
||||||
BufferMemory *mem = &bufferPool_.buffers()[index];
|
|
||||||
mem->planes().clear();
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < dmabufs.size(); ++i) {
|
|
||||||
if (dmabufs[i] == -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
FrameBuffer::Plane plane;
|
|
||||||
plane.fd = FileDescriptor(dmabufs[i]);
|
|
||||||
plane.length = 0;
|
|
||||||
mem->planes().push_back(plane);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove the buffer from the cache and return its index. */
|
|
||||||
bufferCache_.erase(map);
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Unmap a Buffer from its buffer memory
|
|
||||||
* \param[in] buffer The buffer to unmap
|
|
||||||
*
|
|
||||||
* This method releases the buffer memory entry that was mapped by mapBuffer(),
|
|
||||||
* making it available for new mappings.
|
|
||||||
*/
|
|
||||||
void Stream::unmapBuffer(const Buffer *buffer)
|
|
||||||
{
|
|
||||||
ASSERT(memoryType_ == ExternalMemory);
|
|
||||||
|
|
||||||
bufferCache_.emplace_back(buffer->dmabufs(), buffer->index());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Create buffers for the stream
|
|
||||||
* \param[in] count The number of buffers to create
|
|
||||||
* \param[in] memory The stream memory type
|
|
||||||
*
|
|
||||||
* Create \a count empty buffers in the Stream's buffer pool.
|
|
||||||
*/
|
|
||||||
void Stream::createBuffers(MemoryType memory, unsigned int count)
|
|
||||||
{
|
|
||||||
destroyBuffers();
|
|
||||||
if (count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
memoryType_ = memory;
|
|
||||||
bufferPool_.createBuffers(count);
|
|
||||||
|
|
||||||
/* Streams with internal memory usage do not need buffer mapping. */
|
|
||||||
if (memoryType_ == InternalMemory)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Prepare for buffer mapping by adding all buffer memory entries to the
|
|
||||||
* cache.
|
|
||||||
*/
|
|
||||||
bufferCache_.clear();
|
|
||||||
for (unsigned int i = 0; i < bufferPool_.count(); ++i)
|
|
||||||
bufferCache_.emplace_back(std::array<int, 3>{ -1, -1, -1 }, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Destroy buffers in the stream
|
|
||||||
*
|
|
||||||
* If no buffers have been created or if buffers have already been destroyed no
|
|
||||||
* operation is performed.
|
|
||||||
*/
|
|
||||||
void Stream::destroyBuffers()
|
|
||||||
{
|
|
||||||
bufferPool_.destroyBuffers();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \var Stream::bufferPool_
|
|
||||||
* \brief The pool of buffers associated with the stream
|
|
||||||
*
|
|
||||||
* The stream buffer pool is populated by the Camera class after a successful
|
|
||||||
* stream configuration.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \var Stream::configuration_
|
* \var Stream::configuration_
|
||||||
* \brief The stream configuration
|
* \brief The stream configuration
|
||||||
|
@ -659,9 +418,4 @@ void Stream::destroyBuffers()
|
||||||
* next call to Camera::configure() regardless of if it includes the stream.
|
* next call to Camera::configure() regardless of if it includes the stream.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* \var Stream::memoryType_
|
|
||||||
* \brief The stream memory type
|
|
||||||
*/
|
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue