summaryrefslogtreecommitdiffstats
path: root/gst/rtpmanager/rtpjitterbuffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst/rtpmanager/rtpjitterbuffer.c')
-rw-r--r--gst/rtpmanager/rtpjitterbuffer.c82
1 files changed, 48 insertions, 34 deletions
diff --git a/gst/rtpmanager/rtpjitterbuffer.c b/gst/rtpmanager/rtpjitterbuffer.c
index 70a49c1e..050adef0 100644
--- a/gst/rtpmanager/rtpjitterbuffer.c
+++ b/gst/rtpmanager/rtpjitterbuffer.c
@@ -104,6 +104,7 @@ rtp_jitter_buffer_reset_skew (RTPJitterBuffer * jbuf)
{
jbuf->base_time = -1;
jbuf->base_rtptime = -1;
+ jbuf->base_extrtp = -1;
jbuf->ext_rtptime = -1;
jbuf->window_pos = 0;
jbuf->window_filling = TRUE;
@@ -185,21 +186,23 @@ calculate_skew (RTPJitterBuffer * jbuf, guint32 rtptime, GstClockTime time,
gstrtptime = gst_util_uint64_scale_int (ext_rtptime, GST_SECOND, clock_rate);
-again:
/* first time, lock on to time and gstrtptime */
- if (jbuf->base_time == -1)
+ if (G_UNLIKELY (jbuf->base_time == -1))
jbuf->base_time = time;
- if (jbuf->base_rtptime == -1)
+ if (G_UNLIKELY (jbuf->base_rtptime == -1)) {
jbuf->base_rtptime = gstrtptime;
+ jbuf->base_extrtp = ext_rtptime;
+ }
- if (gstrtptime >= jbuf->base_rtptime)
+ if (G_LIKELY (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;
+ jbuf->base_rtptime = gstrtptime;
+ jbuf->base_extrtp = ext_rtptime;
send_diff = 0;
}
@@ -208,27 +211,6 @@ again:
GST_TIME_ARGS (gstrtptime), GST_TIME_ARGS (jbuf->base_rtptime),
GST_TIME_ARGS (send_diff));
- if (jbuf->prev_send_diff != -1 && time != -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. This value is sortof arbitrary and can be a bad measurement up if
- * there are many packets missing because then we get a big gap that is
- * unrelated to a timestamp switch. */
- if (delta_diff > GST_SECOND) {
- 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 */
if (time == -1)
@@ -244,17 +226,30 @@ again:
/* measure the diff */
delta = ((gint64) recv_diff) - ((gint64) send_diff);
+ /* if the difference between the sender timeline and the receiver timeline
+ * changed too quickly we have to resync because the server likely restarted
+ * its timestamps. */
+ if (ABS (delta - jbuf->skew) > GST_SECOND) {
+ GST_DEBUG ("delta %" GST_TIME_FORMAT " too big, reset skew",
+ delta - jbuf->skew);
+ jbuf->base_time = time;
+ jbuf->base_rtptime = gstrtptime;
+ jbuf->base_extrtp = ext_rtptime;
+ send_diff = 0;
+ delta = 0;
+ }
+
pos = jbuf->window_pos;
- if (jbuf->window_filling) {
+ if (G_UNLIKELY (jbuf->window_filling)) {
/* we are filling the window */
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)
+ if (G_UNLIKELY (pos == 1 || delta < jbuf->window_min))
jbuf->window_min = delta;
- if (send_diff >= MAX_TIME || pos >= MAX_WINDOW) {
+ if (G_UNLIKELY (send_diff >= MAX_TIME || pos >= MAX_WINDOW)) {
jbuf->window_size = pos;
/* window filled */
@@ -288,11 +283,11 @@ again:
old = jbuf->window[pos];
jbuf->window[pos++] = delta;
- if (delta <= jbuf->window_min) {
+ if (G_UNLIKELY (delta <= jbuf->window_min)) {
/* if the new value we inserted is smaller or equal to the current min,
* it becomes the new min */
jbuf->window_min = delta;
- } else if (old == jbuf->window_min) {
+ } else if (G_UNLIKELY (old == jbuf->window_min)) {
gint64 min = G_MAXINT64;
/* if we removed the old min, we have to find a new min */
@@ -313,7 +308,7 @@ again:
delta, jbuf->window_min);
}
/* wrap around in the window */
- if (pos >= jbuf->window_size)
+ if (G_UNLIKELY (pos >= jbuf->window_size))
pos = 0;
jbuf->window_pos = pos;
@@ -382,14 +377,14 @@ rtp_jitter_buffer_insert (RTPJitterBuffer * jbuf, GstBuffer * buf,
time = calculate_skew (jbuf, rtptime, time, clock_rate);
GST_BUFFER_TIMESTAMP (buf) = time;
- if (list)
+ if (G_LIKELY (list))
g_queue_insert_before (jbuf->packets, list, buf);
else
g_queue_push_tail (jbuf->packets, buf);
/* tail was changed when we did not find a previous packet, we set the return
* flag when requested. */
- if (tail)
+ if (G_UNLIKELY (tail))
*tail = (list == NULL);
return TRUE;
@@ -514,3 +509,22 @@ rtp_jitter_buffer_get_ts_diff (RTPJitterBuffer * jbuf)
}
return result;
}
+
+/**
+ * rtp_jitter_buffer_get_sync:
+ * @jbuf: an #RTPJitterBuffer
+ * @rtptime: result RTP time
+ * @timestamp: result GStreamer timestamp
+ *
+ * Returns the relation between the RTP timestamp and the GStreamer timestamp
+ * used for constructing timestamps.
+ */
+void
+rtp_jitter_buffer_get_sync (RTPJitterBuffer * jbuf, guint64 * rtptime,
+ guint64 * timestamp)
+{
+ if (rtptime)
+ *rtptime = jbuf->base_extrtp;
+ if (timestamp)
+ *timestamp = jbuf->base_time + jbuf->skew;
+}