gst/rtpmanager/gstrtpjitterbuffer.c: Remove some old unused variables.
authorWim Taymans <wim.taymans@gmail.com>
Tue, 2 Oct 2007 10:27:45 +0000 (10:27 +0000)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Tue, 11 Aug 2009 01:30:30 +0000 (02:30 +0100)
Original commit message from CVS:
* gst/rtpmanager/gstrtpjitterbuffer.c:
(gst_rtp_jitter_buffer_flush_start),
(gst_rtp_jitter_buffer_flush_stop),
(gst_rtp_jitter_buffer_change_state), (apply_offset),
(gst_rtp_jitter_buffer_loop):
Remove some old unused variables.
Don't add the latency to the skew corrected timestamp, latency is only
used to sync against the clock.
Improve debugging.
* gst/rtpmanager/rtpjitterbuffer.c: (rtp_jitter_buffer_init),
(rtp_jitter_buffer_reset_skew), (calculate_skew):
* gst/rtpmanager/rtpjitterbuffer.h:
Handle case where server timestamp goes backwards or wildly jumps by
temporarily pausing the skew correction.
Improve debugging.

gst/rtpmanager/gstrtpjitterbuffer.c
gst/rtpmanager/rtpjitterbuffer.c
gst/rtpmanager/rtpjitterbuffer.h

index 2155df8..e087a7f 100644 (file)
@@ -152,7 +152,6 @@ struct _GstRtpJitterBufferPrivate
   /* clock rate and rtp timestamp offset */
   gint32 clock_rate;
   gint64 clock_base;
-  guint64 exttimestamp;
   gint64 prev_ts_offset;
 
   /* when we are shutting down */
@@ -525,7 +524,6 @@ gst_rtp_jitter_buffer_flush_start (GstRtpJitterBuffer * jitterbuffer)
   GST_DEBUG_OBJECT (jitterbuffer, "Disabling pop on queue");
   /* this unblocks any waiting pops on the src pad task */
   JBUF_SIGNAL (priv);
-  rtp_jitter_buffer_flush (priv->jbuf);
   /* unlock clock, we just unschedule, the entry will be released by the 
    * locking streaming thread. */
   if (priv->clock_id)
@@ -549,7 +547,8 @@ gst_rtp_jitter_buffer_flush_stop (GstRtpJitterBuffer * jitterbuffer)
   priv->next_seqnum = -1;
   priv->clock_rate = -1;
   priv->eos = FALSE;
-  priv->exttimestamp = -1;
+  rtp_jitter_buffer_flush (priv->jbuf);
+  rtp_jitter_buffer_reset_skew (priv->jbuf);
   JBUF_UNLOCK (priv);
 }
 
@@ -606,7 +605,8 @@ gst_rtp_jitter_buffer_change_state (GstElement * element,
       priv->peer_latency = 0;
       /* block until we go to PLAYING */
       priv->blocked = TRUE;
-      priv->exttimestamp = -1;
+      /* reset skew detection initialy */
+      rtp_jitter_buffer_reset_skew (priv->jbuf);
       JBUF_UNLOCK (priv);
       break;
     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
@@ -943,7 +943,7 @@ duplicate:
 }
 
 static GstClockTime
-apply_latency (GstRtpJitterBuffer * jitterbuffer, GstClockTime timestamp)
+apply_offset (GstRtpJitterBuffer * jitterbuffer, GstClockTime timestamp)
 {
   GstRtpJitterBufferPrivate *priv;
 
@@ -955,10 +955,6 @@ apply_latency (GstRtpJitterBuffer * jitterbuffer, GstClockTime timestamp)
   /* apply the timestamp offset */
   timestamp += priv->ts_offset;
 
-  /* add latency, this includes our own latency and the peer latency. */
-  timestamp += (priv->latency_ms * GST_MSECOND);
-  timestamp += priv->peer_latency;
-
   return timestamp;
 }
 
@@ -1011,8 +1007,9 @@ again:
       seqnum, GST_TIME_ARGS (timestamp),
       rtp_jitter_buffer_num_packets (priv->jbuf));
 
-  /* apply our latency to the incomming buffer before syncing. */
-  out_time = apply_latency (jitterbuffer, timestamp);
+  /* apply our timestamp offset to the incomming buffer, this will be our output
+   * timestamp. */
+  out_time = apply_offset (jitterbuffer, timestamp);
 
   /* If we don't know what the next seqnum should be (== -1) we have to wait
    * because it might be possible that we are not receiving this buffer in-order,
@@ -1054,6 +1051,9 @@ again:
 
     /* prepare for sync against clock */
     sync_time = out_time + GST_ELEMENT_CAST (jitterbuffer)->base_time;
