[libcamera-devel] [RFC 08/12] libcamera: buffer: Add a buffer allocator

Jacopo Mondi jacopo at jmondi.org
Fri Nov 15 16:11:56 CET 2019


Hi Niklas,

On Mon, Oct 28, 2019 at 03:25:21AM +0100, Niklas Söderlund wrote:
> From an applications point of view buffers shall not be allocated
> directly by a camera or stream. Instead they shall be allocated
> externally and used by a camera.
>
> To model this behavior add a buffer allocator that is exposed to
> applications. How the allocator creates buffers is pipeline specific and
> handled by sub-classing the stream class.

I would dare to question the whole allocator idea here... I mean, the
allocator basically uses the streams' virtual allocateBuffer, whose
importBuffers counterpart is the invoked at Camera::start().

We still need to call Camera::allocateBuffers() for internal buffers
allocation, which makes the 'buffer allocation' operations quite a
few...

I wonder if, as the allocator really need to be exposed to
applications..

I assume for the internally allocated buffer it could be simply
replaced by calling Stream::allocate() on each Stream part of the
camera configuration.

I still fail to find how externally allocated buffers are imported
now, will they go through the buffer allocator as well ?

>
> Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> ---
>  include/libcamera/buffer.h | 17 ++++++++++++++
>  include/libcamera/stream.h |  1 +
>  src/libcamera/buffer.cpp   | 48 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 66 insertions(+)
>
> diff --git a/include/libcamera/buffer.h b/include/libcamera/buffer.h
> index c626f669040b3c04..adb642ad5da072d2 100644
> --- a/include/libcamera/buffer.h
> +++ b/include/libcamera/buffer.h
> @@ -8,11 +8,14 @@
>  #define __LIBCAMERA_BUFFER_H__
>
>  #include <array>
> +#include <map>
> +#include <memory>
>  #include <stdint.h>
>  #include <vector>
>
>  namespace libcamera {
>
> +class Camera;
>  class Request;
>  class Stream;
>
> @@ -139,6 +142,20 @@ private:
>  	std::vector<PlaneInfo> planes_;
>  };
>
> +class BufferAllocator
> +{
> +public:
> +	BufferAllocator(std::shared_ptr<Camera> camera);
> +	~BufferAllocator();
> +
> +	int allocate(Stream *stream);
> +	std::vector<Buffer *> get(Stream *stream);
> +
> +private:
> +	std::shared_ptr<Camera> camera_;
> +	std::map<Stream *, std::vector<Buffer *>> allocated_;
> +};
> +
>  } /* namespace libcamera */
>
>  #endif /* __LIBCAMERA_BUFFER_H__ */
> diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h
> index dac4831cfa1a9b1d..b051341511a7ab7c 100644
> --- a/include/libcamera/stream.h
> +++ b/include/libcamera/stream.h
> @@ -84,6 +84,7 @@ public:
>  	MemoryType memoryType() const { return memoryType_; }
>
>  protected:
> +	friend class BufferAllocator;
>  	friend class Camera;
>
>  	virtual int allocateBuffers(std::vector<Buffer *> *buffers) { return -EINVAL; }
> diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp
> index 10b16a862393b536..fce1ce5e49cbbf42 100644
> --- a/src/libcamera/buffer.cpp
> +++ b/src/libcamera/buffer.cpp
> @@ -12,6 +12,9 @@
>  #include <sys/mman.h>
>  #include <unistd.h>
>
> +#include <libcamera/camera.h>
> +#include <libcamera/stream.h>
> +
>  #include "log.h"
>
>  /**
> @@ -393,4 +396,49 @@ void Buffer::cancel()
>   * The intended callers are Request::prepare() and Request::completeBuffer().
>   */
>
> +BufferAllocator::BufferAllocator(std::shared_ptr<Camera> camera)
> +	: camera_(camera)
> +{
> +}
> +
> +BufferAllocator::~BufferAllocator()
> +{
> +	for (auto &it : allocated_) {
> +		Stream *stream = it.first;
> +		std::vector<Buffer *> &buffers = it.second;
> +
> +		for (Buffer *buffer : buffers)
> +			delete buffer;
> +
> +		buffers.clear();
> +
> +		stream->allocateBuffers(nullptr);
> +	}
> +}
> +
> +int BufferAllocator::allocate(Stream *stream)
> +{
> +	bool found = false;
> +
> +	for (const Stream *s : camera_->streams()) {
> +		if (stream == s) {
> +			found = true;
> +			break;
> +		}
> +	}
> +
> +	if (!found)
> +		return -EINVAL;
> +
> +	return stream->allocateBuffers(&allocated_[stream]);
> +}
> +
> +std::vector<Buffer *> BufferAllocator::get(Stream *stream)
> +{
> +	if (allocated_.find(stream) == allocated_.end())
> +		return {};
> +
> +	return allocated_[stream];
> +}
> +
>  } /* namespace libcamera */
> --
> 2.23.0
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel at lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://lists.libcamera.org/pipermail/libcamera-devel/attachments/20191115/83e110a1/attachment.sig>


More information about the libcamera-devel mailing list