diff --git a/subprojects/gst-plugins-good/docs/gst_plugins_cache.json b/subprojects/gst-plugins-good/docs/gst_plugins_cache.json index 0b03c5bd5d..86e530d79c 100644 --- a/subprojects/gst-plugins-good/docs/gst_plugins_cache.json +++ b/subprojects/gst-plugins-good/docs/gst_plugins_cache.json @@ -17401,6 +17401,18 @@ "type": "guint", "writable": true }, + "update-ntp64-header-ext": { + "blurb": "Whether RTP NTP header extension should be updated with actual NTP time", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "true", + "mutable": "null", + "readable": true, + "type": "gboolean", + "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, @@ -19318,6 +19330,18 @@ "type": "GstStructure", "writable": false }, + "update-ntp64-header-ext": { + "blurb": "Whether RTP NTP header extension should be updated with actual NTP time", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "true", + "mutable": "null", + "readable": true, + "type": "gboolean", + "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, @@ -20083,6 +20107,18 @@ "readable": true, "type": "guint64", "writable": true + }, + "update-ntp64-header-ext": { + "blurb": "Whether RTP NTP header extension should be updated with actual NTP time", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "true", + "mutable": "null", + "readable": true, + "type": "gboolean", + "writable": true } }, "signals": { diff --git a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.c b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.c index bee500eeef..0fbf0820c1 100644 --- a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.c +++ b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.c @@ -357,6 +357,7 @@ enum #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 +#define DEFAULT_UPDATE_NTP64_HEADER_EXT TRUE enum { @@ -389,6 +390,7 @@ enum PROP_TS_OFFSET_SMOOTHING_FACTOR, PROP_FEC_DECODERS, PROP_FEC_ENCODERS, + PROP_UPDATE_NTP64_HEADER_EXT, }; #define GST_RTP_BIN_RTCP_SYNC_TYPE (gst_rtp_bin_rtcp_sync_get_type()) @@ -777,6 +779,10 @@ create_session (GstRtpBin * rtpbin, gint id) g_object_set (session, "max-dropout-time", rtpbin->max_dropout_time, "max-misorder-time", rtpbin->max_misorder_time, NULL); + + g_object_set (session, "update-ntp64-header-ext", + rtpbin->update_ntp64_header_ext, NULL); + GST_OBJECT_UNLOCK (rtpbin); /* provide clock_rate to the session manager when needed */ @@ -2980,6 +2986,22 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass) "fec-encoders='fec,0=\"rtpst2022-1-fecenc\\ rows\\=5\\ columns\\=5\";'", GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstRtpBin:update-ntp64-header-ext: + * + * Whether RTP NTP header extension should be updated with actual + * NTP time. If not, use the NTP time from buffer timestamp metadata + * + * Since: 1.22 + */ + g_object_class_install_property (gobject_class, + PROP_UPDATE_NTP64_HEADER_EXT, + g_param_spec_boolean ("update-ntp64-header-ext", + "Update NTP-64 RTP Header Extension", + "Whether RTP NTP header extension should be updated with actual NTP time", + DEFAULT_UPDATE_NTP64_HEADER_EXT, + 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); @@ -3070,6 +3092,7 @@ gst_rtp_bin_init (GstRtpBin * rtpbin) 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; + rtpbin->update_ntp64_header_ext = DEFAULT_UPDATE_NTP64_HEADER_EXT; /* some default SDES entries */ cname = g_strdup_printf ("user%u@host-%x", g_random_int (), g_random_int ()); @@ -3409,6 +3432,13 @@ gst_rtp_bin_set_property (GObject * object, guint prop_id, case PROP_FEC_ENCODERS: gst_rtp_bin_set_fec_encoders_struct (rtpbin, g_value_get_boxed (value)); break; + case PROP_UPDATE_NTP64_HEADER_EXT: + GST_RTP_BIN_LOCK (rtpbin); + rtpbin->update_ntp64_header_ext = g_value_get_boolean (value); + GST_RTP_BIN_UNLOCK (rtpbin); + gst_rtp_bin_propagate_property_to_session (rtpbin, + "update-ntp64-header-ext", value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -3518,6 +3548,9 @@ gst_rtp_bin_get_property (GObject * object, guint prop_id, case PROP_FEC_ENCODERS: g_value_take_boxed (value, gst_rtp_bin_get_fec_encoders_struct (rtpbin)); break; + case PROP_UPDATE_NTP64_HEADER_EXT: + g_value_set_boolean (value, rtpbin->update_ntp64_header_ext); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.h b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.h index afb322ac2e..eb98eb28e8 100644 --- a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.h +++ b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.h @@ -98,6 +98,8 @@ struct _GstRtpBin { /* the default FEC encoder factories for sessions */ GstStructure *fec_encoders; + gboolean update_ntp64_header_ext; + /*< private >*/ GstRtpBinPrivate *priv; }; diff --git a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpsession.c b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpsession.c index 3d38e14736..b131e77611 100644 --- a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpsession.c +++ b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpsession.c @@ -223,6 +223,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_UPDATE_NTP64_HEADER_EXT TRUE enum { @@ -244,7 +245,8 @@ enum PROP_TWCC_STATS, PROP_RTP_PROFILE, PROP_NTP_TIME_SOURCE, - PROP_RTCP_SYNC_SEND_TIME + PROP_RTCP_SYNC_SEND_TIME, + PROP_UPDATE_NTP64_HEADER_EXT }; #define GST_RTP_SESSION_LOCK(sess) g_mutex_lock (&(sess)->priv->lock) @@ -810,6 +812,22 @@ gst_rtp_session_class_init (GstRtpSessionClass * klass) DEFAULT_RTCP_SYNC_SEND_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstRtpSession:update-ntp64-header-ext: + * + * Whether RTP NTP header extension should be updated with actual + * NTP time. If not, use the NTP time from buffer timestamp metadata + * + * Since: 1.22 + */ + g_object_class_install_property (gobject_class, + PROP_UPDATE_NTP64_HEADER_EXT, + g_param_spec_boolean ("update-ntp64-header-ext", + "Update NTP-64 RTP Header Extension", + "Whether RTP NTP header extension should be updated with actual NTP time", + DEFAULT_UPDATE_NTP64_HEADER_EXT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_session_change_state); gstelement_class->request_new_pad = @@ -982,6 +1000,10 @@ gst_rtp_session_set_property (GObject * object, guint prop_id, case PROP_RTCP_SYNC_SEND_TIME: priv->rtcp_sync_send_time = g_value_get_boolean (value); break; + case PROP_UPDATE_NTP64_HEADER_EXT: + g_object_set_property (G_OBJECT (priv->session), + "update-ntp64-header-ext", value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1061,6 +1083,10 @@ gst_rtp_session_get_property (GObject * object, guint prop_id, case PROP_RTCP_SYNC_SEND_TIME: g_value_set_boolean (value, priv->rtcp_sync_send_time); break; + case PROP_UPDATE_NTP64_HEADER_EXT: + g_object_get_property (G_OBJECT (priv->session), + "update-ntp64-header-ext", value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/subprojects/gst-plugins-good/gst/rtpmanager/rtpsession.c b/subprojects/gst-plugins-good/gst/rtpmanager/rtpsession.c index 838c24c4bf..294bcf0c17 100644 --- a/subprojects/gst-plugins-good/gst/rtpmanager/rtpsession.c +++ b/subprojects/gst-plugins-good/gst/rtpmanager/rtpsession.c @@ -81,6 +81,7 @@ enum #define DEFAULT_RTCP_DISABLE_SR_TIMESTAMP FALSE #define DEFAULT_FAVOR_NEW FALSE #define DEFAULT_TWCC_FEEDBACK_INTERVAL GST_CLOCK_TIME_NONE +#define DEFAULT_UPDATE_NTP64_HEADER_EXT TRUE enum { @@ -108,6 +109,7 @@ enum PROP_RTCP_REDUCED_SIZE, PROP_RTCP_DISABLE_SR_TIMESTAMP, PROP_TWCC_FEEDBACK_INTERVAL, + PROP_UPDATE_NTP64_HEADER_EXT, PROP_LAST, }; @@ -643,6 +645,21 @@ rtp_session_class_init (RTPSessionClass * klass) 0, G_MAXUINT64, DEFAULT_TWCC_FEEDBACK_INTERVAL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * RTPSession:update-ntp64-header-ext: + * + * Whether RTP NTP header extension should be updated with actual + * NTP time. If not, use the NTP time from buffer timestamp metadata + * + * Since: 1.22 + */ + properties[PROP_UPDATE_NTP64_HEADER_EXT] = + g_param_spec_boolean ("update-ntp64-header-ext", + "Update NTP-64 RTP Header Extension", + "Whether RTP NTP header extension should be updated with actual NTP time", + DEFAULT_UPDATE_NTP64_HEADER_EXT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (gobject_class, PROP_LAST, properties); klass->get_source_by_ssrc = @@ -688,6 +705,8 @@ rtp_session_init (RTPSession * sess) sess->header_len = UDP_IP_HEADER_OVERHEAD; sess->mtu = DEFAULT_RTCP_MTU; + sess->update_ntp64_header_ext = DEFAULT_UPDATE_NTP64_HEADER_EXT; + sess->probation = DEFAULT_PROBATION; sess->max_dropout_time = DEFAULT_MAX_DROPOUT_TIME; sess->max_misorder_time = DEFAULT_MAX_MISORDER_TIME; @@ -928,6 +947,9 @@ rtp_session_set_property (GObject * object, guint prop_id, rtp_twcc_manager_set_feedback_interval (sess->twcc, g_value_get_uint64 (value)); break; + case PROP_UPDATE_NTP64_HEADER_EXT: + sess->update_ntp64_header_ext = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1014,6 +1036,9 @@ rtp_session_get_property (GObject * object, guint prop_id, g_value_set_uint64 (value, rtp_twcc_manager_get_feedback_interval (sess->twcc)); break; + case PROP_UPDATE_NTP64_HEADER_EXT: + g_value_set_boolean (value, sess->update_ntp64_header_ext); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -3422,7 +3447,9 @@ rtp_session_send_rtp (RTPSession * sess, gpointer data, gboolean is_list, goto invalid_packet; /* Update any 64-bit NTP header extensions with the actual NTP time here */ - update_ntp64_header_ext (&pinfo); + if (sess->update_ntp64_header_ext) + update_ntp64_header_ext (&pinfo); + rtp_twcc_manager_send_packet (sess->twcc, &pinfo); source = obtain_internal_source (sess, pinfo.ssrc, &created, current_time); diff --git a/subprojects/gst-plugins-good/gst/rtpmanager/rtpsession.h b/subprojects/gst-plugins-good/gst/rtpmanager/rtpsession.h index eb512c78f3..84b2948dc4 100644 --- a/subprojects/gst-plugins-good/gst/rtpmanager/rtpsession.h +++ b/subprojects/gst-plugins-good/gst/rtpmanager/rtpsession.h @@ -313,6 +313,8 @@ struct _RTPSession { /* RFC6051 64-bit NTP header extension */ guint8 send_ntp64_ext_id; + gboolean update_ntp64_header_ext; + /* Transport-wide cc-extension */ RTPTWCCManager *twcc; RTPTWCCStats *twcc_stats;