@@ -200,6 +200,7 @@ Af::Af(Controller *controller)
200200 sceneChangeCount_(0 ),
201201 scanMaxContrast_(0.0 ),
202202 scanMinContrast_(1.0e9 ),
203+ scanStep_(0.0 ),
203204 scanData_(),
204205 reportState_(AfState::Idle)
205206{
@@ -251,13 +252,14 @@ void Af::switchMode(CameraMode const &cameraMode, [[maybe_unused]] Metadata *met
251252 << statsRegion_.height ;
252253 invalidateWeights ();
253254
254- if (scanState_ >= ScanState::Coarse && scanState_ < ScanState::Settle) {
255+ if (scanState_ >= ScanState::Coarse1 && scanState_ < ScanState::Settle) {
255256 /*
256257 * If a scan was in progress, re-start it, as CDAF statistics
257258 * may have changed. Though if the application is just about
258259 * to take a still picture, this will not help...
259260 */
260261 startProgrammedScan ();
262+ updateLensPosition ();
261263 }
262264 skipCount_ = cfg_.skipFrames ;
263265}
@@ -543,31 +545,42 @@ void Af::doScan(double contrast, double phase, double conf)
543545 scanMinContrast_ = contrast;
544546 scanData_.emplace_back (ScanRecord{ ftarget_, contrast, phase, conf });
545547
546- if (scanState_ == ScanState::Coarse) {
547- if (ftarget_ >= cfg_.ranges [range_].focusMax ||
548- contrast < cfg_.speeds [speed_].contrastRatio * scanMaxContrast_) {
549- /*
550- * Finished course scan, or termination based on contrast.
551- * Jump to just after max contrast and start fine scan.
552- */
553- ftarget_ = std::min (ftarget_, findPeak (scanMaxIndex_) +
554- 2.0 * cfg_.speeds [speed_].stepFine );
555- scanState_ = ScanState::Fine;
556- scanData_.clear ();
557- } else
558- ftarget_ += cfg_.speeds [speed_].stepCoarse ;
559- } else { /* ScanState::Fine */
560- if (ftarget_ <= cfg_.ranges [range_].focusMin || scanData_.size () >= 5 ||
561- contrast < cfg_.speeds [speed_].contrastRatio * scanMaxContrast_) {
562- /*
563- * Finished fine scan, or termination based on contrast.
564- * Use quadratic peak-finding to find best contrast position.
565- */
566- ftarget_ = findPeak (scanMaxIndex_);
548+ if ((scanStep_ >= 0.0 && ftarget_ >= cfg_.ranges [range_].focusMax ) ||
549+ (scanStep_ <= 0.0 && ftarget_ <= cfg_.ranges [range_].focusMin ) ||
550+ (scanState_ == ScanState::Fine && scanData_.size () >= 3 ) ||
551+ contrast < cfg_.speeds [speed_].contrastRatio * scanMaxContrast_) {
552+ double pk = findPeak (scanMaxIndex_);
553+ /*
554+ * Finished a scan, by hitting a limit or due to constrast dropping off.
555+ * If this is a first coarse scan and we didn't bracket the peak, reverse!
556+ * If this is a fine scan, or no fine step was defined, we've finished.
557+ * Otherwise, start fine scan in opposite direction.
558+ */
559+ if (scanState_ == ScanState::Coarse1 &&
560+ scanData_[0 ].contrast >= cfg_.speeds [speed_].contrastRatio * scanMaxContrast_) {
561+ scanStep_ = -scanStep_;
562+ scanState_ = ScanState::Coarse2;
563+ } else if (scanState_ == ScanState::Fine || cfg_.speeds [speed_].stepFine <= 0.0 ) {
564+ ftarget_ = pk;
567565 scanState_ = ScanState::Settle;
568- } else
569- ftarget_ -= cfg_.speeds [speed_].stepFine ;
570- }
566+ } else if (scanState_ == ScanState::Coarse1 &&
567+ scanData_[0 ].contrast >= cfg_.speeds [speed_].contrastRatio * scanMaxContrast_) {
568+ scanStep_ = -scanStep_;
569+ scanState_ = ScanState::Coarse2;
570+ } else if (scanStep_ >= 0.0 ) {
571+ ftarget_ = std::min (pk + cfg_.speeds [speed_].stepFine ,
572+ cfg_.ranges [range_].focusMax );
573+ scanStep_ = -cfg_.speeds [speed_].stepFine ;
574+ scanState_ = ScanState::Fine;
575+ } else {
576+ ftarget_ = std::max (pk - cfg_.speeds [speed_].stepFine ,
577+ cfg_.ranges [range_].focusMin );
578+ scanStep_ = cfg_.speeds [speed_].stepFine ;
579+ scanState_ = ScanState::Fine;
580+ }
581+ scanData_.clear ();
582+ } else
583+ ftarget_ += scanStep_;
571584
572585 stepCount_ = (ftarget_ == fsmooth_) ? 0 : cfg_.speeds [speed_].stepFrames ;
573586}
@@ -622,7 +635,7 @@ void Af::doAF(double contrast, double phase, double conf)
622635 /* else fall through to waiting for a scene change */
623636 }
624637 }
625- if (scanState_ < ScanState::Coarse && mode_ == AfModeContinuous) {
638+ if (scanState_ < ScanState::Coarse1 && mode_ == AfModeContinuous) {
626639 /*
627640 * In CAF mode, not in a scan, and PDAF is unavailable.
628641 * Wait for a scene change, followed by stability.
@@ -642,7 +655,7 @@ void Af::doAF(double contrast, double phase, double conf)
642655 sceneChangeCount_++;
643656 if (sceneChangeCount_ >= cfg_.speeds [speed_].retriggerDelay )
644657 startProgrammedScan ();
645- } else if (scanState_ >= ScanState::Coarse && fsmooth_ == ftarget_) {
658+ } else if (scanState_ >= ScanState::Coarse1 && fsmooth_ == ftarget_) {
646659 /*
647660 * CDAF-based scanning sequence.
648661 * Allow a delay between steps for CDAF FoM statistics to be
@@ -714,15 +727,27 @@ void Af::startAF()
714727 oldSceneContrast_ = 0.0 ;
715728 sceneChangeCount_ = 0 ;
716729 reportState_ = AfState::Scanning;
717- } else
730+ } else {
718731 startProgrammedScan ();
732+ updateLensPosition ();
733+ }
719734}
720735
721736void Af::startProgrammedScan ()
722737{
723- ftarget_ = cfg_.ranges [range_].focusMin ;
724- updateLensPosition ();
725- scanState_ = ScanState::Coarse;
738+ if (!initted_ || mode_ != AfModeContinuous ||
739+ fsmooth_ <= cfg_.ranges [range_].focusMin + 2.0 * cfg_.speeds [speed_].stepCoarse ) {
740+ ftarget_ = cfg_.ranges [range_].focusMin ;
741+ scanStep_ = cfg_.speeds [speed_].stepCoarse ;
742+ scanState_ = ScanState::Coarse2;
743+ } else if (fsmooth_ >= cfg_.ranges [range_].focusMax - 2.0 * cfg_.speeds [speed_].stepCoarse ) {
744+ ftarget_ = cfg_.ranges [range_].focusMax ;
745+ scanStep_ = -cfg_.speeds [speed_].stepCoarse ;
746+ scanState_ = ScanState::Coarse2;
747+ } else {
748+ scanStep_ = -cfg_.speeds [speed_].stepCoarse ;
749+ scanState_ = ScanState::Coarse1;
750+ }
726751 scanMaxContrast_ = 0.0 ;
727752 scanMinContrast_ = 1.0e9 ;
728753 scanMaxIndex_ = 0 ;
@@ -785,7 +810,9 @@ void Af::prepare(Metadata *imageMetadata)
785810 else
786811 status.pauseState = AfPauseState::Running;
787812
788- if (mode_ == AfModeAuto && scanState_ != ScanState::Idle)
813+ if (scanState_ == ScanState::Idle)
814+ status.state = AfState::Idle;
815+ else if (mode_ == AfModeAuto)
789816 status.state = AfState::Scanning;
790817 else
791818 status.state = reportState_;
@@ -907,7 +934,7 @@ void Af::setMode(AfAlgorithm::AfMode mode)
907934 pauseFlag_ = false ;
908935 if (mode == AfModeContinuous)
909936 scanState_ = ScanState::Trigger;
910- else if (mode != AfModeAuto || scanState_ < ScanState::Coarse )
937+ else if (mode != AfModeAuto || scanState_ < ScanState::Coarse1 )
911938 goIdle ();
912939 }
913940}
@@ -923,11 +950,11 @@ void Af::pause(AfAlgorithm::AfPause pause)
923950 if (mode_ == AfModeContinuous) {
924951 if (pause == AfPauseResume && pauseFlag_) {
925952 pauseFlag_ = false ;
926- if (scanState_ < ScanState::Coarse )
953+ if (scanState_ < ScanState::Coarse1 )
927954 scanState_ = ScanState::Trigger;
928955 } else if (pause != AfPauseResume && !pauseFlag_) {
929956 pauseFlag_ = true ;
930- if (pause == AfPauseImmediate || scanState_ < ScanState::Coarse )
957+ if (pause == AfPauseImmediate || scanState_ < ScanState::Coarse1 )
931958 goIdle ();
932959 }
933960 }
0 commit comments