From patchwork Thu Jun 22 11:17:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 18757 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 92BACC3237 for ; Thu, 22 Jun 2023 11:17:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EA12C61E40; Thu, 22 Jun 2023 13:17:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1687432647; bh=hx3CRN8TIsb5RH2JzUgcjhX4mDe8eFsmw6PV2no4Tbo=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=q9lOwyMLt6OajpCpK4VL1TZ0K1vu33ITGLXARMcQdmtrHD8xYlYCJRSmZqMmsb+Vf RfuTlu2GwsDPBGf5pw5KO0nhVsK9Q54f/yRiWzb6pDUmmjM9ngVFIDajipNycUkfeh LtCcFs4dG5gQXFDEfPa0aItSkcMcIYl9qyH57AcAYLhbA3Mwjv5gu2NlWzBWDJpHIk K8Et8q5aRRC7aREFwe+VAnYIzsGykmWbsaYqDjAJqFk2QUgyDNDlbmvfO7gu3xo15i 6AP8yFl7rKq4OCVBwe04YxUo0iOsfOpeKGF8CgsUZq+P1qMO4gi+KSnfdJ8cM3oUYW yS9HfMPiQgCgw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8ECF26002B for ; Thu, 22 Jun 2023 13:17:26 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="lUU2ljTC"; dkim-atps=neutral Received: from umang.jainideasonboard.com (unknown [103.95.123.182]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DCC384DE; Thu, 22 Jun 2023 13:16:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1687432610; bh=hx3CRN8TIsb5RH2JzUgcjhX4mDe8eFsmw6PV2no4Tbo=; h=From:To:Cc:Subject:Date:From; b=lUU2ljTCJrUnRVI6+LKpDcoTlE0S1MLinjFHX2MeF2tkMvSYvDAs/BFG4eoqaEXFr ATMuS+RMx/0MOCysAyKEOLvhKu64C3gT+b87Dle1IAJUE4t7S8wz59AC7DSMV0qhHB 5nZHQWKwRZU+GVODgn7t9UoKHfQl89iHiFk2ewIw= To: libcamera-devel@lists.libcamera.org Date: Thu, 22 Jun 2023 16:47:17 +0530 Message-Id: <20230622111717.32236-1-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.39.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH] 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 , 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, abort early 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 --- Cedric, Can you please help test this? (I'm travelling so have tested this on my RPi and inferring from libcamera/gstreamer logs, it seems to have not broken anything) An additional test from your side would be appreciated. --- src/gstreamer/gstlibcamerasrc.cpp | 45 ++++++++++++++++++++++--------- src/gstreamer/gstlibcamerasrc.h | 6 ++--- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index 47d8ff43..a2266310 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -146,7 +146,7 @@ struct _GstLibcameraSrc { GstTask *task; gchar *camera_name; - controls::AfModeEnum auto_focus_mode = controls::AfModeManual; + ControlList *controls; GstLibcameraSrcState *state; GstLibcameraAllocator *allocator; @@ -462,7 +462,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"); @@ -579,18 +581,31 @@ 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 the controls set on libcamerasrc is supported by the camera. + * This can be easily done by CameraControlValidator but it is an internal + * libcamera class. Hence avoid adding a internal header even though + * gstreamer links with libcamera-private. + */ + 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; + break; } } + 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, @@ -674,7 +689,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); @@ -693,9 +709,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; @@ -760,6 +778,7 @@ gst_libcamera_src_finalize(GObject *object) g_rec_mutex_clear(&self->stream_lock); g_clear_object(&self->task); g_free(self->camera_name); + delete self->controls; delete self->state; return klass->finalize(object); @@ -783,6 +802,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", },