[libcamera-devel] [PATCH v4 06/12] libcamera: ipu3: Queue requests for multiple streams

Jacopo Mondi jacopo at jmondi.org
Tue Apr 9 21:25:42 CEST 2019


Add support for queueing requests for multiple streams in the IPU3
pipeline handler class. The output video node should be queued with
buffers even if not part of the requested streams.

Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
---
 src/libcamera/pipeline/ipu3/ipu3.cpp | 46 +++++++++++++++++++++-------
 1 file changed, 35 insertions(+), 11 deletions(-)

diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index f5d768f9f87f..bb8d4ce644ca 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -146,6 +146,7 @@ public:
 	std::string name_;
 	ImgUDevice::ImgUOutput *device_;
 	const StreamConfiguration *cfg_;
+	unsigned int bufferCount;
 };
 
 class PipelineHandlerIPU3 : public PipelineHandler
@@ -473,6 +474,9 @@ int PipelineHandlerIPU3::start(Camera *camera)
 	ImgUDevice *imgu = data->imgu_;
 	int ret;
 
+	if (!data->outStream_.active_)
+		data->outStream_.bufferCount = 0;
+
 	/*
 	 * Start the ImgU video devices, buffers will be queued to the
 	 * ImgU output and viewfinder when requests will be queued.
@@ -513,20 +517,40 @@ void PipelineHandlerIPU3::stop(Camera *camera)
 int PipelineHandlerIPU3::queueRequest(Camera *camera, Request *request)
 {
 	IPU3CameraData *data = cameraData(camera);
-	V4L2Device *output = data->imgu_->output_.dev;
-	IPU3Stream *stream = &data->outStream_;
+	IPU3Stream *output = &data->outStream_;
+	bool outputRequested = false;
 
-	/* Queue a buffer to the ImgU output for capture. */
-	Buffer *buffer = request->findBuffer(stream);
-	if (!buffer) {
-		LOG(IPU3, Error)
-			<< "Attempt to queue request with invalid stream";
-		return -ENOENT;
+	for (auto const &bufferMap : request->bufferMap()) {
+		IPU3Stream *stream = static_cast<IPU3Stream *>(bufferMap.first);
+		Buffer *buffer = bufferMap.second;
+
+		int ret = stream->device_->dev->queueBuffer(buffer);
+		if (ret)
+			continue;
+
+		if (stream == output)
+			outputRequested = true;
 	}
 
-	int ret = output->queueBuffer(buffer);
-	if (ret < 0)
-		return ret;
+	/*
+	 * The output node should be queued with buffers even if not part
+	 * of the request, otherwise the ImgU stalls.
+	 *
+	 * Use buffers from the stream's pool or the internal pool depending
+	 * if the output stream has been configured or not.
+	 */
+	if (!outputRequested) {
+		BufferPool *pool = output->active_ ? &output->bufferPool()
+						   : output->device_->pool;
+		Buffer *buffer = &pool->buffers()[output->bufferCount];
+		unsigned int numBuffers = pool->count();
+
+		int ret = output->device_->dev->queueBuffer(buffer);
+		if (ret)
+			return ret;
+
+		output->bufferCount = (output->bufferCount + 1) % numBuffers;
+	}
 
 	PipelineHandler::queueRequest(camera, request);
 
-- 
2.21.0



More information about the libcamera-devel mailing list