Commit db442b9e authored by Mathieu Duponchelle's avatar Mathieu Duponchelle 🐸

rtpstats: factor in packet spacing calculations

parent f57dbae8
Pipeline #9181 passed with stages
in 2 minutes and 18 seconds
......@@ -309,9 +309,8 @@ struct _GstRtpJitterBufferPrivate
guint32 seqnum_base;
/* last output time */
GstClockTime last_out_time;
/* last valid input timestamp and rtptime pair */
GstClockTime ips_pts;
guint64 ips_rtptime;
RTPPacketSpacingCtx packet_spacing_ctx;
GstClockTime packet_spacing;
gint equidistant;
......@@ -1564,8 +1563,6 @@ gst_rtp_jitter_buffer_flush_stop (GstRtpJitterBuffer * jitterbuffer)
priv->last_out_time = GST_CLOCK_TIME_NONE;
priv->next_seqnum = -1;
priv->seqnum_base = -1;
priv->ips_rtptime = -1;
priv->ips_pts = GST_CLOCK_TIME_NONE;
priv->packet_spacing = 0;
priv->next_in_seqnum = -1;
priv->clock_rate = -1;
......@@ -1587,6 +1584,7 @@ gst_rtp_jitter_buffer_flush_stop (GstRtpJitterBuffer * jitterbuffer)
remove_all_timers (jitterbuffer);
g_queue_foreach (&priv->gap_packets, (GFunc) gst_buffer_unref, NULL);
g_queue_clear (&priv->gap_packets);
gst_rtp_packet_spacing_ctx_reset (&priv->packet_spacing_ctx);
JBUF_UNLOCK (priv);
}
......@@ -2424,46 +2422,6 @@ update_timers (GstRtpJitterBuffer * jitterbuffer, guint16 seqnum,
}
}
static void
calculate_packet_spacing (GstRtpJitterBuffer * jitterbuffer, guint32 rtptime,
GstClockTime pts)
{
GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
/* we need consecutive seqnums with a different
* rtptime to estimate the packet spacing. */
if (priv->ips_rtptime != rtptime) {
/* rtptime changed, check pts diff */
if (priv->ips_pts != -1 && pts != -1 && pts > priv->ips_pts) {
GstClockTime new_packet_spacing = pts - priv->ips_pts;
GstClockTime old_packet_spacing = priv->packet_spacing;
/* Biased towards bigger packet spacings to prevent
* too many unneeded retransmission requests for next
* packets that just arrive a little later than we would
* expect */
if (old_packet_spacing > new_packet_spacing)
priv->packet_spacing =
(new_packet_spacing + 3 * old_packet_spacing) / 4;
else if (old_packet_spacing > 0)
priv->packet_spacing =
(3 * new_packet_spacing + old_packet_spacing) / 4;
else
priv->packet_spacing = new_packet_spacing;
GST_DEBUG_OBJECT (jitterbuffer,
"new packet spacing %" GST_TIME_FORMAT
" old packet spacing %" GST_TIME_FORMAT
" combined to %" GST_TIME_FORMAT,
GST_TIME_ARGS (new_packet_spacing),
GST_TIME_ARGS (old_packet_spacing),
GST_TIME_ARGS (priv->packet_spacing));
}
priv->ips_rtptime = rtptime;
priv->ips_pts = pts;
}
}
static void
calculate_expected (GstRtpJitterBuffer * jitterbuffer, guint32 expected,
guint16 seqnum, GstClockTime pts, gint gap)
......@@ -2799,14 +2757,11 @@ gst_rtp_jitter_buffer_reset (GstRtpJitterBuffer * jitterbuffer,
JBUF_SIGNAL_EVENT (priv);
/* reset spacing estimation when gap */
priv->ips_rtptime = -1;
priv->ips_pts = GST_CLOCK_TIME_NONE;
gst_rtp_packet_spacing_ctx_reset (&priv->packet_spacing_ctx);
buffers = g_list_copy (priv->gap_packets.head);
g_queue_clear (&priv->gap_packets);
priv->ips_rtptime = -1;
priv->ips_pts = GST_CLOCK_TIME_NONE;
JBUF_UNLOCK (jitterbuffer->priv);
for (l = buffers; l; l = l->next) {
......@@ -3011,9 +2966,7 @@ gst_rtp_jitter_buffer_chain (GstPad * pad, GstObject * parent,
do_next_seqnum = TRUE;
/* take rtptime and pts to calculate packet spacing */
priv->ips_rtptime = rtptime;
priv->ips_pts = pts;
gst_rtp_packet_spacing_ctx_update (&priv->packet_spacing_ctx, rtptime, pts);
} else {
gint gap;
/* now calculate gap */
......@@ -3060,7 +3013,9 @@ gst_rtp_jitter_buffer_chain (GstPad * pad, GstObject * parent,
if (G_LIKELY (gap == 0)) {
/* packet is expected */
calculate_packet_spacing (jitterbuffer, rtptime, pts);
priv->packet_spacing =
gst_rtp_packet_spacing_ctx_get (&priv->packet_spacing_ctx, rtptime,
pts);
do_next_seqnum = TRUE;
} else {
......@@ -3076,8 +3031,7 @@ gst_rtp_jitter_buffer_chain (GstPad * pad, GstObject * parent,
}
/* reset spacing estimation when gap */
priv->ips_rtptime = -1;
priv->ips_pts = GST_CLOCK_TIME_NONE;
gst_rtp_packet_spacing_ctx_reset (&priv->packet_spacing_ctx);
}
}
......
......@@ -228,46 +228,6 @@ done:
return res;
}
/* With SJB_LOCK */
static void
sjb_calculate_packet_spacing (GstRtpSimpleJitterBuffer * self, guint32 rtptime,
GstClockTime pts)
{
/* we need consecutive seqnums with a different
* rtptime to estimate the packet spacing. */
if (self->ips_rtptime != rtptime) {
/* rtptime changed, check pts diff */
if (self->ips_pts != G_MAXUINT64 && GST_CLOCK_TIME_IS_VALID (pts)
&& pts > self->ips_pts) {
GstClockTime new_packet_spacing = pts - self->ips_pts;
GstClockTime old_packet_spacing = self->packet_spacing;
/* Biased towards bigger packet spacings to prevent
* too many unneeded retransmission requests for next
* packets that just arrive a little later than we would
* expect */
if (old_packet_spacing > new_packet_spacing)
self->packet_spacing =
(new_packet_spacing + 3 * old_packet_spacing) / 4;
else if (old_packet_spacing > 0)
self->packet_spacing =
(3 * new_packet_spacing + old_packet_spacing) / 4;
else
self->packet_spacing = new_packet_spacing;
GST_DEBUG_OBJECT (self,
"new packet spacing %" GST_TIME_FORMAT
" old packet spacing %" GST_TIME_FORMAT
" combined to %" GST_TIME_FORMAT,
GST_TIME_ARGS (new_packet_spacing),
GST_TIME_ARGS (old_packet_spacing),
GST_TIME_ARGS (self->packet_spacing));
}
self->ips_rtptime = rtptime;
self->ips_pts = pts;
}
}
static gint
compare_buffer_seqnum (GstBuffer * a, GstBuffer * b, gpointer user_data)
{
......@@ -357,8 +317,7 @@ sjb_reset (GstRtpSimpleJitterBuffer * self,
self->last_in_seqnum = -1;
/* reset spacing estimation when gap */
self->ips_rtptime = -1;
self->ips_pts = GST_CLOCK_TIME_NONE;
gst_rtp_packet_spacing_ctx_reset (&self->packet_spacing_ctx);
buffers = g_list_copy (self->gap_packets.head);
g_queue_clear (&self->gap_packets);
......@@ -440,8 +399,7 @@ sjb_store (GstPad * pad, GstObject * parent, GstBuffer * buffer)
}
if (self->clock_rate == -1) {
self->ips_rtptime = rtptime;
self->ips_pts = pts;
gst_rtp_packet_spacing_ctx_update (&self->packet_spacing_ctx, rtptime, pts);
}
GST_DEBUG_OBJECT (self,
......@@ -497,7 +455,9 @@ sjb_store (GstPad * pad, GstObject * parent, GstBuffer * buffer)
/* self->last_popped_seqnum >= seqnum, we're too late. */
if (gap == 1) {
sjb_calculate_packet_spacing (self, rtptime, pts);
self->packet_spacing =
gst_rtp_packet_spacing_ctx_get (&self->packet_spacing_ctx, rtptime,
pts);
} else if ((gap != -1 && gap < -max_misorder) || (gap >= max_dropout)) {
gboolean reset = handle_big_gap_buffer (self, buffer, pt, seqnum,
gap, max_dropout, max_misorder);
......@@ -859,10 +819,8 @@ sjb_flush (GstRtpSimpleJitterBuffer * self)
self->last_in_seqnum = -1;
self->last_popped_pts = GST_CLOCK_TIME_NONE;
self->flushing = FALSE;
self->ips_rtptime = -1;
self->last_rtptime = -1;
self->equidistant = 0;
self->ips_pts = GST_CLOCK_TIME_NONE;
self->packet_spacing = 0;
self->earliest = NULL;
self->num_lost = 0;
......
......@@ -65,8 +65,7 @@ struct _GstRtpSimpleJitterBuffer
guint32 last_popped_seqnum; /* Used to determine whether a packet is too late, and what seqnums to send lost events for */
GstClockTime last_popped_pts; /* Used to determine the timestamp of lost events */
guint32 last_in_seqnum; /* Used to determine packet spacing and detect large gaps */
GstClockTime ips_pts; /* Used to determine packet spacing */
guint64 ips_rtptime; /* Used to determine packet spacing */
RTPPacketSpacingCtx packet_spacing_ctx; /* Used to determine packet spacing */
GstClockTime packet_spacing; /* Used to determine whether packets should be sent out */
RTPJitterBufferItem *earliest; /* Used to determine whether packets should be sent out */
gint equidistant; /* Used to determine whether our lost events should have a duration */
......
......@@ -428,3 +428,57 @@ __g_socket_address_to_string (GSocketAddress * addr)
return ret;
}
void
gst_rtp_packet_spacing_ctx_reset (RTPPacketSpacingCtx * ctx)
{
ctx->ips_rtptime = -1;
ctx->ips_pts = GST_CLOCK_TIME_NONE;
ctx->packet_spacing = 0;
}
void
gst_rtp_packet_spacing_ctx_update (RTPPacketSpacingCtx * ctx, guint32 rtptime,
GstClockTime pts)
{
ctx->ips_rtptime = rtptime;
ctx->ips_pts = pts;
}
GstClockTime
gst_rtp_packet_spacing_ctx_get (RTPPacketSpacingCtx * ctx, guint32 rtptime,
GstClockTime pts)
{
/* we need consecutive seqnums with a different
* rtptime to estimate the packet spacing. */
if (ctx->ips_rtptime != rtptime) {
/* rtptime changed, check pts diff */
if (ctx->ips_pts != -1 && pts != -1 && pts > ctx->ips_pts) {
GstClockTime new_packet_spacing = pts - ctx->ips_pts;
GstClockTime old_packet_spacing = ctx->packet_spacing;
/* Biased towards bigger packet spacings to prevent
* too many unneeded retransmission requests for next
* packets that just arrive a little later than we would
* expect */
if (old_packet_spacing > new_packet_spacing)
ctx->packet_spacing = (new_packet_spacing + 3 * old_packet_spacing) / 4;
else if (old_packet_spacing > 0)
ctx->packet_spacing = (3 * new_packet_spacing + old_packet_spacing) / 4;
else
ctx->packet_spacing = new_packet_spacing;
GST_DEBUG_OBJECT (ctx,
"new packet spacing %" GST_TIME_FORMAT
" old packet spacing %" GST_TIME_FORMAT
" combined to %" GST_TIME_FORMAT,
GST_TIME_ARGS (new_packet_spacing),
GST_TIME_ARGS (old_packet_spacing),
GST_TIME_ARGS (ctx->packet_spacing));
}
ctx->ips_rtptime = rtptime;
ctx->ips_pts = pts;
}
return ctx->packet_spacing;
}
......@@ -219,6 +219,17 @@ guint32 gst_rtp_packet_rate_ctx_get (RTPPacketRateCtx *ctx);
guint32 gst_rtp_packet_rate_ctx_get_max_dropout (RTPPacketRateCtx *ctx, gint32 time_ms);
guint32 gst_rtp_packet_rate_ctx_get_max_misorder (RTPPacketRateCtx *ctx, gint32 time_ms);
typedef struct {
/* last valid input timestamp and rtptime pair */
GstClockTime ips_pts;
guint64 ips_rtptime;
GstClockTime packet_spacing;
} RTPPacketSpacingCtx;
void gst_rtp_packet_spacing_ctx_reset (RTPPacketSpacingCtx *ctx);
void gst_rtp_packet_spacing_ctx_update (RTPPacketSpacingCtx *ctx, guint32 rtptime, GstClockTime pts);
GstClockTime gst_rtp_packet_spacing_ctx_get (RTPPacketSpacingCtx *ctx, guint32 rtptime, GstClockTime pts);
/**
* RTPSessionStats:
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment