diff options
author | Wim Taymans <wim.taymans@collabora.co.uk> | 2010-10-13 02:17:28 +0200 |
---|---|---|
committer | Wim Taymans <wim.taymans@collabora.co.uk> | 2010-12-03 11:28:52 +0100 |
commit | 14542a0d46efd5b9071575fdeaafd36e3dd87a07 (patch) | |
tree | 2a6a9eabba4e2c94f0379450a73acceb930c2c0f /gst | |
parent | 1c79181afd97ae371280c6019fac8fedddb9134d (diff) |
pad: add invalidate function
More small optimisations, remove the unneeded valid boolean.
Add function to invalide the cache.
Invalidate the cache on unlink.
Diffstat (limited to 'gst')
-rw-r--r-- | gst/gstpad.c | 52 |
1 files changed, 39 insertions, 13 deletions
diff --git a/gst/gstpad.c b/gst/gstpad.c index 2c6eb7caad..a365c3b7ba 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -99,12 +99,17 @@ typedef struct _GstPadPushCache GstPadPushCache; struct _GstPadPushCache { - gboolean valid; GstPad *peer; /* reffed peer pad */ GstCaps *caps; /* caps for this link */ GstPadChainFunction chainfunc; }; +static GstPadPushCache _pad_cache_invalid = { NULL, }; + +#define PAD_CACHE_INVALID (&_pad_cache_invalid) + +static void pad_invalidate_cache (GstPad * pad); + #define GST_PAD_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_PAD, GstPadPrivate)) @@ -1730,6 +1735,8 @@ gst_pad_unlink (GstPad * srcpad, GstPad * sinkpad) GST_PAD_UNLINKFUNC (sinkpad) (sinkpad); } + pad_invalidate_cache (srcpad); + /* first clear peers */ GST_PAD_PEER (srcpad) = NULL; GST_PAD_PEER (sinkpad) = NULL; @@ -4157,9 +4164,6 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data, gboolean caps_changed; GstFlowReturn ret; gboolean emit_signal; - gboolean do_cache; - - do_cache = cache ? cache->valid : FALSE; GST_PAD_STREAM_LOCK (pad); @@ -4176,7 +4180,7 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data, /* see if the signal should be emited, we emit before caps nego as * we might drop the buffer and do capsnego for nothing. */ if (G_UNLIKELY (emit_signal)) { - do_cache = FALSE; + cache = NULL; if (G_LIKELY (is_buffer)) { if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (data))) goto dropping; @@ -4208,12 +4212,10 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data, GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "calling chainfunction &%s", GST_DEBUG_FUNCPTR_NAME (chainfunc)); - if (do_cache) { + if (cache) { cache->peer = gst_object_ref (pad); cache->caps = caps ? gst_caps_ref (caps) : NULL; cache->chainfunc = chainfunc; - } else if (cache) { - cache->valid = FALSE; } ret = chainfunc (pad, GST_BUFFER_CAST (data)); @@ -4223,7 +4225,6 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data, GST_DEBUG_FUNCPTR_NAME (chainfunc), gst_flow_get_name (ret)); } else { GstPadChainListFunction chainlistfunc; - cache->valid = FALSE; if (G_UNLIKELY ((chainlistfunc = GST_PAD_CHAINLISTFUNC (pad)) == NULL)) goto chain_groups; @@ -4410,8 +4411,7 @@ gst_pad_push_data (GstPad * pad, gboolean is_buffer, void *data, /* 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)) { - if (cache) - cache->valid = FALSE; + cache = NULL; /* unlock before emitting */ GST_OBJECT_UNLOCK (pad); @@ -4531,6 +4531,10 @@ pad_take_cache (GstPad * pad, gpointer * cache_ptr) * with it */ } while (!g_atomic_pointer_compare_and_exchange (cache_ptr, cache, NULL)); + /* we could have a leftover invalid entry */ + if (G_UNLIKELY (cache == PAD_CACHE_INVALID)) + cache = NULL; + return cache; } @@ -4552,6 +4556,28 @@ pad_put_cache (GstPad * pad, GstPadPushCache * cache, gpointer * cache_ptr) } } +static void +pad_invalidate_cache (GstPad * pad) +{ + GstPadPushCache *cache; + gpointer *cache_ptr; + + cache_ptr = (gpointer *) & pad->abidata.ABI.priv->cache_ptr; + + /* try to get the cached data */ + do { + cache = g_atomic_pointer_get (cache_ptr); + /* now try to replace the pointer with INVALID. If nothing is busy with this + * caps, we get the cache and clean it up. If something is busy, we replace + * with INVALID so that when the function finishes and tries to put the + * cache back, it'll fail and cleanup */ + } while (!g_atomic_pointer_compare_and_exchange (cache_ptr, cache, + PAD_CACHE_INVALID)); + + if (G_LIKELY (cache && cache != PAD_CACHE_INVALID)) + pad_free_cache (cache); +} + /** * gst_pad_push: * @pad: a source #GstPad, returns #GST_FLOW_ERROR if not. @@ -4620,13 +4646,13 @@ gst_pad_push (GstPad * pad, GstBuffer * buffer) /* slow path */ slow_path: { - GstPadPushCache scache = { TRUE, NULL, NULL }; + GstPadPushCache scache = { NULL, }; GST_LOG_OBJECT (pad, "Taking slow path"); ret = gst_pad_push_data (pad, TRUE, buffer, &scache); - if (scache.valid) { + if (scache.peer) { GstPadPushCache *ncache; GST_LOG_OBJECT (pad, "Caching push data"); |