+    /* add latency, this includes our own latency and the peer latency. */
+    sync_time += (priv->latency_ms * GST_MSECOND);
+    sync_time += priv->peer_latency;
 
     /* create an entry for the clock */
     id = priv->clock_id = gst_clock_new_single_shot_id (clock, sync_time);
@@ -1093,7 +1093,7 @@ again:
       goto again;
     }
     /* Get new timestamp, latency might have changed */
-    out_time = apply_latency (jitterbuffer, timestamp);
+    out_time = apply_offset (jitterbuffer, timestamp);
   }
 push_buffer:
   /* check if we are pushing something unexpected */
@@ -1115,7 +1115,7 @@ push_buffer:
     GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
   }
 
-  /* apply timestamp to buffer now */
+  /* apply timestamp with offset to buffer now */
   GST_BUFFER_TIMESTAMP (outbuf) = out_time;
 
   /* now we are ready to push the buffer. Save the seqnum and release the lock
index d030419..a002cc3 100644 (file)
@@ -65,13 +65,8 @@ static void
 rtp_jitter_buffer_init (RTPJitterBuffer * jbuf)
 {
   jbuf->packets = g_queue_new ();
-  jbuf->base_time = -1;
-  jbuf->base_rtptime = -1;
-  jbuf->ext_rtptime = -1;
-  jbuf->window_pos = 0;
-  jbuf->window_filling = TRUE;
-  jbuf->window_min = 0;
-  jbuf->skew = 0;
+
+  rtp_jitter_buffer_reset_skew (jbuf);
 }
 
 static void
@@ -130,6 +125,18 @@ rtp_jitter_buffer_get_clock_rate (RTPJitterBuffer * jbuf)
   return jbuf->clock_rate;
 }
 
+void
+rtp_jitter_buffer_reset_skew (RTPJitterBuffer * jbuf)
+{
+  jbuf->base_time = -1;
+  jbuf->base_rtptime = -1;
+  jbuf->ext_rtptime = -1;
+  jbuf->window_pos = 0;
+  jbuf->window_filling = TRUE;
+  jbuf->window_min = 0;
+  jbuf->skew = 0;
+  jbuf->prev_send_diff = -1;
+}
 
 /* For the clock skew we use a windowed low point averaging algorithm as can be
  * found in http://www.grame.fr/pub/TR-050601.pdf. The idea is that the jitter is
@@ -204,14 +211,47 @@ calculate_skew (RTPJitterBuffer * jbuf, guint32 rtptime, GstClockTime time)
   gstrtptime =
       gst_util_uint64_scale_int (ext_rtptime, GST_SECOND, jbuf->clock_rate);
 
+again:
   /* first time, lock on to time and gstrtptime */
   if (jbuf->base_time == -1)
     jbuf->base_time = time;
   if (jbuf->base_rtptime == -1)
     jbuf->base_rtptime = gstrtptime;
 
-  /* elapsed time at sender */
-  send_diff = gstrtptime - jbuf->base_rtptime;
+  if (gstrtptime >= jbuf->base_rtptime)
+    send_diff = gstrtptime - jbuf->base_rtptime;
+  else {
+    /* elapsed time at sender, timestamps can go backwards and thus be smaller
+     * than our base time, take a new base time in that case. */
+    GST_DEBUG ("backward timestamps at server, taking new base time");
+    jbuf->base_rtptime = gstrtptime;
+    jbuf->base_time = time;
+    send_diff = 0;
+  }
+
+  GST_DEBUG ("extrtp %" G_GUINT64_FORMAT ", gstrtp %" GST_TIME_FORMAT ", base %"
+      GST_TIME_FORMAT ", send_diff %" GST_TIME_FORMAT, ext_rtptime,
+      GST_TIME_ARGS (gstrtptime), GST_TIME_ARGS (jbuf->base_rtptime),
+      GST_TIME_ARGS (send_diff));
+
+  if (jbuf->prev_send_diff != -1) {
+    gint64 delta_diff;
+
+    if (send_diff > jbuf->prev_send_diff)
+      delta_diff = send_diff - jbuf->prev_send_diff;
+    else
+      delta_diff = jbuf->prev_send_diff - send_diff;
+
+    /* server changed rtp timestamps too quickly, reset skew detection and start
+     * again. */
+    if (delta_diff > GST_SECOND / 4) {
+      GST_DEBUG ("delta changed too quickly %" GST_TIME_FORMAT " reset skew",
+          GST_TIME_ARGS (delta_diff));
+      rtp_jitter_buffer_reset_skew (jbuf);
+      goto again;
+    }
+  }
+  jbuf->prev_send_diff = send_diff;
 
   /* we don't have an arrival timestamp so we can't do skew detection. we
    * should still apply a timestamp based on RTP timestamp and base_time */
