diff options
Diffstat (limited to 'gst/gstpad.c')
-rw-r--r-- | gst/gstpad.c | 260 |
1 files changed, 63 insertions, 197 deletions
diff --git a/gst/gstpad.c b/gst/gstpad.c index 196f9f24b..73b43fba3 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -81,7 +81,6 @@ enum PAD_LINKED, PAD_UNLINKED, PAD_REQUEST_LINK, - PAD_HAVE_DATA, /* FILL ME */ LAST_SIGNAL }; @@ -102,9 +101,11 @@ struct _GstPadPushCache GstPad *peer; /* reffed peer pad */ }; +#if 0 static GstPadPushCache _pad_cache_invalid = { NULL, }; #define PAD_CACHE_INVALID (&_pad_cache_invalid) +#endif #define GST_PAD_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_PAD, GstPadPrivate)) @@ -160,9 +161,29 @@ typedef enum #define PAD_GET_STATE(p) g_atomic_int_get(&PAD_STATE(p)) #define PAD_UPDATE_STATE(p,o,n) g_atomic_int_compare_and_exchange (&PAD_STATE(p),(o),(n)) +#define PAD_STATE_SET(p,f) \ + G_STMT_START { \ + gint state, updated; \ + do { \ + state = PAD_GET_STATE (p); \ + updated = STATE_SET (state, f); \ + } while (!PAD_UPDATE_STATE (p, state, updated));\ + } G_STMT_END + +#define PAD_STATE_UNSET(p,f) \ + G_STMT_START { \ + gint state, updated; \ + do { \ + state = PAD_GET_STATE (p); \ + updated = STATE_UNSET (state, f); \ + } while (!PAD_UPDATE_STATE (p, state, updated));\ + } G_STMT_END + struct _GstPadPrivate { +#if 0 GstPadPushCache *cache_ptr; +#endif PadEvent events[GST_EVENT_MAX_STICKY]; @@ -273,6 +294,7 @@ gst_flow_to_quark (GstFlowReturn ret) G_DEFINE_TYPE_WITH_CODE (GstPad, gst_pad, GST_TYPE_OBJECT, _do_init); +#if 0 static gboolean _gst_do_pass_data_accumulator (GSignalInvocationHint * ihint, GValue * return_accu, const GValue * handler_return, gpointer dummy) @@ -290,6 +312,7 @@ default_have_data (GstPad * pad, GstMiniObject * o) { return TRUE; } +#endif static void gst_pad_class_init (GstPadClass * klass) @@ -343,24 +366,6 @@ gst_pad_class_init (GstPadClass * klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstPadClass, request_link), NULL, NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 0); - /** - * GstPad::have-data: - * @pad: the pad that emitted the signal - * @mini_obj: new data - * - * Signals that new data is available on the pad. This signal is used - * internally for implementing pad probes. - * See gst_pad_add_*_probe functions. - * - * Returns: %TRUE to keep the data, %FALSE to drop it - */ - gst_pad_signals[PAD_HAVE_DATA] = - g_signal_new ("have-data", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - G_STRUCT_OFFSET (GstPadClass, have_data), - _gst_do_pass_data_accumulator, - NULL, gst_marshal_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); - pspec_caps = g_param_spec_boxed ("caps", "Caps", "The capabilities of the pad", GST_TYPE_CAPS, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); @@ -385,8 +390,6 @@ gst_pad_class_init (GstPadClass * klass) GST_DEBUG_REGISTER_FUNCPTR (gst_pad_query_default); GST_DEBUG_REGISTER_FUNCPTR (gst_pad_iterate_internal_links_default); GST_DEBUG_REGISTER_FUNCPTR (gst_pad_acceptcaps_default); - - klass->have_data = default_have_data; } static void @@ -706,16 +709,16 @@ pre_activate (GstPad * pad, GstActivateMode new_mode) GST_DEBUG_OBJECT (pad, "setting ACTIVATE_MODE %d, unset flushing", new_mode); GST_PAD_UNSET_FLUSHING (pad); - PAD_STATE (pad) &= ~STATE_FLUSHING; + PAD_STATE_UNSET (pad, STATE_FLUSHING); GST_PAD_ACTIVATE_MODE (pad) = new_mode; GST_OBJECT_UNLOCK (pad); break; case GST_ACTIVATE_NONE: GST_OBJECT_LOCK (pad); GST_DEBUG_OBJECT (pad, "setting ACTIVATE_MODE NONE, set flushing"); - _priv_gst_pad_invalidate_cache (pad); + //_priv_gst_pad_invalidate_cache (pad); GST_PAD_SET_FLUSHING (pad); - PAD_STATE (pad) |= STATE_FLUSHING; + PAD_STATE_SET (pad, STATE_FLUSHING); GST_PAD_ACTIVATE_MODE (pad) = new_mode; /* unlock blocked pads so element can resume and stop */ GST_PAD_BLOCK_BROADCAST (pad); @@ -970,9 +973,9 @@ failure: GST_OBJECT_LOCK (pad); GST_CAT_INFO_OBJECT (GST_CAT_PADS, pad, "failed to %s in pull mode", active ? "activate" : "deactivate"); - _priv_gst_pad_invalidate_cache (pad); + //_priv_gst_pad_invalidate_cache (pad); GST_PAD_SET_FLUSHING (pad); - PAD_STATE (pad) |= STATE_FLUSHING; + PAD_STATE_SET (pad, STATE_FLUSHING); GST_PAD_ACTIVATE_MODE (pad) = old; GST_OBJECT_UNLOCK (pad); return FALSE; @@ -1077,9 +1080,9 @@ failure: GST_OBJECT_LOCK (pad); GST_CAT_INFO_OBJECT (GST_CAT_PADS, pad, "failed to %s in push mode", active ? "activate" : "deactivate"); - _priv_gst_pad_invalidate_cache (pad); + //_priv_gst_pad_invalidate_cache (pad); GST_PAD_SET_FLUSHING (pad); - PAD_STATE (pad) |= STATE_FLUSHING; + PAD_STATE_SET (pad, STATE_FLUSHING); GST_PAD_ACTIVATE_MODE (pad) = old; GST_OBJECT_UNLOCK (pad); return FALSE; @@ -1161,7 +1164,7 @@ gst_pad_set_blocked_async_full (GstPad * pad, gboolean blocked, if (blocked) { GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "blocking pad"); - _priv_gst_pad_invalidate_cache (pad); + //_priv_gst_pad_invalidate_cache (pad); GST_OBJECT_FLAG_SET (pad, GST_PAD_BLOCKED); if (pad->block_destroy_data && pad->block_data) @@ -1785,15 +1788,14 @@ gst_pad_unlink (GstPad * srcpad, GstPad * sinkpad) if (GST_PAD_UNLINKFUNC (sinkpad)) { GST_PAD_UNLINKFUNC (sinkpad) (sinkpad); } - - _priv_gst_pad_invalidate_cache (srcpad); + //_priv_gst_pad_invalidate_cache (srcpad); /* first clear peers */ GST_PAD_PEER (srcpad) = NULL; GST_PAD_PEER (sinkpad) = NULL; - PAD_STATE (srcpad) |= STATE_UNLINKED; - PAD_STATE (sinkpad) |= STATE_UNLINKED; + PAD_STATE_SET (srcpad, STATE_UNLINKED); + PAD_STATE_SET (sinkpad, STATE_UNLINKED); /* clear pending caps if any */ for (i = 0; i < GST_EVENT_MAX_STICKY; i++) @@ -2147,8 +2149,8 @@ gst_pad_link_full (GstPad * srcpad, GstPad * sinkpad, GstPadLinkCheck flags) GST_PAD_PEER (srcpad) = sinkpad; GST_PAD_PEER (sinkpad) = srcpad; - PAD_STATE (srcpad) &= ~STATE_UNLINKED; - PAD_STATE (sinkpad) &= ~STATE_UNLINKED; + PAD_STATE_UNSET (srcpad, STATE_UNLINKED); + PAD_STATE_UNSET (sinkpad, STATE_UNLINKED); /* make sure we push the events from the source to this new peer, for this we * copy the events on the sinkpad and mark EVENTS_PENDING */ @@ -3767,6 +3769,7 @@ done: } +#if 0 /********************************************************************** * Data passing functions */ @@ -3803,6 +3806,7 @@ gst_pad_emit_have_data_signal (GstPad * pad, GstMiniObject * obj) return res; } +#endif static void gst_pad_data_unref (gboolean is_buffer, void *data) @@ -3823,7 +3827,6 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data, { gboolean needs_events; GstFlowReturn ret; - gboolean emit_signal; GST_PAD_STREAM_LOCK (pad); @@ -3840,22 +3843,8 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data, if (G_UNLIKELY (ret != GST_FLOW_OK)) goto events_error; } - emit_signal = GST_PAD_DO_BUFFER_SIGNALS (pad) > 0; GST_OBJECT_UNLOCK (pad); - /* see if the signal should be emited */ - if (G_UNLIKELY (emit_signal)) { - cache = NULL; - if (G_LIKELY (is_buffer)) { - if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT_CAST (data))) - goto dropping; - } else { - /* chain all groups in the buffer list one by one to avoid problems with - * buffer probes that push buffers or events */ - goto chain_groups; - } - } - /* NOTE: we read the chainfunc unlocked. * we cannot hold the lock for the pad so we might send * the data to the wrong function. This is not really a @@ -3938,13 +3927,6 @@ flushing: GST_PAD_STREAM_UNLOCK (pad); return GST_FLOW_WRONG_STATE; } -dropping: - { - gst_pad_data_unref (is_buffer, data); - GST_DEBUG_OBJECT (pad, "Dropping buffer due to FALSE probe return"); - GST_PAD_STREAM_UNLOCK (pad); - return GST_FLOW_OK; - } events_error: { gst_pad_data_unref (is_buffer, data); @@ -4042,6 +4024,7 @@ gst_pad_chain_list (GstPad * pad, GstBufferList * list) return gst_pad_chain_data_unchecked (pad, FALSE, list, NULL); } +#if 0 static GstFlowReturn gst_pad_push_data (GstPad * pad, gboolean is_buffer, void *data, GstPadPushCache * cache) @@ -4057,25 +4040,6 @@ gst_pad_push_data (GstPad * pad, gboolean is_buffer, void *data, if ((ret = handle_pad_block (pad)) != GST_FLOW_OK) goto flushed; - /* we emit signals on the pad arg, the peer will have a chance to - * emit in the _chain() function */ - if (G_UNLIKELY (GST_PAD_DO_BUFFER_SIGNALS (pad) > 0)) { - cache = NULL; - /* unlock before emitting */ - GST_OBJECT_UNLOCK (pad); - - if (G_LIKELY (is_buffer)) { - /* if the signal handler returned FALSE, it means we should just drop the - * buffer */ - if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT_CAST (data))) - goto dropped; - } else { - /* push all buffers in the list */ - goto push_groups; - } - GST_OBJECT_LOCK (pad); - } - if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL)) goto not_linked; @@ -4134,7 +4098,9 @@ not_linked: return GST_FLOW_NOT_LINKED; } } +#endif +#if 0 static inline GstPadPushCache * pad_take_cache (GstPad * pad, gpointer * cache_ptr) { @@ -4202,6 +4168,7 @@ _priv_gst_pad_invalidate_cache (GstPad * pad) if (G_LIKELY (cache && cache != PAD_CACHE_INVALID)) pad_free_cache (cache); } +#endif /* do initial checks on @pad before dereffing the peer. * We have 2 possibilities: @@ -4215,7 +4182,7 @@ _priv_gst_pad_invalidate_cache (GstPad * pad) * when the pad was not in use. */ static GstFlowReturn -start_streaming (GstPad * pad) +start_streaming (GstPad * pad, GstPad ** peer) { GstFlowReturn ret; PadState state, updated; @@ -4255,6 +4222,11 @@ again: if (!PAD_UPDATE_STATE (pad, state, updated)) goto again; + /* FIXME, racy, the pad can go away. What we need to do is copy and ref the + * pad to some space */ + if (G_UNLIKELY ((*peer = GST_PAD_PEER (pad)) == NULL)) + goto not_linked; + return GST_FLOW_OK; /* ERRORS */ @@ -4280,7 +4252,7 @@ not_linked: * the FLUSHING, UNLINKED or BLOCK_PENDING flags */ static GstFlowReturn -stop_streaming (GstPad * pad) +stop_streaming (GstPad * pad, GstPad * peer) { GstFlowReturn ret; PadState state, updated; @@ -4385,12 +4357,9 @@ gst_pad_push (GstPad * pad, GstBuffer * buffer) g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR); g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR); - if ((ret = start_streaming (pad)) != GST_FLOW_OK) + if ((ret = start_streaming (pad, &peer)) != GST_FLOW_OK) goto error; - if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL)) - goto not_linked; - GST_PAD_STREAM_LOCK (peer); GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, @@ -4406,7 +4375,7 @@ gst_pad_push (GstPad * pad, GstBuffer * buffer) GST_PAD_STREAM_UNLOCK (peer); - stop_streaming (pad); + stop_streaming (pad, peer); return ret; @@ -4416,11 +4385,6 @@ error: GST_DEBUG_OBJECT (pad, "got an error %s", gst_flow_get_name (ret)); return ret; } -not_linked: - { - GST_DEBUG_OBJECT (pad, "no peer"); - return GST_FLOW_NOT_LINKED; - } } /** @@ -4462,64 +4426,32 @@ not_linked: GstFlowReturn gst_pad_push_list (GstPad * pad, GstBufferList * list) { - GstPadPushCache *cache; GstFlowReturn ret; - gpointer *cache_ptr; GstPad *peer; g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR); g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR); g_return_val_if_fail (GST_IS_BUFFER_LIST (list), GST_FLOW_ERROR); - cache_ptr = (gpointer *) & pad->priv->cache_ptr; - - cache = pad_take_cache (pad, cache_ptr); - - if (G_UNLIKELY (cache == NULL)) - goto slow_path; - - peer = cache->peer; + if ((ret = start_streaming (pad, &peer)) != GST_FLOW_OK) + goto error; GST_PAD_STREAM_LOCK (peer); - if (G_UNLIKELY (g_atomic_pointer_get (cache_ptr) == PAD_CACHE_INVALID)) - goto invalid; ret = GST_PAD_CHAINLISTFUNC (peer) (peer, list); GST_PAD_STREAM_UNLOCK (peer); - pad_put_cache (pad, cache, cache_ptr); + stop_streaming (pad, peer); return ret; /* slow path */ -slow_path: +error: { - GstPadPushCache scache = { NULL, }; - - GST_LOG_OBJECT (pad, "Taking slow path"); - - ret = gst_pad_push_data (pad, FALSE, list, &scache); - - if (scache.peer) { - GstPadPushCache *ncache; - - GST_LOG_OBJECT (pad, "Caching push data"); - - /* make cache structure */ - ncache = g_slice_new (GstPadPushCache); - *ncache = scache; - - pad_put_cache (pad, ncache, cache_ptr); - } + GST_DEBUG_OBJECT (pad, "got an error %s", gst_flow_get_name (ret)); return ret; } -invalid: - { - GST_PAD_STREAM_UNLOCK (peer); - pad_free_cache (cache); - goto slow_path; - } } static GstFlowReturn @@ -4528,15 +4460,12 @@ gst_pad_get_range_unchecked (GstPad * pad, guint64 offset, guint size, { GstFlowReturn ret; GstPadGetRangeFunction getrangefunc; - gboolean emit_signal; GST_PAD_STREAM_LOCK (pad); GST_OBJECT_LOCK (pad); if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad))) goto flushing; - - emit_signal = GST_PAD_DO_BUFFER_SIGNALS (pad) > 0; GST_OBJECT_UNLOCK (pad); if (G_UNLIKELY ((getrangefunc = GST_PAD_GETRANGEFUNC (pad)) == NULL)) @@ -4549,11 +4478,6 @@ gst_pad_get_range_unchecked (GstPad * pad, guint64 offset, guint size, ret = getrangefunc (pad, offset, size, buffer); - /* can only fire the signal if we have a valid buffer */ - if (G_UNLIKELY (emit_signal) && (ret == GST_FLOW_OK)) { - if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT_CAST (*buffer))) - goto dropping; - } GST_PAD_STREAM_UNLOCK (pad); if (G_UNLIKELY (ret != GST_FLOW_OK)) @@ -4578,15 +4502,6 @@ no_function: GST_PAD_STREAM_UNLOCK (pad); return GST_FLOW_NOT_SUPPORTED; } -dropping: - { - GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, - "Dropping data after FALSE probe return"); - GST_PAD_STREAM_UNLOCK (pad); - gst_buffer_unref (*buffer); - *buffer = NULL; - return GST_FLOW_UNEXPECTED; - } get_range_failed: { *buffer = NULL; @@ -4666,7 +4581,6 @@ gst_pad_pull_range (GstPad * pad, guint64 offset, guint size, { GstPad *peer; GstFlowReturn ret; - gboolean emit_signal; gboolean needs_events; g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR); @@ -4681,10 +4595,6 @@ gst_pad_pull_range (GstPad * pad, guint64 offset, guint size, if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL)) goto not_connected; - /* signal emision for the pad, peer has chance to emit when - * we call _get_range() */ - emit_signal = GST_PAD_DO_BUFFER_SIGNALS (pad) > 0; - gst_object_ref (peer); GST_OBJECT_UNLOCK (pad); @@ -4695,12 +4605,6 @@ gst_pad_pull_range (GstPad * pad, guint64 offset, guint size, if (G_UNLIKELY (ret != GST_FLOW_OK)) goto pull_range_failed; - /* can only fire the signal if we have a valid buffer */ - if (G_UNLIKELY (emit_signal)) { - if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT_CAST (*buffer))) - goto dropping; - } - GST_OBJECT_LOCK (pad); needs_events = GST_PAD_NEEDS_EVENTS (pad); @@ -4732,14 +4636,6 @@ pull_range_failed: pad, "pullrange failed, flow: %s", gst_flow_get_name (ret)); return ret; } -dropping: - { - GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, - "Dropping data after FALSE probe return"); - gst_buffer_unref (*buffer); - *buffer = NULL; - return GST_FLOW_UNEXPECTED; - } events_error: { GST_OBJECT_UNLOCK (pad); @@ -4787,9 +4683,9 @@ gst_pad_push_event (GstPad * pad, GstEvent * event) * . handle pad blocking */ switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_START: - _priv_gst_pad_invalidate_cache (pad); + //_priv_gst_pad_invalidate_cache (pad); GST_PAD_SET_FLUSHING (pad); - PAD_STATE (pad) |= STATE_FLUSHING; + PAD_STATE_SET (pad, STATE_FLUSHING); if (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad))) { @@ -4804,7 +4700,7 @@ gst_pad_push_event (GstPad * pad, GstEvent * event) break; case GST_EVENT_FLUSH_STOP: GST_PAD_UNSET_FLUSHING (pad); - PAD_STATE (pad) &= ~STATE_FLUSHING; + PAD_STATE_UNSET (pad, STATE_FLUSHING); /* if we are blocked, flush away the FLUSH_STOP event */ if (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad))) { @@ -4824,15 +4720,6 @@ gst_pad_push_event (GstPad * pad, GstEvent * event) break; } - if (G_UNLIKELY (GST_PAD_DO_EVENT_SIGNALS (pad) > 0)) { - GST_OBJECT_UNLOCK (pad); - - if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT_CAST (event))) - goto dropping; - - GST_OBJECT_LOCK (pad); - } - /* store the event on the pad, but only on srcpads */ if (GST_PAD_IS_SRC (pad) && GST_EVENT_IS_STICKY (event)) { guint idx; @@ -4901,12 +4788,6 @@ gst_pad_push_event (GstPad * pad, GstEvent * event) return result; /* ERROR handling */ -dropping: - { - GST_DEBUG_OBJECT (pad, "Dropping event after FALSE probe return"); - gst_event_unref (event); - return FALSE; - } not_linked: { GST_DEBUG_OBJECT (pad, "Dropping event because pad is not linked"); @@ -4974,15 +4855,6 @@ gst_pad_send_event (GstPad * pad, GstEvent * event) } else goto unknown_direction; - /* pad signals */ - if (G_UNLIKELY (GST_PAD_DO_EVENT_SIGNALS (pad) > 0)) { - GST_OBJECT_UNLOCK (pad); - - if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT_CAST (event))) - goto dropping; - - GST_OBJECT_LOCK (pad); - } /* get the flag first, we clear it when we have a FLUSH or a non-serialized * event. */ needs_events = GST_PAD_NEEDS_EVENTS (pad); @@ -4996,16 +4868,16 @@ gst_pad_send_event (GstPad * pad, GstEvent * event) if (GST_PAD_IS_FLUSHING (pad)) goto flushing; - _priv_gst_pad_invalidate_cache (pad); + //_priv_gst_pad_invalidate_cache (pad); GST_PAD_SET_FLUSHING (pad); - PAD_STATE (pad) |= STATE_FLUSHING; + PAD_STATE_SET (pad, STATE_FLUSHING); GST_CAT_DEBUG_OBJECT (GST_CAT_EVENT, pad, "set flush flag"); needs_events = FALSE; break; case GST_EVENT_FLUSH_STOP: if (G_LIKELY (GST_PAD_ACTIVATE_MODE (pad) != GST_ACTIVATE_NONE)) { GST_PAD_UNSET_FLUSHING (pad); - PAD_STATE (pad) &= ~STATE_FLUSHING; + PAD_STATE_UNSET (pad, STATE_FLUSHING); GST_CAT_DEBUG_OBJECT (GST_CAT_EVENT, pad, "cleared flush flag"); } GST_OBJECT_UNLOCK (pad); @@ -5146,12 +5018,6 @@ flushing: gst_event_unref (event); return FALSE; } -dropping: - { - GST_DEBUG_OBJECT (pad, "Dropping event after FALSE probe return"); - gst_event_unref (event); - return FALSE; - } update_failed: { GST_OBJECT_UNLOCK (pad); |