summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Hervey <edward@centricular.com>2015-04-29 15:56:39 +0200
committerEdward Hervey <bilboed@bilboed.com>2015-08-15 18:50:06 +0200
commit2d3743e37dd13d2211e4ec2c596c5a420e944d18 (patch)
treeb6b697ac037f9c670eb4c5b6205dbaca2ad20b72
parentd19f34722313dea3d4e1d13e914d89236c83e2e0 (diff)
decodebin2: Forward event/queries for unlinked groups
When upstream events/queries reach sinkpads of unlinked groups (i.e. no longer linked to the upstream demuxer), this patch attempts to find the linked group and forward it upstream of that group. This is done by adding upstream event/query probes on new group sinkpads and then: * Checking if the pad is linked or not (has a peer or not) * If there is a peer, just let the event/query follow through normally * If there is no peer, we find a pad to which to proxy it and return GST_PROBE_HANDLED if it succeeded (allowing the event/query to be properly returned to the initial called) Note that this is definitely not thread-safe for the time being https://bugzilla.gnome.org/show_bug.cgi?id=606382
-rw-r--r--gst/playback/gstdecodebin2.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c
index 0cf65e6dc..bb1909570 100644
--- a/gst/playback/gstdecodebin2.c
+++ b/gst/playback/gstdecodebin2.c
@@ -2853,6 +2853,81 @@ pad_added_cb (GstElement * element, GstPad * pad, GstDecodeChain * chain)
EXPOSE_UNLOCK (dbin);
}
+static GstPadProbeReturn
+sink_pad_event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
+{
+ GstDecodeGroup *group = (GstDecodeGroup *) user_data;
+ GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
+ GstPad *peer = gst_pad_get_peer (pad);
+ GstPadProbeReturn proberet = GST_PAD_PROBE_OK;
+
+ GST_DEBUG_OBJECT (pad, "Got upstream event %s", GST_EVENT_TYPE_NAME (event));
+
+ if (peer == NULL) {
+ GST_DEBUG_OBJECT (pad, "We are unlinked !");
+ if (group->parent && group->parent->next_groups) {
+ GstDecodeGroup *last_group =
+ g_list_last (group->parent->next_groups)->data;
+ GST_DEBUG_OBJECT (pad, "We could send the event to another group (%p)",
+ last_group);
+ /* Grab another sinkpad for that last group through which we will forward this event */
+ if (last_group->reqpads) {
+ GstPad *sinkpad = (GstPad *) last_group->reqpads->data;
+ GstPad *otherpeer = gst_pad_get_peer (sinkpad);
+ if (otherpeer) {
+ GST_DEBUG_OBJECT (otherpeer, "Attempting to forward event");
+ if (gst_pad_send_event (otherpeer, gst_event_ref (event))) {
+ proberet = GST_PAD_PROBE_HANDLED;
+ }
+ gst_object_unref (otherpeer);
+ }
+ } else
+ GST_DEBUG_OBJECT (pad, "No request pads, can't forward event");
+ }
+ } else
+ gst_object_unref (peer);
+
+ return proberet;
+}
+
+static GstPadProbeReturn
+sink_pad_query_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
+{
+ GstDecodeGroup *group = (GstDecodeGroup *) user_data;
+ GstPad *peer = gst_pad_get_peer (pad);
+ GstQuery *query = GST_PAD_PROBE_INFO_QUERY (info);
+ GstPadProbeReturn proberet = GST_PAD_PROBE_OK;
+
+ GST_DEBUG_OBJECT (pad, "Got upstream query %s", GST_QUERY_TYPE_NAME (query));
+
+ if (peer == NULL) {
+ GST_DEBUG_OBJECT (pad, "We are unlinked !");
+ if (group->parent && group->parent->next_groups) {
+ GstDecodeGroup *last_group =
+ g_list_last (group->parent->next_groups)->data;
+ GST_DEBUG_OBJECT (pad, "We could send the query to another group");
+ /* Grab another sinkpad for that last group through which we will forward this event */
+ if (last_group->reqpads) {
+ GstPad *sinkpad = (GstPad *) last_group->reqpads->data;
+ GstPad *otherpeer = gst_pad_get_peer (sinkpad);
+ if (otherpeer) {
+ GST_DEBUG_OBJECT (otherpeer, "Attempting to forward query");
+ if (gst_pad_query (otherpeer, query)) {
+ proberet = GST_PAD_PROBE_HANDLED;
+ } else
+ GST_DEBUG ("FAILURE");
+ gst_object_unref (otherpeer);
+ } else
+ GST_DEBUG_OBJECT (sinkpad, "request pad not connected ??");
+ } else
+ GST_DEBUG_OBJECT (pad, "No request pads ???");
+ }
+ } else
+ gst_object_unref (peer);
+
+ return proberet;
+}
+
static void
pad_removed_cb (GstElement * element, GstPad * pad, GstDecodeChain * chain)
{
@@ -3675,6 +3750,11 @@ gst_decode_group_control_demuxer_pad (GstDecodeGroup * group, GstPad * pad)
sinkpad);
goto error;
}
+ gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
+ sink_pad_event_probe, group, NULL);
+ gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_QUERY_UPSTREAM,
+ sink_pad_query_probe, group, NULL);
+
CHAIN_MUTEX_LOCK (group->parent);
group->reqpads = g_list_prepend (group->reqpads, gst_object_ref (sinkpad));
CHAIN_MUTEX_UNLOCK (group->parent);