[PATCH v2 2/2] ipa: rkisp1: Have algos initialize FrameContext
Stefan Klug
stefan.klug at ideasonboard.com
Tue Nov 12 17:35:52 CET 2024
Hi Jacopo,
Thank you for the patch.
On Wed, Oct 30, 2024 at 05:48:52PM +0100, Jacopo Mondi wrote:
> The RkISP1 AGC algorithms assumes the metering mode to be
> "MeteringMatrix" and pre-fill an array of weights associated
> with it stored in meteringModes_[MeteringMatrix] when intializing
> the algorithm in parseMeteringModes().
>
> It laters fetches the weights when computing parameters using the
> FrameContext.agc.meteringMode as index of the meteringModes_ array.
>
> When a Request gets queued to the algorithm, the
> FrameContext.agc.meteringMode index is populated from the algorithm's
> active state, and optionally updated if the application has specified
> a different metering mode.
>
> In case of Request underrun however, a non-initialized FrameContext
> gets provided to the algorithm, causing an (unhandled) exception when
> accessing the meteringModes_ array.
>
> To handle the situation when a Request underrun occours and let
> algorithms initialize a FrameContext to safe defaults:
>
> - Add an 'underrun' flag to FrameContext
> - Add an 'initFrameContext()' function to RkISP1 algorithms
> - If a FrameContext is get() before being allocated, pass it through
> the algorithms' initFrameContext() to safely initialize it
>
> Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> ---
> src/ipa/libipa/fc_queue.cpp | 6 ++++++
> src/ipa/libipa/fc_queue.h | 5 +++++
> src/ipa/rkisp1/algorithms/agc.cpp | 8 ++++++++
> src/ipa/rkisp1/algorithms/agc.h | 4 ++++
> src/ipa/rkisp1/algorithms/algorithm.h | 5 +++++
> src/ipa/rkisp1/rkisp1.cpp | 9 +++++++++
> 6 files changed, 37 insertions(+)
>
> diff --git a/src/ipa/libipa/fc_queue.cpp b/src/ipa/libipa/fc_queue.cpp
> index 0365e9197748..44f9d866ad1b 100644
> --- a/src/ipa/libipa/fc_queue.cpp
> +++ b/src/ipa/libipa/fc_queue.cpp
> @@ -36,6 +36,12 @@ namespace ipa {
> *
> * \var FrameContext::frame
> * \brief The frame number
> + *
> + * \var FrameContext::underrun
> + * \brief Boolean flag that reports if the FrameContext has been accessed with
> + * a FCQeueu::get() call before being FCQueue::alloc()-ated. If the flag is set
> + * to True then the frame context needs to be initialized by algorithms to safe
> + * defaults as it won't be initialized with any non-user provided control.
> */
>
> /**
> diff --git a/src/ipa/libipa/fc_queue.h b/src/ipa/libipa/fc_queue.h
> index a1d136521107..d70ca9601bd7 100644
> --- a/src/ipa/libipa/fc_queue.h
> +++ b/src/ipa/libipa/fc_queue.h
> @@ -22,6 +22,9 @@ template<typename FrameContext>
> class FCQueue;
>
> struct FrameContext {
> +public:
> + bool underrun = false;
> +
> private:
> template<typename T> friend class FCQueue;
> uint32_t frame;
> @@ -97,6 +100,7 @@ public:
> * is called before alloc() by the IPA for frame#0.
> */
> init(frameContext, frame);
> + frameContext.underrun = true;
I can't find the place where the flag is reset to false (In case there
are temporary underruns).
>
> return frameContext;
> }
> @@ -117,6 +121,7 @@ public:
> << "Obtained an uninitialised FrameContext for " << frame;
>
> init(frameContext, frame);
> + frameContext.underrun = true;
>
> return frameContext;
> }
> diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp
> index 301b7ec26508..4122f665b3ee 100644
> --- a/src/ipa/rkisp1/algorithms/agc.cpp
> +++ b/src/ipa/rkisp1/algorithms/agc.cpp
> @@ -204,6 +204,14 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)
> return 0;
> }
>
> +void Agc::initFrameContext(IPAContext &context,
> + IPAFrameContext &frameContext)
> +{
> + auto &agc = context.activeState.agc;
> +
> + frameContext.agc.meteringMode = agc.meteringMode;
> +}
> +
I'm unsure if we really need the separate function.
>From an algorithm point of view, I can't see the difference between
calling
initFrameContext(ipaContext, frameContext)
and
queueRequest(ipaContext, frameContext.frame, frameContext, {})
Couldn't we just rename queueRequest to initFrameContext, so that we
don't have to implement two separate functions?
> /**
> * \copydoc libcamera::ipa::Algorithm::queueRequest
> */
> diff --git a/src/ipa/rkisp1/algorithms/agc.h b/src/ipa/rkisp1/algorithms/agc.h
> index aa86f2c5bc21..c1adf91bbc4e 100644
> --- a/src/ipa/rkisp1/algorithms/agc.h
> +++ b/src/ipa/rkisp1/algorithms/agc.h
> @@ -30,6 +30,10 @@ public:
>
> int init(IPAContext &context, const YamlObject &tuningData) override;
> int configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override;
> +
> + void initFrameContext(IPAContext &context,
> + IPAFrameContext &frameContext) override;
> +
> void queueRequest(IPAContext &context,
> const uint32_t frame,
> IPAFrameContext &frameContext,
> diff --git a/src/ipa/rkisp1/algorithms/algorithm.h b/src/ipa/rkisp1/algorithms/algorithm.h
> index 715cfcd8298b..82603b7b372d 100644
> --- a/src/ipa/rkisp1/algorithms/algorithm.h
> +++ b/src/ipa/rkisp1/algorithms/algorithm.h
> @@ -23,6 +23,11 @@ public:
> {
> }
>
> + virtual void initFrameContext([[maybe_unused]] IPAContext &context,
> + [[maybe_unused]] IPAFrameContext &frameContext)
> + {
> + }
> +
> bool disabled_;
> bool supportsRaw_;
> };
> diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
> index 9e161cabdea4..b743de9ff6af 100644
> --- a/src/ipa/rkisp1/rkisp1.cpp
> +++ b/src/ipa/rkisp1/rkisp1.cpp
> @@ -353,6 +353,15 @@ void IPARkISP1::processStatsBuffer(const uint32_t frame, const uint32_t bufferId
> {
> IPAFrameContext &frameContext = context_.frameContexts.get(frame);
>
> + if (frameContext.underrun) {
> + for (auto const &a : algorithms()) {
> + Algorithm *algo = static_cast<Algorithm *>(a.get());
> + if (algo->disabled_)
> + continue;
> + algo->initFrameContext(context_, frameContext);
> + }
Maybe that would be the place for frameContext.underrun = false?
Best regards,
Stefan
> + }
> +
> /*
> * In raw capture mode, the ISP is bypassed and no statistics buffer is
> * provided.
> --
> 2.47.0
>
More information about the libcamera-devel
mailing list