From patchwork Wed Jun 28 21:34:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 18765 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 115A4BDB1D for ; Wed, 28 Jun 2023 21:35:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 67D7E61E3B; Wed, 28 Jun 2023 23:34:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1687988099; bh=RSHVbzrhsU7phrA8rG2CCxif2Ir5mdahqkjp7tg2Ucs=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=hDBDQiVjBTETrhVYF/uOgxBeuL8o3M6NZ99jir1U6QJa1DJsSRhRF05Whw+IH5Xgt YDLy68EMBzCHp9sXAlirnaCx8+MnQZaQGlOyf1NACH8yis6F8fEexsB2mrKAdSWiOg QiC3Eu/jWW0p1enFhrKoNm8DH8LrXu/un7SJcUvJlnMzsdWFsGocaXH6ZFbPx7cKGT 5RdxCKxKd2aBYCQOfehe8JKY67dKeH0j3kqN1HhX1gKmAqykm5y++WtW3jBtdpi2DY 0J8HLFcFqfNg52y4oWEN1LXFw+0HAC/Pzzx+rt6M02CEBm4bunzZG/fA9w9Hh1UWmg 26CAr6HVRyhug== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CA0CF61E3B for ; Wed, 28 Jun 2023 23:34:57 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="hJ3Uumer"; 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 0081D9CA; Wed, 28 Jun 2023 23:34:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1687988057; bh=RSHVbzrhsU7phrA8rG2CCxif2Ir5mdahqkjp7tg2Ucs=; h=From:To:Cc:Subject:Date:From; b=hJ3Uumerpq0lF9Lg6mIAUCTDRzPVdostlnVl3gSWqS9rIvCgJyqeBL+c0y347WLeE /Vx0GQcBU++U3WYfjuyKDgrN0Zy4L1yxBYgG7u6FYv8vjn33WeTmf7zCGNlQ8lXNiq K1uXuf8VPRqs7oU1Rt4UEyB8YvxfgNofp3wE9dCE= To: libcamera-devel@lists.libcamera.org Date: Wed, 28 Jun 2023 23:34:52 +0200 Message-Id: <20230628213452.15531-1-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.39.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3] 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 --- Changes in v3: - Rebase over "[PATCH] gstreamer: Drop libcamera_private dependency" Changes in v2: - Edit commit message - Drop a break; so that all unsupported user-provided controls are reported at once. --- src/gstreamer/gstlibcamerasrc.cpp | 44 ++++++++++++++++++++++--------- src/gstreamer/gstlibcamerasrc.h | 6 ++--- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index f764a87a..b5c6e9ab 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,30 @@ 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; } } + 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 +684,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 +704,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 +774,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 +800,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", },