diff options
author | Jaslo Ziska <jaslo@ziska.de> | 2023-11-14 13:18:57 +0100 |
---|---|---|
committer | Umang Jain <umang.jain@ideasonboard.com> | 2023-11-22 01:18:19 +0530 |
commit | fd84180d7a09eb9f4891f740735b28af68c201af (patch) | |
tree | 366c9db2e030458d1279134c1f76713c30f0ff18 | |
parent | 091591b52e5535065eef141339c3d69406185136 (diff) |
gstreamer: Implement element EOS handling
This commit implements EOS handling for events sent to the libcamerasrc
element by the send_event method (which can happen when pressing
Ctrl-C while running gst-launch-1.0 -e, see below). EOS events from
downstream elements returning GST_FLOW_EOS are not considered here.
To archive this add a function for the send_event method which handles
the GST_EVENT_EOS event. This function will set an atomic to the
received event and push this EOS event to all source pads in the running
task.
Also set the GST_ELEMENT_FLAG_SOURCE flag to identify libcamerasrc as a
source element which enables it to receive EOS events sent to the
(pipeline) bin containing it. This in turn enables libcamerasrc
to receive EOS events, for example, from gst-launch-1.0 with
the -e (--eos-on-shutdown) flag applied.
Bug: https://bugs.libcamera.org/show_bug.cgi?id=91
Signed-off-by: Jaslo Ziska <jaslo@ziska.de>
Acked-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
-rw-r--r-- | src/gstreamer/gstlibcamerasrc.cpp | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index 63d99571..767017db 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -9,7 +9,6 @@ /** * \todo The following is a list of items that needs implementation in the GStreamer plugin * - Implement GstElement::send_event - * + Allowing application to send EOS * + Allowing application to use FLUSH/FLUSH_STOP * + Prevent the main thread from accessing streaming thread * - Implement renegotiation (even if slow) @@ -29,6 +28,7 @@ #include "gstlibcamerasrc.h" +#include <atomic> #include <queue> #include <vector> @@ -144,6 +144,8 @@ struct _GstLibcameraSrc { gchar *camera_name; controls::AfModeEnum auto_focus_mode = controls::AfModeManual; + std::atomic<GstEvent *> pending_eos; + GstLibcameraSrcState *state; GstLibcameraAllocator *allocator; GstFlowCombiner *flow_combiner; @@ -397,6 +399,14 @@ gst_libcamera_src_task_run(gpointer user_data) bool doResume = false; + g_autoptr(GstEvent) event = self->pending_eos.exchange(nullptr); + if (event) { + for (GstPad *srcpad : state->srcpads_) + gst_pad_push_event(srcpad, gst_event_ref(event)); + + return; + } + /* * Create and queue one request. If no buffers are available the * function returns -ENOBUFS, which we ignore here as that's not a @@ -747,6 +757,27 @@ gst_libcamera_src_change_state(GstElement *element, GstStateChange transition) return ret; } +static gboolean +gst_libcamera_src_send_event(GstElement *element, GstEvent *event) +{ + GstLibcameraSrc *self = GST_LIBCAMERA_SRC(element); + gboolean ret = FALSE; + + switch (GST_EVENT_TYPE(event)) { + case GST_EVENT_EOS: { + g_autoptr(GstEvent) oldEvent = self->pending_eos.exchange(event); + + ret = TRUE; + break; + } + default: + gst_event_unref(event); + break; + } + + return ret; +} + static void gst_libcamera_src_finalize(GObject *object) { @@ -779,6 +810,8 @@ gst_libcamera_src_init(GstLibcameraSrc *self) state->srcpads_.push_back(gst_pad_new_from_template(templ, "src")); gst_element_add_pad(GST_ELEMENT(self), state->srcpads_.back()); + GST_OBJECT_FLAG_SET(self, GST_ELEMENT_FLAG_SOURCE); + /* C-style friend. */ state->src_ = self; self->state = state; @@ -844,6 +877,7 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass) element_class->request_new_pad = gst_libcamera_src_request_new_pad; element_class->release_pad = gst_libcamera_src_release_pad; element_class->change_state = gst_libcamera_src_change_state; + element_class->send_event = gst_libcamera_src_send_event; gst_element_class_set_metadata(element_class, "libcamera Source", "Source/Video", |