From 01c0f8723f9891da75357212293ccd0839d41523 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 21 Sep 2015 13:47:21 +0200 Subject: [PATCH] rtpbin/rtpjitterbuffer/rtspsrc: Add property to set maximum ms between RTCP SR RTP time and last observed RTP time https://bugzilla.gnome.org/show_bug.cgi?id=755125 --- gst/rtpmanager/gstrtpbin.c | 26 +++++++++++++++++++++++++- gst/rtpmanager/gstrtpbin.h | 1 + gst/rtpmanager/gstrtpjitterbuffer.c | 37 +++++++++++++++++++++++++++++++++++-- gst/rtsp/gstrtspsrc.c | 23 ++++++++++++++++++++++- gst/rtsp/gstrtspsrc.h | 1 + 5 files changed, 84 insertions(+), 4 deletions(-) diff --git a/gst/rtpmanager/gstrtpbin.c b/gst/rtpmanager/gstrtpbin.c index a65fc7c..0b81ba5 100644 --- a/gst/rtpmanager/gstrtpbin.c +++ b/gst/rtpmanager/gstrtpbin.c @@ -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; diff --git a/gst/rtpmanager/gstrtpbin.h b/gst/rtpmanager/gstrtpbin.h index 41ab38c..b8cfee2 100644 --- a/gst/rtpmanager/gstrtpbin.h +++ b/gst/rtpmanager/gstrtpbin.h @@ -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; diff --git a/gst/rtpmanager/gstrtpjitterbuffer.c b/gst/rtpmanager/gstrtpjitterbuffer.c index 433e61d..1014f58 100644 --- a/gst/rtpmanager/gstrtpjitterbuffer.c +++ b/gst/rtpmanager/gstrtpjitterbuffer.c @@ -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; diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c index 1f22e98..88464e9 100644 --- a/gst/rtsp/gstrtspsrc.c +++ b/gst/rtsp/gstrtspsrc.c @@ -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 */ diff --git a/gst/rtsp/gstrtspsrc.h b/gst/rtsp/gstrtspsrc.h index a3d0a9a..dc218dc 100644 --- a/gst/rtsp/gstrtspsrc.h +++ b/gst/rtsp/gstrtspsrc.h @@ -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; -- 2.7.4