mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 07:47:17 +00:00
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
This commit is contained in:
parent
94d2e4c223
commit
ce65017d03
3 changed files with 60 additions and 44 deletions
|
@ -268,8 +268,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 {
|
||||
|
|
|
@ -1506,7 +1506,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;
|
||||
}
|
||||
|
||||
|
@ -1538,11 +1538,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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1627,10 +1633,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,
|
||||
|
@ -1657,32 +1689,13 @@ multiqueue_src_probe (GstPad * pad, GstPadProbeInfo * info,
|
|||
|
||||
free_multiqueue_slot_async (dbin, slot);
|
||||
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;
|
||||
|
|
|
@ -1109,19 +1109,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;
|
||||
}
|
||||
|
||||
|
@ -1134,11 +1130,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:
|
||||
|
@ -1301,8 +1298,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");
|
||||
|
||||
|
@ -1442,8 +1440,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");
|
||||
|
|
Loading…
Reference in a new issue