rtpstats: add utility for calculating RTP packet rate
authorMiguel París Díaz <mparisdiaz@gmail.com>
Tue, 30 Jun 2015 14:56:19 +0000 (16:56 +0200)
committerLuis de Bethencourt <luisbg@osg.samsung.com>
Fri, 2 Oct 2015 18:25:27 +0000 (19:25 +0100)
gst/rtpmanager/rtpstats.c
gst/rtpmanager/rtpstats.h

index f9f7c2c..d47578d 100644 (file)
 
 #include "rtpstats.h"
 
+void
+gst_rtp_packet_rate_ctx_reset (RTPPacketRateCtx * ctx, guint32 clock_rate)
+{
+  ctx->clock_rate = clock_rate;
+  ctx->probed = FALSE;
+  ctx->avg_packet_rate = -1;
+}
+
+guint32
+gst_rtp_packet_rate_ctx_update (RTPPacketRateCtx * ctx, guint16 seqnum,
+    guint32 ts)
+{
+  guint64 new_ts, diff_ts;
+  gint diff_seqnum;
+  guint32 new_packet_rate;
+
+  if (ctx->clock_rate <= 0) {
+    return ctx->avg_packet_rate;
+  }
+
+  if (!ctx->probed) {
+    ctx->last_seqnum = seqnum;
+    ctx->last_ts = ts;
+    ctx->probed = TRUE;
+    return ctx->avg_packet_rate;
+  }
+
+  new_ts = ctx->last_ts;
+  gst_rtp_buffer_ext_timestamp (&new_ts, ts);
+  diff_seqnum = gst_rtp_buffer_compare_seqnum (ctx->last_seqnum, seqnum);
+  if (diff_seqnum <= 0 || new_ts <= ctx->last_ts) {
+    return ctx->avg_packet_rate;
+  }
+
+  diff_ts = new_ts - ctx->last_ts;
+  diff_ts = gst_util_uint64_scale_int (diff_ts, GST_SECOND, ctx->clock_rate);
+  new_packet_rate = gst_util_uint64_scale (diff_seqnum, GST_SECOND, diff_ts);
+
+  /* The goal is that higher packet rates "win".
+   * If there's a sudden burst, the average will go up fast,
+   * but it will go down again slowly.
+   * This is useful for bursty cases, where a lot of packets are close
+   * to each other and should allow a higher reorder/dropout there.
+   */
+  if (ctx->avg_packet_rate > new_packet_rate) {
+    ctx->avg_packet_rate = (7 * ctx->avg_packet_rate + new_packet_rate + 7) / 8;
+  } else {
+    ctx->avg_packet_rate = (ctx->avg_packet_rate + new_packet_rate + 1) / 2;
+  }
+
+  ctx->last_seqnum = seqnum;
+  ctx->last_ts = new_ts;
+
+  return ctx->avg_packet_rate;
+}
+
+guint32
+gst_rtp_packet_rate_ctx_get (RTPPacketRateCtx * ctx)
+{
+  return ctx->avg_packet_rate;
+}
+
 /**
  * rtp_stats_init_defaults:
  * @stats: an #RTPSessionStats struct
index d221aea..9c74039 100644 (file)
@@ -194,6 +194,23 @@ typedef struct {
 #define RTP_MAX_MISORDER     100
 
 /**
+ * RTPPacketRateCtx:
+ *
+ * Context to calculate the pseudo-average packet rate.
+ */
+typedef struct {
+  gboolean probed;
+  guint32 clock_rate;
+  guint16 last_seqnum;
+  guint64 last_ts;
+  guint32 avg_packet_rate;
+} RTPPacketRateCtx;
+
+void gst_rtp_packet_rate_ctx_reset (RTPPacketRateCtx * ctx, guint32 clock_rate);
+guint32 gst_rtp_packet_rate_ctx_update (RTPPacketRateCtx *ctx, guint16 seqnum, guint32 ts);
+guint32 gst_rtp_packet_rate_ctx_get (RTPPacketRateCtx *ctx);
+
+/**
  * RTPSessionStats:
  *
  * Stats kept for a session and used to produce RTCP packet timeouts.