summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacopo Mondi <jacopo@jmondi.org>2019-03-19 12:00:10 +0100
committerJacopo Mondi <jacopo@jmondi.org>2019-04-19 16:00:03 +0200
commit57c84b4f3f691be97e319b7b9fa9076440b1a4f9 (patch)
tree80428ba68c957923669b4a28ecf4bd1d95ff7af8
parent2aa2bbaae9551687d52d3554012d3057cc22027a (diff)
libcamera: ipu3: Add multiple stream memory management
Perform allocation and setup of memory sharing between the CIO2 output and the ImgU input and allocate memory for each active stream. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
-rw-r--r--src/libcamera/pipeline/ipu3/ipu3.cpp64
1 files changed, 48 insertions, 16 deletions
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index d81af7a0..fad7f140 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -93,6 +93,7 @@ public:
BufferPool vfPool_;
BufferPool statPool_;
+ BufferPool outPool_;
};
class CIO2Device
@@ -440,11 +441,20 @@ 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();
+ IPU3Stream *outStream = &data->outStream_;
+ IPU3Stream *vfStream = &data->vfStream_;
CIO2Device *cio2 = &data->cio2_;
ImgUDevice *imgu = data->imgu_;
unsigned int bufferCount;
@@ -459,28 +469,49 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera,
if (ret)
goto error;
- /* Export ImgU output buffers to the stream's pool. */
- ret = imgu->exportBuffers(&imgu->output_, &stream->bufferPool());
- if (ret)
- goto error;
-
/*
- * Reserve memory in viewfinder and stat output devices. Use the
- * same number of buffers as the ones requested for the output
- * stream.
+ * Use for the stat's internal pool the same number of buffer as
+ * for the input pool.
+ * \todo To be revised when we'll actually use the stat node.
*/
- bufferCount = stream->bufferPool().count();
-
- imgu->viewfinder_.pool->createBuffers(bufferCount);
- ret = imgu->exportBuffers(&imgu->viewfinder_, imgu->viewfinder_.pool);
- if (ret)
- goto error;
-
+ bufferCount = pool->count();
imgu->stat_.pool->createBuffers(bufferCount);
ret = imgu->exportBuffers(&imgu->stat_, imgu->stat_.pool);
if (ret)
goto error;
+ /* Allocate buffers for each active stream. */
+ for (Stream *s : streams) {
+ IPU3Stream *stream = static_cast<IPU3Stream *>(s);
+ ImgUDevice::ImgUOutput *dev = stream->device_;
+
+ ret = imgu->exportBuffers(dev, &stream->bufferPool());
+ if (ret)
+ goto error;
+ }
+
+ /*
+ * Allocate buffers also on non-active outputs; use the same number
+ * of buffers as the active ones.
+ */
+ if (!outStream->active_) {
+ bufferCount = vfStream->bufferPool().count();
+ outStream->device_->pool->createBuffers(bufferCount);
+ ret = imgu->exportBuffers(outStream->device_,
+ outStream->device_->pool);
+ if (ret)
+ goto error;
+ }
+
+ if (!vfStream->active_) {
+ bufferCount = outStream->bufferPool().count();
+ vfStream->device_->pool->createBuffers(bufferCount);
+ ret = imgu->exportBuffers(vfStream->device_,
+ vfStream->device_->pool);
+ if (ret)
+ goto error;
+ }
+
return 0;
error:
@@ -845,6 +876,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");