summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Hervey <edward@centricular.com>2017-08-09 16:23:03 +0200
committerSebastian Dröge <sebastian@centricular.com>2017-08-17 13:36:58 +0300
commite87bc670dab96543a3681b2e9464348b6aef81e0 (patch)
tree3dd2f81491cf2794a2153cbdde11c8d0652f8628
parent53abe88230b5517a293e4aaa8ea6b484316b8c19 (diff)
downloadgstreamer-plugins-base-e87bc670dab96543a3681b2e9464348b6aef81e0.tar.gz
decodebin3/urisourcebin: Switch to actual EOS events internally
Use the intended sequence for re-using elements: * EOS * STREAM_START if element is to be re-used This avoids having elements (such as queue/multiqueue/queue2) not properly resetting themselves. When delaying EOS propagation (because we want to wait until all streams of a group are done for example), we re-trigger them by first sending the cached STREAM_START and then EOS (which will cause elements to re-set themselves if needed and accept new buffers/events). https://bugzilla.gnome.org/show_bug.cgi?id=785951
-rw-r--r--gst/playback/gstdecodebin3-parse.c7
-rw-r--r--gst/playback/gstdecodebin3.c69
-rw-r--r--gst/playback/gsturisourcebin.c28
3 files changed, 60 insertions, 44 deletions
diff --git a/gst/playback/gstdecodebin3-parse.c b/gst/playback/gstdecodebin3-parse.c
index 8c51d916c..e00f05602 100644
--- a/gst/playback/gstdecodebin3-parse.c
+++ b/gst/playback/gstdecodebin3-parse.c
@@ -263,8 +263,11 @@ parse_chain_output_probe (GstPad * pad, GstPadProbeInfo * info,
GST_DEBUG_OBJECT (pad,
"Got EOS end of input stream, post custom-eos");
- s = gst_structure_new_empty ("decodebin3-custom-eos");
- event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);
+ event = gst_event_new_eos ();
+ gst_event_set_seqnum (event, gst_event_get_seqnum (ev));
+ s = gst_event_writable_structure (event);
+ gst_structure_set (s, "decodebin3-custom-eos", G_TYPE_BOOLEAN, TRUE,
+ NULL);
gst_pad_send_event (peer, event);
gst_object_unref (peer);
} else {
diff --git a/gst/playback/gstdecodebin3.c b/gst/playback/gstdecodebin3.c
index 47d21a76b..c6a8f37f4 100644
--- a/gst/playback/gstdecodebin3.c
+++ b/gst/playback/gstdecodebin3.c
@@ -1495,7 +1495,7 @@ check_all_slot_for_eos (GstDecodebin3 * dbin)
continue;
if (slot->is_drained) {
- GST_DEBUG_OBJECT (slot->sink_pad, "slot %p is draned", slot);
+ GST_LOG_OBJECT (slot->sink_pad, "slot %p is drained", slot);
continue;
}
@@ -1527,11 +1527,17 @@ check_all_slot_for_eos (GstDecodebin3 * dbin)
DecodebinInputStream *input = (DecodebinInputStream *) iter->data;
GstPad *peer = gst_pad_get_peer (input->srcpad);
- /* Send EOS and then remove elements */
+ /* Send EOS to all slots */
if (peer) {
+ GstEvent *stream_start =
+ gst_pad_get_sticky_event (input->srcpad, GST_EVENT_STREAM_START, 0);
+ /* First forward the STREAM_START event to reset the EOS status (if any) */
+ if (stream_start)
+ gst_pad_send_event (peer, stream_start);
gst_pad_send_event (peer, gst_event_new_eos ());
gst_object_unref (peer);
- }
+ } else
+ GST_DEBUG_OBJECT (dbin, "no output");
}
}
}
@@ -1616,10 +1622,36 @@ multiqueue_src_probe (GstPad * pad, GstPadProbeInfo * info,
}
break;
case GST_EVENT_EOS:
- /* FIXME : Figure out */
+ {
+ const GstStructure *s = gst_event_get_structure (ev);
+ slot->is_drained = TRUE;
+
+ /* Custom EOS handling first */
+ if (s && gst_structure_has_field (s, "decodebin3-custom-eos")) {
+ ret = GST_PAD_PROBE_DROP;
+ SELECTION_LOCK (dbin);
+ if (slot->input == NULL) {
+ GST_DEBUG_OBJECT (pad,
+ "Got custom-eos from null input stream, remove output stream");
+ /* Remove the output */
+ if (slot->output) {
+ DecodebinOutputStream *output = slot->output;
+ dbin->output_streams =
+ g_list_remove (dbin->output_streams, output);
+ free_output_stream (dbin, output);
+ }
+ slot->probe_id = 0;
+ dbin->slots = g_list_remove (dbin->slots, slot);
+ free_multiqueue_slot_async (dbin, slot);
+ ret = GST_PAD_PROBE_REMOVE;
+ } else {
+ check_all_slot_for_eos (dbin);
+ }
+ SELECTION_UNLOCK (dbin);
+ break;
+ }
GST_FIXME_OBJECT (pad, "EOS on multiqueue source pad. input:%p",
slot->input);
- slot->is_drained = TRUE;
if (slot->input == NULL) {
GstPad *peer;
GST_DEBUG_OBJECT (pad,
@@ -1645,32 +1677,13 @@ multiqueue_src_probe (GstPad * pad, GstPadProbeInfo * info,
free_multiqueue_slot_async (dbin, slot);
SELECTION_UNLOCK (dbin);
ret = GST_PAD_PROBE_REMOVE;
- }
- break;
- case GST_EVENT_CUSTOM_DOWNSTREAM:
- if (gst_event_has_name (ev, "decodebin3-custom-eos")) {
- slot->is_drained = TRUE;
- ret = GST_PAD_PROBE_DROP;
+ } else {
+ GST_DEBUG_OBJECT (pad, "What happens with event ?");
SELECTION_LOCK (dbin);
- if (slot->input == NULL) {
- GST_DEBUG_OBJECT (pad,
- "Got custom-eos from null input stream, remove output stream");
- /* Remove the output */
- if (slot->output) {
- DecodebinOutputStream *output = slot->output;
- dbin->output_streams =
- g_list_remove (dbin->output_streams, output);
- free_output_stream (dbin, output);
- }
- slot->probe_id = 0;
- dbin->slots = g_list_remove (dbin->slots, slot);
- free_multiqueue_slot_async (dbin, slot);
- ret = GST_PAD_PROBE_REMOVE;
- } else {
- check_all_slot_for_eos (dbin);
- }
+ check_all_slot_for_eos (dbin);
SELECTION_UNLOCK (dbin);
}
+ }
break;
default:
break;
diff --git a/gst/playback/gsturisourcebin.c b/gst/playback/gsturisourcebin.c
index 03da4a986..1e394e049 100644
--- a/gst/playback/gsturisourcebin.c
+++ b/gst/playback/gsturisourcebin.c
@@ -1108,19 +1108,15 @@ demux_pad_events (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
switch (GST_EVENT_TYPE (ev)) {
case GST_EVENT_EOS:
{
- GstEvent *event;
GstStructure *s;
- guint32 seqnum = gst_event_get_seqnum (ev);
GST_LOG_OBJECT (urisrc, "EOS on pad %" GST_PTR_FORMAT, pad);
- /* never forward actual EOS to slot */
- ret = GST_PAD_PROBE_DROP;
-
if ((urisrc->pending_pads &&
link_pending_pad_to_output (urisrc, child_info->output_slot))) {
/* Found a new source pad to give this slot data - no need to send EOS */
GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+ ret = GST_PAD_PROBE_DROP;
goto done;
}
@@ -1133,11 +1129,12 @@ demux_pad_events (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
remove_buffering_msgs (urisrc,
GST_OBJECT_CAST (child_info->output_slot->queue));
- /* Actually feed a custom EOS event to avoid marking pads as EOSed */
- s = gst_structure_new_empty ("urisourcebin-custom-eos");
- event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);
- gst_event_set_seqnum (event, seqnum);
- gst_pad_send_event (child_info->output_slot->sinkpad, event);
+ /* Mark this custom EOS */
+ ev = gst_event_make_writable (ev);
+ GST_PAD_PROBE_INFO_DATA (info) = ev;
+ s = gst_event_writable_structure (ev);
+ gst_structure_set (s, "urisourcebin-custom-eos", G_TYPE_BOOLEAN, TRUE,
+ NULL);
}
break;
case GST_EVENT_CAPS:
@@ -1299,8 +1296,9 @@ source_pad_event_probe (GstPad * pad, GstPadProbeInfo * info,
GST_LOG_OBJECT (pad, "%s, urisrc %p", GST_EVENT_TYPE_NAME (event), event);
- if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_DOWNSTREAM &&
- gst_event_has_name (event, "urisourcebin-custom-eos")) {
+ if (GST_EVENT_TYPE (event) == GST_EVENT_EOS && gst_event_get_structure (event)
+ && gst_structure_has_field (gst_event_get_structure (event),
+ "urisourcebin-custom-eos")) {
OutputSlotInfo *slot;
GST_DEBUG_OBJECT (pad, "we received EOS");
@@ -1431,8 +1429,10 @@ pad_removed_cb (GstElement * element, GstPad * pad, GstURISourceBin * urisrc)
GST_LOG_OBJECT (element,
"Pad %" GST_PTR_FORMAT " was removed without EOS. Sending.", pad);
- s = gst_structure_new_empty ("urisourcebin-custom-eos");
- event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);
+ event = gst_event_new_eos ();
+ s = gst_event_writable_structure (event);
+ gst_structure_set (s, "urisourcebin-custom-eos", G_TYPE_BOOLEAN, TRUE,
+ NULL);
gst_pad_send_event (slot->sinkpad, event);
} else {
GST_LOG_OBJECT (urisrc, "Removed pad has no output slot");