mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-21 15:56:42 +00:00
gst/rtpmanager/gstrtpjitterbuffer.c: When checking the seqnum, reset the jitterbuffer if the gap is too big, we need ...
Original commit message from CVS: * gst/rtpmanager/gstrtpjitterbuffer.c: (gst_rtp_jitter_buffer_chain), (gst_rtp_jitter_buffer_loop): When checking the seqnum, reset the jitterbuffer if the gap is too big, we need to do this so that we can better handle a restarted source. Fix some comments. * gst/rtpmanager/rtpjitterbuffer.c: (calculate_skew), (rtp_jitter_buffer_insert): Tweak the skew resync diff. Use our working seqnum compare function in -base. Rework the jitterbuffer insert code to make it clearer and more performant by only retrieving the seqnum of the input buffer once and by adding some G_LIKELY compiler hints. Improve debugging for duplicate packets. * gst/rtpmanager/rtpsource.c: (rtp_source_process_rtp): Fix a comment, we don't do skew correction here..
This commit is contained in:
parent
ff79f31297
commit
987a903d89
4 changed files with 81 additions and 38 deletions
20
ChangeLog
20
ChangeLog
|
@ -1,3 +1,23 @@
|
||||||
|
2008-05-26 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||||
|
|
||||||
|
* gst/rtpmanager/gstrtpjitterbuffer.c:
|
||||||
|
(gst_rtp_jitter_buffer_chain), (gst_rtp_jitter_buffer_loop):
|
||||||
|
When checking the seqnum, reset the jitterbuffer if the gap is too big,
|
||||||
|
we need to do this so that we can better handle a restarted source.
|
||||||
|
Fix some comments.
|
||||||
|
|
||||||
|
* gst/rtpmanager/rtpjitterbuffer.c: (calculate_skew),
|
||||||
|
(rtp_jitter_buffer_insert):
|
||||||
|
Tweak the skew resync diff.
|
||||||
|
Use our working seqnum compare function in -base.
|
||||||
|
Rework the jitterbuffer insert code to make it clearer and more
|
||||||
|
performant by only retrieving the seqnum of the input buffer once and by
|
||||||
|
adding some G_LIKELY compiler hints.
|
||||||
|
Improve debugging for duplicate packets.
|
||||||
|
|
||||||
|
* gst/rtpmanager/rtpsource.c: (rtp_source_process_rtp):
|
||||||
|
Fix a comment, we don't do skew correction here..
|
||||||
|
|
||||||
2008-05-26 Wim Taymans <wim.taymans@collabora.co.uk>
|
2008-05-26 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||||
|
|
||||||
Patch by: Håvard Graff <havard dot graff at tandberg dot com>
|
Patch by: Håvard Graff <havard dot graff at tandberg dot com>
|
||||||
|
|
|
@ -885,12 +885,32 @@ gst_rtp_jitter_buffer_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
if (priv->eos)
|
if (priv->eos)
|
||||||
goto have_eos;
|
goto have_eos;
|
||||||
|
|
||||||
/* let's check if this buffer is too late, we cannot accept packets with
|
/* let's check if this buffer is too late, we can only accept packets with
|
||||||
* bigger seqnum than the one we already pushed. */
|
* bigger seqnum than the one we last pushed. */
|
||||||
if (priv->last_popped_seqnum != -1) {
|
if (priv->last_popped_seqnum != -1) {
|
||||||
/* FIXME. isn't this supposed to be <= ? */
|
gint gap;
|
||||||
if (gst_rtp_buffer_compare_seqnum (priv->last_popped_seqnum, seqnum) < 0)
|
|
||||||
goto too_late;
|
gap = gst_rtp_buffer_compare_seqnum (priv->last_popped_seqnum, seqnum);
|
||||||
|
|
||||||
|
if (gap <= 0) {
|
||||||
|
/* priv->last_popped_seqnum >= seqnum, this packet is too late or the
|
||||||
|
* sender might have been restarted with different seqnum. */
|
||||||
|
if (gap < -100) {
|
||||||
|
GST_DEBUG_OBJECT (jitterbuffer, "reset: buffer too old %d", gap);
|
||||||
|
priv->last_popped_seqnum = -1;
|
||||||
|
priv->next_seqnum = -1;
|
||||||
|
} else {
|
||||||
|
goto too_late;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* priv->last_popped_seqnum < seqnum, this is a new packet */
|
||||||
|
if (gap > 3000) {
|
||||||
|
GST_DEBUG_OBJECT (jitterbuffer, "reset: too many dropped packets %d",
|
||||||
|
gap);
|
||||||
|
priv->last_popped_seqnum = -1;
|
||||||
|
priv->next_seqnum = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* let's drop oldest packet if the queue is already full and drop-on-latency
|
/* let's drop oldest packet if the queue is already full and drop-on-latency
|
||||||
|
@ -1041,7 +1061,7 @@ again:
|
||||||
if (priv->eos)
|
if (priv->eos)
|
||||||
goto do_eos;
|
goto do_eos;
|
||||||
}
|
}
|
||||||
/* wait for packets or flushing now */
|
/* underrun, wait for packets or flushing now */
|
||||||
priv->waiting = TRUE;
|
priv->waiting = TRUE;
|
||||||
JBUF_WAIT_CHECK (priv, flushing);
|
JBUF_WAIT_CHECK (priv, flushing);
|
||||||
priv->waiting = FALSE;
|
priv->waiting = FALSE;
|
||||||
|
@ -1187,7 +1207,7 @@ again:
|
||||||
if (gap > 0) {
|
if (gap > 0) {
|
||||||
GstEvent *event;
|
GstEvent *event;
|
||||||
|
|
||||||
/* we had a gap and thus we lost a packet. Creat an event for this. */
|
/* we had a gap and thus we lost a packet. Create an event for this. */
|
||||||
GST_DEBUG_OBJECT (jitterbuffer, "Packet #%d lost", next_seqnum);
|
GST_DEBUG_OBJECT (jitterbuffer, "Packet #%d lost", next_seqnum);
|
||||||
priv->num_late++;
|
priv->num_late++;
|
||||||
discont = TRUE;
|
discont = TRUE;
|
||||||
|
|
|
@ -217,8 +217,10 @@ again:
|
||||||
delta_diff = jbuf->prev_send_diff - send_diff;
|
delta_diff = jbuf->prev_send_diff - send_diff;
|
||||||
|
|
||||||
/* server changed rtp timestamps too quickly, reset skew detection and start
|
/* server changed rtp timestamps too quickly, reset skew detection and start
|
||||||
* again. */
|
* again. This value is sortof arbitrary and can be a bad measurement up if
|
||||||
if (delta_diff > GST_SECOND / 4) {
|
* 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_DEBUG ("delta changed too quickly %" GST_TIME_FORMAT " reset skew",
|
||||||
GST_TIME_ARGS (delta_diff));
|
GST_TIME_ARGS (delta_diff));
|
||||||
rtp_jitter_buffer_reset_skew (jbuf);
|
rtp_jitter_buffer_reset_skew (jbuf);
|
||||||
|
@ -326,23 +328,6 @@ no_skew:
|
||||||
return out_time;
|
return out_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
|
||||||
compare_seqnum (GstBuffer * a, GstBuffer * b, RTPJitterBuffer * jbuf)
|
|
||||||
{
|
|
||||||
guint16 seq1, seq2;
|
|
||||||
|
|
||||||
seq1 = gst_rtp_buffer_get_seq (a);
|
|
||||||
seq2 = gst_rtp_buffer_get_seq (b);
|
|
||||||
|
|
||||||
/* check if diff more than half of the 16bit range */
|
|
||||||
if (abs (seq2 - seq1) > (1 << 15)) {
|
|
||||||
/* one of a/b has wrapped */
|
|
||||||
return seq1 - seq2;
|
|
||||||
} else {
|
|
||||||
return seq2 - seq1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rtp_jitter_buffer_insert:
|
* rtp_jitter_buffer_insert:
|
||||||
* @jbuf: an #RTPJitterBuffer
|
* @jbuf: an #RTPJitterBuffer
|
||||||
|
@ -362,22 +347,32 @@ rtp_jitter_buffer_insert (RTPJitterBuffer * jbuf, GstBuffer * buf,
|
||||||
GstClockTime time, guint32 clock_rate, gboolean * tail)
|
GstClockTime time, guint32 clock_rate, gboolean * tail)
|
||||||
{
|
{
|
||||||
GList *list;
|
GList *list;
|
||||||
gint func_ret = 1;
|
|
||||||
guint32 rtptime;
|
guint32 rtptime;
|
||||||
|
guint16 seqnum;
|
||||||
|
|
||||||
g_return_val_if_fail (jbuf != NULL, FALSE);
|
g_return_val_if_fail (jbuf != NULL, FALSE);
|
||||||
g_return_val_if_fail (buf != NULL, FALSE);
|
g_return_val_if_fail (buf != NULL, FALSE);
|
||||||
|
|
||||||
/* loop the list to skip strictly smaller seqnum buffers */
|
seqnum = gst_rtp_buffer_get_seq (buf);
|
||||||
list = jbuf->packets->head;
|
|
||||||
while (list
|
|
||||||
&& (func_ret =
|
|
||||||
compare_seqnum (GST_BUFFER_CAST (list->data), buf, jbuf)) < 0)
|
|
||||||
list = list->next;
|
|
||||||
|
|
||||||
/* we hit a packet with the same seqnum, return FALSE to notify a duplicate */
|
/* loop the list to skip strictly smaller seqnum buffers */
|
||||||
if (func_ret == 0)
|
for (list = jbuf->packets->head; list; list = g_list_next (list)) {
|
||||||
return FALSE;
|
guint16 qseq;
|
||||||
|
gint gap;
|
||||||
|
|
||||||
|
qseq = gst_rtp_buffer_get_seq (GST_BUFFER_CAST (list->data));
|
||||||
|
|
||||||
|
/* compare the new seqnum to the one in the buffer */
|
||||||
|
gap = gst_rtp_buffer_compare_seqnum (seqnum, qseq);
|
||||||
|
|
||||||
|
/* we hit a packet with the same seqnum, notify a duplicate */
|
||||||
|
if (G_UNLIKELY (gap == 0))
|
||||||
|
goto duplicate;
|
||||||
|
|
||||||
|
/* seqnum > qseq, we can stop looking */
|
||||||
|
if (G_LIKELY (gap < 0))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* do skew calculation by measuring the difference between rtptime and the
|
/* do skew calculation by measuring the difference between rtptime and the
|
||||||
* receive time, this function will retimestamp @buf with the skew corrected
|
* receive time, this function will retimestamp @buf with the skew corrected
|
||||||
|
@ -391,11 +386,19 @@ rtp_jitter_buffer_insert (RTPJitterBuffer * jbuf, GstBuffer * buf,
|
||||||
else
|
else
|
||||||
g_queue_push_tail (jbuf->packets, buf);
|
g_queue_push_tail (jbuf->packets, buf);
|
||||||
|
|
||||||
/* tail was changed when we did not find a previous packet */
|
/* tail was changed when we did not find a previous packet, we set the return
|
||||||
|
* flag when requested. */
|
||||||
if (tail)
|
if (tail)
|
||||||
*tail = (list == NULL);
|
*tail = (list == NULL);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
duplicate:
|
||||||
|
{
|
||||||
|
GST_WARNING ("duplicate packet %d found", (gint) seqnum);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -940,7 +940,7 @@ rtp_source_process_rtp (RTPSource * src, GstBuffer * buffer,
|
||||||
GST_DEBUG ("seq %d, PC: %" G_GUINT64_FORMAT ", OC: %" G_GUINT64_FORMAT,
|
GST_DEBUG ("seq %d, PC: %" G_GUINT64_FORMAT ", OC: %" G_GUINT64_FORMAT,
|
||||||
seqnr, src->stats.packets_received, src->stats.octets_received);
|
seqnr, src->stats.packets_received, src->stats.octets_received);
|
||||||
|
|
||||||
/* calculate jitter and perform skew correction */
|
/* calculate jitter for the stats */
|
||||||
calculate_jitter (src, buffer, arrival);
|
calculate_jitter (src, buffer, arrival);
|
||||||
|
|
||||||
/* we're ready to push the RTP packet now */
|
/* we're ready to push the RTP packet now */
|
||||||
|
|
Loading…
Reference in a new issue