[libcamera-devel] [PATCH v4 06/12] libcamera: ipu3: Queue requests for multiple streams
Niklas Söderlund
niklas.soderlund at ragnatech.se
Sun Apr 14 22:05:16 CEST 2019
Hi Jacopo,
Thanks for your work.
On 2019-04-09 21:25:42 +0200, Jacopo Mondi wrote:
> 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;
I do not understand the full usage of bufferCount, I think see bellow.
> };
>
> 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;
This looks worthy of a comment to me, I can't really tell what's going
on. You cyclically pick buffers from the pool's buffers. I'm the first
one to admit I'm no expert in the Buffer part of libcamera so I have to
ask, is there any grantee the buffer picked is free? I'm thinking about
under-run situations. Maybe it's just my inexperience that is showing
and this is correct.
> + }
>
> PipelineHandler::queueRequest(camera, request);
>
> --
> 2.21.0
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel at lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel
--
Regards,
Niklas Söderlund
More information about the libcamera-devel
mailing list