[libcamera-devel] [PATCH v1 3/4] ipa: ipu3: Prevent over queuing of requests
Jacopo Mondi
jacopo at jmondi.org
Fri Jun 10 09:49:05 CEST 2022
Hi Umang,
On Fri, Jun 03, 2022 at 03:22:58PM +0200, Umang Jain via libcamera-devel wrote:
> The IPAIPU3 processes each IPAFrameContext present in the FCQueue
> ring buffer. If the application queues the requests at a pace where
> IPAFrameContext(s) can get potentially over-written without getting
> processed by the IPA, it would lead to un-desirable effects.
>
> Hence, inspect the FCQueue if it is full and reject any further
> queuing of requests. This requires changes to the IPAIPU3 mojom
> interface. The IPAIPU3::queueRequest() cannot be [async] anymore
> since we need to return a success/failure value.
>
> The rejection by the IPA doesn't mean it cannot be queued
> later. The request is still preserved in
> IPU3CameraData::pendingRequests_. It shall be queued sequentially
> on subsequent calls to IPU3CameraData::queuePendingRequests().
>
> Signed-off-by: Umang Jain <umang.jain at ideasonboard.com>
> ---
> I am not super-happy with changing the interface and dropping [async]
> but this is what I've for now. Would appreciate any other ideas...
I feel like this change handles the issue at the very bottom of the
call stack, once a request has been queued from the ph to the IPA.
I wonder if we shouldn't try to tackle the problem from the top
instead, which means at the time a request is queued to the camera by
the application.
The lenght of the FCQueue represents the maximum number of requests
in-flight at a time, iow the number of requests queued to the camera
and not yet completed.
Would it make sense to make this a global camera property and have the
base pipeline handler class defer queueing requests when too many are
in-flight ?
Thanks
j
> ---
> include/libcamera/ipa/ipu3.mojom | 2 +-
> src/ipa/ipu3/ipu3.cpp | 11 +++++++++--
> src/libcamera/pipeline/ipu3/ipu3.cpp | 10 +++++++++-
> 3 files changed, 19 insertions(+), 4 deletions(-)
>
> diff --git a/include/libcamera/ipa/ipu3.mojom b/include/libcamera/ipa/ipu3.mojom
> index d1b1c6b8..3faffd9c 100644
> --- a/include/libcamera/ipa/ipu3.mojom
> +++ b/include/libcamera/ipa/ipu3.mojom
> @@ -30,7 +30,7 @@ interface IPAIPU3Interface {
> mapBuffers(array<libcamera.IPABuffer> buffers);
> unmapBuffers(array<uint32> ids);
>
> - [async] queueRequest(uint32 frame, libcamera.ControlList controls);
> + queueRequest(uint32 frame, libcamera.ControlList controls) => (int32 ret);
> [async] fillParamsBuffer(uint32 frame, uint32 bufferId);
> [async] processStatsBuffer(uint32 frame, int64 frameTimestamp,
> uint32 bufferId, libcamera.ControlList sensorControls);
> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
> index 1d6ee515..63aa9b56 100644
> --- a/src/ipa/ipu3/ipu3.cpp
> +++ b/src/ipa/ipu3/ipu3.cpp
> @@ -145,7 +145,7 @@ public:
> void mapBuffers(const std::vector<IPABuffer> &buffers) override;
> void unmapBuffers(const std::vector<unsigned int> &ids) override;
>
> - void queueRequest(const uint32_t frame, const ControlList &controls) override;
> + int queueRequest(const uint32_t frame, const ControlList &controls) override;
> void fillParamsBuffer(const uint32_t frame, const uint32_t bufferId) override;
> void processStatsBuffer(const uint32_t frame, const int64_t frameTimestamp,
> const uint32_t bufferId,
> @@ -616,11 +616,18 @@ void IPAIPU3::processStatsBuffer(const uint32_t frame,
> *
> * Parse the request to handle any IPA-managed controls that were set from the
> * application such as manual sensor settings.
> + *
> + * \return 0 if successful, -EPERM otherwise.
> */
> -void IPAIPU3::queueRequest(const uint32_t frame, const ControlList &controls)
> +int IPAIPU3::queueRequest(const uint32_t frame, const ControlList &controls)
> {
> + if (context_.frameContexts.isFull())
> + return -EPERM;
> +
> /* \todo Start processing for 'frame' based on 'controls'. */
> *context_.frameContexts.get(frame) = { frame, controls };
> +
> + return 0;
> }
>
> /**
> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
> index fd989e61..d69e28d4 100644
> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> @@ -874,7 +874,15 @@ void IPU3CameraData::queuePendingRequests()
>
> info->rawBuffer = rawBuffer;
>
> - ipa_->queueRequest(info->id, request->controls());
> + /*
> + * Queueing request to the IPA can fail in cases like over-flowing
> + * its queue. Hence, keep the request preserved in pendingRequests_
> + * if a failure occurs.
> + */
> + if (ipa_->queueRequest(info->id, request->controls()) != 0) {
> + frameInfos_.remove(info);
> + break;
> + }
>
> pendingRequests_.pop();
> processingRequests_.push(request);
> --
> 2.31.1
>
More information about the libcamera-devel
mailing list