@@ -27,6 +27,8 @@ interface IPARkISP1Interface {
map<uint32, libcamera.IPAStream> streamConfig)
=> (int32 ret, libcamera.ControlInfoMap ipaControls);
+ updateControlsLimits(uint32 frame) => (int32 ret, libcamera.ControlInfoMap ipaControls);
+
mapBuffers(array<libcamera.IPABuffer> buffers);
unmapBuffers(array<uint32> ids);
@@ -585,6 +585,8 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
* frameContext.agc.exposure;
maxExposureTime = minExposureTime;
}
+ frameContext.agc.minExposureTime = minExposureTime;
+ frameContext.agc.maxExposureTime = maxExposureTime;
if (frameContext.agc.autoGainEnabled) {
minAnalogueGain = context.configuration.sensor.minAnalogueGain;
@@ -606,6 +608,7 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
* applied to the sensor when the statistics were collected.
*/
utils::Duration exposureTime = lineDuration * frameContext.sensor.exposure;
+ frameContext.agc.exposureTime = exposureTime;
double analogueGain = frameContext.sensor.gain;
utils::Duration effectiveExposureValue = exposureTime * analogueGain;
@@ -143,6 +143,9 @@ struct IPAActiveState {
struct IPAFrameContext : public FrameContext {
struct {
+ utils::Duration minExposureTime;
+ utils::Duration maxExposureTime;
+ utils::Duration exposureTime;
uint32_t exposure;
double gain;
double exposureValue;
@@ -62,6 +62,8 @@ public:
int configure(const IPAConfigInfo &ipaConfig,
const std::map<uint32_t, IPAStream> &streamConfig,
ControlInfoMap *ipaControls) override;
+ int updateControlsLimits(const uint32_t frame,
+ ControlInfoMap *ipaControls) override;
void mapBuffers(const std::vector<IPABuffer> &buffers) override;
void unmapBuffers(const std::vector<unsigned int> &ids) override;
@@ -294,6 +296,30 @@ int IPARkISP1::configure(const IPAConfigInfo &ipaConfig,
return 0;
}
+int IPARkISP1::updateControlsLimits(const uint32_t frame, ControlInfoMap *ipaControls)
+{
+ IPAFrameContext &frameContext = context_.frameContexts.get(frame);
+
+ /*
+ * Update the exposure time and frame duration limits with the
+ * settings computed by the AGC for the frame at hand.
+ */
+ assert(ipaControls->find(&controls::ExposureTime) != ipaControls->end());
+ assert(ipaControls->find(&controls::FrameDurationLimits) != ipaControls->end());
+
+ ControlValue eMin(static_cast<int32_t>(frameContext.agc.minExposureTime.get<std::micro>()));
+ ControlValue eMax(static_cast<int32_t>(frameContext.agc.maxExposureTime.get<std::micro>()));
+ ControlValue eDef(static_cast<int32_t>(frameContext.agc.exposureTime.get<std::micro>()));
+ ipaControls->at(controls::ExposureTime.id()) = ControlInfo(eMin, eMax, eDef);
+
+ ControlValue fMin(static_cast<int32_t>(frameContext.agc.minFrameDuration.get<std::micro>()));
+ ControlValue fMax(static_cast<int32_t>(frameContext.agc.maxFrameDuration.get<std::micro>()));
+ ControlValue fDef(static_cast<int32_t>(frameContext.agc.frameDuration.get<std::micro>()));
+ ipaControls->at(controls::FrameDurationLimits.id()) = ControlInfo(fMin, fMax, fDef);
+
+ return 0;
+}
+
void IPARkISP1::mapBuffers(const std::vector<IPABuffer> &buffers)
{
for (const IPABuffer &buffer : buffers) {
@@ -1494,6 +1494,9 @@ void PipelineHandlerRkISP1::tryCompleteRequest(RkISP1FrameInfo *info)
if (!isRaw_ && !info->paramDequeued)
return;
+ /* Update controls before completing the request */
+ data->ipa_->updateControlsLimits(info->frame, &data->controlInfo_);
+
data->frameInfo_.destroy(info->frame);
completeRequest(request);
The limits (min and max values) for the Camera controls are registered at Camera configuration time and never updated. Some controls, like FrameDurationLimits have a direct impact on the limits of other controls, such as the ExposureTime and as they can be configured by the application, this has to be taken into account. Currently, when a user changes the frame duration, the limits for both the ExposureTime and FrameDurationControls are not updated. The timing at which the controls limits should be updated is also critical: the new control values take effect once the Request they belong to is completed. To support this operation model introduce a new IPA function 'updateControlsLimits()' which the pipeline handler calls before completing a Request. Store the exposure time limits in the FrameContext (frame duration limits were already there) and update the Camera::controls() control info map with the limits as computed for the Request that has just completed. Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> --- include/libcamera/ipa/rkisp1.mojom | 2 ++ src/ipa/rkisp1/algorithms/agc.cpp | 3 +++ src/ipa/rkisp1/ipa_context.h | 3 +++ src/ipa/rkisp1/rkisp1.cpp | 26 ++++++++++++++++++++++++++ src/libcamera/pipeline/rkisp1/rkisp1.cpp | 3 +++ 5 files changed, 37 insertions(+)