mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-26 01:55:51 +03:00
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:
parent
1d7b6297f2
commit
5aef825764
7 changed files with 177 additions and 0 deletions
|
@ -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();
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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',
|
||||||
|
|
44
include/libcamera/request.h
Normal file
44
include/libcamera/request.h
Normal 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__ */
|
|
@ -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
|
||||||
|
|
|
@ -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
122
src/libcamera/request.cpp
Normal 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 */
|
Loading…
Add table
Add a link
Reference in a new issue