summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacopo Mondi <jacopo.mondi@ideasonboard.com>2024-10-30 17:30:43 +0100
committerJacopo Mondi <jacopo.mondi@ideasonboard.com>2024-10-30 17:37:56 +0100
commit442842b4b4d88bc44e653bda5b8546dda5c2cb7a (patch)
treee38a561ec712cca6acc8e38d9df1cd04c42b4e67
parentc31050d2a77a7960282bce6b3f6efff06a718d1c (diff)
ipa: rkisp1: Have algos initialize FrameContextpfc/rkisp1-free-run-v2
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@ideasonboard.com>
-rw-r--r--src/ipa/libipa/fc_queue.cpp6
-rw-r--r--src/ipa/libipa/fc_queue.h5
-rw-r--r--src/ipa/rkisp1/algorithms/agc.cpp8
-rw-r--r--src/ipa/rkisp1/algorithms/agc.h4
-rw-r--r--src/ipa/rkisp1/algorithms/algorithm.h5
-rw-r--r--src/ipa/rkisp1/rkisp1.cpp9
6 files changed, 37 insertions, 0 deletions
diff --git a/src/ipa/libipa/fc_queue.cpp b/src/ipa/libipa/fc_queue.cpp
index 0365e919..44f9d866 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 a1d13652..d70ca960 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;
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 17d074d9..1e41df5b 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;
+}
+
/**
* \copydoc libcamera::ipa::Algorithm::queueRequest
*/
diff --git a/src/ipa/rkisp1/algorithms/agc.h b/src/ipa/rkisp1/algorithms/agc.h
index aa86f2c5..c1adf91b 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 715cfcd8..82603b7b 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 005c17ca..78459c80 100644
--- a/src/ipa/rkisp1/rkisp1.cpp
+++ b/src/ipa/rkisp1/rkisp1.cpp
@@ -353,6 +353,15 @@ void IPARkISP1::processStats(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);
+ }
+ }
+
/*
* In raw capture mode, the ISP is bypassed and no statistics buffer is
* provided.