rtpbin/rtpjitterbuffer/rtspsrc: Add property to set maximum ms between RTCP SR RTP...
authorSebastian Dröge <sebastian@centricular.com>
Mon, 21 Sep 2015 11:47:21 +0000 (13:47 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Fri, 25 Sep 2015 21:55:05 +0000 (23:55 +0200)
https://bugzilla.gnome.org/show_bug.cgi?id=755125

gst/rtpmanager/gstrtpbin.c
gst/rtpmanager/gstrtpbin.h
gst/rtpmanager/gstrtpjitterbuffer.c
gst/rtsp/gstrtspsrc.c
gst/rtsp/gstrtspsrc.h

index a65fc7c..0b81ba5 100644 (file)
@@ -291,6 +291,7 @@ enum
 #define DEFAULT_RTP_PROFILE          GST_RTP_PROFILE_AVP
 #define DEFAULT_NTP_TIME_SOURCE      GST_RTP_NTP_TIME_SOURCE_NTP
 #define DEFAULT_RTCP_SYNC_SEND_TIME  TRUE
+#define DEFAULT_MAX_RTCP_RTP_TIME_DIFF 1000
 
 enum
 {
@@ -310,7 +311,8 @@ enum
   PROP_DO_RETRANSMISSION,
   PROP_RTP_PROFILE,
   PROP_NTP_TIME_SOURCE,
-  PROP_RTCP_SYNC_SEND_TIME
+  PROP_RTCP_SYNC_SEND_TIME,
+  PROP_MAX_RTCP_RTP_TIME_DIFF
 };
 
 #define GST_RTP_BIN_RTCP_SYNC_TYPE (gst_rtp_bin_rtcp_sync_get_type())
@@ -1552,6 +1554,8 @@ create_stream (GstRtpBinSession * session, guint32 ssrc)
   g_object_set (buffer, "do-lost", rtpbin->do_lost, NULL);
   g_object_set (buffer, "mode", rtpbin->buffer_mode, NULL);
   g_object_set (buffer, "do-retransmission", rtpbin->do_retransmission, NULL);
+  g_object_set (buffer, "max-rtcp-rtp-time-diff",
+      rtpbin->max_rtcp_rtp_time_diff, NULL);
 
   g_signal_emit (rtpbin, gst_rtp_bin_signals[SIGNAL_NEW_JITTERBUFFER], 0,
       buffer, session->id, ssrc);
@@ -2181,6 +2185,13 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass)
           DEFAULT_RTCP_SYNC_SEND_TIME,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_MAX_RTCP_RTP_TIME_DIFF,
+      g_param_spec_int ("max-rtcp-rtp-time-diff", "Max RTCP RTP Time Diff",
+          "Maximum amount of time in ms that the RTP time in RTCP SRs "
+          "is allowed to be ahead (-1 disabled)", -1, G_MAXINT,
+          DEFAULT_MAX_RTCP_RTP_TIME_DIFF,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_bin_change_state);
   gstelement_class->request_new_pad =
       GST_DEBUG_FUNCPTR (gst_rtp_bin_request_new_pad);
@@ -2246,6 +2257,7 @@ gst_rtp_bin_init (GstRtpBin * rtpbin)
   rtpbin->rtp_profile = DEFAULT_RTP_PROFILE;
   rtpbin->ntp_time_source = DEFAULT_NTP_TIME_SOURCE;
   rtpbin->rtcp_sync_send_time = DEFAULT_RTCP_SYNC_SEND_TIME;
+  rtpbin->max_rtcp_rtp_time_diff = DEFAULT_MAX_RTCP_RTP_TIME_DIFF;
 
   /* some default SDES entries */
   cname = g_strdup_printf ("user%u@host-%x", g_random_int (), g_random_int ());
@@ -2437,6 +2449,13 @@ gst_rtp_bin_set_property (GObject * object, guint prop_id,
       GST_RTP_BIN_UNLOCK (rtpbin);
       break;
     }
