diff options
-rw-r--r-- | include/libcamera/camera.h | 3 | ||||
-rw-r--r-- | include/libcamera/libcamera.h | 1 | ||||
-rw-r--r-- | include/libcamera/meson.build | 1 | ||||
-rw-r--r-- | include/libcamera/request.h | 44 | ||||
-rw-r--r-- | src/libcamera/camera.cpp | 5 | ||||
-rw-r--r-- | src/libcamera/meson.build | 1 | ||||
-rw-r--r-- | src/libcamera/request.cpp | 122 |
7 files changed, 177 insertions, 0 deletions
diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 4940c344..bbe2696e 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -11,10 +11,12 @@ #include <memory> #include <string> +#include <libcamera/request.h> #include <libcamera/signal.h> namespace libcamera { +class Buffer; class PipelineHandler; class Stream; class StreamConfiguration; @@ -31,6 +33,7 @@ public: const std::string &name() const; + Signal<Request *, const std::map<Stream *, Buffer *> &> requestCompleted; Signal<Camera *> disconnected; int acquire(); diff --git a/include/libcamera/libcamera.h b/include/libcamera/libcamera.h index 8167e809..dda576e9 100644 --- a/include/libcamera/libcamera.h +++ b/include/libcamera/libcamera.h @@ -12,6 +12,7 @@ #include <libcamera/camera_manager.h> #include <libcamera/event_dispatcher.h> #include <libcamera/event_notifier.h> +#include <libcamera/request.h> #include <libcamera/signal.h> #include <libcamera/stream.h> #include <libcamera/timer.h> diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build index 8c14423b..5788e9bb 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 00000000..ef081177 --- /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 <map> +#include <unordered_set> + +#include <libcamera/signal.h> + +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<Stream *, Buffer *> &streamMap); + Buffer *findBuffer(Stream *stream) const; + +private: + friend class Camera; + + int prepare(); + void bufferCompleted(Buffer *buffer); + + Camera *camera_; + std::map<Stream *, Buffer *> bufferMap_; + std::unordered_set<Buffer *> pending_; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_REQUEST_H__ */ diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index bcf3d54a..e8dab6f0 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -98,6 +98,11 @@ const std::string &Camera::name() const } /** + * \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 ac991dc5..c5354c13 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 00000000..922682a3 --- /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 <map> + +#include <libcamera/buffer.h> +#include <libcamera/camera.h> +#include <libcamera/request.h> +#include <libcamera/stream.h> + +#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<Stream *, Buffer *> &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<Stream *, Buffer *> buffers(std::move(bufferMap_)); + camera_->requestCompleted.emit(this, buffers); + } +} + +} /* namespace libcamera */ |