From 40228b4aa52a6f27f14d916265e19627adccfe41 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 26 May 2011 17:39:17 +0200 Subject: [PATCH] pad: refactor pre push code Refactor the code that is executed as the first step of a push operation where we check the probes and blocking and resolve the peer. --- gst/gstpad.c | 63 ++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/gst/gstpad.c b/gst/gstpad.c index f9581d2..ab7ef87 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -3897,22 +3897,25 @@ gst_pad_chain_list (GstPad * pad, GstBufferList * list) } static GstFlowReturn -gst_pad_push_data (GstPad * pad, gboolean is_buffer, void *data) +pad_pre_push (GstPad * pad, GstPad ** peer, gpointer data) { - GstPad *peer; GstFlowReturn ret; + gboolean need_probes, did_probes = FALSE; +again: GST_OBJECT_LOCK (pad); - /* FIXME: this check can go away; pad_set_blocked could be implemented with * probes completely or probes with an extended pad block. */ while (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad))) if ((ret = handle_pad_block (pad)) != GST_FLOW_OK) goto flushed; + need_probes = GST_PAD_DO_BUFFER_SIGNALS (pad) > 0; + /* 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 (G_UNLIKELY (need_probes && !did_probes)) { + did_probes = TRUE; /* unlock before emitting */ GST_OBJECT_UNLOCK (pad); @@ -3921,39 +3924,32 @@ gst_pad_push_data (GstPad * pad, gboolean is_buffer, void *data) if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT_CAST (data))) goto dropped; - GST_OBJECT_LOCK (pad); + goto again; } - if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL)) + if (G_UNLIKELY ((*peer = GST_PAD_PEER (pad)) == NULL)) goto not_linked; /* take ref to peer pad before releasing the lock */ - gst_object_ref (peer); + gst_object_ref (*peer); GST_OBJECT_UNLOCK (pad); - ret = gst_pad_chain_data_unchecked (peer, is_buffer, data); - - gst_object_unref (peer); - - return ret; + return GST_FLOW_OK; - /* ERROR recovery here */ + /* ERRORS */ flushed: { - gst_pad_data_unref (is_buffer, data); GST_DEBUG_OBJECT (pad, "pad block stopped by flush"); GST_OBJECT_UNLOCK (pad); return ret; } dropped: { - gst_pad_data_unref (is_buffer, data); GST_DEBUG_OBJECT (pad, "Dropping buffer due to FALSE probe return"); - return GST_FLOW_OK; + return GST_FLOW_CUSTOM_SUCCESS; } not_linked: { - gst_pad_data_unref (is_buffer, data); GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pushing, but it was not linked"); GST_OBJECT_UNLOCK (pad); @@ -3961,6 +3957,39 @@ not_linked: } } +static GstFlowReturn +gst_pad_push_data (GstPad * pad, gboolean is_buffer, void *data) +{ + GstPad *peer; + GstFlowReturn ret; + + if ((ret = pad_pre_push (pad, &peer, data)) != GST_FLOW_OK) + goto error; + + ret = gst_pad_chain_data_unchecked (peer, is_buffer, data); + + gst_object_unref (peer); + + return ret; + + /* ERROR recovery here */ +error: + { + gst_pad_data_unref (is_buffer, data); + + switch (ret) { + case GST_FLOW_CUSTOM_SUCCESS: + GST_DEBUG_OBJECT (pad, "dropped buffer"); + ret = GST_FLOW_OK; + break; + default: + GST_DEBUG_OBJECT (pad, "en error occured %s", gst_flow_get_name (ret)); + break; + } + return ret; + } +} + /** * gst_pad_push: * @pad: a source #GstPad, returns #GST_FLOW_ERROR if not. -- 2.7.4