+    case PROP_MAX_RTCP_RTP_TIME_DIFF:
+      GST_RTP_BIN_LOCK (rtpbin);
+      rtpbin->max_rtcp_rtp_time_diff = g_value_get_int (value);
+      GST_RTP_BIN_UNLOCK (rtpbin);
+      gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
+          "max-rtcp-rtp-time-diff", value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -2508,6 +2527,11 @@ gst_rtp_bin_get_property (GObject * object, guint prop_id,
     case PROP_RTCP_SYNC_SEND_TIME:
       g_value_set_boolean (value, rtpbin->rtcp_sync_send_time);
       break;
+    case PROP_MAX_RTCP_RTP_TIME_DIFF:
+      GST_RTP_BIN_LOCK (rtpbin);
+      g_value_set_int (value, rtpbin->max_rtcp_rtp_time_diff);
+      GST_RTP_BIN_UNLOCK (rtpbin);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
index 41ab38c..b8cfee2 100644 (file)
@@ -70,6 +70,7 @@ struct _GstRtpBin {
   gboolean        do_retransmission;
   GstRTPProfile   rtp_profile;
   gboolean        rtcp_sync_send_time;
+  gint            max_rtcp_rtp_time_diff;
 
   /* a list of session */
   GSList         *sessions;
index 433e61d..1014f58 100644 (file)
@@ -136,6 +136,7 @@ enum
 #define DEFAULT_RTX_MIN_RETRY_TIMEOUT   -1
 #define DEFAULT_RTX_RETRY_PERIOD    -1
 #define DEFAULT_RTX_MAX_RETRIES    -1
+#define DEFAULT_MAX_RTCP_RTP_TIME_DIFF 1000
 
 #define DEFAULT_AUTO_RTX_DELAY (20 * GST_MSECOND)
 #define DEFAULT_AUTO_RTX_TIMEOUT (40 * GST_MSECOND)
@@ -158,7 +159,8 @@ enum
   PROP_RTX_MIN_RETRY_TIMEOUT,
   PROP_RTX_RETRY_PERIOD,
   PROP_RTX_MAX_RETRIES,
-  PROP_STATS
+  PROP_STATS,
+  PROP_MAX_RTCP_RTP_TIME_DIFF
 };
 
 #define JBUF_LOCK(priv)   (g_mutex_lock (&(priv)->jbuf_lock))
@@ -255,6 +257,7 @@ struct _GstRtpJitterBufferPrivate
   gint rtx_min_retry_timeout;
   gint rtx_retry_period;
   gint rtx_max_retries;
+  gint max_rtcp_rtp_time_diff;
 
   /* the last seqnum we pushed out */
   guint32 last_popped_seqnum;
@@ -706,6 +709,22 @@ gst_rtp_jitter_buffer_class_init (GstRtpJitterBufferClass * klass)
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 
   /**
+   * GstRtpJitterBuffer:max-rtcp-rtp-time-diff
+   *
+   * The maximum amount of time in ms that the RTP time in the RTCP SRs
+   * is allowed to be ahead of the last RTP packet we received. Use
+   * -1 to disable ignoring of RTCP packets.
+   *
+   * Since: 1.8
+   */
+  g_object_class_install_property (gobject_class, PROP_MAX_RTCP_RTP_TIME_DIFF,
+      g_param_spec_int ("max-rtcp-rtp-time-diff", "Max RTCP RTP Time Diff",
+          "Maximum amount of time in ms that the RTP time in RTCP SRs "
+          "is allowed to be ahead (-1 disabled)", -1, G_MAXINT,
+          DEFAULT_MAX_RTCP_RTP_TIME_DIFF,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
    * GstRtpJitterBuffer::request-pt-map:
    * @buffer: the object which received the signal
    * @pt: the pt
@@ -822,6 +841,7 @@ gst_rtp_jitter_buffer_init (GstRtpJitterBuffer * jitterbuffer)
   priv->rtx_min_retry_timeout = DEFAULT_RTX_MIN_RETRY_TIMEOUT;
   priv->rtx_retry_period = DEFAULT_RTX_RETRY_PERIOD;
   priv->rtx_max_retries = DEFAULT_RTX_MAX_RETRIES;
+  priv->max_rtcp_rtp_time_diff = DEFAULT_MAX_RTCP_RTP_TIME_DIFF;
 
   priv->last_dts = -1;
   priv->last_rtptime = -1;
@@ -3552,7 +3572,10 @@ do_handle_sync (GstRtpJitterBuffer * jitterbuffer)
         /* check how far ahead it is to our RTP timestamps */
         diff = ext_rtptime - last_rtptime;
         /* if bigger than 1 second, we drop it */
-        if (diff > clock_rate) {
+        if (jitterbuffer->priv->max_rtcp_rtp_time_diff != -1 &&
+            diff >
+            gst_util_uint64_scale (jitterbuffer->priv->max_rtcp_rtp_time_diff,
+                clock_rate, 1000)) {
           GST_DEBUG_OBJECT (jitterbuffer, "too far ahead");
           /* should drop this, but some RTSP servers end up with bogus
            * way too ahead RTCP packet when repeated PAUSE/PLAY,
@@ -3929,6 +3952,11 @@ gst_rtp_jitter_buffer_set_property (GObject * object,
       priv->rtx_max_retries = g_value_get_int (value);
       JBUF_UNLOCK (priv);
       break;
+    case PROP_MAX_RTCP_RTP_TIME_DIFF:
+      JBUF_LOCK (priv);
+      priv->max_rtcp_rtp_time_diff = g_value_get_int (value);
+      JBUF_UNLOCK (priv);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -4034,6 +4062,11 @@ gst_rtp_jitter_buffer_get_property (GObject * object,
       g_value_take_boxed (value,
           gst_rtp_jitter_buffer_create_stats (jitterbuffer));
       break;
+    case PROP_MAX_RTCP_RTP_TIME_DIFF:
+      JBUF_LOCK (priv);
+      g_value_set_int (value, priv->max_rtcp_rtp_time_diff);
+      JBUF_UNLOCK (priv);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
index 1f22e98..88464e9 100644 (file)
@@ -232,6 +232,7 @@ gst_rtsp_src_ntp_time_source_get_type (void)
 #define DEFAULT_DO_RETRANSMISSION        TRUE
 #define DEFAULT_NTP_TIME_SOURCE  NTP_TIME_SOURCE_NTP
 #define DEFAULT_USER_AGENT       "GStreamer/" PACKAGE_VERSION
+#define DEFAULT_MAX_RTCP_RTP_TIME_DIFF 1000
 
 enum
 {
@@ -269,7 +270,8 @@ enum
   PROP_TLS_INTERACTION,
   PROP_DO_RETRANSMISSION,
   PROP_NTP_TIME_SOURCE,
-  PROP_USER_AGENT
+  PROP_USER_AGENT,
+  PROP_MAX_RTCP_RTP_TIME_DIFF
 };
 
 #define GST_TYPE_RTSP_NAT_METHOD (gst_rtsp_nat_method_get_type())
@@ -732,6 +734,13 @@ gst_rtspsrc_class_init (GstRTSPSrcClass * klass)
           "The User-Agent string to send to the server",
           DEFAULT_USER_AGENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_MAX_RTCP_RTP_TIME_DIFF,
+      g_param_spec_int ("max-rtcp-rtp-time-diff", "Max RTCP RTP Time Diff",
+          "Maximum amount of time in ms that the RTP time in RTCP SRs "
+          "is allowed to be ahead (-1 disabled)", -1, G_MAXINT,
+          DEFAULT_MAX_RTCP_RTP_TIME_DIFF,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   /**
    * GstRTSPSrc::handle-request:
    * @rtspsrc: a #GstRTSPSrc
@@ -879,6 +888,7 @@ gst_rtspsrc_init (GstRTSPSrc * src)
   src->do_retransmission = DEFAULT_DO_RETRANSMISSION;
   src->ntp_time_source = DEFAULT_NTP_TIME_SOURCE;
   src->user_agent = g_strdup (DEFAULT_USER_AGENT);
+  src->max_rtcp_rtp_time_diff = DEFAULT_MAX_RTCP_RTP_TIME_DIFF;
 
   /* get a list of all extensions */
   src->extensions = gst_rtsp_ext_list_get ();
@@ -1161,6 +1171,9 @@ gst_rtspsrc_set_property (GObject * object, guint prop_id, const GValue * value,
       g_free (rtspsrc->user_agent);
       rtspsrc->user_agent = g_value_dup_string (value);
       break;
+    case PROP_MAX_RTCP_RTP_TIME_DIFF:
+      rtspsrc->max_rtcp_rtp_time_diff = g_value_get_int (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1304,6 +1317,9 @@ gst_rtspsrc_get_property (GObject * object, guint prop_id, GValue * value,
     case PROP_USER_AGENT:
       g_value_set_string (value, rtspsrc->user_agent);
       break;
+    case PROP_MAX_RTCP_RTP_TIME_DIFF:
+      g_value_set_int (value, rtspsrc->max_rtcp_rtp_time_diff);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -3493,6 +3509,11 @@ gst_rtspsrc_stream_configure_manager (GstRTSPSrc * src, GstRTSPStream * stream,
             NULL);
       }
 
+      if (g_object_class_find_property (klass, "max-rtcp-rtp-time-diff")) {
+        g_object_set (src->manager, "max-rtcp-rtp-time-diff",
+            src->max_rtcp_rtp_time_diff, NULL);
+      }
+
       /* buffer mode pauses are handled by adding offsets to buffer times,
        * but some depayloaders may have a hard time syncing output times
        * with such input times, e.g. container ones, most notably ASF */
index a3d0a9a..dc218dc 100644 (file)
@@ -238,6 +238,7 @@ struct _GstRTSPSrc {
   gboolean          do_retransmission;
   gint              ntp_time_source;
   gchar            *user_agent;
+  GstClockTime      max_rtcp_rtp_time_diff;
 
   /* state */
   GstRTSPState       state;