android: camera_stream: Create buffer pool

Add a FrameBufferAllocator class member to the CameraStream class.
The allocator is constructed for CameraStream instances that needs
internal allocation and automatically deleted.

Allocate FrameBuffers using the allocator_ class member in the
CameraStream class at CameraStream::configure() time and add two
methods to the CameraStream class to get and put FrameBuffer pointers
from the pool of allocated buffers. As buffer allocation can take place
only after the Camera has been configured, move the CameraStream
configuration loop in the CameraDevice class after camera_->configure()
call.

The newly created pool will be used to provide buffers to CameraStream
that need to provide memory to libcamera where to deliver frames.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
This commit is contained in:
Jacopo Mondi 2020-10-03 13:21:50 +02:00
parent 6c8837da5e
commit b84e35dc97
3 changed files with 67 additions and 11 deletions

View file

@ -1282,6 +1282,17 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
return -EINVAL;
}
/*
* Once the CameraConfiguration has been adjusted/validated
* it can be applied to the camera.
*/
int ret = camera_->configure(config_.get());
if (ret) {
LOG(HAL, Error) << "Failed to configure camera '"
<< camera_->id() << "'";
return ret;
}
/*
* Configure the HAL CameraStream instances using the associated
* StreamConfiguration and set the number of required buffers in
@ -1295,17 +1306,6 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
}
}
/*
* Once the CameraConfiguration has been adjusted/validated
* it can be applied to the camera.
*/
int ret = camera_->configure(config_.get());
if (ret) {
LOG(HAL, Error) << "Failed to configure camera '"
<< camera_->id() << "'";
return ret;
}
return 0;
}

View file

@ -26,6 +26,11 @@ CameraStream::CameraStream(CameraDevice *cameraDevice, Type type,
if (type_ == Type::Internal || type_ == Type::Mapped)
encoder_ = std::make_unique<EncoderLibJpeg>();
if (type == Type::Internal) {
allocator_ = std::make_unique<FrameBufferAllocator>(cameraDevice_->camera());
mutex_ = std::make_unique<std::mutex>();
}
}
const StreamConfiguration &CameraStream::configuration() const
@ -46,6 +51,16 @@ int CameraStream::configure()
return ret;
}
if (allocator_) {
int ret = allocator_->allocate(stream());
if (ret < 0)
return ret;
/* Save a pointer to the reserved frame buffers */
for (const auto &frameBuffer : allocator_->buffers(stream()))
buffers_.push_back(frameBuffer.get());
}
camera3Stream_->max_buffers = configuration().bufferCount;
return 0;
@ -109,3 +124,31 @@ int CameraStream::process(const libcamera::FrameBuffer &source,
return 0;
}
FrameBuffer *CameraStream::getBuffer()
{
if (!allocator_)
return nullptr;
std::lock_guard<std::mutex> locker(*mutex_);
if (buffers_.empty()) {
LOG(HAL, Error) << "Buffer underrun";
return nullptr;
}
FrameBuffer *buffer = buffers_.back();
buffers_.pop_back();
return buffer;
}
void CameraStream::putBuffer(libcamera::FrameBuffer *buffer)
{
if (!allocator_)
return;
std::lock_guard<std::mutex> locker(*mutex_);
buffers_.push_back(buffer);
}

View file

@ -8,11 +8,14 @@
#define __ANDROID_CAMERA_STREAM_H__
#include <memory>
#include <mutex>
#include <vector>
#include <hardware/camera3.h>
#include <libcamera/buffer.h>
#include <libcamera/camera.h>
#include <libcamera/framebuffer_allocator.h>
#include <libcamera/geometry.h>
#include <libcamera/pixel_format.h>
@ -117,6 +120,8 @@ public:
int configure();
int process(const libcamera::FrameBuffer &source,
MappedCamera3Buffer *dest, CameraMetadata *metadata);
libcamera::FrameBuffer *getBuffer();
void putBuffer(libcamera::FrameBuffer *buffer);
private:
CameraDevice *cameraDevice_;
@ -129,7 +134,15 @@ private:
* one or more streams to the Android framework.
*/
unsigned int index_;
std::unique_ptr<Encoder> encoder_;
std::unique_ptr<libcamera::FrameBufferAllocator> allocator_;
std::vector<libcamera::FrameBuffer *> buffers_;
/*
* The class has to be MoveConstructible as instances are stored in
* an std::vector in CameraDevice.
*/
std::unique_ptr<std::mutex> mutex_;
};
#endif /* __ANDROID_CAMERA_STREAM__ */