From 1e1c12e87ed1d4ec135330653c9390522d3e04dc Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 14 May 2007 15:28:36 +0000 Subject: gst/rtpmanager/async_jitter_queue.c: Fix leak when flushing. Original commit message from CVS: * gst/rtpmanager/async_jitter_queue.c: (async_jitter_queue_set_flushing_unlocked): Fix leak when flushing. * gst/rtpmanager/gstrtpbin.c: (gst_rtp_bin_clear_pt_map), (gst_rtp_bin_class_init): * gst/rtpmanager/gstrtpbin.h: Add clear-pt-map signal. * gst/rtpmanager/gstrtpjitterbuffer.c: (gst_rtp_jitter_buffer_flush_stop), (gst_rtp_jitter_buffer_sink_event), (gst_rtp_jitter_buffer_loop): Init clock-rate to -1 to mark unknow clock rate. Fix flushing. --- gst/rtpmanager/async_jitter_queue.c | 5 ++++- gst/rtpmanager/gstrtpbin.c | 25 +++++++++++++++++++++++++ gst/rtpmanager/gstrtpbin.h | 2 ++ gst/rtpmanager/gstrtpjitterbuffer.c | 13 ++++++++++--- 4 files changed, 41 insertions(+), 4 deletions(-) (limited to 'gst/rtpmanager') diff --git a/gst/rtpmanager/async_jitter_queue.c b/gst/rtpmanager/async_jitter_queue.c index ba14d98e..77980c98 100644 --- a/gst/rtpmanager/async_jitter_queue.c +++ b/gst/rtpmanager/async_jitter_queue.c @@ -632,6 +632,8 @@ void async_jitter_queue_set_flushing_unlocked (AsyncJitterQueue * queue, GFunc free_func, gpointer user_data) { + gpointer elem; + g_return_if_fail (queue); g_return_if_fail (g_atomic_int_get (&queue->ref_count) > 0); @@ -640,7 +642,8 @@ async_jitter_queue_set_flushing_unlocked (AsyncJitterQueue * queue, if (queue->waiting_threads > 0) g_cond_broadcast (queue->cond); /* free data from queue */ - g_queue_foreach (queue->queue, free_func, user_data); + while ((elem = g_queue_pop_head (queue->queue))) + free_func (elem, user_data); } /** diff --git a/gst/rtpmanager/gstrtpbin.c b/gst/rtpmanager/gstrtpbin.c index 927755f5..a6cd3840 100644 --- a/gst/rtpmanager/gstrtpbin.c +++ b/gst/rtpmanager/gstrtpbin.c @@ -113,6 +113,7 @@ struct _GstRTPBinPrivate enum { SIGNAL_REQUEST_PT_MAP, + SIGNAL_CLEAR_PT_MAP, LAST_SIGNAL }; @@ -334,6 +335,22 @@ no_caps: } } +static void +gst_rtp_bin_clear_pt_map (GstRTPBin * bin) +{ + GSList *walk; + + GST_RTP_BIN_LOCK (bin); + for (walk = bin->sessions; walk; walk = g_slist_next (walk)) { + GstRTPBinSession *session = (GstRTPBinSession *) walk->data; + + GST_RTP_SESSION_LOCK (session); + g_hash_table_remove_all (session->ptmap); + GST_RTP_SESSION_UNLOCK (session); + } + GST_RTP_BIN_UNLOCK (bin); +} + /* create a new stream with @ssrc in @session. Must be called with * RTP_SESSION_LOCK. */ static GstRTPBinStream * @@ -412,6 +429,7 @@ static GstStateChangeReturn gst_rtp_bin_change_state (GstElement * element, static GstPad *gst_rtp_bin_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * name); static void gst_rtp_bin_release_pad (GstElement * element, GstPad * pad); +static void gst_rtp_bin_clear_pt_map (GstRTPBin * bin); GST_BOILERPLATE (GstRTPBin, gst_rtp_bin, GstBin, GST_TYPE_BIN); @@ -473,6 +491,11 @@ gst_rtp_bin_class_init (GstRTPBinClass * klass) NULL, NULL, gst_rtp_bin_marshal_BOXED__UINT_UINT, GST_TYPE_CAPS, 2, G_TYPE_UINT, G_TYPE_UINT); + gst_rtp_bin_signals[SIGNAL_CLEAR_PT_MAP] = + g_signal_new ("clear-pt-map", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTPBinClass, clear_pt_map), + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); + gstelement_class->provide_clock = GST_DEBUG_FUNCPTR (gst_rtp_bin_provide_clock); gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_bin_change_state); @@ -480,6 +503,8 @@ gst_rtp_bin_class_init (GstRTPBinClass * klass) GST_DEBUG_FUNCPTR (gst_rtp_bin_request_new_pad); gstelement_class->release_pad = GST_DEBUG_FUNCPTR (gst_rtp_bin_release_pad); + klass->clear_pt_map = GST_DEBUG_FUNCPTR (gst_rtp_bin_clear_pt_map); + GST_DEBUG_CATEGORY_INIT (gst_rtp_bin_debug, "rtpbin", 0, "RTP bin"); } diff --git a/gst/rtpmanager/gstrtpbin.h b/gst/rtpmanager/gstrtpbin.h index 523eb789..24eb38d1 100644 --- a/gst/rtpmanager/gstrtpbin.h +++ b/gst/rtpmanager/gstrtpbin.h @@ -56,6 +56,8 @@ struct _GstRTPBinClass { /* get the caps for pt */ GstCaps* (*request_pt_map) (GstRTPBin *rtpbin, guint session, guint pt); + + void (*clear_pt_map) (GstRTPBin *rtpbin); }; GType gst_rtp_bin_get_type (void); diff --git a/gst/rtpmanager/gstrtpjitterbuffer.c b/gst/rtpmanager/gstrtpjitterbuffer.c index 0bd0cb1a..e49f41a6 100644 --- a/gst/rtpmanager/gstrtpjitterbuffer.c +++ b/gst/rtpmanager/gstrtpjitterbuffer.c @@ -468,6 +468,7 @@ gst_rtp_jitter_buffer_flush_stop (GstRTPJitterBuffer * jitterbuffer) gst_segment_init (&priv->segment, GST_FORMAT_TIME); priv->last_popped_seqnum = -1; priv->next_seqnum = -1; + priv->clock_rate = -1; /* allow pops from the src pad task */ async_jitter_queue_unset_flushing_unlocked (jitterbuffer->priv->queue); async_jitter_queue_unlock (priv->queue); @@ -617,6 +618,8 @@ gst_rtp_jitter_buffer_sink_event (GstPad * pad, GstEvent * event) jitterbuffer = GST_RTP_JITTER_BUFFER (gst_pad_get_parent (pad)); priv = jitterbuffer->priv; + GST_DEBUG_OBJECT (jitterbuffer, "received %s", GST_EVENT_TYPE_NAME (event)); + switch (GST_EVENT_TYPE (event)) { case GST_EVENT_NEWSEGMENT: { @@ -649,14 +652,17 @@ gst_rtp_jitter_buffer_sink_event (GstPad * pad, GstEvent * event) } case GST_EVENT_FLUSH_START: gst_rtp_jitter_buffer_flush_start (jitterbuffer); + ret = gst_pad_push_event (priv->srcpad, event); break; case GST_EVENT_FLUSH_STOP: - gst_rtp_jitter_buffer_flush_stop (jitterbuffer); + ret = gst_pad_push_event (priv->srcpad, event); + ret = gst_rtp_jitter_buffer_src_activate_push (priv->srcpad, TRUE); break; case GST_EVENT_EOS: { /* push EOS in queue. We always push it at the head */ async_jitter_queue_lock (priv->queue); + GST_DEBUG_OBJECT (jitterbuffer, "queuing EOS"); /* check for flushing, we need to discard the event and return FALSE when * we are flushing */ ret = priv->srcresult == GST_FLOW_OK; @@ -947,8 +953,9 @@ again: /* bring timestamp to gst time */ timestamp = gst_util_uint64_scale (GST_SECOND, rtp_time, priv->clock_rate); - GST_DEBUG_OBJECT (jitterbuffer, "rtptime %u, timestamp %" GST_TIME_FORMAT, - rtp_time, GST_TIME_ARGS (timestamp)); + GST_DEBUG_OBJECT (jitterbuffer, + "rtptime %u, clock-rate %u, timestamp %" GST_TIME_FORMAT, rtp_time, + priv->clock_rate, GST_TIME_ARGS (timestamp)); /* bring to running time */ running_time = gst_segment_to_running_time (&priv->segment, GST_FORMAT_TIME, -- cgit v1.2.1