[libcamera-devel] [PATCH v3 4/8] libcamera: ipu3: Add multiple stream memory management
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Fri Apr 5 17:45:01 CEST 2019
Hi Jacopo,
Thank you for the patch.
On Wed, Apr 03, 2019 at 05:07:31PM +0200, Jacopo Mondi wrote:
> Perform allocation and setup of memory sharing betweent the CIO2 output
s/betweent/between/
> 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
s/buffer number/number of buffers/
s/as the input one/as for the input pool/
> + * one: it should match the pipeline lenght.
s/lenght/length/
And what do you mean by pipeline length here ?
> */
> - 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();
I think you can keep the variable declaration here, there's no need to
move it to the beginning of the function.
> 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;
> + }
> + }
As for the previous patch, I think you should allocate memory for the
streams present in the set in a loop without caring about the stream
type, and then for the other devices outside of the loop. It should also
ease error handling, which is missing here.
> +
> 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");
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list