<div dir="ltr">Cameras such as the PiCam 3 support auto-focus, but the GStreamer plugin<br>for libcamera does not enable auto-focus. With this patch auto-focus can<br>be enabled for cameras that support it. By default it is disabled, which<br>means default behaviour remains unchanged. For cameras that do not<br>support auto-focus, an error message shows up if it auto-focus is<br>enabled.<br><br>This was tested on cameras that do not support auto-focus (e.g. PiCam2)<br>and was tested on a camera that does support auto-focus (PiCam3) by<br>enabling it, observing auto-focus, and by disabling it or by not setting<br>the option, both resulting in auto-focus being disabled.<br><br>Signed-off-by: Cedric Nugteren <<a href="mailto:web@cedricnugteren.nl">web@cedricnugteren.nl</a>><br>---<br> src/gstreamer/gstlibcameraprovider.cpp | 13 ++++++++++++<br> src/gstreamer/gstlibcamerasrc.cpp      | 29 +++++++++++++++++++++++++-<br> 2 files changed, 41 insertions(+), 1 deletion(-)<br><br>diff --git a/src/gstreamer/gstlibcameraprovider.cpp b/src/gstreamer/gstlibcameraprovider.cpp<br>index 6eb0a0eb..86fa2542 100644<br>--- a/src/gstreamer/gstlibcameraprovider.cpp<br>+++ b/src/gstreamer/gstlibcameraprovider.cpp<br>@@ -31,6 +31,7 @@ GST_DEBUG_CATEGORY_STATIC(provider_debug);<br> <br> enum {<br>         PROP_DEVICE_NAME = 1,<br>+        PROP_ENABLE_AUTO_FOCUS = 2,<br> };<br> <br> #define GST_TYPE_LIBCAMERA_DEVICE gst_libcamera_device_get_type()<br>@@ -40,6 +41,7 @@ G_DECLARE_FINAL_TYPE(GstLibcameraDevice, gst_libcamera_device,<br> struct _GstLibcameraDevice {<br>         GstDevice parent;<br>    gchar *name;<br>+ gboolean enable_auto_focus = false;<br> };<br> <br> G_DEFINE_TYPE(GstLibcameraDevice, gst_libcamera_device, GST_TYPE_DEVICE)<br>@@ -56,6 +58,7 @@ gst_libcamera_device_create_element(GstDevice *device, const gchar *name)<br>       g_assert(source);<br> <br>        g_object_set(source, "camera-name", GST_LIBCAMERA_DEVICE(device)->name, nullptr);<br>+       g_object_set(source, "enable-auto-focus", GST_LIBCAMERA_DEVICE(device)->enable_auto_focus, nullptr);<br> <br>        return source;<br> }<br>@@ -68,6 +71,7 @@ gst_libcamera_device_reconfigure_element(GstDevice *device,<br>           return FALSE;<br> <br>    g_object_set(element, "camera-name", GST_LIBCAMERA_DEVICE(device)->name, nullptr);<br>+      g_object_set(element, "enable-auto-focus", GST_LIBCAMERA_DEVICE(device)->enable_auto_focus, nullptr);<br> <br>       return TRUE;<br> }<br>@@ -82,6 +86,9 @@ gst_libcamera_device_set_property(GObject *object, guint prop_id,<br>       case PROP_DEVICE_NAME:<br>               device->name = g_value_dup_string(value);<br>                 break;<br>+       case PROP_ENABLE_AUTO_FOCUS:<br>+         device->enable_auto_focus = g_value_get_boolean(value);<br>+           break;<br>       default:<br>             G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);<br>           break;<br>@@ -121,6 +128,12 @@ gst_libcamera_device_class_init(GstLibcameraDeviceClass *klass)<br>                                                 (GParamFlags)(G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE |<br>                                                          G_PARAM_CONSTRUCT_ONLY));<br>   g_object_class_install_property(object_class, PROP_DEVICE_NAME, pspec);<br>+      GParamSpec *spec2 = g_param_spec_boolean("enable-auto-focus",<br>+                              "Enable auto-focus",<br>+                           "Enable auto-focus if set to true, "<br>+                           "disable it if set to false",<br>+                           FALSE, G_PARAM_WRITABLE);<br>+       g_object_class_install_property(object_class, PROP_ENABLE_AUTO_FOCUS, spec2);<br> }<br> <br> static GstDevice *<br>diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp<br>index a10cbd4f..672ea38a 100644<br>--- a/src/gstreamer/gstlibcamerasrc.cpp<br>+++ b/src/gstreamer/gstlibcamerasrc.cpp<br>@@ -146,6 +146,7 @@ struct _GstLibcameraSrc {<br>   GstTask *task;<br> <br>   gchar *camera_name;<br>+  gboolean enable_auto_focus = false;<br> <br>      GstLibcameraSrcState *state;<br>         GstLibcameraAllocator *allocator;<br>@@ -154,7 +155,8 @@ struct _GstLibcameraSrc {<br> <br> enum {<br>       PROP_0,<br>-      PROP_CAMERA_NAME<br>+     PROP_CAMERA_NAME,<br>+    PROP_ENABLE_AUTO_FOCUS,<br> };<br> <br> G_DEFINE_TYPE_WITH_CODE(GstLibcameraSrc, gst_libcamera_src, GST_TYPE_ELEMENT,<br>@@ -577,6 +579,18 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread,<br>               gst_flow_combiner_add_pad(self->flow_combiner, srcpad);<br>   }<br> <br>+        if (self->enable_auto_focus) {<br>+            const ControlInfoMap &infoMap = state->cam_->controls();<br>+           if (infoMap.find(&controls::AfMode) != infoMap.end()) {<br>+                  state->initControls_.set(controls::AfMode, controls::AfModeContinuous);<br>+           } else {<br>+                     GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS,<br>+                          ("Failed to enable auto focus"),<br>+                           ("AfMode not found in camera controls, "<br>+                           "please retry with 'enable-auto-focus=false'"));<br>+           }<br>+    }<br>+<br>         ret = state->cam_->start(&state->initControls_);<br>        if (ret) {<br>           GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS,<br>@@ -659,6 +673,9 @@ gst_libcamera_src_set_property(GObject *object, guint prop_id,<br>              g_free(self->camera_name);<br>                self->camera_name = g_value_dup_string(value);<br>            break;<br>+       case PROP_ENABLE_AUTO_FOCUS:<br>+         self->enable_auto_focus = g_value_get_boolean(value);<br>+             break;<br>       default:<br>             G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);<br>           break;<br>@@ -676,6 +693,9 @@ gst_libcamera_src_get_property(GObject *object, guint prop_id, GValue *value,<br>    case PROP_CAMERA_NAME:<br>               g_value_set_string(value, self->camera_name);<br>             break;<br>+       case PROP_ENABLE_AUTO_FOCUS:<br>+         g_value_set_boolean(value, self->enable_auto_focus);<br>+              break;<br>       default:<br>             G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);<br>           break;<br>@@ -844,4 +864,11 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass)<br>                                                            | G_PARAM_READWRITE<br>                                                        | G_PARAM_STATIC_STRINGS));<br>   g_object_class_install_property(object_class, PROP_CAMERA_NAME, spec);<br>+       GParamSpec *spec2 = g_param_spec_boolean("enable-auto-focus",<br>+                              "Enable auto-focus",<br>+                           "Enable auto-focus if set to true, "<br>+                           "disable it if set to false",<br>+                           FALSE, G_PARAM_WRITABLE);<br>+       g_object_class_install_property(object_class, PROP_ENABLE_AUTO_FOCUS, spec2);<br>+<br> }<br>-- <br>2.34.1<br></div>