[libcamera-devel] [PATCH v1 10/23] gst: libcamerasrc: Start/Stop the streaming thread
Nicolas Dufresne
nicolas at ndufresne.ca
Wed Jan 29 04:31:57 CET 2020
From: Nicolas Dufresne <nicolas.dufresne at collabora.com>
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 <nicolas.dufresne at collabora.com>
---
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;
--
2.24.1
More information about the libcamera-devel
mailing list