Skip to content

Commit 5a14243

Browse files
Cedric NugterenUmang Jain
Cedric Nugteren
authored and
Umang Jain
committed
gstreamer: Add enable_auto_focus option to the GStreamer plugin
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 <cedric@plumerai.com> 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> Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
1 parent b9113a8 commit 5a14243

File tree

3 files changed

+76
-1
lines changed

3 files changed

+76
-1
lines changed

src/gstreamer/gstlibcameraprovider.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ GST_DEBUG_CATEGORY_STATIC(provider_debug);
3131

3232
enum {
3333
PROP_DEVICE_NAME = 1,
34+
PROP_AUTO_FOCUS_MODE = 2,
3435
};
3536

3637
#define GST_TYPE_LIBCAMERA_DEVICE gst_libcamera_device_get_type()
@@ -40,6 +41,7 @@ G_DECLARE_FINAL_TYPE(GstLibcameraDevice, gst_libcamera_device,
4041
struct _GstLibcameraDevice {
4142
GstDevice parent;
4243
gchar *name;
44+
controls::AfModeEnum auto_focus_mode = controls::AfModeManual;
4345
};
4446

4547
G_DEFINE_TYPE(GstLibcameraDevice, gst_libcamera_device, GST_TYPE_DEVICE)
@@ -56,6 +58,7 @@ gst_libcamera_device_create_element(GstDevice *device, const gchar *name)
5658
g_assert(source);
5759

5860
g_object_set(source, "camera-name", GST_LIBCAMERA_DEVICE(device)->name, nullptr);
61+
g_object_set(source, "auto-focus-mode", GST_LIBCAMERA_DEVICE(device)->auto_focus_mode, nullptr);
5962

6063
return source;
6164
}
@@ -82,6 +85,9 @@ gst_libcamera_device_set_property(GObject *object, guint prop_id,
8285
case PROP_DEVICE_NAME:
8386
device->name = g_value_dup_string(value);
8487
break;
88+
case PROP_AUTO_FOCUS_MODE:
89+
device->auto_focus_mode = static_cast<controls::AfModeEnum>(g_value_get_enum(value));
90+
break;
8591
default:
8692
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
8793
break;
@@ -121,6 +127,15 @@ gst_libcamera_device_class_init(GstLibcameraDeviceClass *klass)
121127
(GParamFlags)(G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE |
122128
G_PARAM_CONSTRUCT_ONLY));
123129
g_object_class_install_property(object_class, PROP_DEVICE_NAME, pspec);
130+
131+
pspec = g_param_spec_enum("auto-focus-mode",
132+
"Set auto-focus mode",
133+
"Available options: AfModeManual, "
134+
"AfModeAuto or AfModeContinuous.",
135+
gst_libcamera_auto_focus_get_type(),
136+
static_cast<gint>(controls::AfModeManual),
137+
G_PARAM_WRITABLE);
138+
g_object_class_install_property(object_class, PROP_AUTO_FOCUS_MODE, pspec);
124139
}
125140

126141
static GstDevice *

src/gstreamer/gstlibcamerasrc.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ struct _GstLibcameraSrc {
146146
GstTask *task;
147147

148148
gchar *camera_name;
149+
controls::AfModeEnum auto_focus_mode = controls::AfModeManual;
149150

150151
GstLibcameraSrcState *state;
151152
GstLibcameraAllocator *allocator;
@@ -154,7 +155,8 @@ struct _GstLibcameraSrc {
154155

155156
enum {
156157
PROP_0,
157-
PROP_CAMERA_NAME
158+
PROP_CAMERA_NAME,
159+
PROP_AUTO_FOCUS_MODE,
158160
};
159161

160162
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,
577579
gst_flow_combiner_add_pad(self->flow_combiner, srcpad);
578580
}
579581

582+
if (self->auto_focus_mode != controls::AfModeManual) {
583+
const ControlInfoMap &infoMap = state->cam_->controls();
584+
if (infoMap.find(&controls::AfMode) != infoMap.end()) {
585+
state->initControls_.set(controls::AfMode, self->auto_focus_mode);
586+
} else {
587+
GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS,
588+
("Failed to enable auto focus"),
589+
("AfMode not supported by this camera, "
590+
"please retry with 'auto-focus-mode=AfModeManual'"));
591+
}
592+
}
593+
580594
ret = state->cam_->start(&state->initControls_);
581595
if (ret) {
582596
GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS,
@@ -659,6 +673,9 @@ gst_libcamera_src_set_property(GObject *object, guint prop_id,
659673
g_free(self->camera_name);
660674
self->camera_name = g_value_dup_string(value);
661675
break;
676+
case PROP_AUTO_FOCUS_MODE:
677+
self->auto_focus_mode = static_cast<controls::AfModeEnum>(g_value_get_enum(value));
678+
break;
662679
default:
663680
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
664681
break;
@@ -676,6 +693,9 @@ gst_libcamera_src_get_property(GObject *object, guint prop_id, GValue *value,
676693
case PROP_CAMERA_NAME:
677694
g_value_set_string(value, self->camera_name);
678695
break;
696+
case PROP_AUTO_FOCUS_MODE:
697+
g_value_set_enum(value, static_cast<gint>(self->auto_focus_mode));
698+
break;
679699
default:
680700
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
681701
break;
@@ -844,4 +864,13 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass)
844864
| G_PARAM_READWRITE
845865
| G_PARAM_STATIC_STRINGS));
846866
g_object_class_install_property(object_class, PROP_CAMERA_NAME, spec);
867+
868+
spec = g_param_spec_enum("auto-focus-mode",
869+
"Set auto-focus mode",
870+
"Available options: AfModeManual, "
871+
"AfModeAuto or AfModeContinuous.",
872+
gst_libcamera_auto_focus_get_type(),
873+
static_cast<gint>(controls::AfModeManual),
874+
G_PARAM_WRITABLE);
875+
g_object_class_install_property(object_class, PROP_AUTO_FOCUS_MODE, spec);
847876
}

src/gstreamer/gstlibcamerasrc.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#pragma once
1010

11+
#include <libcamera/control_ids.h>
12+
1113
#include <gst/gst.h>
1214

1315
G_BEGIN_DECLS
@@ -17,3 +19,32 @@ G_DECLARE_FINAL_TYPE(GstLibcameraSrc, gst_libcamera_src,
1719
GST_LIBCAMERA, SRC, GstElement)
1820

1921
G_END_DECLS
22+
23+
inline GType
24+
gst_libcamera_auto_focus_get_type()
25+
{
26+
static GType type = 0;
27+
static const GEnumValue values[] = {
28+
{
29+
static_cast<gint>(libcamera::controls::AfModeManual),
30+
"AfModeManual",
31+
"manual-focus",
32+
},
33+
{
34+
static_cast<gint>(libcamera::controls::AfModeAuto),
35+
"AfModeAuto",
36+
"automatic-auto-focus",
37+
},
38+
{
39+
static_cast<gint>(libcamera::controls::AfModeContinuous),
40+
"AfModeContinuous",
41+
"continuous-auto-focus",
42+
},
43+
{ 0, NULL, NULL }
44+
};
45+
46+
if (!type)
47+
type = g_enum_register_static("GstLibcameraAutoFocus", values);
48+
49+
return type;
50+
}

0 commit comments

Comments
 (0)