[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