diff options
author | Srimanta Panda <srimanta@axis.com> | 2014-04-11 19:52:02 +0200 |
---|---|---|
committer | Olivier CrĂȘte <olivier.crete@collabora.com> | 2014-04-17 19:14:34 -0400 |
commit | 094fdfee7ec31019a54beb347457435cf9f62a0c (patch) | |
tree | 5585981b9754b7355da2114c1a0491a9687f12af | |
parent | 8b51e9dc60fcba2bf4a1c6cdaaffb562d2e7e6d3 (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.c | 29 | ||||
-rw-r--r-- | tests/check/elements/funnel.c | 22 |
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")); |