Message ID | 20230609143142.77049-1-web@cedricnugteren.nl |
---|---|
State | Accepted |
Headers | show |
Series |
|
Related | show |
Hey, Can confirm it helps my v3 camera to focus. Together with patches to set hflip/vflip (to rotate 180°) and setting flicker mode, the v3 is better than v2 was with gstreamer's rpicamsrc. I don't need to use a screwdriver any more to set a fixed focus. :-) Reviewed-by: Maarten Lankhorst <dev@lankhorst.se> On 2023-06-09 16:31, Cedric Nugteren via libcamera-devel wrote: > Subject: > [libcamera-devel] [PATCH v3] gstreamer: Add enable_auto_focus option to the GStreamer plugin > From: > Cedric Nugteren via libcamera-devel <libcamera-devel@lists.libcamera.org> > Date: > 2023-06-09 16:31 > > To: > libcamera-devel@lists.libcamera.org > CC: > Cedric Nugteren <web@cedricnugteren.nl> > > > 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) by > setting it to AfModeContinous, observing auto-focus, and by setting it > to AfModeManual or by not setting the option, 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. > > --- > src/gstreamer/gstlibcameraprovider.cpp | 14 ++++++++++++ > src/gstreamer/gstlibcamerasrc.cpp | 30 ++++++++++++++++++++++++- > src/gstreamer/gstlibcamerasrc.h | 31 ++++++++++++++++++++++++++ > 3 files changed, 74 insertions(+), 1 deletion(-) > > diff --git a/src/gstreamer/gstlibcameraprovider.cpp b/src/gstreamer/gstlibcameraprovider.cpp > index 6eb0a0eb..aece3506 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; > + int auto_focus_mode = libcamera::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<int>(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>(libcamera::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..cfb8f70c 100644 > --- a/src/gstreamer/gstlibcamerasrc.cpp > +++ b/src/gstreamer/gstlibcamerasrc.cpp > @@ -146,6 +146,7 @@ struct _GstLibcameraSrc { > GstTask *task; > > gchar *camera_name; > + int auto_focus_mode = libcamera::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 != libcamera::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<int>(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,12 @@ 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>(libcamera::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; > +} > -- 2.34.1
Hi Cedric, Thank you for taking this on. Quoting Cedric Nugteren via libcamera-devel (2023-06-09 15:31:42) > 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) by > setting it to AfModeContinous, observing auto-focus, and by setting it > to AfModeManual or by not setting the option, both resulting in > auto-focus being disabled. > > Bug: https://bugs.libcamera.org/show_bug.cgi?id=188. No period required at the end of a link. I can remove that when we get to applying. I don't think we need another version of this patch. > 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. > > --- > src/gstreamer/gstlibcameraprovider.cpp | 14 ++++++++++++ > src/gstreamer/gstlibcamerasrc.cpp | 30 ++++++++++++++++++++++++- > src/gstreamer/gstlibcamerasrc.h | 31 ++++++++++++++++++++++++++ > 3 files changed, 74 insertions(+), 1 deletion(-) > > diff --git a/src/gstreamer/gstlibcameraprovider.cpp b/src/gstreamer/gstlibcameraprovider.cpp > index 6eb0a0eb..aece3506 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; > + int auto_focus_mode = libcamera::controls::AfModeManual; I think this could be an enum ... it would be controls::AfModeEnum ... I think we can also drop the libcamera:: namespace as we have a 'using namespace libcamera;' statement in the file. Doing so here produces the following diff: diff --git a/src/gstreamer/gstlibcameraprovider.cpp b/src/gstreamer/gstlibcameraprovider.cpp index aece3506653f..d92160460f91 100644 --- a/src/gstreamer/gstlibcameraprovider.cpp +++ b/src/gstreamer/gstlibcameraprovider.cpp @@ -41,7 +41,7 @@ G_DECLARE_FINAL_TYPE(GstLibcameraDevice, gst_libcamera_device, struct _GstLibcameraDevice { GstDevice parent; gchar *name; - int auto_focus_mode = libcamera::controls::AfModeManual; + controls::AfModeEnum auto_focus_mode = controls::AfModeManual; }; G_DEFINE_TYPE(GstLibcameraDevice, gst_libcamera_device, GST_TYPE_DEVICE) @@ -86,7 +86,7 @@ gst_libcamera_device_set_property(GObject *object, guint prop_id, device->name = g_value_dup_string(value); break; case PROP_AUTO_FOCUS_MODE: - device->auto_focus_mode = static_cast<int>(g_value_get_enum(value)); + 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); @@ -132,7 +132,7 @@ gst_libcamera_device_class_init(GstLibcameraDeviceClass *klass) "Available options: AfModeManual, " "AfModeAuto or AfModeContinuous.", gst_libcamera_auto_focus_get_type(), - static_cast<gint>(libcamera::controls::AfModeManual), + static_cast<gint>(controls::AfModeManual), G_PARAM_WRITABLE); g_object_class_install_property(object_class, PROP_AUTO_FOCUS_MODE, pspec); } diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index cfb8f70c69b7..78e7422b337a 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -146,7 +146,7 @@ struct _GstLibcameraSrc { GstTask *task; gchar *camera_name; - int auto_focus_mode = libcamera::controls::AfModeManual; + controls::AfModeEnum auto_focus_mode = controls::AfModeManual; GstLibcameraSrcState *state; GstLibcameraAllocator *allocator; @@ -579,7 +579,7 @@ 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 != libcamera::controls::AfModeManual) { + 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); @@ -674,7 +674,7 @@ gst_libcamera_src_set_property(GObject *object, guint prop_id, self->camera_name = g_value_dup_string(value); break; case PROP_AUTO_FOCUS_MODE: - self->auto_focus_mode = static_cast<int>(g_value_get_enum(value)); + 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); @@ -869,7 +869,7 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass) "Available options: AfModeManual, " "AfModeAuto or AfModeContinuous.", gst_libcamera_auto_focus_get_type(), - static_cast<gint>(libcamera::controls::AfModeManual), + static_cast<gint>(controls::AfModeManual), G_PARAM_WRITABLE); g_object_class_install_property(object_class, PROP_AUTO_FOCUS_MODE, spec); } Some lines get longer, some get shorter ;-) Anyway, either with or without the above diff suggestion, it looks to me like you've catered for all of Nicholas' previous review comments and I don't have anything more than the diff above so: Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > }; > > 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<int>(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>(libcamera::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..cfb8f70c 100644 > --- a/src/gstreamer/gstlibcamerasrc.cpp > +++ b/src/gstreamer/gstlibcamerasrc.cpp > @@ -146,6 +146,7 @@ struct _GstLibcameraSrc { > GstTask *task; > > gchar *camera_name; > + int auto_focus_mode = libcamera::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 != libcamera::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<int>(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,12 @@ 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>(libcamera::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; > +} > -- > 2.34.1 >
Hi Cedric On 6/9/23 8:01 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) by > setting it to AfModeContinous, observing auto-focus, and by setting it > to AfModeManual or by not setting the option, both resulting in > auto-focus being disabled. This is a very long sentence - probably worth splitting it out. ``` 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. > > --- > src/gstreamer/gstlibcameraprovider.cpp | 14 ++++++++++++ > src/gstreamer/gstlibcamerasrc.cpp | 30 ++++++++++++++++++++++++- > src/gstreamer/gstlibcamerasrc.h | 31 ++++++++++++++++++++++++++ > 3 files changed, 74 insertions(+), 1 deletion(-) > > diff --git a/src/gstreamer/gstlibcameraprovider.cpp b/src/gstreamer/gstlibcameraprovider.cpp > index 6eb0a0eb..aece3506 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; > + int auto_focus_mode = libcamera::controls::AfModeManual; Probably enums as Kieran pointed out. > }; > > 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<int>(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>(libcamera::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..cfb8f70c 100644 > --- a/src/gstreamer/gstlibcamerasrc.cpp > +++ b/src/gstreamer/gstlibcamerasrc.cpp > @@ -146,6 +146,7 @@ struct _GstLibcameraSrc { > GstTask *task; > > gchar *camera_name; > + int auto_focus_mode = libcamera::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 != libcamera::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<int>(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,12 @@ 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", new line ? Rest looks good to me: Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> > + "Set auto-focus mode", > + "Available options: AfModeManual, " > + "AfModeAuto or AfModeContinuous.", > + gst_libcamera_auto_focus_get_type(), > + static_cast<gint>(libcamera::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/9/23 8:01 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) by > setting it to AfModeContinous, observing auto-focus, and by setting it > to AfModeManual or by not setting the option, 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> I have tested it as well on raspberrypi Pi with PDAF supported IMX519. So I think the plumbing is correct and just needs to address the comments. 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. > > --- > src/gstreamer/gstlibcameraprovider.cpp | 14 ++++++++++++ > src/gstreamer/gstlibcamerasrc.cpp | 30 ++++++++++++++++++++++++- > src/gstreamer/gstlibcamerasrc.h | 31 ++++++++++++++++++++++++++ > 3 files changed, 74 insertions(+), 1 deletion(-) > > diff --git a/src/gstreamer/gstlibcameraprovider.cpp b/src/gstreamer/gstlibcameraprovider.cpp > index 6eb0a0eb..aece3506 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; > + int auto_focus_mode = libcamera::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<int>(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>(libcamera::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..cfb8f70c 100644 > --- a/src/gstreamer/gstlibcamerasrc.cpp > +++ b/src/gstreamer/gstlibcamerasrc.cpp > @@ -146,6 +146,7 @@ struct _GstLibcameraSrc { > GstTask *task; > > gchar *camera_name; > + int auto_focus_mode = libcamera::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 != libcamera::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<int>(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,12 @@ 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>(libcamera::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..aece3506 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; + int auto_focus_mode = libcamera::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<int>(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>(libcamera::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..cfb8f70c 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -146,6 +146,7 @@ struct _GstLibcameraSrc { GstTask *task; gchar *camera_name; + int auto_focus_mode = libcamera::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 != libcamera::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<int>(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,12 @@ 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>(libcamera::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) by setting it to AfModeContinous, observing auto-focus, and by setting it to AfModeManual or by not setting the option, 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. --- src/gstreamer/gstlibcameraprovider.cpp | 14 ++++++++++++ src/gstreamer/gstlibcamerasrc.cpp | 30 ++++++++++++++++++++++++- src/gstreamer/gstlibcamerasrc.h | 31 ++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-)