summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSrimanta Panda <srimanta@axis.com>2014-04-11 19:52:02 +0200
committerOlivier CrĂȘte <olivier.crete@collabora.com>2014-04-17 19:14:34 -0400
commit094fdfee7ec31019a54beb347457435cf9f62a0c (patch)
tree5585981b9754b7355da2114c1a0491a9687f12af
parent8b51e9dc60fcba2bf4a1c6cdaaffb562d2e7e6d3 (diff)
funnel: Handle end of stream event on sink pad
Handle end of stream events on sink pad. Check all the sink pad has received eos before forwarding to source pad. Fixes : https://bugzilla.gnome.org/show_bug.cgi?id=727945
-rw-r--r--plugins/elements/gstfunnel.c29
-rw-r--r--tests/check/elements/funnel.c22
2 files changed, 43 insertions, 8 deletions
diff --git a/plugins/elements/gstfunnel.c b/plugins/elements/gstfunnel.c
index 6a7dde5b8d..1a1b0af29f 100644
--- a/plugins/elements/gstfunnel.c
+++ b/plugins/elements/gstfunnel.c
@@ -150,27 +150,38 @@ gst_funnel_request_new_pad (GstElement * element, GstPadTemplate * templ,
}
static gboolean
-gst_funnel_all_sinkpads_eos_unlocked (GstFunnel * funnel)
+gst_funnel_all_sinkpads_eos_unlocked (GstFunnel * funnel, GstPad * pad)
{
GstElement *element = GST_ELEMENT_CAST (funnel);
GList *item;
+ gboolean all_eos = FALSE;
+
+ GST_OBJECT_LOCK (funnel);
if (element->numsinkpads == 0)
- return FALSE;
+ goto done;
for (item = element->sinkpads; item != NULL; item = g_list_next (item)) {
GstPad *sinkpad = item->data;
GstEvent *eos;
+ /* eos event has not enrolled for current pad, we don't check for current pad */
+ if (pad == sinkpad)
+ continue;
+
eos = gst_pad_get_sticky_event (sinkpad, GST_EVENT_EOS, 0);
if (eos)
gst_event_unref (eos);
if (eos == NULL)
- return FALSE;
+ goto done;
}
- return TRUE;
+ all_eos = TRUE;
+
+done:
+ GST_OBJECT_UNLOCK (funnel);
+ return all_eos;
}
static void
@@ -190,12 +201,10 @@ gst_funnel_release_pad (GstElement * element, GstPad * pad)
gst_element_remove_pad (GST_ELEMENT_CAST (funnel), pad);
- GST_OBJECT_LOCK (funnel);
- if (eos == NULL && gst_funnel_all_sinkpads_eos_unlocked (funnel)) {
+ if (eos == NULL && gst_funnel_all_sinkpads_eos_unlocked (funnel, NULL)) {
GST_DEBUG_OBJECT (funnel, "Pad removed. All others are EOS. Sending EOS");
send_eos = TRUE;
}
- GST_OBJECT_UNLOCK (funnel);
if (send_eos)
if (!gst_pad_push_event (funnel->srcpad, gst_event_new_eos ()))
@@ -251,8 +260,12 @@ gst_funnel_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
unlock = TRUE;
GST_PAD_STREAM_LOCK (funnel->srcpad);
- if (pad != funnel->last_sinkpad)
+ if ((GST_EVENT_TYPE (event) == GST_EVENT_EOS) &&
+ (!gst_funnel_all_sinkpads_eos_unlocked (funnel, pad))) {
forward = FALSE;
+ } else if (pad != funnel->last_sinkpad) {
+ forward = FALSE;
+ }
}
if (forward)
diff --git a/tests/check/elements/funnel.c b/tests/check/elements/funnel.c
index fd41a73c6c..4b47917a06 100644
--- a/tests/check/elements/funnel.c
+++ b/tests/check/elements/funnel.c
@@ -212,6 +212,28 @@ GST_START_TEST (test_funnel_eos)
gst_object_unref (td.funnelsink11);
fail_unless (num_eos == 2);
+ /* send only eos to check, it handles empty streams */
+ td.funnelsink11 = gst_element_get_request_pad (td.funnel, "sink_11");
+ fail_unless (td.funnelsink11 != NULL);
+ fail_unless (!strcmp (GST_OBJECT_NAME (td.funnelsink11), "sink_11"));
+
+ fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (td.mysrc1,
+ td.funnelsink11)));
+
+ fail_unless (gst_pad_push_event (td.mysrc1, gst_event_new_flush_start ()));
+ fail_unless (gst_pad_push_event (td.mysrc1, gst_event_new_flush_stop (TRUE)));
+ fail_unless (gst_pad_push_event (td.mysrc2, gst_event_new_flush_start ()));
+ fail_unless (gst_pad_push_event (td.mysrc2, gst_event_new_flush_stop (TRUE)));
+
+ fail_unless (gst_pad_push_event (td.mysrc1, gst_event_new_eos ()));
+ fail_unless (gst_pad_push_event (td.mysrc2, gst_event_new_eos ()));
+ fail_unless (num_eos == 2);
+
+ fail_unless (gst_pad_unlink (td.mysrc1, td.funnelsink11));
+ gst_element_release_request_pad (td.funnel, td.funnelsink11);
+ gst_object_unref (td.funnelsink11);
+ fail_unless (num_eos == 3);
+
td.funnelsink11 = gst_element_get_request_pad (td.funnel, "sink_11");
fail_unless (td.funnelsink11 != NULL);
fail_unless (!strcmp (GST_OBJECT_NAME (td.funnelsink11), "sink_11"));