rtpbin: add ts-offset-smoothing-factor property
authorRobert Rosengren <robertr@axis.com>
Tue, 23 Nov 2021 08:03:28 +0000 (09:03 +0100)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Tue, 8 Feb 2022 11:11:35 +0000 (11:11 +0000)
Add property to set the TS offset smoothing factor and set default value
to not use it.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1409>

subprojects/gst-plugins-good/docs/gst_plugins_cache.json
subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.c
subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.h

index ac1819a..5571c2a 100644 (file)
                         "type": "GstStructure",
                         "writable": true
                     },
+                    "ts-offset-smoothing-factor": {
+                        "blurb": "Sets a smoothing factor for the timestamp offset in number of values for a calculated running moving average. (0 = no smoothing factor)",
+                        "conditionally-available": false,
+                        "construct": false,
+                        "construct-only": false,
+                        "controllable": false,
+                        "default": "0",
+                        "max": "-1",
+                        "min": "0",
+                        "mutable": "null",
+                        "readable": true,
+                        "type": "guint",
+                        "writable": true
+                    },
                     "use-pipeline-clock": {
                         "blurb": "Use the pipeline running-time to set the NTP time in the RTCP SR messages (DEPRECATED: Use ntp-time-source property)",
                         "conditionally-available": false,
index 6708fd2..17362ef 100644 (file)
@@ -354,6 +354,7 @@ enum
 #define DEFAULT_MAX_TS_OFFSET_ADJUSTMENT G_GUINT64_CONSTANT(0)
 #define DEFAULT_MAX_TS_OFFSET        G_GINT64_CONSTANT(3000000000)
 #define DEFAULT_MIN_TS_OFFSET        MIN_TS_OFFSET_ROUND_OFF_COMP
+#define DEFAULT_TS_OFFSET_SMOOTHING_FACTOR  0
 
 enum
 {
@@ -382,6 +383,7 @@ enum
   PROP_MAX_TS_OFFSET_ADJUSTMENT,
   PROP_MAX_TS_OFFSET,
   PROP_MIN_TS_OFFSET,
+  PROP_TS_OFFSET_SMOOTHING_FACTOR,
   PROP_FEC_DECODERS,
   PROP_FEC_ENCODERS,
 };
@@ -1347,11 +1349,17 @@ stream_set_ts_offset (GstRtpBin * bin, GstRtpBinStream * stream,
     return;
   }
 
-  if (!stream->is_initialized) {
-    stream->avg_ts_offset = ts_offset;
-    stream->is_initialized = TRUE;
+  if (bin->ts_offset_smoothing_factor > 0) {
+    if (!stream->is_initialized) {
+      stream->avg_ts_offset = ts_offset;
+      stream->is_initialized = TRUE;
+    } else {
+      stream->avg_ts_offset =
+          ((bin->ts_offset_smoothing_factor - 1) * stream->avg_ts_offset +
+          ts_offset) / bin->ts_offset_smoothing_factor;
+    }
   } else {
-    stream->avg_ts_offset = (9 * stream->avg_ts_offset + ts_offset) / 10;
+    stream->avg_ts_offset = ts_offset;
   }
 
   g_object_get (stream->buffer, "ts-offset", &prev_ts_offset, NULL);
@@ -2800,6 +2808,30 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass)
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   /**
+   * GstRtpBin:ts-offset-smoothing-factor:
+   *
+   * Controls the weighting between previous and current timestamp offsets in
+   * a running moving average (RMA):
+   * ts_offset_average(n) =
+   *   ((ts-offset-smoothing-factor - 1) * ts_offset_average(n - 1) + ts_offset(n)) /
+   *   ts-offset-smoothing-factor
+   *
+   * This can stabilize the timestamp offset and prevent unnecessary skew
+   * corrections due to jitter introduced by network or system load.
+   *
+   * Since: 1.22
+   */
+  g_object_class_install_property (gobject_class,
+      PROP_TS_OFFSET_SMOOTHING_FACTOR,
+      g_param_spec_uint ("ts-offset-smoothing-factor",
+          "Timestamp Offset Smoothing Factor",
+          "Sets a smoothing factor for the timestamp offset in number of "
+          "values for a calculated running moving average. "
+          "(0 = no smoothing factor)", 0, G_MAXUINT,
+          DEFAULT_TS_OFFSET_SMOOTHING_FACTOR,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
    * GstRtpBin:fec-decoders:
    *
    * Used to provide a factory used to build the FEC decoder for a
@@ -2923,6 +2955,7 @@ gst_rtp_bin_init (GstRtpBin * rtpbin)
   rtpbin->max_ts_offset_is_set = FALSE;
   rtpbin->min_ts_offset = DEFAULT_MIN_TS_OFFSET;
   rtpbin->min_ts_offset_is_set = FALSE;
+  rtpbin->ts_offset_smoothing_factor = DEFAULT_TS_OFFSET_SMOOTHING_FACTOR;
 
   /* some default SDES entries */
   cname = g_strdup_printf ("user%u@host-%x", g_random_int (), g_random_int ());
@@ -3248,6 +3281,9 @@ gst_rtp_bin_set_property (GObject * object, guint prop_id,
       rtpbin->min_ts_offset = g_value_get_uint64 (value);
       rtpbin->min_ts_offset_is_set = TRUE;
       break;
+    case PROP_TS_OFFSET_SMOOTHING_FACTOR:
+      rtpbin->ts_offset_smoothing_factor = g_value_get_uint (value);
+      break;
     case PROP_FEC_DECODERS:
       gst_rtp_bin_set_fec_decoders_struct (rtpbin, g_value_get_boxed (value));
       break;
@@ -3351,6 +3387,9 @@ gst_rtp_bin_get_property (GObject * object, guint prop_id,
     case PROP_MIN_TS_OFFSET:
       g_value_set_uint64 (value, rtpbin->min_ts_offset);
       break;
+    case PROP_TS_OFFSET_SMOOTHING_FACTOR:
+      g_value_set_uint (value, rtpbin->ts_offset_smoothing_factor);
+      break;
     case PROP_FEC_DECODERS:
       g_value_take_boxed (value, gst_rtp_bin_get_fec_decoders_struct (rtpbin));
       break;
index a53dede..4e2e467 100644 (file)
@@ -80,6 +80,7 @@ struct _GstRtpBin {
   gboolean        max_ts_offset_is_set;
   guint64         min_ts_offset;
   gboolean        min_ts_offset_is_set;
+  guint           ts_offset_smoothing_factor;
 
   /* a list of session */
   GSList         *sessions;