From patchwork Wed Jan 29 03:31:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Dufresne X-Patchwork-Id: 2744 Return-Path: Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 11921608CA for ; Wed, 29 Jan 2020 04:35:30 +0100 (CET) Received: from nicolas-tpx395.localdomain (unknown [IPv6:2002:c0de:c115:0:66fc:8b:2a38:8313]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: nicolas) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id 72EC828EA9F; Wed, 29 Jan 2020 03:35:28 +0000 (GMT) From: Nicolas Dufresne To: libcamera-devel@lists.libcamera.org Cc: Nicolas Dufresne Date: Tue, 28 Jan 2020 22:31:57 -0500 Message-Id: <20200129033210.278800-11-nicolas@ndufresne.ca> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200129033210.278800-1-nicolas@ndufresne.ca> References: <20200129033210.278800-1-nicolas@ndufresne.ca> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 10/23] gst: libcamerasrc: Start/Stop the streaming thread 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-List-Received-Date: Wed, 29 Jan 2020 03:35:30 -0000 From: Nicolas Dufresne Use a GstTask as our internal streaming thread. Unlike GstBaseSrc, we will be running an streaming thread at the element level rather then per pad. This is needed to combine buffer request for multiple pads. Signed-off-by: Nicolas Dufresne --- src/gstreamer/gstlibcamerasrc.cpp | 45 +++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index abb376b..4d0c7d0 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -26,7 +26,11 @@ struct GstLibcameraSrcState { struct _GstLibcameraSrc { GstElement parent; + + GRecMutex stream_lock; + GstTask *task; GstPad *srcpad; + gchar *camera_name; GstLibcameraSrcState *state; @@ -112,6 +116,30 @@ gst_libcamera_src_open(GstLibcameraSrc *self) return true; } +static void +gst_libcamera_src_task_run(gpointer user_data) +{ + GstLibcameraSrc *self = GST_LIBCAMERA_SRC(user_data); + + GST_DEBUG_OBJECT(self, "Streaming thread it now capturing"); +} + +static void +gst_libcamera_src_task_enter(GstTask *task, GThread *thread, gpointer user_data) +{ + GstLibcameraSrc *self = GST_LIBCAMERA_SRC(user_data); + + GST_DEBUG_OBJECT(self, "Streaming thread has started"); +} + +static void +gst_libcamera_src_task_leave(GstTask *task, GThread *thread, gpointer user_data) +{ + GstLibcameraSrc *self = GST_LIBCAMERA_SRC(user_data); + + GST_DEBUG_OBJECT(self, "Streaming thread is about to stop"); +} + static void gst_libcamera_src_close(GstLibcameraSrc *self) { @@ -182,9 +210,18 @@ gst_libcamera_src_change_state(GstElement *element, GstStateChange transition) return GST_STATE_CHANGE_FAILURE; break; case GST_STATE_CHANGE_READY_TO_PAUSED: + /* This needs to be called after pads activation */ + if (!gst_task_pause(self->task)) + return GST_STATE_CHANGE_FAILURE; + ret = GST_STATE_CHANGE_NO_PREROLL; + break; case GST_STATE_CHANGE_PLAYING_TO_PAUSED: ret = GST_STATE_CHANGE_NO_PREROLL; break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + /* FIXME maybe this should happen before pad deactivation ? */ + gst_task_join(self->task); + break; case GST_STATE_CHANGE_READY_TO_NULL: gst_libcamera_src_close(self); break; @@ -201,6 +238,8 @@ gst_libcamera_src_finalize(GObject *object) GObjectClass *klass = G_OBJECT_CLASS(gst_libcamera_src_parent_class); GstLibcameraSrc *self = GST_LIBCAMERA_SRC(object); + g_rec_mutex_clear(&self->stream_lock); + g_clear_object(&self->task); g_free(self->camera_name); delete self->state; @@ -213,6 +252,12 @@ gst_libcamera_src_init(GstLibcameraSrc *self) GstLibcameraSrcState *state = new GstLibcameraSrcState(); GstPadTemplate *templ = gst_element_get_pad_template(GST_ELEMENT(self), "src"); + g_rec_mutex_init(&self->stream_lock); + self->task = gst_task_new(gst_libcamera_src_task_run, self, nullptr); + gst_task_set_enter_callback(self->task, gst_libcamera_src_task_enter, self, nullptr); + gst_task_set_leave_callback(self->task, gst_libcamera_src_task_leave, self, nullptr); + gst_task_set_lock(self->task, &self->stream_lock); + self->srcpad = gst_pad_new_from_template(templ, "src"); gst_element_add_pad(GST_ELEMENT(self), self->srcpad); self->state = state;