diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2014-02-09 11:06:52 +0100 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2014-02-09 11:06:52 +0100 |
commit | 54ba965e6376891d6d7e580732f2ab2de3d4a9cc (patch) | |
tree | 5f5c2d3ca58c0833fdae43f4e686f5bddd87d5e3 /gst/gstpad.c | |
parent | c05f749f91dae26d011bfd0e78ac7b99c2faf663 (diff) |
Imported Upstream version 1.2.3upstream/1.2.3
Diffstat (limited to 'gst/gstpad.c')
-rw-r--r-- | gst/gstpad.c | 109 |
1 files changed, 79 insertions, 30 deletions
diff --git a/gst/gstpad.c b/gst/gstpad.c index 3c3f484..794814b 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -544,6 +544,7 @@ restart: if (G_UNLIKELY (ev->event != ev_ret.event)) { if (G_UNLIKELY (ev_ret.event == NULL)) { /* function unreffed and set the event to NULL, remove it */ + gst_event_unref (ev->event); g_array_remove_index (events, i); len--; cookie = ++pad->priv->events_cookie; @@ -575,8 +576,9 @@ apply_pad_offset (GstPad * pad, GstEvent * event) gst_event_copy_segment (event, &segment); gst_event_unref (event); - /* adjust and make a new event with the offset applied */ - segment.base += pad->offset; + GST_DEBUG_OBJECT (pad, "apply pad offset %" GST_TIME_FORMAT, + GST_TIME_ARGS (pad->offset)); + gst_segment_offset_running_time (&segment, segment.format, pad->offset); event = gst_event_new_segment (&segment); } return event; @@ -1177,6 +1179,34 @@ gst_pad_is_active (GstPad * pad) return result; } +static void +cleanup_hook (GstPad * pad, GHook * hook) +{ + GstPadProbeType type; + + if (!G_HOOK_IS_VALID (hook)) + return; + + type = (hook->flags) >> G_HOOK_FLAG_USER_SHIFT; + + if (type & GST_PAD_PROBE_TYPE_BLOCKING) { + /* unblock when we remove the last blocking probe */ + pad->num_blocked--; + GST_DEBUG_OBJECT (pad, "remove blocking probe, now %d left", + pad->num_blocked); + + /* Might have new probes now that want to be called */ + GST_PAD_BLOCK_BROADCAST (pad); + + if (pad->num_blocked == 0) { + GST_DEBUG_OBJECT (pad, "last blocking probe removed, unblocking"); + GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_BLOCKED); + } + } + g_hook_destroy_link (&pad->probes, hook); + pad->num_probes--; +} + /** * gst_pad_add_probe: * @pad: the #GstPad to add the probe to @@ -1245,6 +1275,9 @@ gst_pad_add_probe (GstPad * pad, GstPadProbeType mask, GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_BLOCKED); GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "added blocking probe, " "now %d blocking probes", pad->num_blocked); + + /* Might have new probes now that want to be called */ + GST_PAD_BLOCK_BROADCAST (pad); } /* call the callback if we need to be called for idle callbacks */ @@ -1258,13 +1291,42 @@ gst_pad_add_probe (GstPad * pad, GstPadProbeType mask, GST_OBJECT_UNLOCK (pad); } else { GstPadProbeInfo info = { GST_PAD_PROBE_TYPE_IDLE, res, }; + GstPadProbeReturn ret; + + /* Keep another ref, the callback could destroy the pad */ + gst_object_ref (pad); /* the pad is idle now, we can signal the idle callback now */ GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pad is idle, trigger idle callback"); GST_OBJECT_UNLOCK (pad); - callback (pad, &info, user_data); + ret = callback (pad, &info, user_data); + + GST_OBJECT_LOCK (pad); + switch (ret) { + case GST_PAD_PROBE_REMOVE: + /* remove the probe */ + GST_DEBUG_OBJECT (pad, "asked to remove hook"); + cleanup_hook (pad, hook); + res = 0; + break; + case GST_PAD_PROBE_DROP: + GST_DEBUG_OBJECT (pad, "asked to drop item"); + break; + case GST_PAD_PROBE_PASS: + GST_DEBUG_OBJECT (pad, "asked to pass item"); + break; + case GST_PAD_PROBE_OK: + GST_DEBUG_OBJECT (pad, "probe returned OK"); + break; + default: + GST_DEBUG_OBJECT (pad, "probe returned %d", ret); + break; + } + GST_OBJECT_UNLOCK (pad); + + gst_object_unref (pad); } } else { GST_OBJECT_UNLOCK (pad); @@ -1272,31 +1334,6 @@ gst_pad_add_probe (GstPad * pad, GstPadProbeType mask, return res; } -static void -cleanup_hook (GstPad * pad, GHook * hook) -{ - GstPadProbeType type; - - if (!G_HOOK_IS_VALID (hook)) - return; - - type = (hook->flags) >> G_HOOK_FLAG_USER_SHIFT; - - if (type & GST_PAD_PROBE_TYPE_BLOCKING) { - /* unblock when we remove the last blocking probe */ - pad->num_blocked--; - GST_DEBUG_OBJECT (pad, "remove blocking probe, now %d left", - pad->num_blocked); - if (pad->num_blocked == 0) { - GST_DEBUG_OBJECT (pad, "last blocking probe removed, unblocking"); - GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_BLOCKED); - GST_PAD_BLOCK_BROADCAST (pad); - } - } - g_hook_destroy_link (&pad->probes, hook); - pad->num_probes--; -} - /** * gst_pad_remove_probe: * @pad: the #GstPad with the probe @@ -3026,8 +3063,9 @@ probe_hook_marshal (GHook * hook, ProbeMarshall * data) flags = hook->flags >> G_HOOK_FLAG_USER_SHIFT; type = info->type; - /* one of the data types */ - if ((flags & GST_PAD_PROBE_TYPE_ALL_BOTH & type) == 0) + /* one of the data types for non-idle probes */ + if ((type & GST_PAD_PROBE_TYPE_IDLE) == 0 + && (flags & GST_PAD_PROBE_TYPE_ALL_BOTH & type) == 0) goto no_match; /* one of the scheduling types */ if ((flags & GST_PAD_PROBE_TYPE_SCHEDULING & type) == 0) @@ -3036,6 +3074,9 @@ probe_hook_marshal (GHook * hook, ProbeMarshall * data) if ((type & GST_PAD_PROBE_TYPE_BLOCKING) && (flags & GST_PAD_PROBE_TYPE_BLOCKING & type) == 0) goto no_match; + if ((type & GST_PAD_PROBE_TYPE_BLOCKING) == 0 && + (flags & GST_PAD_PROBE_TYPE_BLOCKING)) + goto no_match; /* only probes that have GST_PAD_PROBE_TYPE_EVENT_FLUSH set */ if ((type & GST_PAD_PROBE_TYPE_EVENT_FLUSH) && (flags & GST_PAD_PROBE_TYPE_EVENT_FLUSH & type) == 0) @@ -3193,6 +3234,14 @@ again: GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_BLOCKING); GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "We got unblocked"); + /* if the list changed, call the new callbacks (they will not have their + * cookie set to data.cookie */ + if (cookie != pad->priv->probe_list_cookie) { + GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, + "probe list changed, restarting"); + goto again; + } + if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad))) goto flushing; } |