From patchwork Tue Oct 6 16:06:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 9984 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 8501ABEEE0 for ; Tue, 6 Oct 2020 16:02:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6949263C85; Tue, 6 Oct 2020 18:02:45 +0200 (CEST) Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 434B560363 for ; Tue, 6 Oct 2020 18:02:44 +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 relay8-d.mail.gandi.net (Postfix) with ESMTPSA id D766F1BF207; Tue, 6 Oct 2020 16:02:43 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 6 Oct 2020 18:06:36 +0200 Message-Id: <20201006160637.29841-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201006160637.29841-1-jacopo@jmondi.org> References: <20201006160637.29841-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC 1/2] android: camera_worker: Introduce CameraWorker 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" The CameraWork class creates a Worker instance and runs on an internal thread. The worker waits on a set of fences before queueing a capture requests to the the libcamera::Camera. Signed-off-by: Jacopo Mondi --- src/android/camera_worker.cpp | 67 +++++++++++++++++++++++++++++++ src/android/camera_worker.h | 75 +++++++++++++++++++++++++++++++++++ src/android/meson.build | 1 + 3 files changed, 143 insertions(+) create mode 100644 src/android/camera_worker.cpp create mode 100644 src/android/camera_worker.h diff --git a/src/android/camera_worker.cpp b/src/android/camera_worker.cpp new file mode 100644 index 000000000000..2bb94775a195 --- /dev/null +++ b/src/android/camera_worker.cpp @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * camera_worker.cpp - Process capture request on behalf of the Camera HAL + */ + +#include "camera_worker.h" + +#include +#include + +#include "camera_device.h" + +using namespace libcamera; + +CameraWorker::CameraWorker(const std::shared_ptr &camera) + : camera_(camera), worker_(camera_.get()) +{ + worker_.moveToThread(&thread_); + thread_.start(); +} + +void CameraWorker::queueRequest(std::unique_ptr request) +{ + CaptureRequest *req = request.release(); + worker_.invokeMethod(&Worker::processRequest, ConnectionTypeQueued, req); +} + +int CameraWorker::Worker::waitFence(int fence) +{ + struct pollfd fds = { fence, POLLIN, 0 }; + constexpr unsigned int timeoutMs = 300; + int ret; + + do { + ret = poll(&fds, 1, timeoutMs); + if (ret == 0) + return -ETIME; + + if (ret > 0) { + if (fds.revents & (POLLERR | POLLNVAL)) + return -EINVAL; + + return 0; + } + } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); + + return ret; +} + +void CameraWorker::Worker::processRequest(CaptureRequest *request) +{ + for (int fence : request->acquireFences_) { + if (fence == -1) + continue; + + int ret = waitFence(fence); + if (ret < 0) + return; + + close(fence); + } + + camera_->queueRequest(request->request_); + delete request; +} diff --git a/src/android/camera_worker.h b/src/android/camera_worker.h new file mode 100644 index 000000000000..24b176d6269c --- /dev/null +++ b/src/android/camera_worker.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * camera_worker.h - Process capture request on behalf of the Camera HAL + */ +#ifndef __ANDROID_CAMERA_WORKER_H__ +#define __ANDROID_CAMERA_WORKER_H__ + +#include + +#include +#include +#include +#include +#include + +#include "libcamera/internal/thread.h" + +class CameraDevice; + +struct CaptureRequest { + CaptureRequest(libcamera::Request *request) + : request_(request) + { + } + + void addBuffer(libcamera::Stream *stream, + libcamera::FrameBuffer *buffer, int fence) + { + request_->addBuffer(stream, buffer); + acquireFences_.push_back(fence); + } + +private: + friend class CameraWorker; + + std::vector acquireFences_; + libcamera::Request *request_; +}; + +class CameraWorker +{ +public: + CameraWorker(const std::shared_ptr &camera); + + void queueRequest(std::unique_ptr request); + +private: + class Worker : public libcamera::Object + { + public: + Worker(libcamera::Camera *camera) + : camera_(camera) + { + } + ~Worker() + { + } + + void processRequest(CaptureRequest *request); + + private: + int waitFence(int fence); + + libcamera::Camera *camera_; + }; + + std::shared_ptr camera_; + + Worker worker_; + libcamera::Thread thread_; +}; + +#endif /* __ANDROID_CAMERA_WORKER_H__ */ diff --git a/src/android/meson.build b/src/android/meson.build index 802bb89afe57..b2b2293cf62d 100644 --- a/src/android/meson.build +++ b/src/android/meson.build @@ -21,6 +21,7 @@ android_hal_sources = files([ 'camera_metadata.cpp', 'camera_ops.cpp', 'camera_stream.cpp', + 'camera_worker.cpp', 'jpeg/encoder_libjpeg.cpp', 'jpeg/exif.cpp', ]) From patchwork Tue Oct 6 16:06:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 9985 X-Patchwork-Delegate: jacopo@jmondi.org 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 A91F5BEEE0 for ; Tue, 6 Oct 2020 16:02:47 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 85E9B63C1B; Tue, 6 Oct 2020 18:02:47 +0200 (CEST) Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CACC663C13 for ; Tue, 6 Oct 2020 18:02:44 +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 relay8-d.mail.gandi.net (Postfix) with ESMTPSA id 67FE31BF210; Tue, 6 Oct 2020 16:02:44 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 6 Oct 2020 18:06:37 +0200 Message-Id: <20201006160637.29841-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201006160637.29841-1-jacopo@jmondi.org> References: <20201006160637.29841-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC 2/2] android: camera_device: Queue request to Worker 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 CameraWorker class member to the CameraDevice class and queue capture requests to it to delegate fence handling and capture requests queueing to the camera. Signed-off-by: Jacopo Mondi --- src/android/camera_device.cpp | 21 ++++++++------------- src/android/camera_device.h | 3 +++ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 8da70e817b46..edac9f28ab67 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -194,8 +194,8 @@ CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor() */ CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr &camera) - : id_(id), running_(false), camera_(camera), staticMetadata_(nullptr), - facing_(CAMERA_FACING_FRONT), orientation_(0) + : id_(id), worker_(camera), running_(false), camera_(camera), + staticMetadata_(nullptr), facing_(CAMERA_FACING_FRONT), orientation_(0) { camera_->requestCompleted.connect(this, &CameraDevice::requestComplete); @@ -1375,8 +1375,9 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques new Camera3RequestDescriptor(camera3Request->frame_number, camera3Request->num_output_buffers); - Request *request = - camera_->createRequest(reinterpret_cast(descriptor)); + std::unique_ptr captureRequest = + std::make_unique( + camera_->createRequest(reinterpret_cast(descriptor))); LOG(HAL, Debug) << "Queueing Request to libcamera with " << descriptor->numBuffers << " HAL streams"; @@ -1440,21 +1441,15 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques if (!buffer) { LOG(HAL, Error) << "Failed to create buffer"; - delete request; delete descriptor; return -ENOMEM; } - request->addBuffer(cameraStream->stream(), buffer); + captureRequest->addBuffer(cameraStream->stream(), buffer, + camera3Buffers[i].acquire_fence); } - int ret = camera_->queueRequest(request); - if (ret) { - LOG(HAL, Error) << "Failed to queue request"; - delete request; - delete descriptor; - return ret; - } + worker_.queueRequest(std::move(captureRequest)); return 0; } diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 777d1a35e801..b4b32f77a29a 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -25,6 +25,7 @@ #include "libcamera/internal/message.h" #include "camera_stream.h" +#include "camera_worker.h" #include "jpeg/encoder.h" class CameraMetadata; @@ -108,6 +109,8 @@ private: unsigned int id_; camera3_device_t camera3Device_; + CameraWorker worker_; + bool running_; std::shared_ptr camera_; std::unique_ptr config_;