@@ -156,6 +156,15 @@ int Agc::init(IPAContext &context, const YamlObject &tuningData)
ControlValue(controls::AnalogueGainModeManual) } },
ControlValue(controls::AnalogueGainModeAuto));
context.ctrlMap[&controls::ExposureValue] = ControlInfo(-8.0f, 8.0f, 0.0f);
+ /*
+ * Insert the controlInfo for sync. Since FrameDurationLimits is only
+ * set *after* the algorithms are initialized, we have no information
+ * on it here. Use a sensible default here and update it later in
+ * configure().
+ * \todo Move FrameDurationLimits from the base IPA to AGC
+ */
+ context.ctrlMap[&controls::SyncAdjustment] = controlInfo(120000);
+ /* Insert the controls for agc */
context.ctrlMap.merge(controls());
return 0;
@@ -202,7 +211,11 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)
context.configuration.sensor.minAnalogueGain,
context.configuration.sensor.maxAnalogueGain);
+ context.ctrlMap[&controls::SyncAdjustment] =
+ controlInfo(frameDurationLimits.max().get<int64_t>());
+
resetFrameCount();
+ resetSync();
return 0;
}
@@ -324,6 +337,10 @@ void Agc::queueRequest(IPAContext &context,
}
frameContext.agc.minFrameDuration = agc.minFrameDuration;
frameContext.agc.maxFrameDuration = agc.maxFrameDuration;
+
+ const auto &sync = controls.get(controls::SyncAdjustment);
+ if (sync)
+ setSync(*sync, frameContext.agc.minFrameDuration);
}
/**
@@ -413,6 +430,7 @@ void Agc::fillMetadata(IPAContext &context, IPAFrameContext &frameContext,
metadata.set(controls::AeExposureMode, frameContext.agc.exposureMode);
metadata.set(controls::AeConstraintMode, frameContext.agc.constraintMode);
metadata.set(controls::ExposureValue, frameContext.agc.exposureValue);
+ metadata.set(controls::SyncAdjustment, frameContext.agc.syncAdjustment.count());
}
/**
@@ -471,7 +489,9 @@ void Agc::processFrameDuration(IPAContext &context,
IPACameraSensorInfo &sensorInfo = context.sensorInfo;
utils::Duration lineDuration = context.configuration.sensor.lineDuration;
- frameContext.agc.vblank = (frameDuration / lineDuration) - sensorInfo.outputSize.height;
+ utils::Duration sync = getSync();
+ frameContext.agc.vblank = ((frameDuration + sync) / lineDuration) - sensorInfo.outputSize.height;
+ frameContext.agc.syncAdjustment = sync;
/* Update frame duration accounting for line length quantization. */
frameContext.agc.frameDuration = (sensorInfo.outputSize.height + frameContext.agc.vblank) * lineDuration;
@@ -15,6 +15,7 @@
#include <libcamera/geometry.h>
#include "libipa/agc_mean_luminance.h"
+#include "libipa/sync_helper.h"
#include "algorithm.h"
@@ -22,7 +23,7 @@ namespace libcamera {
namespace ipa::rkisp1::algorithms {
-class Agc : public Algorithm, public AgcMeanLuminance
+class Agc : public Algorithm, public AgcMeanLuminance, public SyncHelper
{
public:
Agc();
@@ -143,6 +143,7 @@ struct IPAFrameContext : public FrameContext {
bool updateMetering;
bool autoExposureModeChange;
bool autoGainModeChange;
+ utils::Duration syncAdjustment;
} agc;
struct {
Add sync support to the RkISP1 IPA using the SyncHelper from libipa. The syncAdjustment is saved in the frameContext (as opposed to getting it from the SyncHelper) to avoid potential races and ensure that the same value that was set into vblank will be returned in metadata. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> --- src/ipa/rkisp1/algorithms/agc.cpp | 22 +++++++++++++++++++++- src/ipa/rkisp1/algorithms/agc.h | 3 ++- src/ipa/rkisp1/ipa_context.h | 1 + 3 files changed, 24 insertions(+), 2 deletions(-)