@@ -221,6 +261,10 @@ calculate_skew (RTPJitterBuffer * jbuf, guint32 rtptime, GstClockTime time)
   /* elapsed time at receiver, includes the jitter */
   recv_diff = time - jbuf->base_time;
 
+  GST_DEBUG ("time %" GST_TIME_FORMAT ", base %" GST_TIME_FORMAT ", recv_diff %"
+      GST_TIME_FORMAT, GST_TIME_ARGS (time), GST_TIME_ARGS (jbuf->base_time),
+      GST_TIME_ARGS (recv_diff));
+
   /* measure the diff */
   delta = ((gint64) recv_diff) - ((gint64) send_diff);
 
@@ -228,8 +272,7 @@ calculate_skew (RTPJitterBuffer * jbuf, guint32 rtptime, GstClockTime time)
 
   if (jbuf->window_filling) {
     /* we are filling the window */
-    GST_DEBUG ("filling %d %" G_GINT64_FORMAT ", send_diff %" G_GUINT64_FORMAT,
-        pos, delta, send_diff);
+    GST_DEBUG ("filling %d, delta %" G_GINT64_FORMAT, pos, delta);
     jbuf->window[pos++] = delta;
     /* calc the min delta we observed */
     if (pos == 1 || delta < jbuf->window_min)
@@ -290,8 +333,8 @@ calculate_skew (RTPJitterBuffer * jbuf, guint32 rtptime, GstClockTime time)
     }
     /* average the min values */
     jbuf->skew = (jbuf->window_min + (124 * jbuf->skew)) / 125;
-    GST_DEBUG ("new min: %" G_GINT64_FORMAT ", skew %" G_GINT64_FORMAT,
-        jbuf->window_min, jbuf->skew);
+    GST_DEBUG ("delta %" G_GINT64_FORMAT ", new min: %" G_GINT64_FORMAT,
+        delta, jbuf->window_min);
   }
   /* wrap around in the window */
   if (pos >= jbuf->window_size)
@@ -303,9 +346,7 @@ no_skew:
    * adjusted for the clock skew .*/
   out_time = jbuf->base_time + send_diff + jbuf->skew;
 
-  GST_DEBUG ("base %" GST_TIME_FORMAT ", diff %" GST_TIME_FORMAT ", skew %"
-      G_GINT64_FORMAT ", out %" GST_TIME_FORMAT,
-      GST_TIME_ARGS (jbuf->base_time), GST_TIME_ARGS (send_diff),
+  GST_DEBUG ("skew %" G_GINT64_FORMAT ", out %" GST_TIME_FORMAT,
       jbuf->skew, GST_TIME_ARGS (out_time));
 
   return out_time;
index fdc8d48..d9903a1 100644 (file)
@@ -66,6 +66,7 @@ struct _RTPJitterBuffer {
   gboolean       window_filling;
   gint64         window_min;
   gint64         skew;
+  gint64         prev_send_diff;
 
   RTPTailChanged tail_changed;
   gpointer       user_data;
@@ -86,6 +87,8 @@ void                  rtp_jitter_buffer_set_tail_changed (RTPJitterBuffer *jbuf,
 void                  rtp_jitter_buffer_set_clock_rate   (RTPJitterBuffer *jbuf, gint clock_rate);
 gint                  rtp_jitter_buffer_get_clock_rate   (RTPJitterBuffer *jbuf);
 
+void                  rtp_jitter_buffer_reset_skew       (RTPJitterBuffer *jbuf);
+
 gboolean              rtp_jitter_buffer_insert           (RTPJitterBuffer *jbuf, GstBuffer *buf, GstClockTime time);
 GstBuffer *           rtp_jitter_buffer_pop              (RTPJitterBuffer *jbuf);