<div dir="ltr"><div dir="ltr">Hi David,<div><br></div><div>Thank you for this work.  I'll kick off with a few questions, but I'm sure there will be more to come :)</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, 13 Dec 2021 at 15:22, David Plowman <<a href="mailto:david.plowman@raspberrypi.com">david.plowman@raspberrypi.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">This patch describes a series of controls that allow applications to<br>
drive AF algorithms:<br>
<br>
AfMode - auto or continuous<br>
AfRange - full, macro or normal<br>
AfSpeed - fast or slow<br>
AfMethod - single or multi-spot<br>
AfWindow - AF window locations<br>
AfTrigger - start (trigger an AF scan) or cancel<br>
LensPosition - position of lens from lens driver<br>
AfState - reset, scanning, focused or failed<br>
---<br>
 src/libcamera/control_ids.yaml | 227 ++++++++++++++++++++++++---------<br>
 1 file changed, 167 insertions(+), 60 deletions(-)<br>
<br>
diff --git a/src/libcamera/control_ids.yaml b/src/libcamera/control_ids.yaml<br>
index 9d4638ae..e579f7b7 100644<br>
--- a/src/libcamera/control_ids.yaml<br>
+++ b/src/libcamera/control_ids.yaml<br>
@@ -406,27 +406,6 @@ controls:<br>
             The camera will cancel any active or completed metering sequence.<br>
             The AE algorithm is reset to its initial state.<br>
<br>
-  - AfTrigger:<br>
-      type: int32_t<br>
-      draft: true<br>
-      description: |<br>
-       Control for AF trigger. Currently identical to<br>
-       ANDROID_CONTROL_AF_TRIGGER.<br>
-<br>
-        Whether the camera device will trigger autofocus for this request.<br>
-      enum:<br>
-        - name: AfTriggerIdle<br>
-          value: 0<br>
-          description: The trigger is idle.<br>
-        - name: AfTriggerStart<br>
-          value: 1<br>
-          description: The AF routine is started by the camera.<br>
-        - name: AfTriggerCancel<br>
-          value: 2<br>
-          description: |<br>
-            The camera will cancel any active trigger and the AF routine is<br>
-            reset to its initial state.<br>
-<br>
   - NoiseReductionMode:<br>
       type: int32_t<br>
       draft: true<br>
@@ -507,45 +486,6 @@ controls:<br>
             The AE algorithm has started a pre-capture metering session.<br>
             \sa AePrecaptureTrigger<br>
<br>
-  - AfState:<br>
-      type: int32_t<br>
-      draft: true<br>
-      description: |<br>
-       Control to report the current AF algorithm state. Currently identical to<br>
-       ANDROID_CONTROL_AF_STATE.<br>
-<br>
-        Current state of the AF algorithm.<br>
-      enum:<br>
-        - name: AfStateInactive<br>
-          value: 0<br>
-          description: The AF algorithm is inactive.<br>
-        - name: AfStatePassiveScan<br>
-          value: 1<br>
-          description: |<br>
-            AF is performing a passive scan of the scene in continuous<br>
-            auto-focus mode.<br>
-        - name: AfStatePassiveFocused<br>
-          value: 2<br>
-          description: |<br>
-            AF believes the scene is in focus, but might restart scanning.<br>
-        - name: AfStateActiveScan<br>
-          value: 3<br>
-          description: |<br>
-            AF is performing a scan triggered by an AF trigger request.<br>
-            \sa AfTrigger<br>
-        - name: AfStateFocusedLock<br>
-          value: 4<br>
-          description: |<br>
-            AF believes has focused correctly and has locked focus.<br>
-        - name: AfStateNotFocusedLock<br>
-          value: 5<br>
-          description: |<br>
-            AF has not been able to focus and has locked.<br>
-        - name: AfStatePassiveUnfocused<br>
-          value: 6<br>
-          description: |<br>
-            AF has completed a passive scan without finding focus.<br>
-<br>
   - AwbState:<br>
       type: int32_t<br>
       draft: true<br>
@@ -690,4 +630,171 @@ controls:<br>
             value. All of the custom test patterns will be static (that is the<br>
             raw image must not vary from frame to frame).<br>
