[libcamera-devel] [PATCH v3 4/8] libcamera: ipu3: Add multiple stream memory management

Jacopo Mondi jacopo at jmondi.org
Wed Apr 3 17:07:31 CEST 2019


Perform allocation and setup of memory sharing betweent the CIO2 output
and the ImgU input and allocate memory for each active stream.
---
 src/libcamera/pipeline/ipu3/ipu3.cpp | 78 ++++++++++++++++++++++------
 1 file changed, 62 insertions(+), 16 deletions(-)

diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index a12e3f9a496d..f7e75fac1dfe 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -91,6 +91,7 @@ public:
 
 	BufferPool vfPool_;
 	BufferPool statPool_;
+	BufferPool outPool_;
 };
 
 class CIO2Device
@@ -428,13 +429,21 @@ int PipelineHandlerIPU3::configureStreams(Camera *camera,
 	return 0;
 }
 
+/**
+ * \todo Clarify if 'viewfinder' and 'stat' nodes have to be set up and
+ * started even if not in use. As of now, if not properly configured and
+ * enabled, the ImgU processing pipeline stalls.
+ *
+ * In order to be able to start the 'viewfinder' and 'stat' nodes, we need
+ * memory to be reserved.
+ */
 int PipelineHandlerIPU3::allocateBuffers(Camera *camera,
 					 const std::set<Stream *> &streams)
 {
 	IPU3CameraData *data = cameraData(camera);
-	Stream *stream = *streams.begin();
 	CIO2Device *cio2 = &data->cio2_;
 	ImgUDevice *imgu = data->imgu_;
+	unsigned int bufferCount;
 	int ret;
 
 	/* Share buffers between CIO2 output and ImgU input. */
@@ -446,28 +455,64 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera,
 	if (ret)
 		return ret;
 
-	/* Export ImgU output buffers to the stream's pool. */
-	ret = imgu->exportBuffers(&imgu->output_, &stream->bufferPool());
-	if (ret)
-		return ret;
-
 	/*
-	 * Reserve memory in viewfinder and stat output devices. Use the
-	 * same number of buffers as the ones requested for the output
-	 * stream.
+	 * Use for internal pools the same buffer number as the input
+	 * one: it should match the pipeline lenght.
 	 */
-	unsigned int bufferCount = stream->bufferPool().count();
-
-	imgu->viewfinder_.pool->createBuffers(bufferCount);
-	ret = imgu->exportBuffers(&imgu->viewfinder_, imgu->viewfinder_.pool);
-	if (ret)
-		return ret;
-
+	bufferCount = pool->count();
 	imgu->stat_.pool->createBuffers(bufferCount);
 	ret = imgu->exportBuffers(&imgu->stat_, imgu->stat_.pool);
 	if (ret)
 		return ret;
 
+	for (Stream *stream : streams) {
+		if (isOutput(data, stream)) {
+			/* Export output buffers to the stream's pool. */
+			ret = imgu->exportBuffers(&imgu->output_,
+						  &stream->bufferPool());
+			if (ret)
+				return ret;
+
+			if (isViewfinderActive(data))
+				continue;
+
+			/*
+			 * Reserve memory in viewfinder device if it is not
+			 * part of the active streams list. Use the same
+			 * number of buffers as the ones requested for the
+			 * output stream.
+			 */
+			bufferCount = stream->bufferPool().count();
+			imgu->viewfinder_.pool->createBuffers(bufferCount);
+			ret = imgu->exportBuffers(&imgu->viewfinder_,
+						  imgu->viewfinder_.pool);
+			if (ret)
+				return ret;
+		} else if (isViewfinder(data, stream)) {
+			/* Export viewfinder buffers to the stream's pool. */
+			ret = imgu->exportBuffers(&imgu->viewfinder_,
+						  &stream->bufferPool());
+			if (ret)
+				return ret;
+
+			if (isOutputActive(data))
+				continue;
+
+			/*
+			 * Reserve memory in output device if it is not part
+			 * of the active streams list. Use the same number
+			 * of buffers as the ones requested for the viewfinder
+			 * stream.
+			 */
+			bufferCount = stream->bufferPool().count();
+			imgu->output_.pool->createBuffers(bufferCount);
+			ret = imgu->exportBuffers(&imgu->output_,
+						  imgu->output_.pool);
+			if (ret)
+				return ret;
+		}
+	}
+
 	return 0;
 }
 
@@ -819,6 +864,7 @@ int ImgUDevice::init(MediaDevice *media, unsigned int index)
 
 	output_.pad = PAD_OUTPUT;
 	output_.name = "output";
+	output_.pool = &outPool_;
 
 	viewfinder_.dev = V4L2Device::fromEntityName(media,
 						     name_ + " viewfinder");
-- 
2.21.0



More information about the libcamera-devel mailing list