[libcamera-devel] [PATCH v4 21/31] RFC: libcamera: pipeline_handlers: Add preAllocateBuffers

Jacopo Mondi jacopo at jmondi.org
Wed Mar 20 17:30:45 CET 2019


Add a preAllocateBuffers virtual method to the PipelineHandler base
class and call it before performing per-stream memory allocation.

Implement the method in the IPU3 pipeline handler to perform memory
allocation on the CIO2 unit and the ImgU input and stat video devices.

Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
---
 src/libcamera/camera.cpp                 | 10 ++++-
 src/libcamera/include/pipeline_handler.h |  5 +++
 src/libcamera/pipeline/ipu3/ipu3.cpp     | 54 ++++++++++++++----------
 src/libcamera/pipeline_handler.cpp       | 21 ++++++++-
 4 files changed, 66 insertions(+), 24 deletions(-)

diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index 8ee9cc086616..8020dff8f8ea 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -455,6 +455,8 @@ int Camera::configureStreams(std::map<Stream *, StreamConfiguration> &config)
  */
 int Camera::allocateBuffers()
 {
+	int ret;
+
 	if (disconnected_)
 		return -ENODEV;
 
@@ -467,8 +469,14 @@ int Camera::allocateBuffers()
 		return -EINVAL;
 	}
 
+	ret = pipe_->preAllocateBuffers(this, activeStreams_);
+	if (ret) {
+		LOG(Camera, Error) << "Buffers pre-allocation failed";
+		return ret;
+	}
+
 	for (Stream *stream : activeStreams_) {
-		int ret = pipe_->allocateBuffers(this, stream);
+		ret = pipe_->allocateBuffers(this, stream);
 		if (ret) {
 			LOG(Camera, Error) << "Failed to allocate buffers";
 			freeBuffers();
diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h
index acb376e07030..7ce5b67cc7fc 100644
--- a/src/libcamera/include/pipeline_handler.h
+++ b/src/libcamera/include/pipeline_handler.h
@@ -57,6 +57,11 @@ public:
 	virtual int configureStreams(Camera *camera,
 				     std::map<Stream *, StreamConfiguration> &config) = 0;
 
+	virtual int preAllocateBuffers(Camera *camera,
+				       const std::set<Stream *> &activeStreams)
+	{
+		return 0;
+	}
 	virtual int allocateBuffers(Camera *camera, Stream *stream) = 0;
 	virtual int freeBuffers(Camera *camera, Stream *stream) = 0;
 
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 0507fc380e68..5f323888d84f 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -105,6 +105,8 @@ public:
 	int configureStreams(Camera *camera,
 			     std::map<Stream *, StreamConfiguration> &config) override;
 
+	int preAllocateBuffers(Camera *camera,
+			       const std::set<Stream *> &activeStreams) override;
 	int allocateBuffers(Camera *camera, Stream *stream) override;
 	int freeBuffers(Camera *camera, Stream *stream) override;
 
@@ -451,40 +453,48 @@ int PipelineHandlerIPU3::configureStreams(Camera *camera,
 	return 0;
 }
 
-int PipelineHandlerIPU3::allocateBuffers(Camera *camera, Stream *stream)
+int PipelineHandlerIPU3::preAllocateBuffers(Camera *camera,
+					    const std::set<Stream *> &activeStreams)
 {
 	IPU3CameraData *data = cameraData(camera);
-	V4L2Device *viewfinder = data->imgu->viewfinder;
-	V4L2Device *output = data->imgu->output;
 	V4L2Device *input = data->imgu->input;
 	V4L2Device *cio2 = data->cio2.output;
 	V4L2Device *stat = data->imgu->stat;
 	ImgUDevice *imgu = data->imgu;
 	int ret;
 
-	if (data->cio2.pool.count() == 0) {
-		/* Share buffers between CIO2 output and ImgU input. */
-		data->cio2.pool.createBuffers(IPU3_CIO2_BUFFER_COUNT);
-		ret = cio2->exportBuffers(&data->cio2.pool);
-		if (ret) {
-			LOG(IPU3, Error) << "Failed to reserve CIO2 memory";
-			return ret;
-		}
+	/* Share buffers between CIO2 output and ImgU input. */
+	data->cio2.pool.createBuffers(IPU3_CIO2_BUFFER_COUNT);
+	ret = cio2->exportBuffers(&data->cio2.pool);
+	if (ret) {
+		LOG(IPU3, Error) << "Failed to reserve CIO2 memory";
+		return ret;
+	}
 
-		ret = input->importBuffers(&data->cio2.pool);
-		if (ret) {
-			LOG(IPU3, Error) << "Failed to import ImgU memory";
-			return ret;
-		}
+	ret = input->importBuffers(&data->cio2.pool);
+	if (ret) {
+		LOG(IPU3, Error) << "Failed to import ImgU memory";
+		return ret;
+	}
 
-		imgu->statPool.createBuffers(IPU3_IMGU_BUFFER_COUNT);
-		ret = stat->exportBuffers(&imgu->statPool);
-		if (ret) {
-			LOG(IPU3, Error) << "Failed to reserve ImgU stat memory";
-			return ret;
-		}
+	imgu->statPool.createBuffers(IPU3_IMGU_BUFFER_COUNT);
+	ret = stat->exportBuffers(&imgu->statPool);
+	if (ret) {
+		LOG(IPU3, Error) << "Failed to reserve ImgU stat memory";
+		return ret;
 	}
 
+	return 0;
+}
+
+int PipelineHandlerIPU3::allocateBuffers(Camera *camera, Stream *stream)
+{
+	IPU3CameraData *data = cameraData(camera);
+	V4L2Device *viewfinder = data->imgu->viewfinder;
+	V4L2Device *output = data->imgu->output;
+	ImgUDevice *imgu = data->imgu;
+	int ret;
+
 	if (isOutput(data, stream)) {
 		/* Export ImgU output buffers to the stream's pool. */
 		ret = output->exportBuffers(&stream->bufferPool());
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index 1a858f2638ce..1f556ed789b6 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -189,6 +189,24 @@ PipelineHandler::~PipelineHandler()
  * \return 0 on success or a negative error code otherwise
  */
 
+/**
+ * \fn PipelineHandler::preAllocateBuffers()
+ * \brief Perform operations to prepare for memory allocation. Optional for
+ * pipeline handlers to implement
+ * \param[in] camera The camera the streams belongs to
+ * \param[in] activeStreams The set of active streams
+ *
+ * If operations to prepare for the per-stream memory allocation are required,
+ * this virtual method provides an entry point for pipeline handlers to do so.
+ *
+ * This method is optional to implement for pipeline handlers, and its intended
+ * caller is the Camera class, which calls it once before performing per-stream
+ * memory allocation by calling the PipelineHandler::allocateBuffers() method
+ * once per each active stream.
+ *
+ * \return 0 on success or a negative error code otherwise
+ */
+
 /**
  * \fn PipelineHandler::allocateBuffers()
  * \brief Allocate buffers for a stream
@@ -198,7 +216,8 @@ PipelineHandler::~PipelineHandler()
  * This method allocates buffers internally in the pipeline handler and
  * associates them with the stream's buffer pool.
  *
- * The intended caller of this method is the Camera class.
+ * The intended caller of this method is the Camera class which calls it
+ * once per each active stream.
  *
  * \return 0 on success or a negative error code otherwise
  */
-- 
2.21.0



More information about the libcamera-devel mailing list