diff options
author | Edward Hervey <edward.hervey@collabora.co.uk> | 2011-10-05 10:57:24 +0200 |
---|---|---|
committer | Edward Hervey <edward.hervey@collabora.co.uk> | 2011-10-05 10:57:24 +0200 |
commit | 2bd53d8623a243d120205931e95c4952aa840a3e (patch) | |
tree | 3f3b8c6d35586a136e85b26cec93edfd7c98ee81 /gnl | |
parent | 033c14da57cebc662c7a31ead93a019918c9f62a (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.c | 119 | ||||
-rw-r--r-- | gnl/gnlghostpad.c | 134 | ||||
-rw-r--r-- | gnl/gnlghostpad.h | 6 | ||||
-rw-r--r-- | gnl/gnloperation.c | 59 | ||||
-rw-r--r-- | gnl/gnlsource.c | 67 |
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, ×tamp); + gst_event_parse_qos (event, &qostype, &prop, &diff, ×tamp); 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, |