From patchwork Thu Nov 30 15:43:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jaslo Ziska X-Patchwork-Id: 19257 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 C61C8BDE6B for ; Thu, 30 Nov 2023 15:54:33 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 85495629C2; Thu, 30 Nov 2023 16:54:33 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1701359673; bh=sub7EUP7Zgfkfnw+cI5Q6+nxIAuZewzIe/zvYkn6eZk=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=rmnmvxSNHX9wyiNanZ7M8hc/auqAAW+MC3HPYopHyLTVOVtWtpFpR+2tUyFm3Jscx 7X3lNSocqXuTfb2S4XEAr46kWSyOak0431S8y4D5xBkdmUuwtTCBGe5AvCFx9aQSGc O4tK3g/mPqtCa0BxXy1Dczl3GOREYL3YQEcYbWN8O6yKasPty8Tcv9SIOAtKQ4w/eO oIkvyoQtkqzGIy4qr6vj8OCmIWVrJLtlI4/S1/CzNv1f2zCbApOglairNyNWC7kCIu VIrInmevsuJPgtvXU5i7y6uh1HghzckifSat6RPVL/wME//B+gCGq38ehpLNwea4gW R/wmjILcuaAyw== Received: from mo4-p00-ob.smtp.rzone.de (mo4-p00-ob.smtp.rzone.de [85.215.255.22]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5EAB361DA0 for ; Thu, 30 Nov 2023 16:54:31 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=ziska.de header.i=@ziska.de header.b="gfIWpS1c"; dkim=permerror (0-bit key) header.d=ziska.de header.i=@ziska.de header.b="c2EcKEd6"; dkim-atps=neutral ARC-Seal: i=1; a=rsa-sha256; t=1701359670; cv=none; d=strato.com; s=strato-dkim-0002; b=kRGk4cQdDddh28Z0QVurZV9LR6iOz5wE95ZNYuAqkkYVQJCdGw9BGoPXwiUR8ShzOW zRbgdJv6xeQFmIoWuanhNWAWPGDzIDr+4xITQZz1saz0r1rheDtHoQEhRR7bbUBFnQGU INixfJZWT++GzyVSYyTw0f0Kvq3OGJkebYd4aNxxMw0D8dUiW8i62gC846DfXM/PjoqP LDDf0fCQQiM2eP2nOyfsvqROF+LygBnYpVBmd6wqqOzUepJXik7aqNMcueKIultmVDhI mGMFtwEELorUsse6YVfc//t11nJbPL1HIbtAx6Ne/L/9UVOjAzILe3BWIHIxuCB1v8zI YNhg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1701359670; s=strato-dkim-0002; d=strato.com; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=Oyty/H1OP9OtthVhCEO8NVCcN5ESVTneZvxybMh1zCM=; b=JuhYXYQNxXt1jW9WOyyy0WN07gmxAKM+FPbuFaZhibWLc0kLqtRZSbt3UCKqdSdp+E 9Kn0SizapZDG4grcnm5dBYOD74xsFsUq1UJ/MASxybNTR9U0X7QzZ+FM9QETTWwIbszM BhLLPKp3QUIogmathxWPlEV3naOb1KrCeDypr4ZU7U5zANkQ2elNKBxOj0RX/YUlN4mb JjnTbTJlALTYAiw0etBJ5QrYn/Ce6OWIb6J6w3tZ8jsaN+ttYohmfYdDFDhQKp2Co60c csA7gUqTLkh6M1BgkPEK+Mp/xNigM4LGH1bXyYZIWnfcK9ajrMX+X/OqjBbP6hnFGf2G 67Ww== ARC-Authentication-Results: i=1; strato.com; arc=none; dkim=none X-RZG-CLASS-ID: mo00 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1701359670; s=strato-dkim-0002; d=ziska.de; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=Oyty/H1OP9OtthVhCEO8NVCcN5ESVTneZvxybMh1zCM=; b=gfIWpS1cPG8dLWRT87o7sS9WjSJhn0UK+Zyz8gp4r2BHMnc3Q7Hu0nfhnWwQCEt0i+ sHejkB6L/PfL9aTnjAtep10CPu1Hu+wd6tNZg+tRIRu7mP55QEgkJwISXdDKBD9wNh4E D2ML4RzyxYb1jab3/wU+RL/Je2IDIz9UAQNPEEiNhc2jiQlutIgXcbxvqVZtboL9NoKi ktga+2ydr8FBqRvp6HbC1eMVT03AGljLXS+9NOxkM/jFpxE86JHgFC6/xX0rs88aOdts pfnGZUWCD8g/R5MmcOZ7abN+vq3Z/4hiWEvOJRX53fJF5zGJj4qWkfhmfVZ9VZxUM/aO Mq5w== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; t=1701359670; s=strato-dkim-0003; d=ziska.de; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=Oyty/H1OP9OtthVhCEO8NVCcN5ESVTneZvxybMh1zCM=; b=c2EcKEd6WP55Tq2aC9kxRMiH4q53PTtoQY+mKvsaAvvJ0icfe8dJCbUiKuLHxhOTpI ZHGMA4bvOLw/BAIZWLBA== X-RZG-AUTH: ":Jm0XeU+IYfb0x77LHmrjN5Wlb7TBwusDqIM6Hizy8VdfzvKi4yoFC9cH04q6BfJa07bS3ov6I8QOM/V5x+uTrCUtBrk=" Received: from archlinux.fritz.box by smtp.strato.de (RZmta 49.9.7 AUTH) with ESMTPSA id n54b84zAUFsU0SA (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Thu, 30 Nov 2023 16:54:30 +0100 (CET) To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Nov 2023 16:43:08 +0100 Message-ID: <20231130155323.13259-2-jaslo@ziska.de> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231130155323.13259-1-jaslo@ziska.de> References: <20231130155323.13259-1-jaslo@ziska.de> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 1/3] gstreamer: Move negotiation logic to separate function 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: Jaslo Ziska via libcamera-devel From: Jaslo Ziska Reply-To: Jaslo Ziska Cc: Jaslo Ziska Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Move the code which negotiates all the source pad caps into a separate function called gst_libcamera_src_negotiate. When the negotiation fails this function will return FALSE and TRUE otherwise. Use this function instead of doing the negotiation manually in gst_libcamera_src_task_enter and remove the now redundant error handling code accordingly. Signed-off-by: Jaslo Ziska Reviewed-by: Nicolas Dufresne Reviewed-by: Laurent Pinchart --- src/gstreamer/gstlibcamerasrc.cpp | 178 +++++++++++++++--------------- 1 file changed, 89 insertions(+), 89 deletions(-) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index a6f240f5..e57ba52f 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -379,6 +379,88 @@ gst_libcamera_src_open(GstLibcameraSrc *self) return true; } +/* Must be called with stream_lock held. */ +static bool +gst_libcamera_src_negotiate(GstLibcameraSrc *self) +{ + GstLibcameraSrcState *state = self->state; + + g_autoptr(GstStructure) element_caps = gst_structure_new_empty("caps"); + + for (gsize i = 0; i < state->srcpads_.size(); i++) { + GstPad *srcpad = state->srcpads_[i]; + StreamConfiguration &stream_cfg = state->config_->at(i); + + /* Retrieve the supported caps. */ + g_autoptr(GstCaps) filter = gst_libcamera_stream_formats_to_caps(stream_cfg.formats()); + g_autoptr(GstCaps) caps = gst_pad_peer_query_caps(srcpad, filter); + if (gst_caps_is_empty(caps)) + return false; + + /* Fixate caps and configure the stream. */ + caps = gst_caps_make_writable(caps); + gst_libcamera_configure_stream_from_caps(stream_cfg, caps); + gst_libcamera_get_framerate_from_caps(caps, element_caps); + } + + /* Validate the configuration. */ + if (state->config_->validate() == CameraConfiguration::Invalid) + return false; + + int ret = state->cam_->configure(state->config_.get()); + if (ret) { + GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS, + ("Failed to configure camera: %s", g_strerror(-ret)), + ("Camera::configure() failed with error code %i", ret)); + return false; + } + + /* Check frame duration bounds within controls::FrameDurationLimits */ + gst_libcamera_clamp_and_set_frameduration(state->initControls_, + state->cam_->controls(), element_caps); + + /* + * Regardless if it has been modified, create clean caps and push the + * caps event. Downstream will decide if the caps are acceptable. + */ + for (gsize i = 0; i < state->srcpads_.size(); i++) { + GstPad *srcpad = state->srcpads_[i]; + const StreamConfiguration &stream_cfg = state->config_->at(i); + + g_autoptr(GstCaps) caps = gst_libcamera_stream_configuration_to_caps(stream_cfg); + gst_libcamera_framerate_to_caps(caps, element_caps); + + if (!gst_pad_push_event(srcpad, gst_event_new_caps(caps))) + return false; + + } + + if (self->allocator) + g_clear_object(&self->allocator); + + self->allocator = gst_libcamera_allocator_new(state->cam_, state->config_.get()); + if (!self->allocator) { + GST_ELEMENT_ERROR(self, RESOURCE, NO_SPACE_LEFT, + ("Failed to allocate memory"), + ("gst_libcamera_allocator_new() failed.")); + return false; + } + + for (gsize i = 0; i < state->srcpads_.size(); i++) { + GstPad *srcpad = state->srcpads_[i]; + const StreamConfiguration &stream_cfg = state->config_->at(i); + + GstLibcameraPool *pool = gst_libcamera_pool_new(self->allocator, + stream_cfg.stream()); + g_signal_connect_swapped(pool, "buffer-notify", + G_CALLBACK(gst_task_resume), self->task); + + gst_libcamera_pad_set_pool(srcpad, pool); + } + + return true; +} + static void gst_libcamera_src_task_run(gpointer user_data) { @@ -468,11 +550,8 @@ 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; - GstFlowReturn flow_ret = GST_FLOW_OK; gint ret; - g_autoptr(GstStructure) element_caps = gst_structure_new_empty("caps"); - GST_DEBUG_OBJECT(self, "Streaming thread has started"); gint stream_id_num = 0; @@ -500,62 +579,16 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread, } g_assert(state->config_->size() == state->srcpads_.size()); - for (gsize i = 0; i < state->srcpads_.size(); i++) { - GstPad *srcpad = state->srcpads_[i]; - StreamConfiguration &stream_cfg = state->config_->at(i); - - /* Retrieve the supported caps. */ - g_autoptr(GstCaps) filter = gst_libcamera_stream_formats_to_caps(stream_cfg.formats()); - g_autoptr(GstCaps) caps = gst_pad_peer_query_caps(srcpad, filter); - if (gst_caps_is_empty(caps)) { - flow_ret = GST_FLOW_NOT_NEGOTIATED; - break; - } - - /* Fixate caps and configure the stream. */ - caps = gst_caps_make_writable(caps); - gst_libcamera_configure_stream_from_caps(stream_cfg, caps); - gst_libcamera_get_framerate_from_caps(caps, element_caps); - } - - if (flow_ret != GST_FLOW_OK) - goto done; - - /* Validate the configuration. */ - if (state->config_->validate() == CameraConfiguration::Invalid) { - flow_ret = GST_FLOW_NOT_NEGOTIATED; - goto done; - } - - ret = state->cam_->configure(state->config_.get()); - if (ret) { - GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS, - ("Failed to configure camera: %s", g_strerror(-ret)), - ("Camera::configure() failed with error code %i", ret)); + if (!gst_libcamera_src_negotiate(self)) { + state->initControls_.clear(); + GST_ELEMENT_FLOW_ERROR(self, GST_FLOW_NOT_NEGOTIATED); gst_task_stop(task); - flow_ret = GST_FLOW_NOT_NEGOTIATED; - goto done; + return; } - /* Check frame duration bounds within controls::FrameDurationLimits */ - gst_libcamera_clamp_and_set_frameduration(state->initControls_, - state->cam_->controls(), element_caps); - - /* - * Regardless if it has been modified, create clean caps and push the - * caps event. Downstream will decide if the caps are acceptable. - */ - for (gsize i = 0; i < state->srcpads_.size(); i++) { - GstPad *srcpad = state->srcpads_[i]; - const StreamConfiguration &stream_cfg = state->config_->at(i); - - g_autoptr(GstCaps) caps = gst_libcamera_stream_configuration_to_caps(stream_cfg); - gst_libcamera_framerate_to_caps(caps, element_caps); - - if (!gst_pad_push_event(srcpad, gst_event_new_caps(caps))) { - flow_ret = GST_FLOW_NOT_NEGOTIATED; - break; - } + self->flow_combiner = gst_flow_combiner_new(); + for (GstPad *srcpad : state->srcpads_) { + gst_flow_combiner_add_pad(self->flow_combiner, srcpad); /* Send an open segment event with time format. */ GstSegment segment; @@ -563,28 +596,6 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread, gst_pad_push_event(srcpad, gst_event_new_segment(&segment)); } - self->allocator = gst_libcamera_allocator_new(state->cam_, state->config_.get()); - if (!self->allocator) { - GST_ELEMENT_ERROR(self, RESOURCE, NO_SPACE_LEFT, - ("Failed to allocate memory"), - ("gst_libcamera_allocator_new() failed.")); - gst_task_stop(task); - return; - } - - self->flow_combiner = gst_flow_combiner_new(); - for (gsize i = 0; i < state->srcpads_.size(); i++) { - GstPad *srcpad = state->srcpads_[i]; - const StreamConfiguration &stream_cfg = state->config_->at(i); - GstLibcameraPool *pool = gst_libcamera_pool_new(self->allocator, - stream_cfg.stream()); - g_signal_connect_swapped(pool, "buffer-notify", - G_CALLBACK(gst_task_resume), task); - - gst_libcamera_pad_set_pool(srcpad, pool); - 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()) { @@ -605,17 +616,6 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread, gst_task_stop(task); return; } - -done: - state->initControls_.clear(); - switch (flow_ret) { - case GST_FLOW_NOT_NEGOTIATED: - GST_ELEMENT_FLOW_ERROR(self, flow_ret); - gst_task_stop(task); - break; - default: - break; - } } static void From patchwork Thu Nov 30 15:43:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jaslo Ziska X-Patchwork-Id: 19258 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 5FEE7BDE6B for ; Thu, 30 Nov 2023 15:54:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 16B3A629D2; Thu, 30 Nov 2023 16:54:41 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1701359681; bh=1HZaUVHwFT/CmpGGSepQsclpDntj8ie64ONJ4vpQrGE=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=SADluEfhT1lHyp5wSr2cF95+LcglC+9T/b1inawDTIocAizXqPNhgxCGppFr8FfDx AtxmC0oELtd555fRJW8lxiFT01zJzj3Wm0+Y2Vfkt+KSdHNoRgZwYgQc6eV+d8BHME 8jpjZK6EF1JLzfnhlJCXKLPxqT0E0rFr5LeU720mCAkOZx88RKqYrafscLCSZddwpr cK6Pv1A+HG+6oyK9Jp/YrqhPD7M25m0dl8tGxz7CTXw4Fukbqk0heB5QH7YmQ4V2qW QJQeIgqJtUlZJ/rGlrNYr690BvXgvUJbjv0WPgC/0r0DHThWg9beTXVJrTUwQFFfdU 232BjKGRRKHtw== Received: from mo4-p00-ob.smtp.rzone.de (mo4-p00-ob.smtp.rzone.de [85.215.255.21]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 373D6629C2 for ; Thu, 30 Nov 2023 16:54:40 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=ziska.de header.i=@ziska.de header.b="Fn0Uf66n"; dkim=permerror (0-bit key) header.d=ziska.de header.i=@ziska.de header.b="UR3PWXVP"; dkim-atps=neutral ARC-Seal: i=1; a=rsa-sha256; t=1701359679; cv=none; d=strato.com; s=strato-dkim-0002; b=TE1VDV0D/L0F/vjDmMzITu5VtdO1IrLln4RIK8IAZJlDn9uMVHjmh6bGqRHUTG0Dzd dQTf/3SuUyWL5d93exUlei7e0FZqnePVfr7k5Sv/UU4OaO7C8K/HR1KTmtp7WlWlAKgk 6d8Juvgmpyw28x4qPJdrxH+J11+YNzh9W9pPYy1QBmPzloE1+HJ9OnquywSwFJyU8ItR +gtVWfPuipWPCq0b5Ij2UbbDNfmE7Obo5BR31az744dg7oU86UmIvLewQlze1W04HP7N CDhyCebYciDE2/7TdzN/OU8mYICZ1c80LgvJRnvfiWseLd43UXyBAtcbTXFc9wBKxTtW DniA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1701359679; s=strato-dkim-0002; d=strato.com; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=D892LkJsjJS9MKLBSKREEFYt7G0gICXHM6Cbxck3a9M=; b=bO2FkWWYCsQiTSVujU+AV7r4rfdsHvk+yfm2L+LrTgsTEBDM7wFru3M9EI9nzKliH1 RCPXBR/Pk4s/VTpEcz7Zp8YnqErBghcFlq2P0BWRlWQXibXiE6u1r1WR9urwnHKZzobV HMoq830YGXh+5bQjuxtkxp1bmncerexhuGJi4QjCxf/+Kn5gsxsZrwGZxPGBy2w/RN88 RE2gUpyvLHEHa6Ss8o80N5ZlxPni46f29tmx4eVxOs4YAMOZwZti3b2lY+YqwDaritKw DVDTeqt3mmk9pkLpc4XRHUH6Bs1dGrfsZuqgQhM6dSfY4CtbYdZKHKoJzQyehQgQCLUS 9niQ== ARC-Authentication-Results: i=1; strato.com; arc=none; dkim=none X-RZG-CLASS-ID: mo00 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1701359679; s=strato-dkim-0002; d=ziska.de; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=D892LkJsjJS9MKLBSKREEFYt7G0gICXHM6Cbxck3a9M=; b=Fn0Uf66n2P9iDnzyJOCIFVgpSs30SwO6Iv18iZJ3wtHZ3f1UyfcIUJHtoEgcT44BpH MRAbrMgq25jnnjcprwhlV8JV/sNK6WY6xc1odWl90aqRAUYg07Gj6Nwx3FIHqFKdTK+J 9T1K9QbvgMxHUbeYGKzwlo2eNlCbphmY6+o7d5ox7oJbdLIDC7Q2Uj9fKp1vY59fEIi6 4zoNeK3VP9zJedp2ZHH82YTf8kMwXDtKQHWovwa94jdBdvl2lndVeFiJu21O3fuOqAov KqP7fY7BFr+kMy91kiO8u6Ui0DyM+LlFCIpkOZY0faIVnhYL5+Jvdz7rdQ1djXXDOWQy AiZA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; t=1701359679; s=strato-dkim-0003; d=ziska.de; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=D892LkJsjJS9MKLBSKREEFYt7G0gICXHM6Cbxck3a9M=; b=UR3PWXVPitQUBRUOb2w3S2azeCMCP9pYfZE+2O3+TS1utHGv0ITb5ijUl5ncN9ycE2 KTfLhNTxaG/9Y6EE0vDw== X-RZG-AUTH: ":Jm0XeU+IYfb0x77LHmrjN5Wlb7TBwusDqIM6Hizy8VdfzvKi4yoFC9cH04q6BfJa07bS3ov6I8QOM/V5x+uTrCUtBrk=" Received: from archlinux.fritz.box by smtp.strato.de (RZmta 49.9.7 AUTH) with ESMTPSA id n54b84zAUFsd0SC (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Thu, 30 Nov 2023 16:54:39 +0100 (CET) To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Nov 2023 16:43:09 +0100 Message-ID: <20231130155323.13259-3-jaslo@ziska.de> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231130155323.13259-1-jaslo@ziska.de> References: <20231130155323.13259-1-jaslo@ziska.de> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/3] gstreamer: Add GstLibcameraSrcState::clearRequests method 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: Jaslo Ziska via libcamera-devel From: Jaslo Ziska Reply-To: Jaslo Ziska Cc: Jaslo Ziska Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add a clearRequests method to GstLibcameraSrcState which clears the GstLibcameraSrcState::completedRequests_ queue. Use this new method in gst_libcamera_src_task_leave instead of doing it manually. Signed-off-by: Jaslo Ziska Reviewed-by: Nicolas Dufresne Reviewed-by: Laurent Pinchart --- src/gstreamer/gstlibcamerasrc.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index e57ba52f..d448a750 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -133,6 +133,7 @@ struct GstLibcameraSrcState { int queueRequest(); void requestCompleted(Request *request); int processRequest(); + void clearRequests(); }; struct _GstLibcameraSrc { @@ -318,6 +319,12 @@ int GstLibcameraSrcState::processRequest() return err; } +void GstLibcameraSrcState::clearRequests() +{ + GLibLocker locker(&lock_); + completedRequests_ = {}; +} + static bool gst_libcamera_src_open(GstLibcameraSrc *self) { @@ -629,11 +636,7 @@ gst_libcamera_src_task_leave([[maybe_unused]] GstTask *task, GST_DEBUG_OBJECT(self, "Streaming thread is about to stop"); state->cam_->stop(); - - { - GLibLocker locker(&state->lock_); - state->completedRequests_ = {}; - } + state->clearRequests(); { GLibRecLocker locker(&self->stream_lock); From patchwork Thu Nov 30 15:43:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jaslo Ziska X-Patchwork-Id: 19259 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 058CCBDE6B for ; Thu, 30 Nov 2023 15:54:44 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B03E6629D2; Thu, 30 Nov 2023 16:54:43 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1701359683; bh=bK7cYUIfRBCf8bf2vdEPvCe1dbC4+QPJg91KvLeMeMs=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=HAfcICaw4AV+Md7vbAo72iqYxuko+VWcEkpgIxoLUTVYmYMltWqWTgTIIg4E1RIWX jNzSyug8jWRDLY8xmIs9UYU3sxUfNr8xEPQkD65ZKFPdwnAZVVlO18X3HE06e6klcp urUjHgp/j/S8EafHuPxPHdG+vcP0ZzKyMbigdx6dau9s14qY6UIu7+7QFoflwNMDcN uEwV9Biww4iSFq27793NFzNbjtSzcb2+o8h/2AKPThqe64i4ioh/ymesiGU+i9wGPK HuE/+kzfGhZ852e+ZdpLkLRIVdugyv8jyQVI6hojdiGocdE9RtA8OxgrcT9J/gkQtS cw/0rgKi7JpNQ== Received: from mo4-p00-ob.smtp.rzone.de (mo4-p00-ob.smtp.rzone.de [81.169.146.160]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 34372629C2 for ; Thu, 30 Nov 2023 16:54:43 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=ziska.de header.i=@ziska.de header.b="p+11Xw4p"; dkim=permerror (0-bit key) header.d=ziska.de header.i=@ziska.de header.b="tXRj9ez9"; dkim-atps=neutral ARC-Seal: i=1; a=rsa-sha256; t=1701359682; cv=none; d=strato.com; s=strato-dkim-0002; b=eWJzw+qEOpV5dS0q64E3tc8xVjYRbUY6iNxaotOWolp5wmt0VP22jW15CJmgpY1K3l 5Ky5Md4QfoKjJzT5Si8/4/BUjn/JqXroEWyeRGC6MCAVpatf3XRtUIJC8b3Xgrj+G+wz 8BIOjXDUz1NZK6cRjD0iRh+oQKXUchBa7WUgDnBTmy47I/3ilG5hi7heewY6flC8ixE9 SBIJUm5kY8Y6M8M1S/C3Df/tbill3CKfxXhwKyw9vUG7ogwYhF6Mcs1hSRycePWICcEe LEQ0DTx1IL5bF2scrU3K4okdJHCdJRvQWhTERk0cjv/L3oNcDK3kx31SEwOG+tilo8lg mGrw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1701359682; s=strato-dkim-0002; d=strato.com; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=ahMdiRm4KDgm5BTPp4irOpCMRK1LsS/UNnMD4ZUT5sM=; b=pCSzdgUDcsJgOH96buAZOLre9NXWssYgCMvXx1Lt7poPQRHZw7eEGI3jd8EfCsz8FZ FpLpErBJ+FmVgjELKakqRV3QuG+XJ9zQmEbfN/6xxoUxL6Rd/OnsW6F2fxu6e7yYO+uk E3NxTllWD8IDvxOv+r3huZCO+MlYhqsXPm1Xk2HcVauT2Bk4deUSlGMv38Tazyrj5usQ z2IM67qwPLxF2b4J0XG2U1Kb+f6eYTyJvekrOjtQIlKhXa/yKgVTj6wHi4aPgWOhHZqr RPbUs21PEkje+Wj5I48e4ScQMN4xc/wTjj+dQ1H5FJAdh7SBpTXLyZCbXHhkLF5KFtUm jtAg== ARC-Authentication-Results: i=1; strato.com; arc=none; dkim=none X-RZG-CLASS-ID: mo00 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1701359682; s=strato-dkim-0002; d=ziska.de; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=ahMdiRm4KDgm5BTPp4irOpCMRK1LsS/UNnMD4ZUT5sM=; b=p+11Xw4pbRiJBnQcG52c2e+NZJ5xG5fxmvoOoBAANSG/KZ7B5+ijwq5t6w9+PB7t+k +SnqzqKysa1/wwvGsx19qo3ioEFcZmRSLyemBAJlWaj8WILqqN6hcirZrKubKr+2T9Lr NIkac4Wsx65oKhfjDEDipIkNYrumhk6ThsJEcOAFntSl+04h21atjeyEwgfWgUMZIM8f N49Y2KpW5n5kLBa13oKsbpHIiCY7YYxEBk3dVXF9SR4nDAe32fpqjdmpMCLWD4Aw/L5J vK9bEjKQzhWSuBWbjsHSNCWhrVYGNtr3mX1a5uaFMSe46W4+WgoW1umlWL+F7Jc1vEGn 1uSw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; t=1701359682; s=strato-dkim-0003; d=ziska.de; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=ahMdiRm4KDgm5BTPp4irOpCMRK1LsS/UNnMD4ZUT5sM=; b=tXRj9ez98ASxA+fMl+7vWG1fVzGaprdvyXPis0QQN+3BhyB1dYgMthVjvdIVCTI0bs C3G/YExiMI5aDngsGSCA== X-RZG-AUTH: ":Jm0XeU+IYfb0x77LHmrjN5Wlb7TBwusDqIM6Hizy8VdfzvKi4yoFC9cH04q6BfJa07bS3ov6I8QOM/V5x+uTrCUtBrk=" Received: from archlinux.fritz.box by smtp.strato.de (RZmta 49.9.7 AUTH) with ESMTPSA id n54b84zAUFsg0SD (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Thu, 30 Nov 2023 16:54:42 +0100 (CET) To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Nov 2023 16:43:10 +0100 Message-ID: <20231130155323.13259-4-jaslo@ziska.de> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231130155323.13259-1-jaslo@ziska.de> References: <20231130155323.13259-1-jaslo@ziska.de> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 3/3] gstreamer: Implement renegotiation 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: Jaslo Ziska via libcamera-devel From: Jaslo Ziska Reply-To: Jaslo Ziska Cc: Jaslo Ziska Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" This commit implements renegotiation of the camera configuration and source pad caps. A renegotiation can happen when a downstream element decides to change caps or the pipeline is dynamically changed. To handle a renegotiation the GST_FLOW_NOT_NEGOTIATED return value has to be handled in GstLibcameraSrcState::processRequest. Otherwise the default would be to print an error and stop streaming. To archive this in a clean way the if statement is altered into a switch statement which now also has a case for GST_FLOW_NOT_NEGOTIATED. In the case of GST_FLOW_NOT_NEGOTIATED every source pad is checked for the reconfiguration flag with gst_pad_needs_reconfigure which does not clear this flag. If at least one pad requested a reconfiguration the function returns without an error and the renegotiation will happen later in the running task. If no pad requested a reconfiguration then the function will return with an error. In gst_libcamera_src_task_run the source pads are checked for the reconfigure flag by calling gst_pad_check_reconfigure and if one pad returns true and the caps are not sufficient anymore then the negotiation is triggered. It is fine to trigger the negotiation after only a single pad returns true for gst_pad_check_reconfigure because the reconfigure flags are cleared in the gst_libcamera_src_negotiate function. If any pad requested a reconfiguration the following will happen: 1. The camera is stopped because changing the configuration may not happen while running. 2. The completedRequests queue will be cleared by calling GstLibcameraSrcState::clearRequests because the completed buffers have the wrong configuration. 3. The new caps are negotiated by calling gst_libcamera_src_negotiate. When the negotiation fails streaming will stop. 4. The camera is started again. Signed-off-by: Jaslo Ziska Reviewed-by: Nicolas Dufresne Reviewed-by: Laurent Pinchart --- src/gstreamer/gstlibcamerasrc.cpp | 72 ++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 11 deletions(-) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index d448a750..8bd32306 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -11,7 +11,6 @@ * - Implement GstElement::send_event * + Allowing application to use FLUSH/FLUSH_STOP * + Prevent the main thread from accessing streaming thread - * - Implement renegotiation (even if slow) * - Implement GstElement::request-new-pad (multi stream) * + Evaluate if a single streaming thread is fine * - Add application driven request (snapshot) @@ -302,18 +301,42 @@ int GstLibcameraSrcState::processRequest() srcpad, ret); } - if (ret != GST_FLOW_OK) { - if (ret == GST_FLOW_EOS) { - g_autoptr(GstEvent) eos = gst_event_new_eos(); - guint32 seqnum = gst_util_seqnum_next(); - gst_event_set_seqnum(eos, seqnum); - for (GstPad *srcpad : srcpads_) - gst_pad_push_event(srcpad, gst_event_ref(eos)); - } else if (ret != GST_FLOW_FLUSHING) { - GST_ELEMENT_FLOW_ERROR(src_, ret); + switch (ret) { + case GST_FLOW_OK: + break; + case GST_FLOW_NOT_NEGOTIATED: { + bool reconfigure = false; + for (GstPad *srcpad : srcpads_) { + if (gst_pad_needs_reconfigure(srcpad)) { + reconfigure = true; + break; + } } - return -EPIPE; + // if no pads needs a reconfiguration something went wrong + if (!reconfigure) + err = -EPIPE; + + break; + } + case GST_FLOW_EOS: { + g_autoptr(GstEvent) eos = gst_event_new_eos(); + guint32 seqnum = gst_util_seqnum_next(); + gst_event_set_seqnum(eos, seqnum); + for (GstPad *srcpad : srcpads_) + gst_pad_push_event(srcpad, gst_event_ref(eos)); + + err = -EPIPE; + break; + } + case GST_FLOW_FLUSHING: + err = -EPIPE; + break; + default: + GST_ELEMENT_FLOW_ERROR(src_, ret); + + err = -EPIPE; + break; } return err; @@ -463,6 +486,8 @@ gst_libcamera_src_negotiate(GstLibcameraSrc *self) G_CALLBACK(gst_task_resume), self->task); gst_libcamera_pad_set_pool(srcpad, pool); + + gst_pad_check_reconfigure(srcpad); // clear all reconfigure flags } return true; @@ -496,6 +521,31 @@ gst_libcamera_src_task_run(gpointer user_data) return; } + // check if a srcpad requested a renegotiation + bool reconfigure = false; + for (GstPad *srcpad : state->srcpads_) { + if (gst_pad_check_reconfigure(srcpad)) { + // check whether the caps even need changing + g_autoptr(GstCaps) caps = gst_pad_get_current_caps(srcpad); + if (!gst_pad_peer_query_accept_caps(srcpad, caps)) { + reconfigure = true; + break; + } + } + } + + if (reconfigure) { + state->cam_->stop(); + state->clearRequests(); + + if (!gst_libcamera_src_negotiate(self)) { + GST_ELEMENT_FLOW_ERROR(self, GST_FLOW_NOT_NEGOTIATED); + gst_task_stop(self->task); + } + + state->cam_->start(&state->initControls_); + } + /* * Create and queue one request. If no buffers are available the * function returns -ENOBUFS, which we ignore here as that's not a