[libcamera-devel] [PATCH v4] gstreamer: Maintain a control list to track libcamerasrc control properties
Kieran Bingham
kieran.bingham at ideasonboard.com
Thu Jun 29 12:21:58 CEST 2023
Quoting Umang Jain via libcamera-devel (2023-06-29 08:11:21)
> As more and more libcamera controls get plumbed, more member variables
> get introduced in struct GstLibcameraSrc. Instead of doing that, now
> maintain a single ControlList which is more appropriate to keep track
> of controls that get sets on libcamerasrc.
/sets/set/
>
> This also brings easy validation of controls set on libcamerasrc. If
> the controls are not supported by camera, fail negotiation and report
> what is not supported.
>
> The current patch migrates previously introduced control,
/migrates previously/migrates the previously/
> auto-focus-mode, to be set directly in control list.
/in control list/in the control list/
>
> Signed-off-by: Umang Jain <umang.jain at ideasonboard.com>
> ---
> src/gstreamer/gstlibcamerasrc.cpp | 39 +++++++++++++++++++++----------
> src/gstreamer/gstlibcamerasrc.h | 6 ++---
> 2 files changed, 30 insertions(+), 15 deletions(-)
>
> diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
> index f764a87a..1f10136b 100644
> --- a/src/gstreamer/gstlibcamerasrc.cpp
> +++ b/src/gstreamer/gstlibcamerasrc.cpp
> @@ -142,7 +142,7 @@ struct _GstLibcameraSrc {
> GstTask *task;
>
> gchar *camera_name;
> - controls::AfModeEnum auto_focus_mode = controls::AfModeManual;
> + ControlList *controls;
>
> GstLibcameraSrcState *state;
> GstLibcameraAllocator *allocator;
> @@ -458,7 +458,9 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread,
> GstLibcameraSrc *self = GST_LIBCAMERA_SRC(user_data);
> GLibRecLocker lock(&self->stream_lock);
> GstLibcameraSrcState *state = self->state;
> + const ControlInfoMap &info_map = state->cam_->controls();
> GstFlowReturn flow_ret = GST_FLOW_OK;
> + gboolean supported_ctrl = true;
> gint ret;
>
> g_autoptr(GstStructure) element_caps = gst_structure_new_empty("caps");
> @@ -575,18 +577,25 @@ 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 {
> + /* Check if the controls set on libcamerasrc is supported by the camera. */
/is/are/
Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> + for (auto iter = self->controls->begin(); iter != self->controls->end(); iter++) {
> + if (info_map.find(iter->first) == info_map.end()) {
> + const ControlIdMap *id_map = self->controls->idMap();
> GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS,
> - ("Failed to enable auto focus"),
> - ("AfMode not supported by this camera, "
> - "please retry with 'auto-focus-mode=AfModeManual'"));
> + ("Failed to set %s", id_map->at(iter->first)->name().c_str()),
> + ("%s not supported by this camera, ", id_map->at(iter->first)->name().c_str()));
> + supported_ctrl = false;
> }
> }
>
> + if (!supported_ctrl) {
> + gst_task_stop(task);
> + flow_ret = GST_FLOW_NOT_NEGOTIATED;
> + goto done;
> + }
> +
> + state->initControls_.merge(*self->controls);
> +
> ret = state->cam_->start(&state->initControls_);
> if (ret) {
> GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS,
> @@ -670,7 +679,8 @@ 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<controls::AfModeEnum>(g_value_get_enum(value));
> + self->controls->set(controls::AfMode,
> + static_cast<controls::AfModeEnum>(g_value_get_enum(value)));
> break;
> default:
> G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
> @@ -689,9 +699,11 @@ 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));
> + case PROP_AUTO_FOCUS_MODE: {
> + auto auto_focus_mode = self->controls->get(controls::AfMode).value_or(controls::AfModeManual);
> + g_value_set_enum(value, auto_focus_mode);
> break;
> + }
> default:
> G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
> break;
> @@ -757,6 +769,7 @@ gst_libcamera_src_finalize(GObject *object)
> g_clear_object(&self->task);
> g_mutex_clear(&self->state->lock_);
> g_free(self->camera_name);
> + delete self->controls;
> delete self->state;
>
> return klass->finalize(object);
> @@ -782,6 +795,8 @@ gst_libcamera_src_init(GstLibcameraSrc *self)
> /* C-style friend. */
> state->src_ = self;
> self->state = state;
> +
> + self->controls = new ControlList(controls::controls, nullptr);
> }
>
> static GstPad *
> diff --git a/src/gstreamer/gstlibcamerasrc.h b/src/gstreamer/gstlibcamerasrc.h
> index 0a88ba02..2e6d74cb 100644
> --- a/src/gstreamer/gstlibcamerasrc.h
> +++ b/src/gstreamer/gstlibcamerasrc.h
> @@ -26,17 +26,17 @@ gst_libcamera_auto_focus_get_type()
> static GType type = 0;
> static const GEnumValue values[] = {
> {
> - static_cast<gint>(libcamera::controls::AfModeManual),
> + libcamera::controls::AfModeManual,
> "AfModeManual",
> "manual-focus",
> },
> {
> - static_cast<gint>(libcamera::controls::AfModeAuto),
> + libcamera::controls::AfModeAuto,
> "AfModeAuto",
> "automatic-auto-focus",
> },
> {
> - static_cast<gint>(libcamera::controls::AfModeContinuous),
> + libcamera::controls::AfModeContinuous,
> "AfModeContinuous",
> "continuous-auto-focus",
> },
> --
> 2.39.1
>
More information about the libcamera-devel
mailing list