[libcamera-devel] [RFC 2/7] libcamera: pipelines: add buffer and request support

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


To allow a pipeline handler to provide buffers for request creation and
later processing of requests it needs to  be extended with methods to
allocate/free buffers and a way to queue requests to the pipeline.

Add the interfaces for these methods in the PipelineHandler base class
and extend all pipeline handler with stubs to be expanded later to
actually perform the appropriate actions for each pipeline.

This initial implementation only considers the allocation of new
buffers. Future work would need to expand this to also cover importing
buffers the camera from an external source.

Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
---
 src/libcamera/include/pipeline_handler.h |  8 ++++
 src/libcamera/pipeline/ipu3/ipu3.cpp     | 24 ++++++++++++
 src/libcamera/pipeline/uvcvideo.cpp      | 24 ++++++++++++
 src/libcamera/pipeline/vimc.cpp          | 24 ++++++++++++
 src/libcamera/pipeline_handler.cpp       | 47 ++++++++++++++++++++++++
 5 files changed, 127 insertions(+)

diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h
index 4bfe45aaf78e34ab..fab6d3ee1f3e04d7 100644
--- a/src/libcamera/include/pipeline_handler.h
+++ b/src/libcamera/include/pipeline_handler.h
@@ -14,10 +14,12 @@
 
 namespace libcamera {
 
+class BufferPool;
 class Camera;
 class CameraManager;
 class DeviceEnumerator;
 class MediaDevice;
+class Request;
 class Stream;
 class StreamConfiguration;
 
@@ -45,9 +47,15 @@ public:
 	virtual int configureStreams(Camera *camera,
 				     std::map<Stream *, StreamConfiguration> &config) = 0;
 
+	virtual std::map<Stream *, BufferPool *> allocateBuffers(Camera *camera,
+			std::map<Stream *, StreamConfiguration> &config) = 0;
+	virtual int freeBuffers(Camera *camera) = 0;
+
 	virtual int start(const Camera *camera) = 0;
 	virtual void stop(const Camera *camera) = 0;
 
+	virtual int queueRequest(const Camera *camera, Request *request) = 0;
+
 	virtual bool match(DeviceEnumerator *enumerator) = 0;
 
 protected:
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 3bf196051f2ebdbc..881afe3a4779f46d 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -34,9 +34,16 @@ public:
 	int configureStreams(Camera *camera,
 			     std::map<Stream *, StreamConfiguration> &config) override;
 
+	std::map<Stream *, BufferPool *>
+	allocateBuffers(Camera *camera,
+			std::map<Stream *, StreamConfiguration> &config) override;
+	int freeBuffers(Camera *camera) override;
+
 	int start(const Camera *camera) override;
 	void stop(const Camera *camera) override;
 
+	int queueRequest(const Camera *camera, Request *request) override;
+
 	bool match(DeviceEnumerator *enumerator);
 
 private:
@@ -107,6 +114,18 @@ int PipelineHandlerIPU3::configureStreams(Camera *camera,
 	return 0;
 }
 
+std::map<Stream *, BufferPool *>
+PipelineHandlerIPU3::allocateBuffers(Camera *camera,
+				     std::map<Stream *, StreamConfiguration> &config)
+{
+	return std::map<Stream *, BufferPool *> {};
+}
+
+int PipelineHandlerIPU3::freeBuffers(Camera *camera)
+{
+	return 0;
+}
+
 int PipelineHandlerIPU3::start(const Camera *camera)
 {
 	LOG(IPU3, Error) << "TODO: start camera";
@@ -118,6 +137,11 @@ void PipelineHandlerIPU3::stop(const Camera *camera)
 	LOG(IPU3, Error) << "TODO: stop camera";
 }
 
+int PipelineHandlerIPU3::queueRequest(const Camera *camera, Request *request)
+{
+	return 0;
+}
+
 bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator)
 {
 	DeviceMatch cio2_dm("ipu3-cio2");
diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
index e6a15c58a63cf76b..8b3f0ce7e2112564 100644
--- a/src/libcamera/pipeline/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo.cpp
@@ -30,9 +30,16 @@ public:
 	int configureStreams(Camera *camera,
 			     std::map<Stream *, StreamConfiguration> &config) override;
 
+	std::map<Stream *, BufferPool *>
+	allocateBuffers(Camera *camera,
+			std::map<Stream *, StreamConfiguration> &config) override;
+	int freeBuffers(Camera *camera) override;
+
 	int start(const Camera *camera) override;
 	void stop(const Camera *camera) override;
 
+	int queueRequest(const Camera *camera, Request *request) override;
+
 	bool match(DeviceEnumerator *enumerator);
 
 private:
@@ -85,6 +92,18 @@ int PipelineHandlerUVC::configureStreams(Camera *camera,
 	return 0;
 }
 
+std::map<Stream *, BufferPool *>
+PipelineHandlerUVC::allocateBuffers(Camera *camera,
+				    std::map<Stream *, StreamConfiguration> &config)
+{
+	return std::map<Stream *, BufferPool *> {};
+}
+
+int PipelineHandlerUVC::freeBuffers(Camera *camera)
+{
+	return 0;
+}
+
 int PipelineHandlerUVC::start(const Camera *camera)
 {
 	LOG(UVC, Error) << "TODO: start camera";
@@ -96,6 +115,11 @@ void PipelineHandlerUVC::stop(const Camera *camera)
 	LOG(UVC, Error) << "TODO: stop camera";
 }
 
+int PipelineHandlerUVC::queueRequest(const Camera *camera, Request *request)
+{
+	return 0;
+}
+
 bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator)
 {
 	DeviceMatch dm("uvcvideo");
diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp
index 11eca0cd4d9a6e0c..23a8250ec8b691b5 100644
--- a/src/libcamera/pipeline/vimc.cpp
+++ b/src/libcamera/pipeline/vimc.cpp
@@ -30,9 +30,16 @@ public:
 	int configureStreams(Camera *camera,
 			     std::map<Stream *, StreamConfiguration> &config) override;
 
+	std::map<Stream *, BufferPool *>
+	allocateBuffers(Camera *camera,
+			std::map<Stream *, StreamConfiguration> &config) override;
+	int freeBuffers(Camera *camera) override;
+
 	int start(const Camera *camera) override;
 	void stop(const Camera *camera) override;
 
+	int queueRequest(const Camera *camera, Request *request) override;
+
 	bool match(DeviceEnumerator *enumerator);
 
 private:
@@ -80,6 +87,18 @@ int PipeHandlerVimc::configureStreams(Camera *camera,
 	return 0;
 }
 
+std::map<Stream *, BufferPool *>
+PipeHandlerVimc::allocateBuffers(Camera *camera,
+				 std::map<Stream *, StreamConfiguration> &config)
+{
+	return std::map<Stream *, BufferPool *> {};
+}
+
+int PipeHandlerVimc::freeBuffers(Camera *camera)
+{
+	return 0;
+}
+
 int PipeHandlerVimc::start(const Camera *camera)
 {
 	LOG(VIMC, Error) << "TODO: start camera";
@@ -91,6 +110,11 @@ void PipeHandlerVimc::stop(const Camera *camera)
 	LOG(VIMC, Error) << "TODO: stop camera";
 }
 
+int PipeHandlerVimc::queueRequest(const Camera *camera, Request *request)
+{
+	return 0;
+}
+
 bool PipeHandlerVimc::match(DeviceEnumerator *enumerator)
 {
 	DeviceMatch dm("vimc");
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index fa5f780cea34fc8f..7df115cfcb90c83a 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -109,6 +109,39 @@ PipelineHandler::~PipelineHandler()
  * \return 0 on success or a negative error code on error.
  */
 
+/**
+ * \fn PipelineHandler::allocateBuffers()
+ * \brief Allocate buffers for a group of streams
+ * \param[in] camera The camera to allocate buffer for
+ * \param[in] config The stream setup and format describing the buffers
+ *
+ * After a camera's format have been configure and before a camera can be
+ * started buffers needs to be associated with it. Allocation new buffers from
+ * the streams involved in the captured is one option to associated buffers
+ * with a capture.
+ *
+ * The intended caller of this interface is the Camera class which is
+ * responsible for configure the streams and formats of a capture sessions
+ * as well as making sure there are buffers available to actually start the
+ * camera.
+ *
+ * \return 0 on success or a negative error code on error.
+ */
+
+/**
+ * \fn PipelineHandler::freeBuffers()
+ * \brief Free all buffers associated to a camera
+ * \param[in] camera The camera to free all buffers from
+ *
+ * After a capture session have been stopped all buffers associated with the
+ * camera needs to be freed to allow the memory to be reused in future capture
+ * sessions. The intended caller of this interface is the Camera object
+ * responsible for stopping the camera and once it's stopped freeing its
+ * resources.
+ *
+ * \return 0 on success or a negative error code on error.
+ */
+
 /**
  * \fn PipelineHandler::start()
  * \brief Start capturing from a group of streams
@@ -136,6 +169,20 @@ PipelineHandler::~PipelineHandler()
  * that the camera was stopped before they could be processed.
  */
 
+/**
+ * \fn PipelineHandler::queueRequest()
+ * \brief Queue a request to the camera
+ * \param[in] camera The camera to queue request on
+ * \param[in] request The request to queue
+ *
+ * Each request the camera should handle needs to be queued to the hardware
+ * thru the pipeline handler. The pipeline handler needs to examine the request,
+ * apply the requested controls with the V4L2 request and queue the buffers
+ * contained in the request to the correct video device.
+ *
+ * \return 0 on success or a negative error code on error.
+ */
+
 /**
  * \fn PipelineHandler::match(DeviceEnumerator *enumerator)
  * \brief Match media devices and create camera instances
-- 
2.20.1



More information about the libcamera-devel mailing list