[libcamera-devel] [RFC 4/7] libcamera: camera: add request support

Niklas Söderlund niklas.soderlund at ragnatech.se
Tue Feb 5 01:06:59 CET 2019


Add support to the camera to create and queue requests. The application
needs methods to get hold of buffers and creating requests. Once a
request is created it can be queued to the camera and the application
will asynchronously be notified once the request is completed and be
able to process all the buffers involved in the request.

At this point the request objects contains no controls be configured,
this needs to be extended in the future once the library supports v4l2
controls and requests.

Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
---
 include/libcamera/camera.h |   7 +++
 src/libcamera/camera.cpp   | 102 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 108 insertions(+), 1 deletion(-)

diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h
index de338c616641c074..f6991a50900e6956 100644
--- a/include/libcamera/camera.h
+++ b/include/libcamera/camera.h
@@ -16,7 +16,9 @@
 namespace libcamera {
 
 class Buffer;
+class BufferPool;
 class PipelineHandler;
+class Request;
 class Stream;
 class StreamConfiguration;
 
@@ -42,6 +44,10 @@ public:
 	streamConfiguration(std::vector<Stream *> &streams);
 	int configureStreams(std::map<Stream *, StreamConfiguration> &config);
 
+	BufferPool *bufferPool(Stream *);
+	Request *createRequest(std::map<Stream *, Buffer *> &resources);
+	int queueRequest(Request *request);
+
 	int start();
 	int stop();
 
@@ -55,6 +61,7 @@ private:
 	std::shared_ptr<PipelineHandler> pipe_;
 	std::string name_;
 	std::vector<Stream *> streams_;
+	std::map<Stream *, BufferPool *> bufferPools_;
 
 	bool acquired_;
 	bool disconnected_;
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index bf09acfdb9cd0007..de78536993601ee3 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -246,7 +246,107 @@ int Camera::configureStreams(std::map<Stream *, StreamConfiguration> &config)
 	if (!config.size())
 		return -EINVAL;
 
-	return pipe_->configureStreams(this, config);
+	int ret = pipe_->configureStreams(this, config);
+	if (ret)
+		return ret;
+
+	bufferPools_ = pipe_->allocateBuffers(this, config);
+	if (!bufferPools_.size())
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ * \brief Retrieve the buffer pool for a stream
+ * \param[in] stream Stream to retrieve buffer pool from
+ *
+ * Retrieve the buffer pool for a specific stream, if one exists. To be able to
+ * queue request to the camera the application needs to create requests and
+ * attache buffers to the request. To get hold of buffers to associate with the
+ * request the streams buffer pool needs to be retrieved. This interface allows
+ * the application to get hold of the streams buffer pool.
+ *
+ * The buffer pools are created when the application configures the camera,
+ * prior to configuration of the camera no buffer pools exists this calling
+ * this function at that time will return a nullptr.
+ *
+ * \return pointer to the buffer pool, nullptr on error
+ */
+BufferPool *Camera::bufferPool(Stream *stream)
+{
+	if (disconnected_)
+		return nullptr;
+
+	if (!acquired_)
+		return nullptr;
+
+	if (bufferPools_.find(stream) == bufferPools_.end())
+		return nullptr;
+
+	return bufferPools_[stream];
+}
+
+/**
+ * \brief Create a request object for the camera
+ * \param[in] resources Array of streams and buffer to create a request from
+ *
+ * Before an application can queue a request to the camera it needs to be
+ * created, this interface allows the application to create such requests. The
+ * application needs to supply a map of streams and buffers that the request
+ * should process once it's queued to the camera.
+ *
+ * Once a request object have been created the application can set controls
+ * that are to be used to capture the particular frame before queuing it to
+ * the camera.
+ *
+ * \return pointer to the buffer pool, nullptr on error
+ */
+Request *Camera::createRequest(std::map<Stream *, Buffer *> &resources)
+{
+	if (disconnected_)
+		return nullptr;
+
+	if (!acquired_)
+		return nullptr;
+
+	if (resources.size() == 0)
+		return nullptr;
+
+	return new Request(resources);
+}
+
+/**
+ * \brief Queue a request to the camera
+ * \param[in] request The request to queue to the camera
+ *
+ * The application can once its got hold of a request queue it to a running
+ * camera at any point. The application get hold of a request by either creating
+ * it or reusing a old request once it's been completed and the application have
+ * no further use of the buffers it contained.
+ *
+ * Once a request have been queued to the camera it will be notified once the
+ * request is complete and the associated buffers can be consumed.
+ *
+ * \return 0 on success or a negative error code on error.
+ * \retval -ENODEV The camera is not connected to any hardware
+ * \retval -EACCES The user has not acquired exclusive access to the camera
+ */
+int Camera::queueRequest(Request *request)
+{
+	if (disconnected_)
+		return -ENODEV;
+
+	if (!acquired_)
+		return -EACCES;
+
+	int ret = request->prepare();
+	if (ret) {
+		LOG(Camera, Error) << "Failed to connect request resources";
+		return ret;
+	}
+
+	return pipe_->queueRequest(this, request);
 }
 
 /**
-- 
2.20.1



More information about the libcamera-devel mailing list