libcamera: Provide a Request object

Implement a Request object used by applications to queue image capture
requests to a camera.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
This commit is contained in:
Jacopo Mondi 2019-02-04 16:33:01 +01:00 committed by Laurent Pinchart
parent 1d7b6297f2
commit 5aef825764
7 changed files with 177 additions and 0 deletions

View file

@ -11,10 +11,12 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <libcamera/request.h>
#include <libcamera/signal.h> #include <libcamera/signal.h>
namespace libcamera { namespace libcamera {
class Buffer;
class PipelineHandler; class PipelineHandler;
class Stream; class Stream;
class StreamConfiguration; class StreamConfiguration;
@ -31,6 +33,7 @@ public:
const std::string &name() const; const std::string &name() const;
Signal<Request *, const std::map<Stream *, Buffer *> &> requestCompleted;
Signal<Camera *> disconnected; Signal<Camera *> disconnected;
int acquire(); int acquire();

View file

@ -12,6 +12,7 @@
#include <libcamera/camera_manager.h> #include <libcamera/camera_manager.h>
#include <libcamera/event_dispatcher.h> #include <libcamera/event_dispatcher.h>
#include <libcamera/event_notifier.h> #include <libcamera/event_notifier.h>
#include <libcamera/request.h>
#include <libcamera/signal.h> #include <libcamera/signal.h>
#include <libcamera/stream.h> #include <libcamera/stream.h>
#include <libcamera/timer.h> #include <libcamera/timer.h>

View file

@ -5,6 +5,7 @@ libcamera_api = files([
'event_dispatcher.h', 'event_dispatcher.h',
'event_notifier.h', 'event_notifier.h',
'libcamera.h', 'libcamera.h',
'request.h',
'signal.h', 'signal.h',
'stream.h', 'stream.h',
'timer.h', 'timer.h',

View file

@ -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__ */

View file

@ -97,6 +97,11 @@ const std::string &Camera::name() const
return name_; return name_;
} }
/**
* \var Camera::requestCompleted
* \brief Signal emitted when a request queued to the camera has completed
*/
/** /**
* \var Camera::disconnected * \var Camera::disconnected
* \brief Signal emitted when the camera is disconnected from the system * \brief Signal emitted when the camera is disconnected from the system

View file

@ -11,6 +11,7 @@ libcamera_sources = files([
'media_device.cpp', 'media_device.cpp',
'media_object.cpp', 'media_object.cpp',
'pipeline_handler.cpp', 'pipeline_handler.cpp',
'request.cpp',
'signal.cpp', 'signal.cpp',
'stream.cpp', 'stream.cpp',
'timer.cpp', 'timer.cpp',

122
src/libcamera/request.cpp Normal file
View file

@ -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 */