ipa: rpi: Defer initialising AF LensPosition ControlInfo and value

This fixes two small bugs:

We previously populated LensPosition's ControlInfo with hard-coded
values, ignoring the tuning file. Now we query the AfAlgorithm to
get limits (over all AF ranges) and default (for AfRangeNormal).

We previously sent a default position to the lens driver, even when
a user-specified starting position would follow. Defer doing this,
to reduce unnecessary lens movement at startup (for some drivers).

Bug: https://bugs.libcamera.org/show_bug.cgi?id=258
Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Nick Hollinghurst
2025-06-20 13:42:22 +01:00
committed by Kieran Bingham
parent 6b5cc1c92a
commit 30114cadd8
4 changed files with 57 additions and 24 deletions
+7 -1
View File
@@ -33,6 +33,10 @@ public:
*
* getMode() is provided mainly for validating controls.
* getLensPosition() is provided for populating DeviceStatus.
*
* getDefaultlensPosition() and getLensLimits() were added for
* populating ControlInfoMap. They return the static API limits
* which should be independent of the current range or mode.
*/
enum AfRange { AfRangeNormal = 0,
@@ -66,7 +70,9 @@ public:
}
virtual void setMode(AfMode mode) = 0;
virtual AfMode getMode() const = 0;
virtual bool setLensPosition(double dioptres, int32_t *hwpos) = 0;
virtual double getDefaultLensPosition() const = 0;
virtual void getLensLimits(double &min, double &max) const = 0;
virtual bool setLensPosition(double dioptres, int32_t *hwpos, bool force = false) = 0;
virtual std::optional<double> getLensPosition() const = 0;
virtual void triggerScan() = 0;
virtual void cancelScan() = 0;
+14 -2
View File
@@ -715,11 +715,23 @@ void Af::setWindows(libcamera::Span<libcamera::Rectangle const> const &wins)
invalidateWeights();
}
bool Af::setLensPosition(double dioptres, int *hwpos)
double Af::getDefaultLensPosition() const
{
return cfg_.ranges[AfRangeNormal].focusDefault;
}
void Af::getLensLimits(double &min, double &max) const
{
/* Limits for manual focus are set by map, not by ranges */
min = cfg_.map.domain().start;
max = cfg_.map.domain().end;
}
bool Af::setLensPosition(double dioptres, int *hwpos, bool force)
{
bool changed = false;
if (mode_ == AfModeManual) {
if (mode_ == AfModeManual || force) {
LOG(RPiAf, Debug) << "setLensPosition: " << dioptres;
ftarget_ = cfg_.map.domain().clamp(dioptres);
changed = !(initted_ && fsmooth_ == ftarget_);
+3 -1
View File
@@ -54,7 +54,9 @@ public:
void setWindows(libcamera::Span<libcamera::Rectangle const> const &wins) override;
void setMode(AfMode mode) override;
AfMode getMode() const override;
bool setLensPosition(double dioptres, int32_t *hwpos) override;
double getDefaultLensPosition() const override;
void getLensLimits(double &min, double &max) const override;
bool setLensPosition(double dioptres, int32_t *hwpos, bool force) override;
std::optional<double> getLensPosition() const override;
void triggerScan() override;
void cancelScan() override;