From f91c75395986fe66fdce7525c2a76701f023b15b Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 1 Jun 2011 19:34:54 +0200 Subject: [PATCH] probes: port to new API for blocking and probes --- gst-libs/gst/pbutils/gstdiscoverer.c | 14 +-- gst/playback/gstdecodebin.c | 17 +-- gst/playback/gstdecodebin2.c | 58 ++++++---- gst/playback/gstplaybasebin.c | 85 ++++++++------- gst/playback/gstplaybin.c | 34 ++++-- gst/playback/gstplaybin2.c | 66 +++++++----- gst/playback/gstplaysink.c | 68 ++++++++---- gst/playback/gstplaysinkaudioconvert.c | 53 +++++---- gst/playback/gstplaysinkaudioconvert.h | 2 +- gst/playback/gstplaysinkvideoconvert.c | 52 +++++---- gst/playback/gstplaysinkvideoconvert.h | 2 +- gst/playback/gststreaminfo.c | 10 +- gst/playback/gstsubtitleoverlay.c | 192 +++++++++++++++------------------ gst/playback/gstsubtitleoverlay.h | 2 + gst/playback/gsturidecodebin.c | 31 +++--- tests/icles/audio-trickplay.c | 13 ++- 16 files changed, 404 insertions(+), 295 deletions(-) diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c index 3a72eed..14d76e9 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/gst-libs/gst/pbutils/gstdiscoverer.c @@ -409,8 +409,9 @@ gst_discoverer_set_timeout (GstDiscoverer * dc, GstClockTime timeout) DISCO_UNLOCK (dc); } -static gboolean -_event_probe (GstPad * pad, GstEvent * event, PrivateStream * ps) +static GstProbeReturn +_event_probe (GstPad * pad, GstProbeType type, GstEvent * event, + PrivateStream * ps) { if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) { GstTagList *tl = NULL, *tmp; @@ -434,7 +435,7 @@ _event_probe (GstPad * pad, GstEvent * event, PrivateStream * ps) DISCO_UNLOCK (ps->dc); } - return TRUE; + return GST_PROBE_OK; } static void @@ -497,7 +498,8 @@ uridecodebin_pad_added_cb (GstElement * uridecodebin, GstPad * pad, gst_object_unref (sinkpad); /* Add an event probe */ - gst_pad_add_event_probe (pad, G_CALLBACK (_event_probe), ps); + gst_pad_add_probe (pad, GST_PROBE_TYPE_EVENT, + (GstPadProbeCallback) _event_probe, ps, NULL); DISCO_LOCK (dc); dc->priv->streams = g_list_append (dc->priv->streams, ps); @@ -989,8 +991,8 @@ discoverer_collect (GstDiscoverer * dc) gst_caps_get_structure (dc->priv->current_info->stream_info->caps, 0); if (g_str_has_prefix (gst_structure_get_name (st), "image/")) - ((GstDiscovererVideoInfo *) dc->priv->current_info-> - stream_info)->is_image = TRUE; + ((GstDiscovererVideoInfo *) dc->priv->current_info->stream_info)-> + is_image = TRUE; } } diff --git a/gst/playback/gstdecodebin.c b/gst/playback/gstdecodebin.c index 95a65d5..ef0571c 100644 --- a/gst/playback/gstdecodebin.c +++ b/gst/playback/gstdecodebin.c @@ -684,7 +684,7 @@ free_pad_probes (GstDecodeBin * decode_bin) for (tmp = decode_bin->probes; tmp; tmp = g_list_next (tmp)) { PadProbeData *data = (PadProbeData *) tmp->data; - gst_pad_remove_data_probe (data->pad, data->sigid); + gst_pad_remove_probe (data->pad, data->sigid); g_free (data); } g_list_free (decode_bin->probes); @@ -702,7 +702,7 @@ free_pad_probe_for_element (GstDecodeBin * decode_bin, GstElement * element) PadProbeData *data = (PadProbeData *) l->data; if (GST_ELEMENT_CAST (GST_PAD_PARENT (data->pad)) == element) { - gst_pad_remove_data_probe (data->pad, data->sigid); + gst_pad_remove_probe (data->pad, data->sigid); decode_bin->probes = g_list_delete_link (decode_bin->probes, l); g_free (data); return; @@ -774,9 +774,12 @@ remove_fakesink (GstDecodeBin * decode_bin) } /* this should be implemented with _pad_block() */ -static gboolean -pad_probe (GstPad * pad, GstMiniObject * data, GstDecodeBin * decode_bin) +static GstProbeReturn +pad_probe (GstPad * pad, GstProbeType type, gpointer type_data, + gpointer user_data) { + GstMiniObject *data = type_data; + GstDecodeBin *decode_bin = user_data; GList *tmp; gboolean alldone = TRUE; @@ -931,9 +934,9 @@ close_pad_link (GstElement * element, GstPad * pad, GstCaps * caps, data->pad = pad; data->done = FALSE; - /* FIXME, use _pad_block() */ - data->sigid = gst_pad_add_data_probe (pad, G_CALLBACK (pad_probe), - decode_bin); + /* FIXME, use pad blocking */ + data->sigid = gst_pad_add_probe (pad, GST_PROBE_TYPE_DATA, pad_probe, + decode_bin, NULL); decode_bin->numwaiting++; decode_bin->probes = g_list_append (decode_bin->probes, data); diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index 1b4a38f..b22ee69 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -465,6 +465,8 @@ struct _GstDecodePad gboolean blocked; /* the *target* pad is blocked */ gboolean exposed; /* the pad is exposed */ gboolean drained; /* an EOS has been seen on the pad */ + + gulong block_id; }; GType gst_decode_pad_get_type (void); @@ -480,7 +482,8 @@ static void gst_decode_pad_unblock (GstDecodePad * dpad); static void gst_decode_pad_set_blocked (GstDecodePad * dpad, gboolean blocked); static void gst_pending_pad_free (GstPendingPad * ppad); -static gboolean pad_event_cb (GstPad * pad, GstEvent * event, gpointer data); +static GstProbeReturn pad_event_cb (GstPad * pad, GstProbeType type, + gpointer type_data, gpointer data); /******************************** * Standard GObject boilerplate * @@ -1614,7 +1617,7 @@ setup_caps_delay: ppad->pad = gst_object_ref (pad); ppad->chain = chain; ppad->event_probe_id = - gst_pad_add_event_probe (pad, (GCallback) pad_event_cb, ppad); + gst_pad_add_probe (pad, GST_PROBE_TYPE_EVENT, pad_event_cb, ppad, NULL); chain->pending_pads = g_list_prepend (chain->pending_pads, ppad); CHAIN_MUTEX_UNLOCK (chain); g_signal_connect (G_OBJECT (pad), "notify::caps", @@ -1841,7 +1844,7 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad, } g_signal_handlers_disconnect_by_func (pp->pad, caps_notify_cb, chain); - gst_pad_remove_event_probe (pp->pad, pp->event_probe_id); + gst_pad_remove_probe (pp->pad, pp->event_probe_id); gst_object_unref (pp->pad); g_slice_free (GstPendingPad, pp); @@ -2135,9 +2138,11 @@ exit: return; } -static gboolean -pad_event_cb (GstPad * pad, GstEvent * event, gpointer data) +static GstProbeReturn +pad_event_cb (GstPad * pad, GstProbeType type, gpointer type_data, + gpointer data) { + GstEvent *event = type_data; GstPendingPad *ppad = (GstPendingPad *) data; GstDecodeChain *chain = ppad->chain; GstDecodeBin *dbin = chain->dbin; @@ -2159,7 +2164,7 @@ pad_event_cb (GstPad * pad, GstEvent * event, gpointer data) default: break; } - return TRUE; + return GST_PROBE_OK; } static void @@ -3454,9 +3459,11 @@ gst_decode_pad_init (GstDecodePad * pad) gst_object_ref_sink (pad); } -static void -source_pad_blocked_cb (GstPad * pad, GstBlockType type, GstDecodePad * dpad) +static GstProbeReturn +source_pad_blocked_cb (GstPad * pad, GstProbeType type, gpointer type_data, + gpointer user_data) { + GstDecodePad *dpad = user_data; GstDecodeChain *chain; GstDecodeBin *dbin; @@ -3473,11 +3480,17 @@ source_pad_blocked_cb (GstPad * pad, GstBlockType type, GstDecodePad * dpad) GST_WARNING_OBJECT (dbin, "Couldn't expose group"); } EXPOSE_UNLOCK (dbin); + + return GST_PROBE_OK; } -static gboolean -source_pad_event_probe (GstPad * pad, GstEvent * event, GstDecodePad * dpad) +static GstProbeReturn +source_pad_event_probe (GstPad * pad, GstProbeType type, gpointer type_data, + gpointer user_data) { + GstEvent *event = type_data; + GstDecodePad *dpad = user_data; + GST_LOG_OBJECT (pad, "%s dpad:%p", GST_EVENT_TYPE_NAME (event), dpad); if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) { @@ -3489,7 +3502,7 @@ source_pad_event_probe (GstPad * pad, GstEvent * event, GstDecodePad * dpad) gst_decode_pad_handle_eos (dpad); } /* never drop events */ - return TRUE; + return GST_PROBE_OK; } static void @@ -3510,11 +3523,15 @@ gst_decode_pad_set_blocked (GstDecodePad * dpad, gboolean blocked) * we do not consider/expect it blocked further below, but use other trick */ if (!blocked || !dbin->shutdown) { if (blocked) { - gst_pad_block (opad, GST_BLOCK_TYPE_DATA, - (GstPadBlockCallback) source_pad_blocked_cb, gst_object_ref (dpad), - (GDestroyNotify) gst_object_unref); + if (dpad->block_id == 0) + dpad->block_id = gst_pad_add_probe (opad, GST_PROBE_TYPE_BLOCK, + source_pad_blocked_cb, gst_object_ref (dpad), + (GDestroyNotify) gst_object_unref); } else { - gst_pad_unblock (opad); + if (dpad->block_id != 0) { + gst_pad_remove_probe (opad, dpad->block_id); + dpad->block_id = 0; + } dpad->blocked = FALSE; } } @@ -3546,8 +3563,8 @@ out: static void gst_decode_pad_add_drained_check (GstDecodePad * dpad) { - gst_pad_add_event_probe (GST_PAD_CAST (dpad), - G_CALLBACK (source_pad_event_probe), dpad); + gst_pad_add_probe (GST_PAD_CAST (dpad), GST_PROBE_TYPE_EVENT, + source_pad_event_probe, dpad, NULL); } static void @@ -3598,7 +3615,7 @@ gst_pending_pad_free (GstPendingPad * ppad) g_assert (ppad->pad); if (ppad->event_probe_id != 0) - gst_pad_remove_event_probe (ppad->pad, ppad->event_probe_id); + gst_pad_remove_probe (ppad->pad, ppad->event_probe_id); gst_object_unref (ppad->pad); g_slice_free (GstPendingPad, ppad); } @@ -3675,7 +3692,10 @@ unblock_pads (GstDecodeBin * dbin) continue; GST_DEBUG_OBJECT (dpad, "unblocking"); - gst_pad_unblock (opad); + if (dpad->block_id != 0) { + gst_pad_remove_probe (opad, dpad->block_id); + dpad->block_id = 0; + } dpad->blocked = FALSE; /* make flushing, prevent NOT_LINKED */ GST_PAD_SET_FLUSHING (GST_PAD_CAST (dpad)); diff --git a/gst/playback/gstplaybasebin.c b/gst/playback/gstplaybasebin.c index 3591f89..492977a 100644 --- a/gst/playback/gstplaybasebin.c +++ b/gst/playback/gstplaybasebin.c @@ -91,8 +91,8 @@ static gboolean has_all_raw_caps (GstPad * pad, gboolean * all_raw); static gboolean prepare_output (GstPlayBaseBin * play_base_bin); static void set_active_source (GstPlayBaseBin * play_base_bin, GstStreamType type, gint source_num); -static gboolean probe_triggered (GstPad * pad, GstEvent * event, - gpointer user_data); +static GstProbeReturn probe_triggered (GstPad * pad, GstProbeType type, + gpointer type_data, gpointer user_data); static void setup_substreams (GstPlayBaseBin * play_base_bin); static GstPipelineClass *parent_class; @@ -527,9 +527,11 @@ fill_buffer (GstPlayBaseBin * play_base_bin, gint percent) gst_message_new_buffering (GST_OBJECT_CAST (play_base_bin), percent)); } -static gboolean -check_queue_event (GstPad * pad, GstEvent * event, gpointer user_data) +static GstProbeReturn +check_queue_event (GstPad * pad, GstProbeType type, gpointer type_data, + gpointer user_data) { + GstEvent *event = type_data; GstElement *queue = GST_ELEMENT_CAST (user_data); switch (GST_EVENT_TYPE (event)) { @@ -545,11 +547,12 @@ check_queue_event (GstPad * pad, GstEvent * event, gpointer user_data) GST_DEBUG ("uninteresting event %s", GST_EVENT_TYPE_NAME (event)); break; } - return TRUE; + return GST_PROBE_OK; } -static gboolean -check_queue (GstPad * pad, GstBuffer * data, gpointer user_data) +static GstProbeReturn +check_queue (GstPad * pad, GstProbeType type, gpointer type_data, + gpointer user_data) { GstElement *queue = GST_ELEMENT_CAST (user_data); GstPlayBaseBin *play_base_bin = g_object_get_data (G_OBJECT (queue), "pbb"); @@ -571,7 +574,7 @@ check_queue (GstPad * pad, GstBuffer * data, gpointer user_data) fill_buffer (play_base_bin, level); /* continue! */ - return TRUE; + return GST_PROBE_OK; } /* If a queue overruns and we are buffer in streaming mode (we have a min-time) @@ -638,7 +641,7 @@ queue_remove_probe (GstElement * queue, GstPlayBaseBin * play_base_bin) GST_DEBUG_PAD_NAME (sinkpad), sinkpad); g_object_set_data (G_OBJECT (queue), "probe", NULL); - gst_pad_remove_buffer_probe (sinkpad, GPOINTER_TO_INT (data)); + gst_pad_remove_probe (sinkpad, GPOINTER_TO_INT (data)); } else { GST_DEBUG_OBJECT (play_base_bin, "No buffer probe to remove from %s:%s (%p)", @@ -753,7 +756,8 @@ queue_out_of_data (GstElement * queue, GstPlayBaseBin * play_base_bin) guint id; sinkpad = gst_element_get_static_pad (queue, "sink"); - id = gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (check_queue), queue); + id = gst_pad_add_probe (sinkpad, GST_PROBE_TYPE_BUFFER, check_queue, queue, + NULL); g_object_set_data (G_OBJECT (queue), "probe", GINT_TO_POINTER (id)); GST_DEBUG_OBJECT (play_base_bin, "Re-attaching buffering probe to pad %s:%s %p", @@ -878,14 +882,15 @@ gen_preroll_element (GstPlayBaseBin * play_base_bin, /* give updates on queue size */ sinkpad = gst_element_get_static_pad (preroll, "sink"); - id = gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (check_queue), preroll); + id = gst_pad_add_probe (sinkpad, GST_PROBE_TYPE_BUFFER, check_queue, + preroll, NULL); GST_DEBUG_OBJECT (play_base_bin, "Attaching probe to pad %s:%s (%p)", GST_DEBUG_PAD_NAME (sinkpad), sinkpad); g_object_set_data (G_OBJECT (preroll), "probe", GINT_TO_POINTER (id)); /* catch eos and flush events so that we can ignore underruns */ - id = gst_pad_add_event_probe (sinkpad, G_CALLBACK (check_queue_event), - preroll); + id = gst_pad_add_probe (sinkpad, GST_PROBE_TYPE_EVENT, check_queue_event, + preroll, NULL); g_object_set_data (G_OBJECT (preroll), "eos_probe", GINT_TO_POINTER (id)); gst_object_unref (sinkpad); @@ -900,7 +905,8 @@ gen_preroll_element (GstPlayBaseBin * play_base_bin, /* listen for EOS so we can switch groups when one ended. */ preroll_pad = gst_element_get_static_pad (preroll, "src"); - gst_pad_add_event_probe (preroll_pad, G_CALLBACK (probe_triggered), info); + gst_pad_add_probe (preroll_pad, GST_PROBE_TYPE_EVENT, probe_triggered, info, + NULL); gst_object_unref (preroll_pad); /* add to group list */ @@ -1159,27 +1165,29 @@ source_no_more_pads (GstElement * element, GstPlayBaseBin * bin) no_more_pads_full (element, FALSE, bin); } -static gboolean -probe_triggered (GstPad * pad, GstEvent * event, gpointer user_data) +static GstProbeReturn +probe_triggered (GstPad * pad, GstProbeType type, gpointer type_data, + gpointer user_data) { + GstEvent *event = type_data; GstPlayBaseGroup *group; GstPlayBaseBin *play_base_bin; GstStreamInfo *info; - GstEventType type; + GstEventType etype; - type = GST_EVENT_TYPE (event); + etype = GST_EVENT_TYPE (event); GST_LOG ("probe triggered, (%d) %s", type, gst_event_type_get_name (type)); /* we only care about EOS */ - if (type != GST_EVENT_EOS) - return TRUE; + if (etype != GST_EVENT_EOS) + return GST_PROBE_OK; info = GST_STREAM_INFO (user_data); group = (GstPlayBaseGroup *) g_object_get_data (G_OBJECT (info), "group"); play_base_bin = group->bin; - if (type == GST_EVENT_EOS) { + if (etype == GST_EVENT_EOS) { gint num_groups = 0; gboolean have_left; @@ -1208,7 +1216,7 @@ probe_triggered (GstPad * pad, GstEvent * event, gpointer user_data) GROUP_UNLOCK (play_base_bin); /* remove the EOS if we have something left */ - return !have_left; + return (have_left ? GST_PROBE_DROP : GST_PROBE_OK); } if (have_left) { @@ -1236,14 +1244,14 @@ probe_triggered (GstPad * pad, GstEvent * event, gpointer user_data) g_object_notify (G_OBJECT (play_base_bin), "stream-info"); /* get rid of the EOS event */ - return FALSE; + return GST_PROBE_DROP; } else { GROUP_UNLOCK (play_base_bin); GST_LOG ("Last group done, EOS"); } } - return TRUE; + return GST_PROBE_OK; } /* This function will be called when the sinkpad of the preroll element @@ -1283,8 +1291,8 @@ preroll_unlinked (GstPad * pad, GstPad * peerpad, /* Mute stream on first data - for header-is-in-stream-stuff * (vorbis, ogmtext). */ -static gboolean -mute_stream (GstPad * pad, GstBuffer * buf, gpointer data) +static GstProbeReturn +mute_stream (GstPad * pad, GstProbeType type, gpointer type_data, gpointer data) { GstStreamInfo *info = GST_STREAM_INFO (data); guint id; @@ -1295,20 +1303,21 @@ mute_stream (GstPad * pad, GstBuffer * buf, gpointer data) id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info), "mute_probe")); g_object_set_data (G_OBJECT (info), "mute_probe", NULL); if (id > 0) - gst_pad_remove_buffer_probe (GST_PAD_CAST (info->object), id); + gst_pad_remove_probe (GST_PAD_CAST (info->object), id); /* no data */ - return FALSE; + return GST_PROBE_DROP; } /* Eat data. */ -static gboolean -silence_stream (GstPad * pad, GstMiniObject * data, gpointer user_data) +static GstProbeReturn +silence_stream (GstPad * pad, GstProbeType type, gpointer type_data, + gpointer user_data) { GST_DEBUG ("silence stream triggered"); /* no data */ - return FALSE; + return GST_PROBE_DROP; } /* Called by the signal handlers when a decodebin (main or subtitle) has @@ -1409,8 +1418,8 @@ new_decoded_pad_full (GstElement * element, GstPad * pad, gboolean last, GST_DEBUG ("Adding silence_stream data probe on type %d (npads %d)", type, group->type[type - 1].npads); - id = gst_pad_add_data_probe (GST_PAD_CAST (pad), - G_CALLBACK (silence_stream), info); + id = gst_pad_add_probe (GST_PAD_CAST (pad), GST_PROBE_TYPE_DATA, + silence_stream, info, NULL); g_object_set_data (G_OBJECT (pad), "eat_probe", GINT_TO_POINTER (id)); } @@ -1760,7 +1769,7 @@ setup_substreams (GstPlayBaseBin * play_base_bin) data = g_object_get_data (G_OBJECT (info->object), "eat_probe"); if (data) { - gst_pad_remove_data_probe (GST_PAD_CAST (info->object), + gst_pad_remove_probe (GST_PAD_CAST (info->object), GPOINTER_TO_INT (data)); g_object_set_data (G_OBJECT (info->object), "eat_probe", NULL); } @@ -1771,8 +1780,8 @@ setup_substreams (GstPlayBaseBin * play_base_bin) id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info), "mute_probe")); if (id == 0) { - id = gst_pad_add_buffer_probe (GST_PAD_CAST (info->object), - G_CALLBACK (mute_stream), info); + id = gst_pad_add_probe (GST_PAD_CAST (info->object), + GST_PROBE_TYPE_BUFFER, mute_stream, info, NULL); g_object_set_data (G_OBJECT (info), "mute_probe", GINT_TO_POINTER (id)); } } @@ -2515,8 +2524,8 @@ set_active_source (GstPlayBaseBin * play_base_bin, GST_LOG_OBJECT (info->object, "Muting source %d of type %d", num, type); - id = gst_pad_add_buffer_probe (GST_PAD_CAST (info->object), - G_CALLBACK (mute_stream), info); + id = gst_pad_add_probe (GST_PAD_CAST (info->object), + GST_PROBE_TYPE_BUFFER, mute_stream, info, NULL); g_object_set_data (G_OBJECT (info), "mute_probe", GINT_TO_POINTER (id)); } num++; diff --git a/gst/playback/gstplaybin.c b/gst/playback/gstplaybin.c index 3b39b8d..8ff5e98 100644 --- a/gst/playback/gstplaybin.c +++ b/gst/playback/gstplaybin.c @@ -287,6 +287,10 @@ struct _GstPlayBin /* indication if the pipeline is live */ gboolean is_live; + + /* probes */ + gulong text_id; + gulong sub_id; }; struct _GstPlayBinClass @@ -504,9 +508,9 @@ gst_play_bin_dispose (GObject * object) G_OBJECT_CLASS (parent_class)->dispose (object); } -static void -gst_play_bin_vis_blocked (GstPad * tee_pad, GstBlockType type, - gpointer user_data) +static GstProbeReturn +gst_play_bin_vis_blocked (GstPad * tee_pad, GstProbeType type, + gpointer type_data, gpointer user_data) { GstPlayBin *play_bin = GST_PLAY_BIN (user_data); GstBin *vis_bin = NULL; @@ -607,8 +611,8 @@ beach: gst_object_unref (vis_bin); } - /* Unblock the pad */ - gst_pad_unblock (tee_pad); + /* unblock the pad and remove the probe */ + return GST_PROBE_REMOVE; } static void @@ -690,7 +694,7 @@ gst_play_bin_set_property (GObject * object, guint prop_id, play_bin->pending_visualisation = pending_visualisation; /* Block with callback */ - gst_pad_block (tee_pad, GST_BLOCK_TYPE_DATA, + gst_pad_add_probe (tee_pad, GST_PROBE_TYPE_BLOCK, gst_play_bin_vis_blocked, play_bin, NULL); beach: if (vis_sink_pad) { @@ -1650,7 +1654,9 @@ setup_sinks (GstPlayBaseBin * play_base_bin, GstPlayBaseGroup * group) "file, ghosting to a suitable hierarchy"); /* Block the pad first, because as soon as we add a ghostpad, the queue * will try and start pushing */ - gst_pad_block (textsrcpad, GST_BLOCK_TYPE_DATA, NULL, NULL, NULL); + play_bin->text_id = + gst_pad_add_probe (textsrcpad, GST_PROBE_TYPE_BLOCK, NULL, NULL, + NULL); origtextsrcpad = gst_object_ref (textsrcpad); ghost = gst_ghost_pad_new ("text_src", textsrcpad); @@ -1694,7 +1700,10 @@ setup_sinks (GstPlayBaseBin * play_base_bin, GstPlayBaseGroup * group) if (textsrcpad) gst_object_unref (textsrcpad); if (origtextsrcpad) { - gst_pad_unblock (origtextsrcpad); + if (play_bin->text_id) { + gst_pad_remove_probe (origtextsrcpad, play_bin->text_id); + play_bin->text_id = 0; + } gst_object_unref (origtextsrcpad); } @@ -1709,12 +1718,17 @@ setup_sinks (GstPlayBaseBin * play_base_bin, GstPlayBaseGroup * group) spu_sink_pad = gst_element_get_static_pad (sink, "subpicture_sink"); if (subpic_pad && spu_sink_pad) { GST_LOG_OBJECT (play_bin, "Linking DVD subpicture stream onto SPU"); - gst_pad_block (subpic_pad, GST_BLOCK_TYPE_DATA, NULL, NULL, NULL); + play_bin->sub_id = + gst_pad_add_probe (subpic_pad, GST_PROBE_TYPE_BLOCK, NULL, NULL, + NULL); if (gst_pad_link (subpic_pad, spu_sink_pad) != GST_PAD_LINK_OK) { GST_WARNING_OBJECT (play_bin, "Failed to link DVD subpicture stream onto SPU"); } - gst_pad_unblock (subpic_pad); + if (play_bin->sub_id) { + gst_pad_remove_probe (subpic_pad, play_bin->sub_id); + play_bin->sub_id = 0; + } } if (subpic_pad) gst_object_unref (subpic_pad); diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c index 39a56aa..4a8192b 100644 --- a/gst/playback/gstplaybin2.c +++ b/gst/playback/gstplaybin2.c @@ -266,6 +266,7 @@ struct _GstSourceSelect */ GstEvent *sinkpad_delayed_event; gulong sinkpad_data_probe; + gulong block_id; }; #define GST_SOURCE_GROUP_GET_LOCK(group) (((GstSourceGroup*)(group))->lock) @@ -324,6 +325,8 @@ struct _GstSourceGroup gulong sub_no_more_pads_id; gulong sub_autoplug_continue_id; + gulong block_id; + GMutex *stream_changed_pending_lock; GList *stream_changed_pending; @@ -557,8 +560,8 @@ static void no_more_pads_cb (GstElement * decodebin, GstSourceGroup * group); static void pad_removed_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group); -static void gst_play_bin_suburidecodebin_block (GstElement * suburidecodebin, - gboolean block); +static void gst_play_bin_suburidecodebin_block (GstSourceGroup * group, + GstElement * suburidecodebin, gboolean block); static void gst_play_bin_suburidecodebin_seek_to_start (GstElement * suburidecodebin); @@ -1131,7 +1134,7 @@ free_group (GstPlayBin * playbin, GstSourceGroup * group) for (n = 0; n < PLAYBIN_STREAM_LAST; n++) { GstSourceSelect *select = &group->selector[n]; if (select->sinkpad && select->sinkpad_data_probe) - gst_pad_remove_data_probe (select->sinkpad, select->sinkpad_data_probe); + gst_pad_remove_probe (select->sinkpad, select->sinkpad_data_probe); if (select->sinkpad_delayed_event) gst_event_unref (select->sinkpad_delayed_event); } @@ -1613,8 +1616,8 @@ gst_play_bin_suburidecodebin_seek_to_start (GstElement * suburidecodebin) } static void -gst_play_bin_suburidecodebin_block (GstElement * suburidecodebin, - gboolean block) +gst_play_bin_suburidecodebin_block (GstSourceGroup * group, + GstElement * suburidecodebin, gboolean block) { GstIterator *it = gst_element_iterate_src_pads (suburidecodebin); gboolean done = FALSE; @@ -1630,10 +1633,14 @@ gst_play_bin_suburidecodebin_block (GstElement * suburidecodebin, switch (gst_iterator_next (it, &item)) { case GST_ITERATOR_OK: sinkpad = g_value_get_object (&item); - if (block) - gst_pad_block (sinkpad, GST_BLOCK_TYPE_DATA, NULL, NULL, NULL); - else - gst_pad_unblock (sinkpad); + if (block) { + group->block_id = + gst_pad_add_probe (sinkpad, GST_PROBE_TYPE_BLOCK, NULL, NULL, + NULL); + } else if (group->block_id) { + gst_pad_remove_probe (sinkpad, group->block_id); + group->block_id = 0; + } g_value_reset (&item); break; case GST_ITERATOR_DONE: @@ -1722,7 +1729,8 @@ gst_play_bin_set_current_text_stream (GstPlayBin * playbin, gint stream) /* Block all suburidecodebin sinkpads */ if (need_block) - gst_play_bin_suburidecodebin_block (group->suburidecodebin, TRUE); + gst_play_bin_suburidecodebin_block (group, group->suburidecodebin, + TRUE); /* activate the selected pad */ g_object_set (selector, "active-pad", sinkpad, NULL); @@ -1745,7 +1753,8 @@ gst_play_bin_set_current_text_stream (GstPlayBin * playbin, gint stream) /* Unblock pads if necessary */ if (need_unblock) - gst_play_bin_suburidecodebin_block (group->suburidecodebin, FALSE); + gst_play_bin_suburidecodebin_block (group, group->suburidecodebin, + FALSE); /* seek to the beginning */ if (need_seek) @@ -2365,14 +2374,15 @@ selector_active_pad_changed (GObject * selector, GParamSpec * pspec, } /* this callback sends a delayed event once the pad becomes unblocked */ -static gboolean -stream_changed_data_probe (GstPad * pad, GstMiniObject * object, gpointer data) +static GstProbeReturn +stream_changed_data_probe (GstPad * pad, GstProbeType type, + GstMiniObject * object, gpointer data) { GstSourceSelect *select = (GstSourceSelect *) data; GstEvent *e; /* we need do this just once, so cleanup first */ - gst_pad_remove_data_probe (pad, select->sinkpad_data_probe); + gst_pad_remove_probe (pad, select->sinkpad_data_probe); select->sinkpad_data_probe = 0; e = select->sinkpad_delayed_event; select->sinkpad_delayed_event = NULL; @@ -2380,7 +2390,7 @@ stream_changed_data_probe (GstPad * pad, GstMiniObject * object, gpointer data) /* really, this should not happen */ if (!e) { GST_WARNING ("Data probed called, but no delayed event"); - return TRUE; + return GST_PROBE_OK; } if (GST_IS_EVENT (object) @@ -2389,11 +2399,11 @@ stream_changed_data_probe (GstPad * pad, GstMiniObject * object, gpointer data) gst_event_ref (GST_EVENT_CAST (object)); gst_pad_send_event (pad, GST_EVENT_CAST (object)); gst_pad_send_event (pad, e); - return FALSE; + return GST_PROBE_DROP; } else { /* send delayed event, then allow the caller to go on */ gst_pad_send_event (pad, e); - return TRUE; + return GST_PROBE_OK; } } @@ -2536,7 +2546,9 @@ pad_added_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group) * streams and connect the sinks, resulting in not-linked errors. After we * configured the sinks we will unblock them all. */ GST_DEBUG_OBJECT (playbin, "blocking %" GST_PTR_FORMAT, select->srcpad); - gst_pad_block (select->srcpad, GST_BLOCK_TYPE_DATA, NULL, NULL, NULL); + select->block_id = + gst_pad_add_probe (select->srcpad, GST_PROBE_TYPE_BLOCK, NULL, NULL, + NULL); } /* get sinkpad for the new stream */ @@ -2831,8 +2843,7 @@ no_more_pads_cb (GstElement * decodebin, GstSourceGroup * group) gst_event_unref (select->sinkpad_delayed_event); select->sinkpad_delayed_event = event; if (select->sinkpad_data_probe) - gst_pad_remove_data_probe (select->sinkpad, - select->sinkpad_data_probe); + gst_pad_remove_probe (select->sinkpad, select->sinkpad_data_probe); /* we go to the trouble of setting a probe on the pad to send the playbin2-stream-changed event as sending it here might @@ -2840,8 +2851,9 @@ no_more_pads_cb (GstElement * decodebin, GstSourceGroup * group) pad might not be linked yet. Additionally, sending it here apparently would be on the wrong thread */ select->sinkpad_data_probe = - gst_pad_add_data_probe (select->sinkpad, - (GCallback) stream_changed_data_probe, (gpointer) select); + gst_pad_add_probe (select->sinkpad, GST_PROBE_TYPE_DATA, + (GstPadProbeCallback) stream_changed_data_probe, (gpointer) select, + NULL); g_mutex_unlock (group->stream_changed_pending_lock); gst_message_unref (msg); @@ -2850,7 +2862,10 @@ no_more_pads_cb (GstElement * decodebin, GstSourceGroup * group) if (select->srcpad) { GST_DEBUG_OBJECT (playbin, "unblocking %" GST_PTR_FORMAT, select->srcpad); - gst_pad_unblock (select->srcpad); + if (select->block_id) { + gst_pad_remove_probe (select->srcpad, select->block_id); + select->block_id = 0; + } } } GST_SOURCE_GROUP_UNLOCK (group); @@ -2882,7 +2897,10 @@ shutdown: } GST_DEBUG_OBJECT (playbin, "unblocking %" GST_PTR_FORMAT, select->srcpad); - gst_pad_unblock (select->srcpad); + if (select->block_id) { + gst_pad_remove_probe (select->srcpad, select->block_id); + select->block_id = 0; + } } } GST_SOURCE_GROUP_UNLOCK (group); diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c index 37c4cf3..b696a88 100644 --- a/gst/playback/gstplaysink.c +++ b/gst/playback/gstplaysink.c @@ -153,6 +153,7 @@ struct _GstPlaySink gboolean audio_pad_blocked; GstPad *audio_srcpad_stream_synchronizer; GstPad *audio_sinkpad_stream_synchronizer; + gulong audio_block_id; /* audio tee */ GstElement *audio_tee; GstPad *audio_tee_sink; @@ -164,11 +165,13 @@ struct _GstPlaySink gboolean video_pad_blocked; GstPad *video_srcpad_stream_synchronizer; GstPad *video_sinkpad_stream_synchronizer; + gulong video_block_id; /* text */ GstPad *text_pad; gboolean text_pad_blocked; GstPad *text_srcpad_stream_synchronizer; GstPad *text_sinkpad_stream_synchronizer; + gulong text_block_id; /* properties */ GstElement *audio_sink; @@ -661,9 +664,9 @@ gst_play_sink_get_sink (GstPlaySink * playsink, GstPlaySinkType type) return result; } -static void -gst_play_sink_vis_blocked (GstPad * tee_pad, GstBlockType type, - gpointer user_data) +static GstProbeReturn +gst_play_sink_vis_blocked (GstPad * tee_pad, GstProbeType type, + gpointer type_data, gpointer user_data) { GstPlaySink *playsink; GstPlayVisChain *chain; @@ -700,9 +703,10 @@ gst_play_sink_vis_blocked (GstPad * tee_pad, GstBlockType type, chain->vissrcpad); done: - /* Unblock the pad */ - gst_pad_unblock (tee_pad); GST_PLAY_SINK_UNLOCK (playsink); + + /* remove the probe and unblock the pad */ + return GST_PROBE_REMOVE; } void @@ -739,7 +743,7 @@ gst_play_sink_set_vis_plugin (GstPlaySink * playsink, GstElement * vis) * function returns FALSE but the previous pad block will do the right thing * anyway. */ GST_DEBUG_OBJECT (playsink, "blocking vis pad"); - gst_pad_block (chain->blockpad, GST_BLOCK_TYPE_DATA, + gst_pad_add_probe (chain->blockpad, GST_PROBE_TYPE_BLOCK, gst_play_sink_vis_blocked, playsink, NULL); done: GST_PLAY_SINK_UNLOCK (playsink); @@ -2858,8 +2862,9 @@ is_raw_pad (GstPad * pad) return raw; } -static void -sinkpad_blocked_cb (GstPad * blockedpad, GstBlockType type, gpointer user_data) +static GstProbeReturn +sinkpad_blocked_cb (GstPad * blockedpad, GstProbeType type, gpointer type_data, + gpointer user_data) { GstPlaySink *playsink = (GstPlaySink *) user_data; GstPad *pad; @@ -2901,7 +2906,8 @@ sinkpad_blocked_cb (GstPad * blockedpad, GstBlockType type, gpointer user_data) GstPad *opad = GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (playsink->video_pad))); - gst_pad_unblock (opad); + gst_pad_remove_probe (opad, playsink->video_block_id); + playsink->video_block_id = 0; gst_object_unref (opad); playsink->video_pad_blocked = FALSE; } @@ -2910,7 +2916,8 @@ sinkpad_blocked_cb (GstPad * blockedpad, GstBlockType type, gpointer user_data) GstPad *opad = GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (playsink->audio_pad))); - gst_pad_unblock (opad); + gst_pad_remove_probe (opad, playsink->audio_block_id); + playsink->audio_block_id = 0; gst_object_unref (opad); playsink->audio_pad_blocked = FALSE; } @@ -2919,7 +2926,8 @@ sinkpad_blocked_cb (GstPad * blockedpad, GstBlockType type, gpointer user_data) GstPad *opad = GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (playsink->text_pad))); - gst_pad_unblock (opad); + gst_pad_remove_probe (opad, playsink->text_block_id); + playsink->text_block_id = 0; gst_object_unref (opad); playsink->text_pad_blocked = FALSE; } @@ -2928,6 +2936,8 @@ sinkpad_blocked_cb (GstPad * blockedpad, GstBlockType type, gpointer user_data) gst_object_unref (pad); GST_PLAY_SINK_UNLOCK (playsink); + + return GST_PROBE_OK; } static void @@ -2965,8 +2975,10 @@ caps_notify_cb (GstPad * pad, GParamSpec * unused, GstPlaySink * playsink) GstPad *opad = GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (playsink->video_pad))); - gst_pad_block (opad, GST_BLOCK_TYPE_DATA, sinkpad_blocked_cb, - gst_object_ref (playsink), (GDestroyNotify) gst_object_unref); + if (playsink->video_block_id == 0) + playsink->video_block_id = + gst_pad_add_probe (opad, GST_PROBE_TYPE_BLOCK, sinkpad_blocked_cb, + gst_object_ref (playsink), (GDestroyNotify) gst_object_unref); gst_object_unref (opad); } @@ -2974,8 +2986,10 @@ caps_notify_cb (GstPad * pad, GParamSpec * unused, GstPlaySink * playsink) GstPad *opad = GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (playsink->audio_pad))); - gst_pad_block (opad, GST_BLOCK_TYPE_DATA, sinkpad_blocked_cb, - gst_object_ref (playsink), (GDestroyNotify) gst_object_unref); + if (playsink->audio_block_id == 0) + playsink->audio_block_id = + gst_pad_add_probe (opad, GST_PROBE_TYPE_BLOCK, sinkpad_blocked_cb, + gst_object_ref (playsink), (GDestroyNotify) gst_object_unref); gst_object_unref (opad); } @@ -2983,8 +2997,10 @@ caps_notify_cb (GstPad * pad, GParamSpec * unused, GstPlaySink * playsink) GstPad *opad = GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (playsink->text_pad))); - gst_pad_block (opad, GST_BLOCK_TYPE_DATA, sinkpad_blocked_cb, - gst_object_ref (playsink), (GDestroyNotify) gst_object_unref); + if (playsink->text_block_id == 0) + playsink->text_block_id = + gst_pad_add_probe (opad, GST_PROBE_TYPE_BLOCK, sinkpad_blocked_cb, + gst_object_ref (playsink), (GDestroyNotify) gst_object_unref); gst_object_unref (opad); } GST_PLAY_SINK_UNLOCK (playsink); @@ -3007,6 +3023,7 @@ gst_play_sink_request_pad (GstPlaySink * playsink, GstPlaySinkType type) gboolean created = FALSE; gboolean activate = TRUE; const gchar *pad_name = NULL; + gulong *block_id = NULL; GST_DEBUG_OBJECT (playsink, "request pad type %d", type); @@ -3046,6 +3063,7 @@ gst_play_sink_request_pad (GstPlaySink * playsink, GstPlaySinkType type) } playsink->audio_pad_raw = FALSE; res = playsink->audio_pad; + block_id = &playsink->audio_block_id; break; case GST_PLAY_SINK_TYPE_VIDEO_RAW: case GST_PLAY_SINK_TYPE_VIDEO: @@ -3060,6 +3078,7 @@ gst_play_sink_request_pad (GstPlaySink * playsink, GstPlaySinkType type) } playsink->video_pad_raw = FALSE; res = playsink->video_pad; + block_id = &playsink->video_block_id; break; case GST_PLAY_SINK_TYPE_TEXT: GST_LOG_OBJECT (playsink, "ghosting text"); @@ -3069,6 +3088,7 @@ gst_play_sink_request_pad (GstPlaySink * playsink, GstPlaySinkType type) created = TRUE; } res = playsink->text_pad; + block_id = &playsink->text_block_id; break; case GST_PLAY_SINK_TYPE_FLUSHING: { @@ -3094,11 +3114,12 @@ gst_play_sink_request_pad (GstPlaySink * playsink, GstPlaySinkType type) * element is 'running' */ gst_pad_set_active (res, TRUE); gst_element_add_pad (GST_ELEMENT_CAST (playsink), res); - if (type != GST_PLAY_SINK_TYPE_FLUSHING) { + if (block_id && *block_id == 0) { GstPad *blockpad = GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (res))); - gst_pad_block (blockpad, GST_BLOCK_TYPE_DATA, sinkpad_blocked_cb, + *block_id = + gst_pad_add_probe (blockpad, GST_PROBE_TYPE_BLOCK, sinkpad_blocked_cb, gst_object_ref (playsink), (GDestroyNotify) gst_object_unref); gst_object_unref (blockpad); } @@ -3350,7 +3371,8 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition) GstPad *opad = GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (playsink->video_pad))); - gst_pad_unblock (opad); + gst_pad_remove_probe (opad, playsink->video_block_id); + playsink->video_block_id = 0; gst_object_unref (opad); playsink->video_pad_blocked = FALSE; } @@ -3360,7 +3382,8 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition) GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (playsink->audio_pad))); - gst_pad_unblock (opad); + gst_pad_remove_probe (opad, playsink->audio_block_id); + playsink->audio_block_id = 0; gst_object_unref (opad); playsink->audio_pad_blocked = FALSE; } @@ -3369,7 +3392,8 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition) GstPad *opad = GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (playsink->text_pad))); - gst_pad_unblock (opad); + gst_pad_remove_probe (opad, playsink->text_block_id); + playsink->text_block_id = 0; gst_object_unref (opad); playsink->text_pad_blocked = FALSE; } diff --git a/gst/playback/gstplaysinkaudioconvert.c b/gst/playback/gstplaysinkaudioconvert.c index b4aba3b..307c96b 100644 --- a/gst/playback/gstplaysinkaudioconvert.c +++ b/gst/playback/gstplaysinkaudioconvert.c @@ -72,15 +72,16 @@ post_missing_element_message (GstPlaySinkAudioConvert * self, gst_element_post_message (GST_ELEMENT_CAST (self), msg); } -static void -pad_blocked_cb (GstPad * pad, gboolean blocked, GstPlaySinkAudioConvert * self) +static GstProbeReturn +pad_blocked_cb (GstPad * pad, GstProbeType type, gpointer type_data, + gpointer user_data) { + GstPlaySinkAudioConvert *self = user_data; GstPad *peer; GstCaps *caps; gboolean raw; GST_PLAY_SINK_AUDIO_CONVERT_LOCK (self); - self->sink_proxypad_blocked = TRUE; GST_DEBUG_OBJECT (self, "Pad blocked"); /* There must be a peer at this point */ @@ -204,11 +205,9 @@ pad_blocked_cb (GstPad * pad, gboolean blocked, GstPlaySinkAudioConvert * self) } unblock: - gst_pad_unblock (self->sink_proxypad); - self->sink_proxypad_blocked = FALSE; - GST_PLAY_SINK_AUDIO_CONVERT_UNLOCK (self); - return; + + return GST_PROBE_REMOVE; link_failed: { @@ -216,9 +215,29 @@ link_failed: (NULL), ("Failed to configure the audio converter.")); gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), self->sink_proxypad); - gst_pad_unblock (self->sink_proxypad); - self->sink_proxypad_blocked = FALSE; - return; + GST_PLAY_SINK_AUDIO_CONVERT_UNLOCK (self); + + return GST_PROBE_REMOVE; + } +} + +static void +block_proxypad (GstPlaySinkAudioConvert * self) +{ + if (self->sink_proxypad_block_id == 0) { + self->sink_proxypad_block_id = + gst_pad_add_probe (self->sink_proxypad, GST_PROBE_TYPE_BLOCK, + pad_blocked_cb, gst_object_ref (self), + (GDestroyNotify) gst_object_unref); + } +} + +static void +unblock_proxypad (GstPlaySinkAudioConvert * self) +{ + if (self->sink_proxypad_block_id != 0) { + gst_pad_remove_probe (self->sink_proxypad, self->sink_proxypad_block_id); + self->sink_proxypad_block_id = 0; } } @@ -270,17 +289,13 @@ gst_play_sink_audio_convert_sink_setcaps (GstPad * pad, GstCaps * caps) if (!self->raw && !gst_pad_is_blocked (self->sink_proxypad)) { GST_DEBUG_OBJECT (self, "Changing caps from non-raw to raw"); reconfigure = TRUE; - gst_pad_block (self->sink_proxypad, GST_BLOCK_TYPE_DATA, - (GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + block_proxypad (self); } } else { if (self->raw && !gst_pad_is_blocked (self->sink_proxypad)) { GST_DEBUG_OBJECT (self, "Changing caps from raw to non-raw"); reconfigure = TRUE; - gst_pad_block (self->sink_proxypad, GST_BLOCK_TYPE_DATA, - (GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + block_proxypad (self); } } @@ -354,8 +369,7 @@ gst_play_sink_audio_convert_change_state (GstElement * element, switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: GST_PLAY_SINK_AUDIO_CONVERT_LOCK (self); - gst_pad_unblock (self->sink_proxypad); - self->sink_proxypad_blocked = FALSE; + unblock_proxypad (self); GST_PLAY_SINK_AUDIO_CONVERT_UNLOCK (self); break; default: @@ -393,8 +407,7 @@ gst_play_sink_audio_convert_change_state (GstElement * element, break; case GST_STATE_CHANGE_READY_TO_PAUSED: GST_PLAY_SINK_AUDIO_CONVERT_LOCK (self); - gst_pad_unblock (self->sink_proxypad); - self->sink_proxypad_blocked = FALSE; + unblock_proxypad (self); GST_PLAY_SINK_AUDIO_CONVERT_UNLOCK (self); default: break; diff --git a/gst/playback/gstplaysinkaudioconvert.h b/gst/playback/gstplaysinkaudioconvert.h index e7d48bc..f9a0791 100644 --- a/gst/playback/gstplaysinkaudioconvert.h +++ b/gst/playback/gstplaysinkaudioconvert.h @@ -64,7 +64,7 @@ struct _GstPlaySinkAudioConvert GMutex *lock; GstPad *sinkpad, *sink_proxypad; - gboolean sink_proxypad_blocked; + gulong sink_proxypad_block_id; GstSegment segment; GstPad *srcpad; diff --git a/gst/playback/gstplaysinkvideoconvert.c b/gst/playback/gstplaysinkvideoconvert.c index 4d44704..5c20fb9 100644 --- a/gst/playback/gstplaysinkvideoconvert.c +++ b/gst/playback/gstplaysinkvideoconvert.c @@ -72,15 +72,16 @@ post_missing_element_message (GstPlaySinkVideoConvert * self, gst_element_post_message (GST_ELEMENT_CAST (self), msg); } -static void -pad_blocked_cb (GstPad * pad, GstBlockType type, GstPlaySinkVideoConvert * self) +static GstProbeReturn +pad_blocked_cb (GstPad * pad, GstProbeType type, gpointer type_data, + gpointer user_data) { + GstPlaySinkVideoConvert *self = user_data; GstPad *peer; GstCaps *caps; gboolean raw; GST_PLAY_SINK_VIDEO_CONVERT_LOCK (self); - self->sink_proxypad_blocked = TRUE; GST_DEBUG_OBJECT (self, "Pad blocked"); /* There must be a peer at this point */ @@ -185,11 +186,9 @@ pad_blocked_cb (GstPad * pad, GstBlockType type, GstPlaySinkVideoConvert * self) } unblock: - gst_pad_unblock (self->sink_proxypad); - self->sink_proxypad_blocked = FALSE; - GST_PLAY_SINK_VIDEO_CONVERT_UNLOCK (self); - return; + + return GST_PROBE_REMOVE; link_failed: { @@ -197,9 +196,29 @@ link_failed: (NULL), ("Failed to configure the video converter.")); gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), self->sink_proxypad); - gst_pad_unblock (self->sink_proxypad); - self->sink_proxypad_blocked = FALSE; + GST_PLAY_SINK_VIDEO_CONVERT_UNLOCK (self); + + return GST_PROBE_REMOVE; + } +} + +static void +block_proxypad (GstPlaySinkVideoConvert * self) +{ + if (self->sink_proxypad_block_id != 0) return; + + self->sink_proxypad_block_id = + gst_pad_add_probe (self->sink_proxypad, GST_PROBE_TYPE_BLOCK, + pad_blocked_cb, gst_object_ref (self), (GDestroyNotify) gst_object_unref); +} + +static void +unblock_proxypad (GstPlaySinkVideoConvert * self) +{ + if (self->sink_proxypad_block_id != 0) { + gst_pad_remove_probe (self->sink_proxypad, self->sink_proxypad_block_id); + self->sink_proxypad_block_id = 0; } } @@ -252,17 +271,13 @@ gst_play_sink_video_convert_sink_setcaps (GstPad * pad, GstCaps * caps) if (!self->raw && !gst_pad_is_blocked (self->sink_proxypad)) { GST_DEBUG_OBJECT (self, "Changing caps from non-raw to raw"); reconfigure = TRUE; - gst_pad_block (self->sink_proxypad, GST_BLOCK_TYPE_DATA, - (GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + block_proxypad (self); } } else { if (self->raw && !gst_pad_is_blocked (self->sink_proxypad)) { GST_DEBUG_OBJECT (self, "Changing caps from raw to non-raw"); reconfigure = TRUE; - gst_pad_block (self->sink_proxypad, GST_BLOCK_TYPE_DATA, - (GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + block_proxypad (self); } } @@ -333,8 +348,7 @@ gst_play_sink_video_convert_change_state (GstElement * element, switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: GST_PLAY_SINK_VIDEO_CONVERT_LOCK (self); - gst_pad_unblock (self->sink_proxypad); - self->sink_proxypad_blocked = FALSE; + unblock_proxypad (self); GST_PLAY_SINK_VIDEO_CONVERT_UNLOCK (self); break; default: @@ -367,9 +381,7 @@ gst_play_sink_video_convert_change_state (GstElement * element, case GST_STATE_CHANGE_READY_TO_PAUSED: GST_PLAY_SINK_VIDEO_CONVERT_LOCK (self); if (!gst_pad_is_blocked (self->sink_proxypad)) - gst_pad_block (self->sink_proxypad, GST_BLOCK_TYPE_DATA, - (GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + block_proxypad (self); GST_PLAY_SINK_VIDEO_CONVERT_UNLOCK (self); default: break; diff --git a/gst/playback/gstplaysinkvideoconvert.h b/gst/playback/gstplaysinkvideoconvert.h index 83b3b1e..9c32976 100644 --- a/gst/playback/gstplaysinkvideoconvert.h +++ b/gst/playback/gstplaysinkvideoconvert.h @@ -64,7 +64,7 @@ struct _GstPlaySinkVideoConvert GMutex *lock; GstPad *sinkpad, *sink_proxypad; - gboolean sink_proxypad_blocked; + gulong sink_proxypad_block_id; GstSegment segment; GstPad *srcpad; diff --git a/gst/playback/gststreaminfo.c b/gst/playback/gststreaminfo.c index 86ec58a..cfbc9b2 100644 --- a/gst/playback/gststreaminfo.c +++ b/gst/playback/gststreaminfo.c @@ -175,9 +175,11 @@ gst_stream_info_init (GstStreamInfo * stream_info) stream_info->caps = NULL; } -static gboolean -cb_probe (GstPad * pad, GstEvent * e, gpointer user_data) +static GstProbeReturn +cb_probe (GstPad * pad, GstProbeType type, gpointer type_data, + gpointer user_data) { + GstEvent *e = type_data; GstStreamInfo *info = user_data; if (GST_EVENT_TYPE (e) == GST_EVENT_TAG) { @@ -225,8 +227,8 @@ gst_stream_info_new (GstObject * object, gst_object_ref (object); if (GST_IS_PAD (object)) { - gst_pad_add_event_probe (GST_PAD_CAST (object), - G_CALLBACK (cb_probe), info); + gst_pad_add_probe (GST_PAD_CAST (object), GST_PROBE_TYPE_EVENT, + cb_probe, info, NULL); } info->object = object; info->type = type; diff --git a/gst/playback/gstsubtitleoverlay.c b/gst/playback/gstsubtitleoverlay.c index 1d6dca5..24deac1 100644 --- a/gst/playback/gstsubtitleoverlay.c +++ b/gst/playback/gstsubtitleoverlay.c @@ -82,9 +82,6 @@ enum #define gst_subtitle_overlay_parent_class parent_class G_DEFINE_TYPE (GstSubtitleOverlay, gst_subtitle_overlay, GST_TYPE_BIN); -static void _pad_blocked_cb (GstPad * pad, GstBlockType type, - gpointer user_data); - static GQuark _subtitle_overlay_event_marker_id = 0; static void @@ -112,6 +109,58 @@ do_async_done (GstSubtitleOverlay * self) } } +static GstProbeReturn +_pad_blocked_cb (GstPad * pad, GstProbeType type, gpointer type_data, + gpointer user_data); + +static void +block_video (GstSubtitleOverlay * self) +{ + if (self->video_block_id != 0) + return; + + if (self->video_block_pad) { + self->video_block_id = + gst_pad_add_probe (self->video_block_pad, GST_PROBE_TYPE_BLOCK, + _pad_blocked_cb, gst_object_ref (self), + (GDestroyNotify) gst_object_unref); + } +} + +static void +unblock_video (GstSubtitleOverlay * self) +{ + if (self->video_block_id) { + gst_pad_remove_probe (self->video_block_pad, self->video_block_id); + self->video_sink_blocked = FALSE; + self->video_block_id = 0; + } +} + +static void +block_subtitle (GstSubtitleOverlay * self) +{ + if (self->subtitle_block_id != 0) + return; + + if (self->subtitle_block_pad) { + self->subtitle_block_id = + gst_pad_add_probe (self->subtitle_block_pad, GST_PROBE_TYPE_BLOCK, + _pad_blocked_cb, gst_object_ref (self), + (GDestroyNotify) gst_object_unref); + } +} + +static void +unblock_subtitle (GstSubtitleOverlay * self) +{ + if (self->subtitle_block_id) { + gst_pad_remove_probe (self->subtitle_block_pad, self->subtitle_block_id); + self->subtitle_sink_blocked = FALSE; + self->subtitle_block_id = 0; + } +} + static void gst_subtitle_overlay_finalize (GObject * object) { @@ -590,13 +639,8 @@ _setup_passthrough (GstSubtitleOverlay * self) out: /* Unblock pads */ - gst_pad_unblock (self->video_block_pad); - self->video_sink_blocked = FALSE; - - if (self->subtitle_sink_blocked) { - gst_pad_unblock (self->subtitle_block_pad); - self->subtitle_sink_blocked = FALSE; - } + unblock_video (self); + unblock_subtitle (self); return TRUE; } @@ -667,8 +711,9 @@ _has_font_desc_property (GstElement * element) return (pspec && pspec->value_type == G_TYPE_STRING); } -static void -_pad_blocked_cb (GstPad * pad, GstBlockType type, gpointer user_data) +static GstProbeReturn +_pad_blocked_cb (GstPad * pad, GstProbeType type, gpointer type_data, + gpointer user_data) { GstSubtitleOverlay *self = GST_SUBTITLE_OVERLAY_CAST (user_data); GstCaps *subcaps; @@ -733,13 +778,8 @@ _pad_blocked_cb (GstPad * pad, GstBlockType type, gpointer user_data) gst_object_unref (target); /* Unblock pads */ - gst_pad_unblock (self->video_block_pad); - self->video_sink_blocked = FALSE; - - if (self->subtitle_sink_blocked) { - gst_pad_unblock (self->subtitle_block_pad); - self->subtitle_sink_blocked = FALSE; - } + unblock_video (self); + unblock_subtitle (self); goto out; } else if (target) { @@ -749,9 +789,7 @@ _pad_blocked_cb (GstPad * pad, GstBlockType type, gpointer user_data) if (self->subtitle_sink_blocked && !self->video_sink_blocked) { GST_DEBUG_OBJECT (self, "Subtitle sink blocked but video not blocked"); - gst_pad_block (self->video_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + block_video (self); goto out; } @@ -1198,10 +1236,8 @@ _pad_blocked_cb (GstPad * pad, GstBlockType type, gpointer user_data) do_async_done (self); } else { GST_DEBUG_OBJECT (self, "Everything worked, unblocking pads"); - gst_pad_unblock (self->video_block_pad); - self->video_sink_blocked = FALSE; - gst_pad_unblock (self->subtitle_block_pad); - self->subtitle_sink_blocked = FALSE; + unblock_video (self); + unblock_subtitle (self); do_async_done (self); } @@ -1209,6 +1245,8 @@ out: if (factories) gst_plugin_feature_list_free (factories); GST_SUBTITLE_OVERLAY_UNLOCK (self); + + return GST_PROBE_OK; } static GstStateChangeReturn @@ -1230,12 +1268,8 @@ gst_subtitle_overlay_change_state (GstElement * element, GST_SUBTITLE_OVERLAY_LOCK (self); /* Set the internal pads to blocking */ - gst_pad_block (self->video_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); - gst_pad_block (self->subtitle_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + block_video (self); + block_subtitle (self); GST_SUBTITLE_OVERLAY_UNLOCK (self); break; case GST_STATE_CHANGE_READY_TO_PAUSED: @@ -1284,9 +1318,7 @@ gst_subtitle_overlay_change_state (GstElement * element, do_async_done (self); break; - case GST_STATE_CHANGE_READY_TO_NULL:{ - GstPad *pad; - + case GST_STATE_CHANGE_READY_TO_NULL: GST_DEBUG_OBJECT (self, "State change READY->NULL"); GST_SUBTITLE_OVERLAY_LOCK (self); @@ -1299,17 +1331,8 @@ gst_subtitle_overlay_change_state (GstElement * element, NULL); /* Unblock pads */ - if (self->video_block_pad) { - pad = self->video_block_pad; - gst_pad_unblock (pad); - self->video_sink_blocked = FALSE; - } - - if (self->subtitle_block_pad) { - pad = self->subtitle_block_pad; - gst_pad_unblock (pad); - self->subtitle_sink_blocked = FALSE; - } + unblock_video (self); + unblock_subtitle (self); /* Remove elements */ self->silent_property = NULL; @@ -1322,7 +1345,6 @@ gst_subtitle_overlay_change_state (GstElement * element, GST_SUBTITLE_OVERLAY_UNLOCK (self); break; - } default: break; } @@ -1367,13 +1389,8 @@ gst_subtitle_overlay_handle_message (GstBin * bin, GstMessage * message) GST_SUBTITLE_OVERLAY_LOCK (self); self->subtitle_error = TRUE; - gst_pad_block (self->subtitle_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); - - gst_pad_block (self->video_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + block_subtitle (self); + block_video (self); GST_SUBTITLE_OVERLAY_UNLOCK (self); } } @@ -1428,13 +1445,8 @@ gst_subtitle_overlay_set_property (GObject * object, guint prop_id, else if (self->renderer) g_object_set (self->renderer, self->silent_property, silent, NULL); } else { - gst_pad_block (self->subtitle_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); - - gst_pad_block (self->video_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + block_subtitle (self); + block_video (self); } GST_SUBTITLE_OVERLAY_UNLOCK (self); break; @@ -1665,13 +1677,8 @@ gst_subtitle_overlay_video_sink_chain (GstPad * pad, GstBuffer * buffer) gst_flow_get_name (ret)); GST_SUBTITLE_OVERLAY_LOCK (self); self->subtitle_error = TRUE; - gst_pad_block (self->subtitle_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); - - gst_pad_block (self->video_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + block_subtitle (self); + block_video (self); GST_SUBTITLE_OVERLAY_UNLOCK (self); return GST_FLOW_OK; @@ -1696,13 +1703,8 @@ gst_subtitle_overlay_subtitle_sink_chain (GstPad * pad, GstBuffer * buffer) gst_flow_get_name (ret)); GST_SUBTITLE_OVERLAY_LOCK (self); self->subtitle_error = TRUE; - gst_pad_block (self->subtitle_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); - - gst_pad_block (self->video_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + block_subtitle (self); + block_video (self); GST_SUBTITLE_OVERLAY_UNLOCK (self); return GST_FLOW_OK; @@ -1772,14 +1774,8 @@ gst_subtitle_overlay_subtitle_sink_setcaps (GstPad * pad, GstCaps * caps) GST_DEBUG_OBJECT (pad, "Target did not accept caps"); self->subtitle_error = FALSE; - - gst_pad_block (self->subtitle_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); - - gst_pad_block (self->video_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + block_subtitle (self); + block_video (self); GST_SUBTITLE_OVERLAY_UNLOCK (self); out: @@ -1814,13 +1810,8 @@ gst_subtitle_overlay_subtitle_sink_link (GstPad * pad, GstPad * peer) self->subtitle_error = FALSE; - gst_pad_block (self->subtitle_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); - - gst_pad_block (self->video_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + block_subtitle (self); + block_video (self); GST_SUBTITLE_OVERLAY_UNLOCK (self); gst_caps_unref (caps); } @@ -1849,15 +1840,8 @@ gst_subtitle_overlay_subtitle_sink_unlink (GstPad * pad) GST_SUBTITLE_OVERLAY_LOCK (self); self->subtitle_error = FALSE; - if (self->subtitle_block_pad) - gst_pad_block (self->subtitle_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); - - if (self->video_block_pad) - gst_pad_block (self->video_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + block_subtitle (self); + block_video (self); GST_SUBTITLE_OVERLAY_UNLOCK (self); gst_object_unref (self); @@ -1875,14 +1859,8 @@ gst_subtitle_overlay_subtitle_sink_event (GstPad * pad, GstEvent * event) GST_SUBTITLE_OVERLAY_LOCK (self); self->subtitle_flush = TRUE; self->subtitle_error = FALSE; - if (self->subtitle_block_pad) - gst_pad_block (self->subtitle_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); - if (self->video_block_pad) - gst_pad_block (self->video_block_pad, GST_BLOCK_TYPE_DATA, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + block_subtitle (self); + block_video (self); GST_SUBTITLE_OVERLAY_UNLOCK (self); gst_event_unref (event); diff --git a/gst/playback/gstsubtitleoverlay.h b/gst/playback/gstsubtitleoverlay.h index a6e0d39..0fe6b1b 100644 --- a/gst/playback/gstsubtitleoverlay.h +++ b/gst/playback/gstsubtitleoverlay.h @@ -72,12 +72,14 @@ struct _GstSubtitleOverlay GstPad *video_sinkpad; GstPad *video_block_pad; + gulong video_block_id; gboolean video_sink_blocked; GstSegment video_segment; gint fps_n, fps_d; GstPad *subtitle_sinkpad; GstPad *subtitle_block_pad; + gulong subtitle_block_id; gboolean subtitle_sink_blocked; GstSegment subtitle_segment; gboolean subtitle_flush; diff --git a/gst/playback/gsturidecodebin.c b/gst/playback/gsturidecodebin.c index 01fe8c2..a49e91c 100644 --- a/gst/playback/gsturidecodebin.c +++ b/gst/playback/gsturidecodebin.c @@ -986,10 +986,13 @@ configure_stream_buffering (GstURIDecodeBin * decoder) gst_object_unref (queue); } -static gboolean -decoded_pad_event_probe (GstPad * pad, GstEvent * event, - GstURIDecodeBin * decoder) +static GstProbeReturn +decoded_pad_event_probe (GstPad * pad, GstProbeType type, gpointer type_data, + gpointer user_data) { + GstEvent *event = type_data; + GstURIDecodeBin *decoder = user_data; + GST_LOG_OBJECT (pad, "%s, decoder %p", GST_EVENT_TYPE_NAME (event), decoder); /* look for a bitrate tag */ @@ -1013,7 +1016,7 @@ decoded_pad_event_probe (GstPad * pad, GstEvent * event, if (stream) { stream->bitrate = bitrate; /* no longer need this probe now */ - gst_pad_remove_event_probe (pad, stream->probe_id); + gst_pad_remove_probe (pad, stream->probe_id); /* configure buffer if possible */ configure_stream_buffering (decoder); } @@ -1025,7 +1028,7 @@ decoded_pad_event_probe (GstPad * pad, GstEvent * event, } /* never drop */ - return TRUE; + return GST_PROBE_OK; } /* Called by the signal handlers when a decodebin has @@ -1059,8 +1062,8 @@ new_decoded_pad_cb (GstElement * element, GstPad * pad, gboolean last, /* add event probe to monitor tags */ stream = g_slice_alloc0 (sizeof (GstURIDecodeBinStream)); stream->probe_id = - gst_pad_add_event_probe (pad, G_CALLBACK (decoded_pad_event_probe), - decoder); + gst_pad_add_probe (pad, GST_PROBE_TYPE_EVENT, decoded_pad_event_probe, + decoder, NULL); GST_URI_DECODE_BIN_LOCK (decoder); g_hash_table_insert (decoder->streams, pad, stream); GST_URI_DECODE_BIN_UNLOCK (decoder); @@ -1069,10 +1072,13 @@ new_decoded_pad_cb (GstElement * element, GstPad * pad, gboolean last, gst_element_add_pad (GST_ELEMENT_CAST (decoder), newpad); } -static gboolean -source_pad_event_probe (GstPad * pad, GstEvent * event, - GstURIDecodeBin * decoder) +static GstProbeReturn +source_pad_event_probe (GstPad * pad, GstProbeType type, gpointer type_data, + gpointer user_data) { + GstEvent *event = type_data; + GstURIDecodeBin *decoder = user_data; + GST_LOG_OBJECT (pad, "%s, decoder %p", GST_EVENT_TYPE_NAME (event), decoder); if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) { @@ -1082,7 +1088,7 @@ source_pad_event_probe (GstPad * pad, GstEvent * event, gst_uri_decode_bin_signals[SIGNAL_DRAINED], 0, NULL); } /* never drop events */ - return TRUE; + return GST_PROBE_OK; } /* called when we found a raw pad on the source element. We need to set up a @@ -1091,7 +1097,8 @@ static void expose_decoded_pad (GstElement * element, GstPad * pad, GstURIDecodeBin * decoder) { - gst_pad_add_event_probe (pad, G_CALLBACK (source_pad_event_probe), decoder); + gst_pad_add_probe (pad, GST_PROBE_TYPE_EVENT, source_pad_event_probe, decoder, + NULL); new_decoded_pad_cb (element, pad, FALSE, decoder); } diff --git a/tests/icles/audio-trickplay.c b/tests/icles/audio-trickplay.c index 7da0be4..1deaaff 100644 --- a/tests/icles/audio-trickplay.c +++ b/tests/icles/audio-trickplay.c @@ -31,12 +31,16 @@ check_position (GstElement * elem, GstQuery * pos, const gchar * info) } } -static gboolean -print_buffer_ts (GstPad * pad, GstBuffer * buffer, gpointer user_data) +static GstProbeReturn +print_buffer_ts (GstPad * pad, GstProbeType type, gpointer type_data, + gpointer user_data) { + GstBuffer *buffer = type_data; + GST_DEBUG_OBJECT (pad, " ts: %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer))); - return TRUE; + + return GST_PROBE_OK; } gint @@ -119,7 +123,8 @@ main (gint argc, gchar ** argv) } src_pad = gst_element_get_static_pad (src, "src"); - gst_pad_add_buffer_probe (src_pad, G_CALLBACK (print_buffer_ts), NULL); + gst_pad_add_probe (src_pad, GST_PROBE_TYPE_BUFFER, print_buffer_ts, NULL, + NULL); gst_object_unref (src_pad); /* add a controller to the source */ -- 2.7.4