[libcamera-devel] [PATCH] pipeline: ipu3: Store requests in the case a buffer shortage
Hirokazu Honda
hiroh at chromium.org
Wed Mar 31 10:51:48 CEST 2021
I should still work for this patch series.
The missing part is to trigger queuePendingRequests() appropriately
when buffers are available.
I couldn't find a good way as availableBuffers notification functions
are separated and trying queuePendingRequests() is not likely
successful and thus inefficient.
I would like to ask anyone for a good idea for this.
Thanks in advance,
-Hiro
On Wed, Mar 31, 2021 at 5:45 PM Hirokazu Honda <hiroh at chromium.org> wrote:
>
> PipelineHandlerIPU3 returns -ENOBUFS and -ENOMEM on queueing a
> request when there are not sufficient buffers for the request.
> Since the request will be successful if it is queued later when
> enough buffers are available. The requests failed due to a buffer
> shortage should be stored and retried later in the FIFO order.
> This introduces the queue in PipelineHandlerIPU3 to do that.
>
> Signed-off-by: Hirokazu Honda <hiroh at chromium.org>
> ---
> src/libcamera/pipeline/ipu3/ipu3.cpp | 62 ++++++++++++++++++----------
> 1 file changed, 41 insertions(+), 21 deletions(-)
>
> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
> index 519cad4f..71dd311f 100644
> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> @@ -153,12 +153,16 @@ private:
> int allocateBuffers(Camera *camera);
> int freeBuffers(Camera *camera);
>
> + int queuePendingRequests();
> +
> ImgUDevice imgu0_;
> ImgUDevice imgu1_;
> MediaDevice *cio2MediaDev_;
> MediaDevice *imguMediaDev_;
>
> std::vector<IPABuffer> ipaBuffers_;
> +
> + std::queue<std::pair<IPU3CameraData *, Request *>> pendingRequests_;
> };
>
> IPU3CameraConfiguration::IPU3CameraConfiguration(IPU3CameraData *data)
> @@ -764,6 +768,8 @@ void PipelineHandlerIPU3::stop(Camera *camera)
> IPU3CameraData *data = cameraData(camera);
> int ret = 0;
>
> + pendingRequests_ = {};
> +
> data->ipa_->stop();
>
> ret |= data->imgu_->stop();
> @@ -774,36 +780,50 @@ void PipelineHandlerIPU3::stop(Camera *camera)
> freeBuffers(camera);
> }
>
> -int PipelineHandlerIPU3::queueRequestDevice(Camera *camera, Request *request)
> +int PipelineHandlerIPU3::queuePendingRequests()
> {
> - IPU3CameraData *data = cameraData(camera);
> + while (!pendingRequests_.empty()) {
> + IPU3CameraData *data = pendingRequests_.front().first;
> + Request *request = pendingRequests_.front().second;
>
> - IPU3Frames::Info *info = data->frameInfos_.create(request);
> - if (!info)
> - return -ENOBUFS;
> + IPU3Frames::Info *info = data->frameInfos_.create(request);
> + if (!info)
> + break;
>
> - /*
> - * Queue a buffer on the CIO2, using the raw stream buffer provided in
> - * the request, if any, or a CIO2 internal buffer otherwise.
> - */
> - FrameBuffer *reqRawBuffer = request->findBuffer(&data->rawStream_);
> - FrameBuffer *rawBuffer = data->cio2_.queueBuffer(request, reqRawBuffer);
> - if (!rawBuffer) {
> - data->frameInfos_.remove(info);
> - return -ENOMEM;
> - }
> + /*
> + * Queue a buffer on the CIO2, using the raw stream buffer
> + * provided in the request, if any, or a CIO2 internal buffer
> + * otherwise.
> + */
> + FrameBuffer *reqRawBuffer = request->findBuffer(&data->rawStream_);
> + FrameBuffer *rawBuffer = data->cio2_.queueBuffer(request, reqRawBuffer);
> + if (!rawBuffer) {
> + data->frameInfos_.remove(info);
> + break;
> + }
>
> - info->rawBuffer = rawBuffer;
> + info->rawBuffer = rawBuffer;
>
> - ipa::ipu3::IPU3Event ev;
> - ev.op = ipa::ipu3::EventProcessControls;
> - ev.frame = info->id;
> - ev.controls = request->controls();
> - data->ipa_->processEvent(ev);
> + ipa::ipu3::IPU3Event ev;
> + ev.op = ipa::ipu3::EventProcessControls;
> + ev.frame = info->id;
> + ev.controls = request->controls();
> + data->ipa_->processEvent(ev);
> +
> + pendingRequests_.pop();
> + }
>
> return 0;
> }
>
> +int PipelineHandlerIPU3::queueRequestDevice(Camera *camera, Request *request)
> +{
> + IPU3CameraData *data = cameraData(camera);
> +
> + pendingRequests_.emplace(data, request);
> + return queuePendingRequests();
> +}
> +
> bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator)
> {
> int ret;
> --
> 2.31.0.291.g576ba9dcdaf-goog
>
More information about the libcamera-devel
mailing list