diff options
-rw-r--r-- | include/libcamera/buffer.h | 61 | ||||
-rw-r--r-- | include/libcamera/stream.h | 23 | ||||
-rw-r--r-- | src/android/camera_device.cpp | 1 | ||||
-rw-r--r-- | src/libcamera/buffer.cpp | 184 | ||||
-rw-r--r-- | src/libcamera/stream.cpp | 250 |
5 files changed, 2 insertions, 517 deletions
diff --git a/include/libcamera/buffer.h b/include/libcamera/buffer.h index 0eb84c32..8e5ec699 100644 --- a/include/libcamera/buffer.h +++ b/include/libcamera/buffer.h @@ -7,7 +7,6 @@ #ifndef __LIBCAMERA_BUFFER_H__ #define __LIBCAMERA_BUFFER_H__ -#include <array> #include <stdint.h> #include <vector> @@ -16,7 +15,6 @@ namespace libcamera { class Request; -class Stream; struct FrameMetadata { enum Status { @@ -71,65 +69,6 @@ private: 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 */ #endif /* __LIBCAMERA_BUFFER_H__ */ diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h index a404eccf..29a8030d 100644 --- a/include/libcamera/stream.h +++ b/include/libcamera/stream.h @@ -36,11 +36,6 @@ private: std::map<PixelFormat, std::vector<SizeRange>> formats_; }; -enum MemoryType { - InternalMemory, - ExternalMemory, -}; - struct StreamConfiguration { StreamConfiguration(); StreamConfiguration(const StreamFormats &formats); @@ -48,7 +43,6 @@ struct StreamConfiguration { PixelFormat pixelFormat; Size size; - MemoryType memoryType; unsigned int bufferCount; Stream *stream() const { return stream_; } @@ -75,29 +69,12 @@ class Stream public: 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_; } - MemoryType memoryType() const { return memoryType_; } protected: 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_; - MemoryType memoryType_; - -private: - std::vector<std::pair<std::array<int, 3>, unsigned int>> bufferCache_; }; } /* namespace libcamera */ diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index ab3e4488..49321db0 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -641,7 +641,6 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list) StreamConfiguration *streamConfiguration = &config_->at(0); streamConfiguration->size.width = camera3Stream->width; streamConfiguration->size.height = camera3Stream->height; - streamConfiguration->memoryType = ExternalMemory; /* * \todo We'll need to translate from Android defined pixel format codes diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp index 92ac2838..673a63d3 100644 --- a/src/libcamera/buffer.cpp +++ b/src/libcamera/buffer.cpp @@ -97,190 +97,6 @@ LOG_DEFINE_CATEGORY(Buffer) */ /** - * \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 * \brief Frame buffer data and its associated dynamic metadata * diff --git a/src/libcamera/stream.cpp b/src/libcamera/stream.cpp index 16a323f1..13789e9e 100644 --- a/src/libcamera/stream.cpp +++ b/src/libcamera/stream.cpp @@ -267,17 +267,6 @@ SizeRange StreamFormats::range(PixelFormat pixelformat) const } /** - * \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 * \brief Configuration parameters for a stream * @@ -290,7 +279,7 @@ SizeRange StreamFormats::range(PixelFormat pixelformat) const * handlers provied StreamFormats. */ 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 */ StreamConfiguration::StreamConfiguration(const StreamFormats &formats) - : pixelFormat(0), memoryType(InternalMemory), stream_(nullptr), - formats_(formats) + : pixelFormat(0), stream_(nullptr), formats_(formats) { } @@ -314,11 +302,6 @@ StreamConfiguration::StreamConfiguration(const StreamFormats &formats) */ /** - * \var StreamConfiguration::memoryType - * \brief The memory type the stream shall use - */ - -/** * \var StreamConfiguration::bufferCount * \brief Requested number of buffers to allocate for the stream */ @@ -421,236 +404,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() * \brief Retrieve 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_ * \brief The stream configuration * @@ -659,9 +418,4 @@ void Stream::destroyBuffers() * next call to Camera::configure() regardless of if it includes the stream. */ -/** - * \var Stream::memoryType_ - * \brief The stream memory type - */ - } /* namespace libcamera */ |