summaryrefslogtreecommitdiff
path: root/gnl
diff options
context:
space:
mode:
authorEdward Hervey <edward.hervey@collabora.co.uk>2011-10-05 10:57:24 +0200
committerEdward Hervey <edward.hervey@collabora.co.uk>2011-10-05 10:57:24 +0200
commit2bd53d8623a243d120205931e95c4952aa840a3e (patch)
tree3f3b8c6d35586a136e85b26cec93edfd7c98ee81 /gnl
parent033c14da57cebc662c7a31ead93a019918c9f62a (diff)
gnl: More porting to 0.11 API
Now properly compiles * Switch to new probe API for pad probes and pad blocking * Switch to new GstIterator API * Switch to new GstSegment API * Switch to new GstEvent API (for SEGMENT and SEEK events)
Diffstat (limited to 'gnl')
-rw-r--r--gnl/gnlcomposition.c119
-rw-r--r--gnl/gnlghostpad.c134
-rw-r--r--gnl/gnlghostpad.h6
-rw-r--r--gnl/gnloperation.c59
-rw-r--r--gnl/gnlsource.c67
5 files changed, 222 insertions, 163 deletions
diff --git a/gnl/gnlcomposition.c b/gnl/gnlcomposition.c
index aafc91f..f736c0d 100644
--- a/gnl/gnlcomposition.c
+++ b/gnl/gnlcomposition.c
@@ -99,7 +99,7 @@ struct _GnlCompositionPrivate
/* source top-level ghostpad */
GstPad *ghostpad;
- guint ghosteventprobe;
+ gulong ghosteventprobe;
/* current stack, list of GnlObject* */
GNode *current;
@@ -164,7 +164,8 @@ static GstStateChangeReturn
gnl_composition_change_state (GstElement * element, GstStateChange transition);
static GstPad *get_src_pad (GstElement * element);
-static void pad_blocked (GstPad * pad, gboolean blocked, GnlComposition * comp);
+static GstProbeReturn pad_blocked (GstPad * pad, GstProbeType type,
+ gpointer type_data, GnlComposition * comp);
static gboolean
seek_handling (GnlComposition * comp, gboolean initial, gboolean update);
@@ -484,19 +485,19 @@ signal_duration_change (GnlComposition * comp)
}
static gboolean
-unblock_child_pads (GstElement * child, GValue * ret G_GNUC_UNUSED,
+unblock_child_pads (GValue * item, GValue * ret G_GNUC_UNUSED,
GnlComposition * comp)
{
GstPad *pad;
+ GstElement *child = g_value_get_object (item);
GST_DEBUG_OBJECT (child, "unblocking pads");
pad = get_src_pad (child);
if (pad) {
- gst_pad_set_blocked_async (pad, FALSE, (GstPadBlockCallback) pad_blocked,
- comp);
+ /* We in fact want to remove the existing probe ... */
+ gnl_ghostpad_remove_probe (pad);
gst_object_unref (pad);
}
- gst_object_unref (child);
return TRUE;
}
@@ -519,10 +520,11 @@ retry:
static gboolean
-reset_child (GstElement * child, GValue * ret G_GNUC_UNUSED, gpointer user_data)
+reset_child (GValue * item, GValue * ret G_GNUC_UNUSED, gpointer user_data)
{
- GnlComposition *comp = GNL_COMPOSITION (user_data);
GnlCompositionEntry *entry;
+ GstElement *child = g_value_get_object (item);
+ GnlComposition *comp = GNL_COMPOSITION (user_data);
GST_DEBUG_OBJECT (child, "unlocking state");
gst_element_set_locked_state (child, FALSE);
@@ -531,18 +533,18 @@ reset_child (GstElement * child, GValue * ret G_GNUC_UNUSED, gpointer user_data)
if (entry->nomorepadshandler)
wait_no_more_pads (comp, child, entry, FALSE);
- gst_object_unref (child);
-
return TRUE;
}
static gboolean
-lock_child_state (GstElement * child, GValue * ret G_GNUC_UNUSED,
+lock_child_state (GValue * item, GValue * ret G_GNUC_UNUSED,
gpointer udata G_GNUC_UNUSED)
{
+ GstElement *child = g_value_get_object (item);
+
GST_DEBUG_OBJECT (child, "locking state");
gst_element_set_locked_state (child, TRUE);
- gst_object_unref (child);
+
return TRUE;
}
@@ -641,16 +643,16 @@ eos_main_thread (GnlComposition * comp)
return FALSE;
}
-static gboolean
-ghost_event_probe_handler (GstPad * ghostpad G_GNUC_UNUSED, GstEvent * event,
- GnlComposition * comp)
+static GstProbeReturn
+ghost_event_probe_handler (GstPad * ghostpad G_GNUC_UNUSED, GstProbeType type,
+ GstEvent * event, GnlComposition * comp)
{
- gboolean keepit = TRUE;
+ GstProbeReturn retval = GST_PROBE_OK;
GST_DEBUG_OBJECT (comp, "event: %s", GST_EVENT_TYPE_NAME (event));
switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_NEWSEGMENT:{
+ case GST_EVENT_SEGMENT:{
COMP_FLUSHING_LOCK (comp);
if (comp->priv->pending_idle) {
GST_DEBUG_OBJECT (comp, "removing pending seek for main thread");
@@ -666,7 +668,7 @@ ghost_event_probe_handler (GstPad * ghostpad G_GNUC_UNUSED, GstEvent * event,
if (comp->priv->flushing) {
GST_DEBUG_OBJECT (comp, "flushing, bailing out");
COMP_FLUSHING_UNLOCK (comp);
- keepit = FALSE;
+ retval = GST_PROBE_DROP;
break;
}
COMP_FLUSHING_UNLOCK (comp);
@@ -684,14 +686,14 @@ ghost_event_probe_handler (GstPad * ghostpad G_GNUC_UNUSED, GstEvent * event,
comp->priv->pending_idle =
g_idle_add ((GSourceFunc) eos_main_thread, (gpointer) comp);
- keepit = FALSE;
+ retval = GST_PROBE_DROP;
}
break;
default:
break;
}
- return keepit;
+ return retval;
}
@@ -873,7 +875,6 @@ get_current_position (GnlComposition * comp)
}
GST_DEBUG_OBJECT (comp, "Downstream position query failed");
/* resetting format/value */
- format = GST_FORMAT_TIME;
value = GST_CLOCK_TIME_NONE;
}
@@ -946,9 +947,9 @@ handle_seek_event (GnlComposition * comp, GstEvent * event)
"start:%" GST_TIME_FORMAT " -- stop:%" GST_TIME_FORMAT " flags:%d",
GST_TIME_ARGS (cur), GST_TIME_ARGS (stop), flags);
- gst_segment_set_seek (comp->priv->segment,
+ gst_segment_do_seek (comp->priv->segment,
rate, format, flags, cur_type, cur, stop_type, stop, NULL);
- gst_segment_set_seek (comp->priv->outside_segment,
+ gst_segment_do_seek (comp->priv->outside_segment,
rate, format, flags, cur_type, cur, stop_type, stop, NULL);
GST_DEBUG_OBJECT (comp, "Segment now has flags:%d",
@@ -989,11 +990,11 @@ gnl_composition_event_handler (GstPad * ghostpad, GstEvent * event)
}
case GST_EVENT_QOS:{
gdouble prop;
+ GstQOSType qostype;
GstClockTimeDiff diff;
GstClockTime timestamp;
- GstClockTimeDiff curdiff;
- gst_event_parse_qos (event, &prop, &diff, &timestamp);
+ gst_event_parse_qos (event, &qostype, &prop, &diff, &timestamp);
GST_INFO_OBJECT (comp,
"timestamp:%" GST_TIME_FORMAT " segment.start:%" GST_TIME_FORMAT
@@ -1029,6 +1030,7 @@ gnl_composition_event_handler (GstPad * ghostpad, GstEvent * event)
*/
if (GST_CLOCK_TIME_IS_VALID (comp->priv->outside_segment->start)) {
+ GstClockTimeDiff curdiff;
/* We'll either create a new event or discard it */
gst_event_unref (event);
@@ -1049,7 +1051,7 @@ gnl_composition_event_handler (GstPad * ghostpad, GstEvent * event)
GST_INFO_OBJECT (comp,
"Creating new QoS event with timestamp %" GST_TIME_FORMAT,
GST_TIME_ARGS (timestamp));
- event = gst_event_new_qos (prop, diff, timestamp);
+ event = gst_event_new_qos (qostype, prop, diff, timestamp);
}
break;
}
@@ -1076,11 +1078,12 @@ beach:
return res;
}
-static void
-pad_blocked (GstPad * pad, gboolean blocked, GnlComposition * comp)
+static GstProbeReturn
+pad_blocked (GstPad * pad, GstProbeType type, gpointer type_data,
+ GnlComposition * comp)
{
- GST_DEBUG_OBJECT (comp, "Pad : %s:%s , blocked:%d",
- GST_DEBUG_PAD_NAME (pad), blocked);
+ GST_DEBUG_OBJECT (comp, "Pad : %s:%s", GST_DEBUG_PAD_NAME (pad));
+ return GST_PROBE_OK;
}
/* gnl_composition_ghost_pad_set_target:
@@ -1126,11 +1129,11 @@ gnl_composition_ghost_pad_set_target (GnlComposition * comp, GstPad * target)
if (ptarget) {
GST_DEBUG_OBJECT (comp, "Previous target was %s:%s, blocking that pad",
GST_DEBUG_PAD_NAME (ptarget));
- gst_pad_set_blocked_async (ptarget, TRUE,
- (GstPadBlockCallback) pad_blocked, comp);
+ gnl_ghostpad_add_probe_outside (ptarget, GST_PROBE_TYPE_BLOCKING,
+ (GstPadProbeCallback) pad_blocked, comp, NULL);
/* remove event probe */
if (comp->priv->ghosteventprobe) {
- gst_pad_remove_event_probe (ptarget, comp->priv->ghosteventprobe);
+ gst_pad_remove_probe (ptarget, comp->priv->ghosteventprobe);
comp->priv->ghosteventprobe = 0;
}
gst_object_unref (ptarget);
@@ -1142,8 +1145,8 @@ gnl_composition_ghost_pad_set_target (GnlComposition * comp, GstPad * target)
if (target && (comp->priv->ghosteventprobe == 0)) {
comp->priv->ghosteventprobe =
- gst_pad_add_event_probe (target, G_CALLBACK (ghost_event_probe_handler),
- comp);
+ gst_pad_add_probe (target, GST_PROBE_TYPE_EVENT,
+ (GstPadProbeCallback) ghost_event_probe_handler, comp, NULL);
GST_DEBUG_OBJECT (comp, "added event probe %d",
comp->priv->ghosteventprobe);
}
@@ -1505,13 +1508,18 @@ get_src_pad (GstElement * element)
{
GstIterator *it;
GstIteratorResult itres;
+ GValue item = { 0, };
GstPad *srcpad;
it = gst_element_iterate_src_pads (element);
- itres = gst_iterator_next (it, (gpointer) & srcpad);
+ itres = gst_iterator_next (it, &item);
if (itres != GST_ITERATOR_OK) {
GST_DEBUG ("%s doesn't have a src pad !", GST_ELEMENT_NAME (element));
srcpad = NULL;
+ } else {
+ srcpad = g_value_get_object (&item);
+ gst_object_ref (srcpad);
+ g_value_reset (&item);
}
gst_iterator_free (it);
return srcpad;
@@ -1525,9 +1533,10 @@ get_src_pad (GstElement * element)
*/
static gboolean
-set_child_caps (GstElement * child, GValue * ret G_GNUC_UNUSED,
- GnlObject * comp)
+set_child_caps (GValue * item, GValue * ret G_GNUC_UNUSED, GnlObject * comp)
{
+ GstElement *child = g_value_get_object (item);
+
gnl_object_set_caps ((GnlObject *) child, comp->caps);
return TRUE;
}
@@ -1801,8 +1810,7 @@ no_more_pads_object_cb (GstElement * element, GnlComposition * comp)
sinkpad, object->priority);
gst_object_unref (sinkpad);
- gst_pad_set_blocked_async (pad, FALSE, (GstPadBlockCallback) pad_blocked,
- comp);
+ gnl_ghostpad_remove_probe (pad);
}
if (comp->priv->current && (comp->priv->waitingpads == 0)
@@ -1839,8 +1847,7 @@ no_more_pads_object_cb (GstElement * element, GnlComposition * comp)
/* 3. unblock ghostpad */
GST_LOG_OBJECT (comp, "About to unblock top-level pad : %s:%s",
GST_DEBUG_PAD_NAME (tpad));
- gst_pad_set_blocked_async (tpad, FALSE,
- (GstPadBlockCallback) pad_blocked, comp);
+ gnl_ghostpad_remove_probe (tpad);
GST_LOG_OBJECT (comp, "Unblocked top-level pad");
} else {
GST_DEBUG ("Element went away from currently configured stack");
@@ -1913,8 +1920,8 @@ compare_relink_single_node (GnlComposition * comp, GNode * node,
if (G_UNLIKELY (!oldnode && srcpad)) {
GST_LOG_OBJECT (comp, "block_async(%s:%s, TRUE)",
GST_DEBUG_PAD_NAME (srcpad));
- gst_pad_set_blocked_async (srcpad, TRUE, (GstPadBlockCallback) pad_blocked,
- comp);
+ gnl_ghostpad_add_probe_outside (srcpad, GST_PROBE_TYPE_BLOCKING,
+ (GstPadProbeCallback) pad_blocked, comp, NULL);
}
entry = COMP_ENTRY (comp, newobj);
@@ -2005,8 +2012,7 @@ compare_relink_single_node (GnlComposition * comp, GNode * node,
/* 4. Unblock source pad */
if ((srcpad && entry->nomorepadshandler == 0) && !G_NODE_IS_ROOT (node)) {
GST_LOG_OBJECT (comp, "Unblocking pad %s:%s", GST_DEBUG_PAD_NAME (srcpad));
- gst_pad_set_blocked_async (srcpad, FALSE,
- (GstPadBlockCallback) pad_blocked, comp);
+ gnl_ghostpad_remove_probe (srcpad);
}
if (G_LIKELY (srcpad))
@@ -2065,8 +2071,8 @@ compare_deactivate_single_node (GnlComposition * comp, GNode * node,
* point. */
GST_LOG_OBJECT (comp, "block_async(%s:%s, TRUE)",
GST_DEBUG_PAD_NAME (srcpad));
- gst_pad_set_blocked_async (srcpad, TRUE, (GstPadBlockCallback) pad_blocked,
- comp);
+ gnl_ghostpad_add_probe_outside (srcpad, GST_PROBE_TYPE_BLOCKING,
+ (GstPadProbeCallback) pad_blocked, comp, NULL);
/* 2. If we have to modify or we have a parent, flush downstream
* This ensures the streaming thread going through the current object has
@@ -2075,7 +2081,7 @@ compare_deactivate_single_node (GnlComposition * comp, GNode * node,
GST_LOG_OBJECT (comp, "Sending flush start/stop downstream ");
gst_pad_send_event (peerpad, gst_event_new_flush_start ());
- gst_pad_send_event (peerpad, gst_event_new_flush_stop ());
+ gst_pad_send_event (peerpad, gst_event_new_flush_stop (TRUE));
GST_DEBUG_OBJECT (comp, "DONE Sending flush events downstream");
gst_object_unref (peerpad);
@@ -2115,7 +2121,7 @@ compare_deactivate_single_node (GnlComposition * comp, GNode * node,
if (srcpad && (peerpad = gst_pad_get_peer (srcpad))) {
GST_LOG_OBJECT (peerpad, "Sending flush start/stop");
gst_pad_send_event (peerpad, gst_event_new_flush_start ());
- gst_pad_send_event (peerpad, gst_event_new_flush_stop ());
+ gst_pad_send_event (peerpad, gst_event_new_flush_stop (TRUE));
gst_pad_unlink (srcpad, peerpad);
gst_object_unref (peerpad);
@@ -2407,8 +2413,7 @@ update_pipeline (GnlComposition * comp, GstClockTime currenttime,
} else {
/* unblock top-level pad */
GST_LOG_OBJECT (comp, "About to unblock top-level srcpad");
- gst_pad_set_blocked_async (pad, FALSE,
- (GstPadBlockCallback) pad_blocked, comp);
+ gnl_ghostpad_remove_probe (pad);
}
gst_object_unref (pad);
} else {
@@ -2519,8 +2524,7 @@ object_pad_removed (GnlObject * object, GstPad * pad, GnlComposition * comp)
comp->priv->ghosteventprobe = 0;
} else {
/* unblock it ! */
- gst_pad_set_blocked_async (pad, FALSE, (GstPadBlockCallback) pad_blocked,
- comp);
+ gnl_ghostpad_remove_probe (pad);
}
}
@@ -2534,8 +2538,8 @@ object_pad_added (GnlObject * object G_GNUC_UNUSED, GstPad * pad,
GST_DEBUG_OBJECT (comp, "pad %s:%s was added, blocking it",
GST_DEBUG_PAD_NAME (pad));
- gst_pad_set_blocked_async (pad, TRUE, (GstPadBlockCallback) pad_blocked,
- comp);
+ gnl_ghostpad_add_probe_outside (pad, GST_PROBE_TYPE_BLOCKING,
+ (GstPadProbeCallback) pad_blocked, comp, NULL);
}
static gboolean
@@ -2762,8 +2766,7 @@ gnl_composition_remove_object (GstBin * bin, GstElement * element)
GstPad *pad = get_src_pad (element);
if (pad) {
- gst_pad_set_blocked_async (pad, FALSE, (GstPadBlockCallback) pad_blocked,
- comp);
+ gnl_ghostpad_remove_probe (pad);
gst_object_unref (pad);
}
}
diff --git a/gnl/gnlghostpad.c b/gnl/gnlghostpad.c
index 70a1044..98cae06 100644
--- a/gnl/gnlghostpad.c
+++ b/gnl/gnlghostpad.c
@@ -35,6 +35,8 @@ struct _GnlPadPrivate
GstPadDirection dir;
GstPadEventFunction eventfunc;
GstPadQueryFunction queryfunc;
+
+ gulong probeid;
};
static GstEvent *
@@ -222,87 +224,81 @@ invalid_format:
}
static GstEvent *
-translate_outgoing_new_segment (GnlObject * object, GstEvent * event)
+translate_outgoing_segment (GnlObject * object, GstEvent * event)
{
+ const GstSegment *orig;
+ GstSegment *segment;
GstEvent *event2;
- gboolean update;
- gdouble rate;
- GstFormat format;
- gint64 start, stop, stream;
- guint64 nstream;
/* only modify the streamtime */
- gst_event_parse_new_segment (event, &update, &rate, &format,
- &start, &stop, &stream);
+ gst_event_parse_segment (event, &orig);
GST_DEBUG_OBJECT (object,
- "Got NEWSEGMENT %" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT " // %"
- GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
- GST_TIME_ARGS (stream));
+ "Got SEGMENT %" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT " // %"
+ GST_TIME_FORMAT, GST_TIME_ARGS (orig->start), GST_TIME_ARGS (orig->stop),
+ GST_TIME_ARGS (orig->time));
- if (G_UNLIKELY (format != GST_FORMAT_TIME)) {
+ if (G_UNLIKELY (orig->format != GST_FORMAT_TIME)) {
GST_WARNING_OBJECT (object,
- "Can't translate newsegments with format != GST_FORMAT_TIME");
+ "Can't translate segments with format != GST_FORMAT_TIME");
return event;
}
- gnl_media_to_object_time (object, stream, &nstream);
+ segment = gst_segment_copy (orig);
+
+ gnl_media_to_object_time (object, orig->time, &segment->time);
- if (G_UNLIKELY (nstream > G_MAXINT64))
+ if (G_UNLIKELY (segment->time > G_MAXINT64))
GST_WARNING_OBJECT (object, "Return value too big...");
GST_DEBUG_OBJECT (object,
- "Sending NEWSEGMENT %" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT " // %"
- GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
- GST_TIME_ARGS (nstream));
- event2 =
- gst_event_new_new_segment (update, rate, format, start, stop,
- (gint64) nstream);
+ "Sending SEGMENT %" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT " // %"
+ GST_TIME_FORMAT, GST_TIME_ARGS (segment->start),
+ GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time));
+
+ event2 = gst_event_new_segment (segment);
gst_event_unref (event);
return event2;
}
static GstEvent *
-translate_incoming_new_segment (GnlObject * object, GstEvent * event)
+translate_incoming_segment (GnlObject * object, GstEvent * event)
{
GstEvent *event2;
- gboolean update;
- gdouble rate;
- GstFormat format;
- gint64 start, stop, stream;
- guint64 nstream;
+ const GstSegment *orig;
+ GstSegment *segment;
/* only modify the streamtime */
- gst_event_parse_new_segment (event, &update, &rate, &format,
- &start, &stop, &stream);
+ gst_event_parse_segment (event, &orig);
GST_DEBUG_OBJECT (object,
- "Got NEWSEGMENT %" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT " // %"
- GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
- GST_TIME_ARGS (stream));
+ "Got SEGMENT %" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT " // %"
+ GST_TIME_FORMAT, GST_TIME_ARGS (orig->start), GST_TIME_ARGS (orig->stop),
+ GST_TIME_ARGS (orig->time));
- if (G_UNLIKELY (format != GST_FORMAT_TIME)) {
+ if (G_UNLIKELY (orig->format != GST_FORMAT_TIME)) {
GST_WARNING_OBJECT (object,
- "Can't translate newsegments with format != GST_FORMAT_TIME");
+ "Can't translate segments with format != GST_FORMAT_TIME");
return event;
}
- if (!gnl_object_to_media_time (object, stream, &nstream)) {
+ segment = gst_segment_copy (orig);
+
+ if (!gnl_object_to_media_time (object, orig->time, &segment->time)) {
GST_DEBUG ("Can't convert media_time, using 0");
- nstream = 0;
+ segment->time = 0;
};
- if (G_UNLIKELY (nstream > G_MAXINT64))
+ if (G_UNLIKELY (segment->time > G_MAXINT64))
GST_WARNING_OBJECT (object, "Return value too big...");
GST_DEBUG_OBJECT (object,
- "Sending NEWSEGMENT %" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT " // %"
- GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
- GST_TIME_ARGS (nstream));
- event2 =
- gst_event_new_new_segment (update, rate, format, start, stop,
- (gint64) nstream);
+ "Sending SEGMENT %" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT " // %"
+ GST_TIME_FORMAT, GST_TIME_ARGS (segment->start),
+ GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time));
+
+ event2 = gst_event_new_segment (segment);
gst_event_unref (event);
return event2;
@@ -326,8 +322,8 @@ internalpad_event_function (GstPad * internal, GstEvent * event)
switch (priv->dir) {
case GST_PAD_SRC:{
switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_NEWSEGMENT:
- event = translate_outgoing_new_segment (object, event);
+ case GST_EVENT_SEGMENT:
+ event = translate_outgoing_segment (object, event);
break;
default:
break;
@@ -499,8 +495,8 @@ ghostpad_event_function (GstPad * ghostpad, GstEvent * event)
break;
case GST_PAD_SINK:{
switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_NEWSEGMENT:
- event = translate_incoming_new_segment (object, event);
+ case GST_EVENT_SEGMENT:
+ event = translate_incoming_segment (object, event);
break;
default:
break;
@@ -753,22 +749,56 @@ gnl_object_ghost_pad_set_target (GnlObject * object, GstPad * ghost,
return FALSE;
if (target) {
- GstCaps *negotiated_caps;
+ GstCaps *current_caps;
/* if the target has negotiated caps, forward them to the ghost */
- if ((negotiated_caps = gst_pad_get_negotiated_caps (target))) {
- gst_pad_set_caps (ghost, negotiated_caps);
- gst_caps_unref (negotiated_caps);
+ /* FIXME : I'm not sure we need this anymore */
+ if ((current_caps = gst_pad_get_current_caps (target))) {
+ gst_pad_set_caps (ghost, current_caps);
+ gst_caps_unref (current_caps);
}
}
- if (!GST_OBJECT_IS_FLOATING (ghost))
+ if (!g_object_is_floating (ghost))
control_internal_pad (ghost, object);
return TRUE;
}
+gboolean
+gnl_ghostpad_add_probe_outside (GstPad * pad, GstProbeType mask,
+ GstPadProbeCallback callback,
+ gpointer user_data, GDestroyNotify destroy_data)
+{
+ GnlPadPrivate *priv = gst_pad_get_element_private (pad);
+
+ g_return_val_if_fail (priv, FALSE);
+ if (G_UNLIKELY (priv->probeid))
+ GST_WARNING_OBJECT (pad, "Pad already had a probe set !");
+
+ priv->probeid =
+ gst_pad_add_probe (pad, mask, callback, user_data, destroy_data);
+
+ if (G_UNLIKELY (priv->probeid == 0))
+ return FALSE;
+
+ return TRUE;
+}
+
+void
+gnl_ghostpad_remove_probe (GstPad * pad)
+{
+ GnlPadPrivate *priv = gst_pad_get_element_private (pad);
+
+ g_return_if_fail (priv);
+
+ if (priv->probeid) {
+ gst_pad_remove_probe (pad, priv->probeid);
+ priv->probeid = 0;
+ }
+}
+
void
gnl_init_ghostpad_category (void)
{
diff --git a/gnl/gnlghostpad.h b/gnl/gnlghostpad.h
index d30d255..78f27d8 100644
--- a/gnl/gnlghostpad.h
+++ b/gnl/gnlghostpad.h
@@ -44,6 +44,12 @@ gboolean gnl_object_ghost_pad_set_target (GnlObject * object,
void gnl_object_remove_ghost_pad (GnlObject * object, GstPad * ghost);
+gboolean gnl_ghostpad_add_probe_outside (GstPad *pad, GstProbeType mask,
+ GstPadProbeCallback callback,
+ gpointer user_data,
+ GDestroyNotify destroy_data);
+void gnl_ghostpad_remove_probe (GstPad *pad);
+
void gnl_init_ghostpad_category (void);
G_END_DECLS
diff --git a/gnl/gnloperation.c b/gnl/gnloperation.c
index 95f16ef..8f3714c 100644
--- a/gnl/gnloperation.c
+++ b/gnl/gnloperation.c
@@ -89,7 +89,7 @@ static gboolean gnl_operation_remove_element (GstBin * bin,
GstElement * element);
static GstPad *gnl_operation_request_new_pad (GstElement * element,
- GstPadTemplate * templ, const gchar * name);
+ GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
static void gnl_operation_release_pad (GstElement * element, GstPad * pad);
static void synchronize_sinks (GnlOperation * operation);
@@ -204,7 +204,7 @@ element_is_valid_filter (GstElement * element, gboolean * isdynamic)
gboolean havesrc = FALSE;
gboolean done = FALSE;
GstIterator *pads;
- gpointer res;
+ GValue item = { 0, };
if (isdynamic)
*isdynamic = FALSE;
@@ -212,17 +212,17 @@ element_is_valid_filter (GstElement * element, gboolean * isdynamic)
pads = gst_element_iterate_pads (element);
while (!done) {
- switch (gst_iterator_next (pads, &res)) {
+ switch (gst_iterator_next (pads, &item)) {
case GST_ITERATOR_OK:
{
- GstPad *pad = (GstPad *) res;
+ GstPad *pad = g_value_get_object (&item);
if (gst_pad_get_direction (pad) == GST_PAD_SRC)
havesrc = TRUE;
else if (gst_pad_get_direction (pad) == GST_PAD_SINK)
havesink = TRUE;
- gst_object_unref (pad);
+ g_value_reset (&item);
break;
}
case GST_ITERATOR_RESYNC:
@@ -236,6 +236,8 @@ element_is_valid_filter (GstElement * element, gboolean * isdynamic)
break;
}
}
+
+ g_value_unset (&item);
gst_iterator_free (pads);
if (G_LIKELY ((factory = gst_element_get_factory (element)))) {
@@ -286,14 +288,18 @@ get_src_pad (GstElement * element)
{
GstIterator *it;
GstIteratorResult itres;
- GstPad *srcpad;
+ GValue item = { 0, };
+ GstPad *srcpad = NULL;
it = gst_element_iterate_src_pads (element);
- itres = gst_iterator_next (it, (gpointer) & srcpad);
+ itres = gst_iterator_next (it, &item);
if (itres != GST_ITERATOR_OK) {
GST_DEBUG ("%s doesn't have a src pad !", GST_ELEMENT_NAME (element));
- srcpad = NULL;
+ } else {
+ srcpad = g_value_get_object (&item);
+ gst_object_ref (srcpad);
}
+ g_value_reset (&item);
gst_iterator_free (it);
return srcpad;
}
@@ -307,17 +313,16 @@ get_nb_static_sinks (GnlOperation * oper)
{
GstIterator *sinkpads;
gboolean done = FALSE;
- gpointer val;
guint nbsinks = 0;
+ GValue item = { 0, };
sinkpads = gst_element_iterate_sink_pads (oper->element);
while (!done) {
- switch (gst_iterator_next (sinkpads, &val)) {
+ switch (gst_iterator_next (sinkpads, &item)) {
case GST_ITERATOR_OK:{
- GstPad *pad = (GstPad *) val;
nbsinks++;
- gst_object_unref (pad);
+ g_value_unset (&item);
}
break;
case GST_ITERATOR_RESYNC:
@@ -330,6 +335,8 @@ get_nb_static_sinks (GnlOperation * oper)
break;
}
}
+
+ g_value_reset (&item);
gst_iterator_free (sinkpads);
GST_DEBUG ("We found %d static sinks", nbsinks);
@@ -459,7 +466,7 @@ get_unused_static_sink_pad (GnlOperation * operation)
{
GstIterator *pads;
gboolean done = FALSE;
- gpointer val;
+ GValue item = { 0, };
GstPad *ret = NULL;
if (!operation->element)
@@ -468,10 +475,10 @@ get_unused_static_sink_pad (GnlOperation * operation)
pads = gst_element_iterate_pads (operation->element);
while (!done) {
- switch (gst_iterator_next (pads, &val)) {
+ switch (gst_iterator_next (pads, &item)) {
case GST_ITERATOR_OK:
{
- GstPad *pad = (GstPad *) val;
+ GstPad *pad = g_value_get_object (&item);
if (gst_pad_get_direction (pad) == GST_PAD_SINK) {
GList *tmp = operation->sinks;
@@ -494,13 +501,12 @@ get_unused_static_sink_pad (GnlOperation * operation)
/* 2. if not taken, return that pad */
if (!istaken) {
+ gst_object_ref (pad);
ret = pad;
done = TRUE;
- } else {
- gst_object_unref (pad);
}
- } else
- gst_object_unref (pad);
+ }
+ g_value_reset (&item);
break;
}
case GST_ITERATOR_RESYNC:
@@ -515,6 +521,8 @@ get_unused_static_sink_pad (GnlOperation * operation)
break;
}
}
+
+ g_value_unset (&item);
gst_iterator_free (pads);
if (ret)
@@ -531,7 +539,7 @@ get_unlinked_sink_ghost_pad (GnlOperation * operation)
{
GstIterator *pads;
gboolean done = FALSE;
- gpointer val;
+ GValue item = { 0, };
GstPad *ret = NULL;
if (!operation->element)
@@ -540,19 +548,20 @@ get_unlinked_sink_ghost_pad (GnlOperation * operation)
pads = gst_element_iterate_sink_pads ((GstElement *) operation);
while (!done) {
- switch (gst_iterator_next (pads, &val)) {
+ switch (gst_iterator_next (pads, &item)) {
case GST_ITERATOR_OK:
{
- GstPad *pad = (GstPad *) val;
+ GstPad *pad = g_value_get_object (&item);
GstPad *peer = gst_pad_get_peer (pad);
if (peer == NULL) {
ret = pad;
+ gst_object_ref (ret);
done = TRUE;
} else {
gst_object_unref (peer);
- gst_object_unref (pad);
}
+ g_value_unset (&item);
break;
}
case GST_ITERATOR_RESYNC:
@@ -567,6 +576,8 @@ get_unlinked_sink_ghost_pad (GnlOperation * operation)
break;
}
}
+
+ g_value_reset (&item);
gst_iterator_free (pads);
if (ret)
@@ -744,7 +755,7 @@ gnl_operation_cleanup (GnlObject * object)
static GstPad *
gnl_operation_request_new_pad (GstElement * element, GstPadTemplate * templ,
- const gchar * name)
+ const gchar * name, const GstCaps * caps)
{
GnlOperation *operation = (GnlOperation *) element;
GstPad *ret;
diff --git a/gnl/gnlsource.c b/gnl/gnlsource.c
index d555335..645a3d1 100644
--- a/gnl/gnlsource.c
+++ b/gnl/gnlsource.c
@@ -57,6 +57,7 @@ struct _GnlSourcePrivate
gulong padremovedid; /* signal handler for element pad-removed signal */
gulong padaddedid; /* signal handler for element pad-added signal */
+ gulong probeid; /* source pad probe id */
gboolean pendingblock; /* We have a pending pad_block */
gboolean areblocked; /* We already got blocked */
@@ -77,7 +78,9 @@ static gboolean gnl_source_send_event (GstElement * element, GstEvent * event);
static GstStateChangeReturn
gnl_source_change_state (GstElement * element, GstStateChange transition);
-static void pad_blocked_cb (GstPad * pad, gboolean blocked, GnlSource * source);
+static GstProbeReturn
+pad_blocked_cb (GstPad * pad, GstProbeType probetype,
+ gpointer udata, GnlSource * source);
static gboolean
gnl_source_control_element_func (GnlSource * source, GstElement * element);
@@ -213,9 +216,9 @@ element_pad_added_cb (GstElement * element G_GNUC_UNUSED, GstPad * pad,
GST_DEBUG_OBJECT (pad, "valid pad, about to add event probe and pad block");
-
- if (!(gst_pad_set_blocked_async (pad, TRUE,
- (GstPadBlockCallback) pad_blocked_cb, source)))
+ source->priv->probeid = gst_pad_add_probe (pad, GST_PROBE_TYPE_BLOCK,
+ (GstPadProbeCallback) pad_blocked_cb, source, NULL);
+ if (source->priv->probeid == 0)
GST_WARNING_OBJECT (source, "Couldn't set Async pad blocking");
else {
source->priv->ghostedpad = pad;
@@ -241,9 +244,8 @@ element_pad_removed_cb (GstElement * element G_GNUC_UNUSED, GstPad * pad,
GST_DEBUG_OBJECT (source, "Clearing up ghostpad");
source->priv->areblocked = FALSE;
- gst_pad_set_blocked_async (pad, FALSE,
- (GstPadBlockCallback) pad_blocked_cb, source);
-
+ gst_pad_remove_probe (pad, source->priv->probeid);
+ source->priv->probeid = 0;
gnl_object_remove_ghost_pad ((GnlObject *) source,
source->priv->ghostpad);
@@ -258,16 +260,16 @@ element_pad_removed_cb (GstElement * element G_GNUC_UNUSED, GstPad * pad,
}
static gint
-compare_src_pad (GstPad * pad, GstCaps * caps)
+compare_src_pad (GValue * item, GstCaps * caps)
{
- gint ret;
+ gint ret = 1;
+ GstPad *pad = g_value_get_object (item);
+
+ GST_DEBUG_OBJECT (pad, "Trying pad for caps %" GST_PTR_FORMAT, caps);
if (gst_pad_accept_caps (pad, caps))
ret = 0;
- else {
- gst_object_unref (pad);
- ret = 1;
- }
+
return ret;
}
@@ -281,18 +283,23 @@ compare_src_pad (GstPad * pad, GstCaps * caps)
static gboolean
get_valid_src_pad (GnlSource * source, GstElement * element, GstPad ** pad)
{
+ gboolean res = FALSE;
GstIterator *srcpads;
+ GValue item = { 0, };
g_return_val_if_fail (pad, FALSE);
srcpads = gst_element_iterate_src_pads (element);
- *pad = (GstPad *) gst_iterator_find_custom (srcpads,
- (GCompareFunc) compare_src_pad, GNL_OBJECT (source)->caps);
+ if (gst_iterator_find_custom (srcpads, (GCompareFunc) compare_src_pad, &item,
+ GNL_OBJECT (source)->caps)) {
+ *pad = g_value_get_object (&item);
+ gst_object_ref (pad);
+ g_value_reset (&item);
+ res = TRUE;
+ }
gst_iterator_free (srcpads);
- if (*pad)
- return TRUE;
- return FALSE;
+ return res;
}
static gpointer
@@ -322,8 +329,8 @@ ghost_seek_pad (GnlSource * source)
GST_DEBUG_OBJECT (source, "about to unblock %s:%s", GST_DEBUG_PAD_NAME (pad));
source->priv->areblocked = FALSE;
- gst_pad_set_blocked_async (pad, FALSE,
- (GstPadBlockCallback) pad_blocked_cb, source);
+ gst_pad_remove_probe (pad, source->priv->probeid);
+ source->priv->probeid = 0;
gst_element_no_more_pads (GST_ELEMENT (source));
source->priv->pendingblock = FALSE;
@@ -332,16 +339,18 @@ beach:
return NULL;
}
-static void
-pad_blocked_cb (GstPad * pad, gboolean blocked, GnlSource * source)
+static GstProbeReturn
+pad_blocked_cb (GstPad * pad, GstProbeType ptype, gpointer unused_data,
+ GnlSource * source)
{
- GST_DEBUG_OBJECT (source, "blocked:%d pad:%s:%s",
- blocked, GST_DEBUG_PAD_NAME (pad));
+ GST_DEBUG_OBJECT (pad, "probe callback");
- if (blocked && !(source->priv->ghostpad) && !(source->priv->areblocked)) {
+ if (!source->priv->ghostpad && !source->priv->areblocked) {
source->priv->areblocked = TRUE;
g_thread_create ((GThreadFunc) ghost_seek_pad, source, FALSE, NULL);
}
+
+ return GST_PROBE_OK;
}
@@ -536,8 +545,8 @@ gnl_source_change_state (GstElement * element, GstStateChange transition)
GST_LOG_OBJECT (source, "Trying to async block source pad %s:%s",
GST_DEBUG_PAD_NAME (pad));
source->priv->ghostedpad = pad;
- gst_pad_set_blocked_async (pad, TRUE,
- (GstPadBlockCallback) pad_blocked_cb, source);
+ source->priv->probeid = gst_pad_add_probe (pad, GST_PROBE_TYPE_BLOCK,
+ (GstPadProbeCallback) pad_blocked_cb, source, NULL);
gst_object_unref (pad);
}
}
@@ -561,8 +570,8 @@ gnl_source_change_state (GstElement * element, GstStateChange transition)
gst_ghost_pad_get_target ((GstGhostPad *) source->priv->ghostpad);
if (target) {
- gst_pad_set_blocked_async (target, FALSE,
- (GstPadBlockCallback) pad_blocked_cb, source);
+ gst_pad_remove_probe (target, source->priv->probeid);
+ source->priv->probeid = 0;
gst_object_unref (target);
}
gnl_object_remove_ghost_pad ((GnlObject *) source,