Message ID | 20230616100327.86707-1-web@cedricnugteren.nl |
---|---|
State | Accepted |
Headers | show |
Series |
|
Related | show |
Hi Cedric, Thank you for v4. On 6/16/23 3:33 PM, Cedric Nugteren via libcamera-devel wrote: > Cameras such as the PiCam 3 support auto-focus, but the GStreamer plugin > for libcamera does not enable auto-focus. With this patch auto-focus can > be enabled for cameras that support it. By default it is disabled, which > means default behaviour remains unchanged. For cameras that do not > support auto-focus, an error message shows up if auto-focus is enabled. > > This was tested on cameras that do not support auto-focus (e.g. PiCam2) > and was tested on a camera that does support auto-focus (PiCam3). The > test involved setting the focus to AfModeContinous and observing it. > However, by not setting "auto-focus-mode" or using AfModeManual as > the "auto-focus-mode" both resulting in auto-focus being disabled. > > Bug:https://bugs.libcamera.org/show_bug.cgi?id=188 > > Signed-off-by: Cedric Nugteren<web@cedricnugteren.nl> Please always collect tags from previous version and append in the commit message: Reviewed-by: Maarten Lankhorst <dev@lankhorst.se> |Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>| ||Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Tested-by: Umang Jain <umang.jain@ideasonboard.com> || > --- > Changes since v1: > - Now re-using the GParamSpec variables instead of re-creating. > - Use bool instead of gboolean for enable_auto_focus. > - Remove changes from the reconfigure_element functions. > > Changes since v2: > - Fix a typo in the commit message (remove 'it'). > - Fix the link to the actual bug. > - Apply the style suggestions of utils/checkstyle.py. > - Start the commit message with 'gstreamer:'. > - Change the boolean to a 3-option AfMode enum and change variable > names and strings accordingly. > > Changes since v3: > - Removed a period at the end of the bug link. > - Split the long sentence in the commit message in three parts. > - Remove unnecessary use of "libcamera::". > - Use controls::AfModeEnum enum instead of int. > - Add a newline before 'g_param_spec_enum'. > > --- > src/gstreamer/gstlibcameraprovider.cpp | 14 ++++++++++++ > src/gstreamer/gstlibcamerasrc.cpp | 31 +++++++++++++++++++++++++- > src/gstreamer/gstlibcamerasrc.h | 31 ++++++++++++++++++++++++++ > 3 files changed, 75 insertions(+), 1 deletion(-) > > diff --git a/src/gstreamer/gstlibcameraprovider.cpp b/src/gstreamer/gstlibcameraprovider.cpp > index 6eb0a0eb..d9216046 100644 > --- a/src/gstreamer/gstlibcameraprovider.cpp > +++ b/src/gstreamer/gstlibcameraprovider.cpp > @@ -31,6 +31,7 @@ GST_DEBUG_CATEGORY_STATIC(provider_debug); > > enum { > PROP_DEVICE_NAME = 1, > + PROP_AUTO_FOCUS_MODE = 2, > }; > > #define GST_TYPE_LIBCAMERA_DEVICE gst_libcamera_device_get_type() > @@ -40,6 +41,7 @@ G_DECLARE_FINAL_TYPE(GstLibcameraDevice, gst_libcamera_device, > struct _GstLibcameraDevice { > GstDevice parent; > gchar *name; > + controls::AfModeEnum auto_focus_mode = controls::AfModeManual; > }; > > G_DEFINE_TYPE(GstLibcameraDevice, gst_libcamera_device, GST_TYPE_DEVICE) > @@ -56,6 +58,7 @@ gst_libcamera_device_create_element(GstDevice *device, const gchar *name) > g_assert(source); > > g_object_set(source, "camera-name", GST_LIBCAMERA_DEVICE(device)->name, nullptr); > + g_object_set(source, "auto-focus-mode", GST_LIBCAMERA_DEVICE(device)->auto_focus_mode, nullptr); > > return source; > } > @@ -82,6 +85,9 @@ gst_libcamera_device_set_property(GObject *object, guint prop_id, > case PROP_DEVICE_NAME: > device->name = g_value_dup_string(value); > break; > + case PROP_AUTO_FOCUS_MODE: > + device->auto_focus_mode = static_cast<controls::AfModeEnum>(g_value_get_enum(value)); > + break; > default: > G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); > break; > @@ -121,6 +127,14 @@ gst_libcamera_device_class_init(GstLibcameraDeviceClass *klass) > (GParamFlags)(G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | > G_PARAM_CONSTRUCT_ONLY)); > g_object_class_install_property(object_class, PROP_DEVICE_NAME, pspec); > + pspec = g_param_spec_enum("auto-focus-mode", Possibly a new line here as well... I can fixup while applying so no need for v5. > + "Set auto-focus mode", > + "Available options: AfModeManual, " > + "AfModeAuto or AfModeContinuous.", > + gst_libcamera_auto_focus_get_type(), > + static_cast<gint>(controls::AfModeManual), > + G_PARAM_WRITABLE); > + g_object_class_install_property(object_class, PROP_AUTO_FOCUS_MODE, pspec); > } > > static GstDevice * > diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp > index a10cbd4f..47d8ff43 100644 > --- a/src/gstreamer/gstlibcamerasrc.cpp > +++ b/src/gstreamer/gstlibcamerasrc.cpp > @@ -146,6 +146,7 @@ struct _GstLibcameraSrc { > GstTask *task; > > gchar *camera_name; > + controls::AfModeEnum auto_focus_mode = controls::AfModeManual; > > GstLibcameraSrcState *state; > GstLibcameraAllocator *allocator; > @@ -154,7 +155,8 @@ struct _GstLibcameraSrc { > > enum { > PROP_0, > - PROP_CAMERA_NAME > + PROP_CAMERA_NAME, > + PROP_AUTO_FOCUS_MODE, > }; > > G_DEFINE_TYPE_WITH_CODE(GstLibcameraSrc, gst_libcamera_src, GST_TYPE_ELEMENT, > @@ -577,6 +579,18 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread, > gst_flow_combiner_add_pad(self->flow_combiner, srcpad); > } > > + if (self->auto_focus_mode != controls::AfModeManual) { > + const ControlInfoMap &infoMap = state->cam_->controls(); > + if (infoMap.find(&controls::AfMode) != infoMap.end()) { > + state->initControls_.set(controls::AfMode, self->auto_focus_mode); > + } else { > + GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS, > + ("Failed to enable auto focus"), > + ("AfMode not supported by this camera, " > + "please retry with 'auto-focus-mode=AfModeManual'")); > + } > + } > + > ret = state->cam_->start(&state->initControls_); > if (ret) { > GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS, > @@ -659,6 +673,9 @@ gst_libcamera_src_set_property(GObject *object, guint prop_id, > g_free(self->camera_name); > self->camera_name = g_value_dup_string(value); > break; > + case PROP_AUTO_FOCUS_MODE: > + self->auto_focus_mode = static_cast<controls::AfModeEnum>(g_value_get_enum(value)); > + break; > default: > G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); > break; > @@ -676,6 +693,9 @@ gst_libcamera_src_get_property(GObject *object, guint prop_id, GValue *value, > case PROP_CAMERA_NAME: > g_value_set_string(value, self->camera_name); > break; > + case PROP_AUTO_FOCUS_MODE: > + g_value_set_enum(value, static_cast<gint>(self->auto_focus_mode)); > + break; > default: > G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); > break; > @@ -844,4 +864,13 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass) > | G_PARAM_READWRITE > | G_PARAM_STATIC_STRINGS)); > g_object_class_install_property(object_class, PROP_CAMERA_NAME, spec); > + > + spec = g_param_spec_enum("auto-focus-mode", > + "Set auto-focus mode", > + "Available options: AfModeManual, " > + "AfModeAuto or AfModeContinuous.", > + gst_libcamera_auto_focus_get_type(), > + static_cast<gint>(controls::AfModeManual), > + G_PARAM_WRITABLE); > + g_object_class_install_property(object_class, PROP_AUTO_FOCUS_MODE, spec); > } > diff --git a/src/gstreamer/gstlibcamerasrc.h b/src/gstreamer/gstlibcamerasrc.h > index fdea2f10..0a88ba02 100644 > --- a/src/gstreamer/gstlibcamerasrc.h > +++ b/src/gstreamer/gstlibcamerasrc.h > @@ -8,6 +8,8 @@ > > #pragma once > > +#include <libcamera/control_ids.h> > + > #include <gst/gst.h> > > G_BEGIN_DECLS > @@ -17,3 +19,32 @@ G_DECLARE_FINAL_TYPE(GstLibcameraSrc, gst_libcamera_src, > GST_LIBCAMERA, SRC, GstElement) > > G_END_DECLS > + > +inline GType > +gst_libcamera_auto_focus_get_type() > +{ > + static GType type = 0; > + static const GEnumValue values[] = { > + { > + static_cast<gint>(libcamera::controls::AfModeManual), > + "AfModeManual", > + "manual-focus", > + }, > + { > + static_cast<gint>(libcamera::controls::AfModeAuto), > + "AfModeAuto", > + "automatic-auto-focus", > + }, > + { > + static_cast<gint>(libcamera::controls::AfModeContinuous), > + "AfModeContinuous", > + "continuous-auto-focus", > + }, > + { 0, NULL, NULL } > + }; > + > + if (!type) > + type = g_enum_register_static("GstLibcameraAutoFocus", values); > + > + return type; > +}
Hi, On 6/16/23 3:48 PM, Umang Jain via libcamera-devel wrote: > Hi Cedric, > > Thank you for v4. > > On 6/16/23 3:33 PM, Cedric Nugteren via libcamera-devel wrote: >> Cameras such as the PiCam 3 support auto-focus, but the GStreamer plugin >> for libcamera does not enable auto-focus. With this patch auto-focus can >> be enabled for cameras that support it. By default it is disabled, which >> means default behaviour remains unchanged. For cameras that do not >> support auto-focus, an error message shows up if auto-focus is enabled. >> >> This was tested on cameras that do not support auto-focus (e.g. PiCam2) >> and was tested on a camera that does support auto-focus (PiCam3). The >> test involved setting the focus to AfModeContinous and observing it. >> However, by not setting "auto-focus-mode" or using AfModeManual as >> the "auto-focus-mode" both resulting in auto-focus being disabled. >> >> Bug:https://bugs.libcamera.org/show_bug.cgi?id=188 >> >> Signed-off-by: Cedric Nugteren<web@cedricnugteren.nl> Merged this patch. However your email as the commit author Cedric Nugteren <cedric@plumerai.com> was different than the S-o-B tag here, The S-o-B should be same as the author Full name and email-ID. Please make sure for future, both refer to the same email. Thanks! > > Please always collect tags from previous version and append in the > commit message: > > Reviewed-by: Maarten Lankhorst <dev@lankhorst.se> > |Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>| > ||Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> > Tested-by: Umang Jain <umang.jain@ideasonboard.com> > || >> --- >> Changes since v1: >> - Now re-using the GParamSpec variables instead of re-creating. >> - Use bool instead of gboolean for enable_auto_focus. >> - Remove changes from the reconfigure_element functions. >> >> Changes since v2: >> - Fix a typo in the commit message (remove 'it'). >> - Fix the link to the actual bug. >> - Apply the style suggestions of utils/checkstyle.py. >> - Start the commit message with 'gstreamer:'. >> - Change the boolean to a 3-option AfMode enum and change variable >> names and strings accordingly. >> >> Changes since v3: >> - Removed a period at the end of the bug link. >> - Split the long sentence in the commit message in three parts. >> - Remove unnecessary use of "libcamera::". >> - Use controls::AfModeEnum enum instead of int. >> - Add a newline before 'g_param_spec_enum'. >> >> --- >> src/gstreamer/gstlibcameraprovider.cpp | 14 ++++++++++++ >> src/gstreamer/gstlibcamerasrc.cpp | 31 +++++++++++++++++++++++++- >> src/gstreamer/gstlibcamerasrc.h | 31 ++++++++++++++++++++++++++ >> 3 files changed, 75 insertions(+), 1 deletion(-) >> >> diff --git a/src/gstreamer/gstlibcameraprovider.cpp b/src/gstreamer/gstlibcameraprovider.cpp >> index 6eb0a0eb..d9216046 100644 >> --- a/src/gstreamer/gstlibcameraprovider.cpp >> +++ b/src/gstreamer/gstlibcameraprovider.cpp >> @@ -31,6 +31,7 @@ GST_DEBUG_CATEGORY_STATIC(provider_debug); >> >> enum { >> PROP_DEVICE_NAME = 1, >> + PROP_AUTO_FOCUS_MODE = 2, >> }; >> >> #define GST_TYPE_LIBCAMERA_DEVICE gst_libcamera_device_get_type() >> @@ -40,6 +41,7 @@ G_DECLARE_FINAL_TYPE(GstLibcameraDevice, gst_libcamera_device, >> struct _GstLibcameraDevice { >> GstDevice parent; >> gchar *name; >> + controls::AfModeEnum auto_focus_mode = controls::AfModeManual; >> }; >> >> G_DEFINE_TYPE(GstLibcameraDevice, gst_libcamera_device, GST_TYPE_DEVICE) >> @@ -56,6 +58,7 @@ gst_libcamera_device_create_element(GstDevice *device, const gchar *name) >> g_assert(source); >> >> g_object_set(source, "camera-name", GST_LIBCAMERA_DEVICE(device)->name, nullptr); >> + g_object_set(source, "auto-focus-mode", GST_LIBCAMERA_DEVICE(device)->auto_focus_mode, nullptr); >> >> return source; >> } >> @@ -82,6 +85,9 @@ gst_libcamera_device_set_property(GObject *object, guint prop_id, >> case PROP_DEVICE_NAME: >> device->name = g_value_dup_string(value); >> break; >> + case PROP_AUTO_FOCUS_MODE: >> + device->auto_focus_mode = static_cast<controls::AfModeEnum>(g_value_get_enum(value)); >> + break; >> default: >> G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); >> break; >> @@ -121,6 +127,14 @@ gst_libcamera_device_class_init(GstLibcameraDeviceClass *klass) >> (GParamFlags)(G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | >> G_PARAM_CONSTRUCT_ONLY)); >> g_object_class_install_property(object_class, PROP_DEVICE_NAME, pspec); >> + pspec = g_param_spec_enum("auto-focus-mode", > > Possibly a new line here as well... I can fixup while applying so no > need for v5. >> + "Set auto-focus mode", >> + "Available options: AfModeManual, " >> + "AfModeAuto or AfModeContinuous.", >> + gst_libcamera_auto_focus_get_type(), >> + static_cast<gint>(controls::AfModeManual), >> + G_PARAM_WRITABLE); >> + g_object_class_install_property(object_class, PROP_AUTO_FOCUS_MODE, pspec); >> } >> >> static GstDevice * >> diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp >> index a10cbd4f..47d8ff43 100644 >> --- a/src/gstreamer/gstlibcamerasrc.cpp >> +++ b/src/gstreamer/gstlibcamerasrc.cpp >> @@ -146,6 +146,7 @@ struct _GstLibcameraSrc { >> GstTask *task; >> >> gchar *camera_name; >> + controls::AfModeEnum auto_focus_mode = controls::AfModeManual; >> >> GstLibcameraSrcState *state; >> GstLibcameraAllocator *allocator; >> @@ -154,7 +155,8 @@ struct _GstLibcameraSrc { >> >> enum { >> PROP_0, >> - PROP_CAMERA_NAME >> + PROP_CAMERA_NAME, >> + PROP_AUTO_FOCUS_MODE, >> }; >> >> G_DEFINE_TYPE_WITH_CODE(GstLibcameraSrc, gst_libcamera_src, GST_TYPE_ELEMENT, >> @@ -577,6 +579,18 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread, >> gst_flow_combiner_add_pad(self->flow_combiner, srcpad); >> } >> >> + if (self->auto_focus_mode != controls::AfModeManual) { >> + const ControlInfoMap &infoMap = state->cam_->controls(); >> + if (infoMap.find(&controls::AfMode) != infoMap.end()) { >> + state->initControls_.set(controls::AfMode, self->auto_focus_mode); >> + } else { >> + GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS, >> + ("Failed to enable auto focus"), >> + ("AfMode not supported by this camera, " >> + "please retry with 'auto-focus-mode=AfModeManual'")); >> + } >> + } >> + >> ret = state->cam_->start(&state->initControls_); >> if (ret) { >> GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS, >> @@ -659,6 +673,9 @@ gst_libcamera_src_set_property(GObject *object, guint prop_id, >> g_free(self->camera_name); >> self->camera_name = g_value_dup_string(value); >> break; >> + case PROP_AUTO_FOCUS_MODE: >> + self->auto_focus_mode = static_cast<controls::AfModeEnum>(g_value_get_enum(value)); >> + break; >> default: >> G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); >> break; >> @@ -676,6 +693,9 @@ gst_libcamera_src_get_property(GObject *object, guint prop_id, GValue *value, >> case PROP_CAMERA_NAME: >> g_value_set_string(value, self->camera_name); >> break; >> + case PROP_AUTO_FOCUS_MODE: >> + g_value_set_enum(value, static_cast<gint>(self->auto_focus_mode)); >> + break; >> default: >> G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); >> break; >> @@ -844,4 +864,13 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass) >> | G_PARAM_READWRITE >> | G_PARAM_STATIC_STRINGS)); >> g_object_class_install_property(object_class, PROP_CAMERA_NAME, spec); >> + >> + spec = g_param_spec_enum("auto-focus-mode", >> + "Set auto-focus mode", >> + "Available options: AfModeManual, " >> + "AfModeAuto or AfModeContinuous.", >> + gst_libcamera_auto_focus_get_type(), >> + static_cast<gint>(controls::AfModeManual), >> + G_PARAM_WRITABLE); >> + g_object_class_install_property(object_class, PROP_AUTO_FOCUS_MODE, spec); >> } >> diff --git a/src/gstreamer/gstlibcamerasrc.h b/src/gstreamer/gstlibcamerasrc.h >> index fdea2f10..0a88ba02 100644 >> --- a/src/gstreamer/gstlibcamerasrc.h >> +++ b/src/gstreamer/gstlibcamerasrc.h >> @@ -8,6 +8,8 @@ >> >> #pragma once >> >> +#include <libcamera/control_ids.h> >> + >> #include <gst/gst.h> >> >> G_BEGIN_DECLS >> @@ -17,3 +19,32 @@ G_DECLARE_FINAL_TYPE(GstLibcameraSrc, gst_libcamera_src, >> GST_LIBCAMERA, SRC, GstElement) >> >> G_END_DECLS >> + >> +inline GType >> +gst_libcamera_auto_focus_get_type() >> +{ >> + static GType type = 0; >> + static const GEnumValue values[] = { >> + { >> + static_cast<gint>(libcamera::controls::AfModeManual), >> + "AfModeManual", >> + "manual-focus", >> + }, >> + { >> + static_cast<gint>(libcamera::controls::AfModeAuto), >> + "AfModeAuto", >> + "automatic-auto-focus", >> + }, >> + { >> + static_cast<gint>(libcamera::controls::AfModeContinuous), >> + "AfModeContinuous", >> + "continuous-auto-focus", >> + }, >> + { 0, NULL, NULL } >> + }; >> + >> + if (!type) >> + type = g_enum_register_static("GstLibcameraAutoFocus", values); >> + >> + return type; >> +} >
diff --git a/src/gstreamer/gstlibcameraprovider.cpp b/src/gstreamer/gstlibcameraprovider.cpp index 6eb0a0eb..d9216046 100644 --- a/src/gstreamer/gstlibcameraprovider.cpp +++ b/src/gstreamer/gstlibcameraprovider.cpp @@ -31,6 +31,7 @@ GST_DEBUG_CATEGORY_STATIC(provider_debug); enum { PROP_DEVICE_NAME = 1, + PROP_AUTO_FOCUS_MODE = 2, }; #define GST_TYPE_LIBCAMERA_DEVICE gst_libcamera_device_get_type() @@ -40,6 +41,7 @@ G_DECLARE_FINAL_TYPE(GstLibcameraDevice, gst_libcamera_device, struct _GstLibcameraDevice { GstDevice parent; gchar *name; + controls::AfModeEnum auto_focus_mode = controls::AfModeManual; }; G_DEFINE_TYPE(GstLibcameraDevice, gst_libcamera_device, GST_TYPE_DEVICE) @@ -56,6 +58,7 @@ gst_libcamera_device_create_element(GstDevice *device, const gchar *name) g_assert(source); g_object_set(source, "camera-name", GST_LIBCAMERA_DEVICE(device)->name, nullptr); + g_object_set(source, "auto-focus-mode", GST_LIBCAMERA_DEVICE(device)->auto_focus_mode, nullptr); return source; } @@ -82,6 +85,9 @@ gst_libcamera_device_set_property(GObject *object, guint prop_id, case PROP_DEVICE_NAME: device->name = g_value_dup_string(value); break; + case PROP_AUTO_FOCUS_MODE: + device->auto_focus_mode = static_cast<controls::AfModeEnum>(g_value_get_enum(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -121,6 +127,14 @@ gst_libcamera_device_class_init(GstLibcameraDeviceClass *klass) (GParamFlags)(G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property(object_class, PROP_DEVICE_NAME, pspec); + pspec = g_param_spec_enum("auto-focus-mode", + "Set auto-focus mode", + "Available options: AfModeManual, " + "AfModeAuto or AfModeContinuous.", + gst_libcamera_auto_focus_get_type(), + static_cast<gint>(controls::AfModeManual), + G_PARAM_WRITABLE); + g_object_class_install_property(object_class, PROP_AUTO_FOCUS_MODE, pspec); } static GstDevice * diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index a10cbd4f..47d8ff43 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -146,6 +146,7 @@ struct _GstLibcameraSrc { GstTask *task; gchar *camera_name; + controls::AfModeEnum auto_focus_mode = controls::AfModeManual; GstLibcameraSrcState *state; GstLibcameraAllocator *allocator; @@ -154,7 +155,8 @@ struct _GstLibcameraSrc { enum { PROP_0, - PROP_CAMERA_NAME + PROP_CAMERA_NAME, + PROP_AUTO_FOCUS_MODE, }; G_DEFINE_TYPE_WITH_CODE(GstLibcameraSrc, gst_libcamera_src, GST_TYPE_ELEMENT, @@ -577,6 +579,18 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread, gst_flow_combiner_add_pad(self->flow_combiner, srcpad); } + if (self->auto_focus_mode != controls::AfModeManual) { + const ControlInfoMap &infoMap = state->cam_->controls(); + if (infoMap.find(&controls::AfMode) != infoMap.end()) { + state->initControls_.set(controls::AfMode, self->auto_focus_mode); + } else { + GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS, + ("Failed to enable auto focus"), + ("AfMode not supported by this camera, " + "please retry with 'auto-focus-mode=AfModeManual'")); + } + } + ret = state->cam_->start(&state->initControls_); if (ret) { GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS, @@ -659,6 +673,9 @@ gst_libcamera_src_set_property(GObject *object, guint prop_id, g_free(self->camera_name); self->camera_name = g_value_dup_string(value); break; + case PROP_AUTO_FOCUS_MODE: + self->auto_focus_mode = static_cast<controls::AfModeEnum>(g_value_get_enum(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -676,6 +693,9 @@ gst_libcamera_src_get_property(GObject *object, guint prop_id, GValue *value, case PROP_CAMERA_NAME: g_value_set_string(value, self->camera_name); break; + case PROP_AUTO_FOCUS_MODE: + g_value_set_enum(value, static_cast<gint>(self->auto_focus_mode)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -844,4 +864,13 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass) | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property(object_class, PROP_CAMERA_NAME, spec); + + spec = g_param_spec_enum("auto-focus-mode", + "Set auto-focus mode", + "Available options: AfModeManual, " + "AfModeAuto or AfModeContinuous.", + gst_libcamera_auto_focus_get_type(), + static_cast<gint>(controls::AfModeManual), + G_PARAM_WRITABLE); + g_object_class_install_property(object_class, PROP_AUTO_FOCUS_MODE, spec); } diff --git a/src/gstreamer/gstlibcamerasrc.h b/src/gstreamer/gstlibcamerasrc.h index fdea2f10..0a88ba02 100644 --- a/src/gstreamer/gstlibcamerasrc.h +++ b/src/gstreamer/gstlibcamerasrc.h @@ -8,6 +8,8 @@ #pragma once +#include <libcamera/control_ids.h> + #include <gst/gst.h> G_BEGIN_DECLS @@ -17,3 +19,32 @@ G_DECLARE_FINAL_TYPE(GstLibcameraSrc, gst_libcamera_src, GST_LIBCAMERA, SRC, GstElement) G_END_DECLS + +inline GType +gst_libcamera_auto_focus_get_type() +{ + static GType type = 0; + static const GEnumValue values[] = { + { + static_cast<gint>(libcamera::controls::AfModeManual), + "AfModeManual", + "manual-focus", + }, + { + static_cast<gint>(libcamera::controls::AfModeAuto), + "AfModeAuto", + "automatic-auto-focus", + }, + { + static_cast<gint>(libcamera::controls::AfModeContinuous), + "AfModeContinuous", + "continuous-auto-focus", + }, + { 0, NULL, NULL } + }; + + if (!type) + type = g_enum_register_static("GstLibcameraAutoFocus", values); + + return type; +}
Cameras such as the PiCam 3 support auto-focus, but the GStreamer plugin for libcamera does not enable auto-focus. With this patch auto-focus can be enabled for cameras that support it. By default it is disabled, which means default behaviour remains unchanged. For cameras that do not support auto-focus, an error message shows up if auto-focus is enabled. This was tested on cameras that do not support auto-focus (e.g. PiCam2) and was tested on a camera that does support auto-focus (PiCam3). The test involved setting the focus to AfModeContinous and observing it. However, by not setting "auto-focus-mode" or using AfModeManual as the "auto-focus-mode" both resulting in auto-focus being disabled. Bug: https://bugs.libcamera.org/show_bug.cgi?id=188 Signed-off-by: Cedric Nugteren <web@cedricnugteren.nl> --- Changes since v1: - Now re-using the GParamSpec variables instead of re-creating. - Use bool instead of gboolean for enable_auto_focus. - Remove changes from the reconfigure_element functions. Changes since v2: - Fix a typo in the commit message (remove 'it'). - Fix the link to the actual bug. - Apply the style suggestions of utils/checkstyle.py. - Start the commit message with 'gstreamer:'. - Change the boolean to a 3-option AfMode enum and change variable names and strings accordingly. Changes since v3: - Removed a period at the end of the bug link. - Split the long sentence in the commit message in three parts. - Remove unnecessary use of "libcamera::". - Use controls::AfModeEnum enum instead of int. - Add a newline before 'g_param_spec_enum'. --- src/gstreamer/gstlibcameraprovider.cpp | 14 ++++++++++++ src/gstreamer/gstlibcamerasrc.cpp | 31 +++++++++++++++++++++++++- src/gstreamer/gstlibcamerasrc.h | 31 ++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-)