From patchwork Wed Oct 7 10:17:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10002 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 16DFFBEEDF for ; Wed, 7 Oct 2020 10:14:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E0CF760455; Wed, 7 Oct 2020 12:14:05 +0200 (CEST) Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [217.70.183.195]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 847FB60396 for ; Wed, 7 Oct 2020 12:14:03 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 9727660005; Wed, 7 Oct 2020 10:14:02 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 7 Oct 2020 12:17:42 +0200 Message-Id: <20201007101745.15104-11-jacopo@jmondi.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201007101745.15104-1-jacopo@jmondi.org> References: <20201007101745.15104-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 10/13] android: camera_stream: Create buffer pool X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" 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 Reviewed-by: Kieran Bingham Signed-off-by: Jacopo Mondi --- src/android/camera_device.cpp | 22 +++++++++--------- src/android/camera_stream.cpp | 43 +++++++++++++++++++++++++++++++++++ src/android/camera_stream.h | 9 ++++++++ 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 1e2cbeeb92d1..ecdc0922e90b 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -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; } diff --git a/src/android/camera_stream.cpp b/src/android/camera_stream.cpp index f899be4fe007..eac1480530f8 100644 --- a/src/android/camera_stream.cpp +++ b/src/android/camera_stream.cpp @@ -26,6 +26,11 @@ CameraStream::CameraStream(CameraDevice *cameraDevice, Type type, if (type_ == Type::Internal || type_ == Type::Mapped) encoder_ = std::make_unique(); + + if (type == Type::Internal) { + allocator_ = std::make_unique(cameraDevice_->camera()); + mutex_ = std::make_unique(); + } } 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 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 locker(*mutex_); + + buffers_.push_back(buffer); +} diff --git a/src/android/camera_stream.h b/src/android/camera_stream.h index 4c51f0fb3393..f929e8260ae3 100644 --- a/src/android/camera_stream.h +++ b/src/android/camera_stream.h @@ -8,11 +8,14 @@ #define __ANDROID_CAMERA_STREAM_H__ #include +#include +#include #include #include #include +#include #include #include @@ -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,11 @@ private: * one or more streams to the Android framework. */ unsigned int index_; + std::unique_ptr encoder_; + std::unique_ptr allocator_; + std::vector buffers_; + std::unique_ptr mutex_; }; #endif /* __ANDROID_CAMERA_STREAM__ */