From patchwork Wed Feb 6 06:08:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 530 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2E5E561020 for ; Wed, 6 Feb 2019 07:08:27 +0100 (CET) Received: from pendragon.ideasonboard.com (d51A4137F.access.telenet.be [81.164.19.127]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id CAAE22DA for ; Wed, 6 Feb 2019 07:08:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1549433306; bh=Uj/kyqoFHyMJhqhmritCjWC5aEfPSffUiyNFq64um0c=; h=From:To:Subject:Date:In-Reply-To:References:From; b=uX1LY6LWACCRqS/y+keXBJfbhTSkNSTEsxQqVuzRCpFGm9S7taKkMJavhVLdfuxCc bknKEenE7fGK52s95nHgPLDKVlkY2y+HolaxXuuf0odjj0LXVgUYjExyJQkkCYVkpX UmsSZyVgLO9gk9CMzkusKZPRc7E/d3heZeLMbfbs= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Wed, 6 Feb 2019 08:08:06 +0200 Message-Id: <20190206060818.13907-16-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190206060818.13907-1-laurent.pinchart@ideasonboard.com> References: <20190206060818.13907-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 15/27] libcamera: Provide a Request object X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 Feb 2019 06:08:29 -0000 From: Jacopo Mondi Implement a Request object used by applications to queue image capture requests to a camera. Signed-off-by: Jacopo Mondi Signed-off-by: Kieran Bingham Signed-off-by: Laurent Pinchart Signed-off-by: Niklas Söderlund --- include/libcamera/camera.h | 3 + include/libcamera/libcamera.h | 1 + include/libcamera/meson.build | 1 + include/libcamera/request.h | 44 ++++++++++++ src/libcamera/camera.cpp | 5 ++ src/libcamera/meson.build | 1 + src/libcamera/request.cpp | 122 ++++++++++++++++++++++++++++++++++ 7 files changed, 177 insertions(+) create mode 100644 include/libcamera/request.h create mode 100644 src/libcamera/request.cpp diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 4940c344440e..bbe2696e837b 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -11,10 +11,12 @@ #include #include +#include #include namespace libcamera { +class Buffer; class PipelineHandler; class Stream; class StreamConfiguration; @@ -31,6 +33,7 @@ public: const std::string &name() const; + Signal &> requestCompleted; Signal disconnected; int acquire(); diff --git a/include/libcamera/libcamera.h b/include/libcamera/libcamera.h index 8167e8099ac0..dda576e906fb 100644 --- a/include/libcamera/libcamera.h +++ b/include/libcamera/libcamera.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build index 8c14423bc444..5788e9bbdf3e 100644 --- a/include/libcamera/meson.build +++ b/include/libcamera/meson.build @@ -5,6 +5,7 @@ libcamera_api = files([ 'event_dispatcher.h', 'event_notifier.h', 'libcamera.h', + 'request.h', 'signal.h', 'stream.h', 'timer.h', diff --git a/include/libcamera/request.h b/include/libcamera/request.h new file mode 100644 index 000000000000..ef081177309f --- /dev/null +++ b/include/libcamera/request.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * request.h - Capture request handling + */ +#ifndef __LIBCAMERA_REQUEST_H__ +#define __LIBCAMERA_REQUEST_H__ + +#include +#include + +#include + +namespace libcamera { + +class Buffer; +class Camera; +class Stream; + +class Request +{ +public: + explicit Request(Camera *camera); + Request(const Request &) = delete; + Request &operator=(const Request &) = delete; + + int setBuffers(const std::map &streamMap); + Buffer *findBuffer(Stream *stream) const; + +private: + friend class Camera; + + int prepare(); + void bufferCompleted(Buffer *buffer); + + Camera *camera_; + std::map bufferMap_; + std::unordered_set pending_; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_REQUEST_H__ */ diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index bcf3d54ab1c3..e8dab6f0bab2 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -97,6 +97,11 @@ const std::string &Camera::name() const return name_; } +/** + * \var Camera::requestCompleted + * \brief Signal emitted when a request queued to the camera has completed + */ + /** * \var Camera::disconnected * \brief Signal emitted when the camera is disconnected from the system diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index ac991dc59d18..c5354c136563 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -11,6 +11,7 @@ libcamera_sources = files([ 'media_device.cpp', 'media_object.cpp', 'pipeline_handler.cpp', + 'request.cpp', 'signal.cpp', 'stream.cpp', 'timer.cpp', diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp new file mode 100644 index 000000000000..922682a32188 --- /dev/null +++ b/src/libcamera/request.cpp @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * request.cpp - Capture request handling + */ + +#include + +#include +#include +#include +#include + +#include "log.h" + +/** + * \file request.h + * \brief Describes a frame capture request to be processed by a camera + */ + +namespace libcamera { + +LOG_DEFINE_CATEGORY(Request) + +/** + * \class Request + * \brief A frame capture request + * + * A Request allows an application to associate buffers and controls on a + * per-frame basis to be queued to the camera device for processing. + */ + +/** + * \brief Create a capture request for a camera + * \param[in] camera The camera that creates the request + */ +Request::Request(Camera *camera) + : camera_(camera) +{ +} + +/** + * \brief Set the streams to capture with associated buffers + * \param[in] streamMap The map of streams to buffers + * \return 0 on success or a negative error code otherwise + * \retval -EBUSY Buffers have already been set + */ +int Request::setBuffers(const std::map &streamMap) +{ + if (!bufferMap_.empty()) { + LOG(Request, Error) << "Buffers already set"; + return -EBUSY; + } + + bufferMap_ = streamMap; + return 0; +} + +/** + * \var Request::bufferMap_ + * \brief Mapping of streams to buffers for this request + * + * The bufferMap_ tracks the buffers associated with each stream. If a stream is + * not utilised in this request there will be no buffer for that stream in the + * map. + */ + +/** + * \brief Return the buffer associated with a stream + * \param[in] stream The stream the buffer is associated to + * + * \return The buffer associated with the stream, or nullptr if the stream is + * not part of this request + */ +Buffer *Request::findBuffer(Stream *stream) const +{ + auto it = bufferMap_.find(stream); + if (it == bufferMap_.end()) + return nullptr; + + return it->second; +} + +/** + * \brief Prepare the resources for the completion handler + */ +int Request::prepare() +{ + for (auto const &pair : bufferMap_) { + Buffer *buffer = pair.second; + buffer->completed.connect(this, &Request::bufferCompleted); + pending_.insert(buffer); + } + + return 0; +} + +/** + * \brief Slot for the buffer completed signal + * + * The bufferCompleted method serves as slot where to connect the + * Buffer::completed signal that is emitted when a buffer has available + * data. + * + * The request completes when all the buffers it contains are ready to be + * presented to the application. + */ +void Request::bufferCompleted(Buffer *buffer) +{ + buffer->completed.disconnect(this, &Request::bufferCompleted); + + int ret = pending_.erase(buffer); + ASSERT(ret == 1); + + if (pending_.empty()) { + std::map buffers(std::move(bufferMap_)); + camera_->requestCompleted.emit(this, buffers); + } +} + +} /* namespace libcamera */