<br>
+  - AfMode:<br>
+      type: int32_t<br>
+      draft: true<br>
+      description: |<br>
+        Control to set the mode of the AF (autofocus) algorithm.<br>
+      enum:<br>
+        - name: AfModeAuto<br>
+          value: 0<br>
+          description: |<br>
+            The AF algorithm is in auto mode. This means that the algorithm<br>
+            will never move the lens or change state unless the AfTrigger<br>
+            control is used. The AfTrigger control can be used to initiate a<br>
+            focus scan, the results of which will be reported by the AfState.<br>
+<br>
+            In this mode, an application can move the lens for itself using<br>
+            the LensPosition control. If the algorithm was scanning when the<br>
+            lens is moved in this way, then the scan is implicitly cancelled.<br>
+        - name: AfModeContinuous<br>
+          value: 1<br>
+          description: |<br>
+            The AF algorithm is in continuous mode. This means that the lens<br>
+            can re-start a scan spontaneously at any moment, without any user<br>
+            intervention. The AfState still reports whether the algorithm is<br>
+            currently scanning or not, though the application has no ability<br>
+            to initiate or cancel scans, nor move the lens for itself.<br>
+<br>
+            The mode can be set to AfModeAuto which has the effect of<br>
+            "pausing" any continuous AF activity, after which it could then<br>
+            be moved back to AfModeContinuous to resume operation.<br></blockquote><div><br></div><div>I wonder if we need a method to tell the lens to move to a "default" position?</div><div>For example, cancel AF or CAF, then move the lens to hyperfocal.  With the</div><div>above description, we can stop AF, and use the LensPosition control to move</div><div>to a specified position, but how do we know what position corresponds to</div><div>hyperfocal?  If the hyperfocal position is defined in the tuning file, the application</div><div>would not have access to the value.  Perhaps an explicit mode to do this?</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+  - AfRange:<br>
+      type: int32_t<br>
+      draft: true<br>
+      description: |<br>
+        Control to set the range of focus distances that is scanned.<br>
+      enum:<br>
+        - name: AfRangeFull<br>
+          value: 0<br>
+          description: The full range of focus distances is scanned.<br>
+        - name: AfRangeMacro<br>
+          value: 1<br>
+          description: Only close distances are scanned.<br>
+        - name: AfRangeNormal<br>
+          value: 2<br>
+          description: |<br>
+            The full range of focus distances is scanned except for some of<br>
+            the closest macro positions.<br></blockquote><div><br></div><div>Is the "closest macro position" a property of the module, or a user preference?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+  - AfSpeed:<br>
+      type: int32_t<br>
+      draft: true<br>
+      description: |<br>
+        Control that determines whether the AF algorithm is to move the lens<br>
+        as quickly as possible or more steadily. For example, during video<br>
+        recording it may be desirable not to move the lens too abruptly, but<br>
+        when in a preview mode (waiting for a still capture) it may be<br>
+        helpful to move the lens as quickly as is reasonably possible.<br>
+      enum:<br>
+        - name: AfSpeedFast<br>
+          value: 0<br>
+          description: Move the lens quickly.<br>
+        - name: AfSpeedSlow<br>
+          value: 0<br>
+          description: Move the lens more steadily.<br>
+<br>
+  - AfMethod:<br>
+      type: int32_t<br>
+      draft: true<br>
+      description: |<br>
+        Control whether the AF algorithm uses a single window in the image to<br>
+        determine the best focus position, or multiple windows simultaneously.<br>
+      enum:<br>
+        - name: AfMethodSingle<br>
+          value: 0<br>
+          description: |<br>
+            A single window within the image, defaulting to the centre, is used<br>
+            to select the best focus distance.<br>
+        - name: AfMethodMultiSpot<br>
+          value: 0<br>
+          description: |<br>
+            Multiple windows within the image are used to select the best focus<br>
+            distance. The best focus distance is found for each one of the<br>
+            windows, and then the distance that is closest to the camera is<br>
+            selected.<br></blockquote><div><br></div><div>Would AFfMethod be used in  continuous focus modes as well?  if yes, then perhaps</div><div>s/AF algorithm/focus algorithms/?  Ditto for AfWindow.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+  - AfWindow:<br>
+      type: Rectangle<br>
+      draft: true<br>
+      description: |<br>
+         Sets the focus windows used by the AF algorithm. The units used express<br>
+         a proportion of the ScalerCrop control (or if unavailable, of the entire<br>
+         image), as u0.16 format numbers.<br>
+<br>
+         In order to be activated, a rectangle must be programmed with non-zero<br>
+         width and height. If no rectangles are programmed in this way, then the<br>
+         system will choose its own single default window in the centre of the<br>
+         image.<br>
+<br>
+         If AfMethod is set to AfMethodSingle, then only the first Rectangle in<br>
+         this list is used (or the system default one if it is unprogrammed).<br>
+<br>
+         If AfMethod is set to AfMethodMultiSpot then all the valid Rectangles in<br>
+         this list are used. The size of the control indicates how many such<br>
+         windows can be programmed and will vary between different platforms.<br>
+<br>
+         size: [platform dependent]<br>
+<br>
+  - AfTrigger:<br>
+      type: int32_t<br>
+      draft: true<br>
+      description: |<br>
+         This control starts an autofocus scan when AfMode is set to AfModeAuto,<br>
+         and can also be used to terminate a scan early.<br>
+<br>
+         It is ignored if AfMode is set to AfModeContinuous.<br>
+         <br>
+      enum:<br>
+        - name: AfTriggerStart<br>
+          value: 0<br>
+          description: Start an AF scan. Ignored if a scan is in progress.<br>
+        - name: AfTriggerCancel<br>
+          value: 1<br>
+          description: Cancel an AF scan. Ingored if no scan is in progress.<br>
+<br>
+  - LensPosition:<br>
+      type: int32_t<br>
+      draft: true<br>
+      description: |<br>
+         Acts as a control to instruct the lens to move to a particular position<br>
+         and also reports back the position of the lens for each frame.<br>
+<br>
+         The units are determined by the lens driver.<br></blockquote><div><br></div><div>This would mean applications might not see the same/consistent behavior with</div><div>different lens modules. Should we define a libcamera range (e.g. 0 -> Infinity,</div><div>1023 -> Macro) and convert to/from lens driver units in the IPA or pipeline handler?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+         If the LensPosition control is used while an AF scan is in progress,<br>
+         the scan is implicitly cancelled and the lens is then moved to the<br>
+         desired location. It is ignored if AfMode is set to AfModeContinuous.<br>
+<br>
+  - AfState:<br>
+      type: int32_t<br>
+      draft: true<br>
+      description: |<br>
+          Reports the current state of the AF algorithm.<br>
+      enum:<br>
+        - name: AfStateReset<br>
+          value: 0<br>
+          description: |<br>
+              The AF algorithm reports this state when:<br>
+                  * The camera system has just been started.<br>
+                  * A scan has been cancelled.<br>
+                  * The lens has been moved by the LensPosition control.<br>
+        - name: AfStateScanning<br>
+          value: 1<br>
+          description:  |<br>
+              AF is performing a scan. This state can be entered spontaneously<br>
+              if AfMode is set to AfModeContinuous, otherwise it requires the<br>
+              application to use the AfTrigger control to start the scan.<br>
+        - name: AfStateFocused<br>
+          value: 2<br>
+          description: |<br>
+              An AF scan has been performed and the algorithm believes the<br>
+              scene is in focus.<br>
+        - name: AfStateFailed<br>
+          value: 3<br>
+          description: |<br>
+              An AF scan has been performed but the algorithm has not been able<br>
+              to find the best focus position.<br>
+<br></blockquote><div><br></div><div>One last point, we currently have a FocusFoM control that returns a focus measure</div><div>to the application.  In light of the new AfWindow measure, should that perhaps be</div><div>redefined?</div><div><br></div><div>Regards,</div><div>Naush</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
 ...<br>
-- <br>
2.30.2<br>
<br>
</blockquote></div></div>