gst/rtpmanager/async_jitter_queue.c: Fix leak when flushing.
authorWim Taymans <wim.taymans@gmail.com>
Mon, 14 May 2007 15:28:36 +0000 (15:28 +0000)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Tue, 11 Aug 2009 01:30:27 +0000 (02:30 +0100)
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
gst/rtpmanager/gstrtpbin.c
gst/rtpmanager/gstrtpbin.h
gst/rtpmanager/gstrtpjitterbuffer.c

index ba14d98..77980c9 100644 (file)
@@ -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);
 }
 
 /**
index 927755f..a6cd384 100644 (file)
@@ -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");
 }
 
index 523eb78..24eb38d 100644 (file)
@@ -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);
index 0bd0cb1..e49f41a 100644 (file)
@@ -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,