From patchwork Thu Jun 29 07:11:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 18766 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 21F5DBDB1D for ; Thu, 29 Jun 2023 07:11:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9C15F628BC; Thu, 29 Jun 2023 09:11:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1688022687; bh=89gHMJ7T1ZWsCNiFic6BFlznnyVvLlKK0zAnyDBPPyc=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=aoWwPF1B9O/JkqVfVXQOCMVauiF0uQbdXkQuckGY8KHpw68F8X60FSmS4+Cyb3hAT hsoq3k7tKKVziGiQK/4NF/dqNrHRJ/FV5JHQY1OAtED/NdMOJvHgjzritAW0a1MeCJ 6Vv53QdlvYU4vcpqTzM+J3qKzZHluru3s23Dhh+WSPFRtCW2QZcS7abLRSO5NW+rYJ mah9szKRUfvsMQzaZVPrlr7lcTD6DNeZLGnicx6Xp0ubBFq/oujX5doEeKscSQwoUA W/VEcecPpGYic0cav0Z07y/Llzp+StBrjq8RABv2nVKMnVHjb/C9ejq8PZmmDHKh9e BguyvIf7gMs2Q== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9CBF760576 for ; Thu, 29 Jun 2023 09:11:26 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="OzC1TztI"; dkim-atps=neutral Received: from umang.jainideasonboard.com (85-160-58-109.reb.o2.cz [85.160.58.109]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7B9EDA4C; Thu, 29 Jun 2023 09:10:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1688022645; bh=89gHMJ7T1ZWsCNiFic6BFlznnyVvLlKK0zAnyDBPPyc=; h=From:To:Cc:Subject:Date:From; b=OzC1TztI9iXn6i7CebJ/2MXb4/QZl3rKHF6qCl9bztAyqz5IJUFMupd/gqL/CrdEn C9Rb3Ay8JcQk71b8k/Fc4SdRhccMRqmPQzd3nwjavd8Zvtdw8B80VOd6X/Dio8lrhQ rvjasqrc/8YN4OZDdYX2aKdx40mzsNrBpwMerxPM= To: libcamera-devel@lists.libcamera.org Date: Thu, 29 Jun 2023 09:11:21 +0200 Message-Id: <20230629071121.21459-1-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.39.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4] gstreamer: Maintain a control list to track libcamerasrc control properties X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Umang Jain via libcamera-devel From: Umang Jain Reply-To: Umang Jain Cc: Cedric Nugteren Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" 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. 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, auto-focus-mode, to be set directly in control list. Signed-off-by: Umang Jain Reviewed-by: Kieran Bingham --- 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. */ + 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(g_value_get_enum(value)); + self->controls->set(controls::AfMode, + static_cast(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(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(libcamera::controls::AfModeManual), + libcamera::controls::AfModeManual, "AfModeManual", "manual-focus", }, { - static_cast(libcamera::controls::AfModeAuto), + libcamera::controls::AfModeAuto, "AfModeAuto", "automatic-auto-focus", }, { - static_cast(libcamera::controls::AfModeContinuous), + libcamera::controls::AfModeContinuous, "AfModeContinuous", "continuous-auto-focus", },