From 8bfba72ea496dd139b0d0879157d123526899695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 17 Apr 2024 17:17:16 +0300 Subject: [PATCH] rtpbin: Add new never/ntp RTCP sync modes Never is useful for some RTSP servers that report plain garbage both via RTCP SR and RTP-Info, for example. NTP is useful if synchronization should only ever happen based on RTCP SR or NTP-64 RTP header extension. Also slightly change the behaviour of always/initial to take RTP-Info based synchronization into account too. It's supposed to give the same values as the RTCP SR and is available earlier, so will generally cause fewer synchronization glitches if it's made use of. Part-of: --- .../docs/gst_plugins_cache.json | 10 ++++++ .../gst/rtpmanager/gstrtpbin.c | 35 +++++++++++++++---- .../gst/rtpmanager/gstrtpbin.h | 34 +++++++++++++++++- 3 files changed, 71 insertions(+), 8 deletions(-) diff --git a/subprojects/gst-plugins-good/docs/gst_plugins_cache.json b/subprojects/gst-plugins-good/docs/gst_plugins_cache.json index bcf6bac254..e8bc8ca3c4 100644 --- a/subprojects/gst-plugins-good/docs/gst_plugins_cache.json +++ b/subprojects/gst-plugins-good/docs/gst_plugins_cache.json @@ -20544,6 +20544,16 @@ "desc": "rtp-info", "name": "rtp-info", "value": "2" + }, + { + "desc": "ntp", + "name": "ntp", + "value": "3" + }, + { + "desc": "never", + "name": "never", + "value": "4" } ] }, diff --git a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.c b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.c index a448d93cc1..1244e862f6 100644 --- a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.c +++ b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.c @@ -404,6 +404,8 @@ gst_rtp_bin_rtcp_sync_get_type (void) {GST_RTP_BIN_RTCP_SYNC_ALWAYS, "always", "always"}, {GST_RTP_BIN_RTCP_SYNC_INITIAL, "initial", "initial"}, {GST_RTP_BIN_RTCP_SYNC_RTP_INFO, "rtp-info", "rtp-info"}, + {GST_RTP_BIN_RTCP_SYNC_NTP, "ntp", "ntp"}, + {GST_RTP_BIN_RTCP_SYNC_NEVER, "never", "never"}, {0, NULL, NULL}, }; @@ -446,7 +448,7 @@ static GstElement *session_request_element (GstRtpBinSession * session, typedef enum { GST_RTP_BIN_STREAM_SYNCED_NONE, - GST_RTP_BIN_STREAM_SYNCED_RTCP, + GST_RTP_BIN_STREAM_SYNCED_NTP, GST_RTP_BIN_STREAM_SYNCED_RTP_INFO } GstRtpBinStreamSynced; @@ -1643,11 +1645,16 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, if (!GST_CLOCK_TIME_IS_VALID (extrtptime) || !GST_CLOCK_TIME_IS_VALID (ntpnstime) || extrtptime < base_rtptime) { - GST_DEBUG_OBJECT (bin, "invalidated sync data, bailing out"); - return; - } + if (!GST_CLOCK_TIME_IS_VALID (npt_start)) { + GST_DEBUG_OBJECT (bin, "invalidated sync data, bailing out"); + return; + } - GST_DEBUG_OBJECT (bin, "Doing RTCP sync"); + rtp_info_sync = TRUE; + GST_DEBUG_OBJECT (bin, "Doing RTP-Info sync"); + } else { + GST_DEBUG_OBJECT (bin, "Doing RTCP sync"); + } break; } case GST_RTP_BIN_RTCP_SYNC_RTP_INFO:{ @@ -1661,6 +1668,20 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, break; } + case GST_RTP_BIN_RTCP_SYNC_NTP:{ + if (!GST_CLOCK_TIME_IS_VALID (extrtptime) + || !GST_CLOCK_TIME_IS_VALID (ntpnstime) + || extrtptime < base_rtptime) { + GST_DEBUG_OBJECT (bin, "invalidated sync data, bailing out"); + return; + } + GST_DEBUG_OBJECT (bin, "Doing RTCP sync"); + break; + } + case GST_RTP_BIN_RTCP_SYNC_NEVER:{ + GST_DEBUG_OBJECT (bin, "Not doing any sync"); + return; + } } gboolean all_sync = TRUE; @@ -1817,7 +1838,7 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, for (walk = client->streams; walk; walk = g_slist_next (walk)) { GstRtpBinStream *ostream = (GstRtpBinStream *) walk->data; - if (rtp_info_sync && ostream->have_sync == GST_RTP_BIN_STREAM_SYNCED_RTCP) { + if (rtp_info_sync && ostream->have_sync == GST_RTP_BIN_STREAM_SYNCED_NTP) { if (ostream->rtp_delta == G_MININT64) { GST_DEBUG_OBJECT (bin, "Switching sync mode, waiting for all streams to be ready"); @@ -1888,7 +1909,7 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, if (rtp_info_sync) ostream->have_sync = GST_RTP_BIN_STREAM_SYNCED_RTP_INFO; else - ostream->have_sync = GST_RTP_BIN_STREAM_SYNCED_RTCP;; + ostream->have_sync = GST_RTP_BIN_STREAM_SYNCED_NTP; } gst_rtp_bin_send_sync_event (stream); diff --git a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.h b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.h index 9f8abc1425..9f7949b52e 100644 --- a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.h +++ b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.h @@ -37,11 +37,43 @@ #define GST_IS_RTP_BIN_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_BIN)) +/** + * GstRTCPSync: + * @GST_RTP_BIN_RTCP_SYNC_ALWAYS: Always do inter-stream synchronization based + * on RTP-Info or RTCP SR or inband NTP-64 header extension. + * @GST_RTP_BIN_RTCP_SYNC_INITIAL: Only do inter-stream synchronization once based + * on RTP-Info or RTCP SR or inband NTP-64 header extension. + * @GST_RTP_BIN_RTCP_SYNC_RTP_INFO: Only do inter-stream synchronization based + * on RTP-Info. + * @GST_RTP_BIN_RTCP_SYNC_NTP: Only do inter-stream synchronization based on + * RTCP SR or inband NTP-64 header extension. (Since 1.26) + * @GST_RTP_BIN_RTCP_SYNC_NEVER: Never do inter-stream synchronization. (Since 1.26) + */ typedef enum { GST_RTP_BIN_RTCP_SYNC_ALWAYS, GST_RTP_BIN_RTCP_SYNC_INITIAL, - GST_RTP_BIN_RTCP_SYNC_RTP_INFO + GST_RTP_BIN_RTCP_SYNC_RTP_INFO, + + /** + * GstRTCPSync::ntp: + * + * Only do inter-stream synchronization based on RTCP SR or inband NTP-64 + * header extension. + * + * Since: 1.26 + */ + GST_RTP_BIN_RTCP_SYNC_NTP, + + /** + * GstRTCPSync::never: + * + * Never do inter-stream synchronization. + * + * Since: 1.26 + */ + + GST_RTP_BIN_RTCP_SYNC_NEVER } GstRTCPSync; typedef struct _GstRtpBin GstRtpBin;