mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-26 17:18:15 +00:00
rtpbin/session: Add new ntp-time-source property and deprecate use-pipeline-clock property
The new property allows to select the time source that should be used for the NTP time in RTCP packets. By default it will continue to calculate the NTP timestamp (1900 epoch) based on the realtime clock. Alternatively it can use the UNIX timestamp (1970 epoch), the pipeline's running time or the pipeline's clock time. The latter is especially useful for synchronizing multiple receivers if all of them share the same clock. If use-pipeline-clock is set to TRUE, it will override the ntp-time-source setting and continue to use the running time plus 70 years. This is only kept for backwards compatibility.
This commit is contained in:
parent
74dcd85de4
commit
dc513eb949
4 changed files with 142 additions and 26 deletions
|
@ -289,6 +289,7 @@ enum
|
|||
#define DEFAULT_DO_SYNC_EVENT FALSE
|
||||
#define DEFAULT_DO_RETRANSMISSION FALSE
|
||||
#define DEFAULT_RTP_PROFILE GST_RTP_PROFILE_AVPF
|
||||
#define DEFAULT_NTP_TIME_SOURCE GST_RTP_NTP_TIME_SOURCE_NTP
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -306,7 +307,8 @@ enum
|
|||
PROP_USE_PIPELINE_CLOCK,
|
||||
PROP_DO_SYNC_EVENT,
|
||||
PROP_DO_RETRANSMISSION,
|
||||
PROP_RTP_PROFILE
|
||||
PROP_RTP_PROFILE,
|
||||
PROP_NTP_TIME_SOURCE
|
||||
};
|
||||
|
||||
#define GST_RTP_BIN_RTCP_SYNC_TYPE (gst_rtp_bin_rtcp_sync_get_type())
|
||||
|
@ -622,8 +624,13 @@ create_session (GstRtpBin * rtpbin, gint id)
|
|||
|
||||
/* configure SDES items */
|
||||
GST_OBJECT_LOCK (rtpbin);
|
||||
g_object_set (session, "sdes", rtpbin->sdes, "use-pipeline-clock",
|
||||
rtpbin->use_pipeline_clock, "rtp-profile", rtpbin->rtp_profile, NULL);
|
||||
g_object_set (session, "sdes", rtpbin->sdes, "rtp-profile",
|
||||
rtpbin->rtp_profile, NULL);
|
||||
if (rtpbin->use_pipeline_clock)
|
||||
g_object_set (session, "use-pipeline-clock", rtpbin->use_pipeline_clock,
|
||||
NULL);
|
||||
else
|
||||
g_object_set (session, "ntp-time-source", rtpbin->ntp_time_source, NULL);
|
||||
GST_OBJECT_UNLOCK (rtpbin);
|
||||
|
||||
/* provide clock_rate to the session manager when needed */
|
||||
|
@ -1004,24 +1011,41 @@ get_current_times (GstRtpBin * bin, GstClockTime * running_time,
|
|||
gst_object_ref (clock);
|
||||
GST_OBJECT_UNLOCK (bin);
|
||||
|
||||
/* get current clock time and convert to running time */
|
||||
clock_time = gst_clock_get_time (clock);
|
||||
rt = clock_time - base_time;
|
||||
|
||||
if (bin->use_pipeline_clock) {
|
||||
ntpns = clock_time - base_time;
|
||||
ntpns = rt;
|
||||
/* add constant to convert from 1970 based time to 1900 based time */
|
||||
ntpns += (2208988800LL * GST_SECOND);
|
||||
} else {
|
||||
GTimeVal current;
|
||||
switch (bin->ntp_time_source) {
|
||||
case GST_RTP_NTP_TIME_SOURCE_NTP:
|
||||
case GST_RTP_NTP_TIME_SOURCE_UNIX:{
|
||||
GTimeVal current;
|
||||
|
||||
/* get current NTP time */
|
||||
g_get_current_time (¤t);
|
||||
ntpns = GST_TIMEVAL_TO_TIME (current);
|
||||
/* get current NTP time */
|
||||
g_get_current_time (¤t);
|
||||
ntpns = GST_TIMEVAL_TO_TIME (current);
|
||||
|
||||
/* add constant to convert from 1970 based time to 1900 based time */
|
||||
if (bin->ntp_time_source == GST_RTP_NTP_TIME_SOURCE_NTP)
|
||||
ntpns += (2208988800LL * GST_SECOND);
|
||||
break;
|
||||
}
|
||||
case GST_RTP_NTP_TIME_SOURCE_RUNNING_TIME:
|
||||
ntpns = rt;
|
||||
break;
|
||||
case GST_RTP_NTP_TIME_SOURCE_CLOCK_TIME:
|
||||
ntpns = clock_time;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* add constant to convert from 1970 based time to 1900 based time */
|
||||
ntpns += (2208988800LL * GST_SECOND);
|
||||
|
||||
/* get current clock time and convert to running time */
|
||||
rt = clock_time - base_time;
|
||||
|
||||
gst_object_unref (clock);
|
||||
} else {
|
||||
GST_OBJECT_UNLOCK (bin);
|
||||
|
@ -2061,9 +2085,10 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass)
|
|||
|
||||
g_object_class_install_property (gobject_class, PROP_USE_PIPELINE_CLOCK,
|
||||
g_param_spec_boolean ("use-pipeline-clock", "Use pipeline clock",
|
||||
"Use the pipeline running-time to set the NTP time in the RTCP SR messages",
|
||||
"Use the pipeline running-time to set the NTP time in the RTCP SR messages "
|
||||
"(DEPRECATED: Use ntp-source property)",
|
||||
DEFAULT_USE_PIPELINE_CLOCK,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_DEPRECATED));
|
||||
/**
|
||||
* GstRtpBin:buffer-mode:
|
||||
*
|
||||
|
@ -2140,6 +2165,12 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass)
|
|||
GST_TYPE_RTP_PROFILE, DEFAULT_RTP_PROFILE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_NTP_TIME_SOURCE,
|
||||
g_param_spec_enum ("ntp-time-source", "NTP Time Source",
|
||||
"NTP time source for RTCP packets",
|
||||
gst_rtp_ntp_time_source_get_type (), DEFAULT_NTP_TIME_SOURCE,
|
||||
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);
|
||||
|
@ -2203,6 +2234,7 @@ gst_rtp_bin_init (GstRtpBin * rtpbin)
|
|||
rtpbin->send_sync_event = DEFAULT_DO_SYNC_EVENT;
|
||||
rtpbin->do_retransmission = DEFAULT_DO_RETRANSMISSION;
|
||||
rtpbin->rtp_profile = DEFAULT_RTP_PROFILE;
|
||||
rtpbin->ntp_time_source = DEFAULT_NTP_TIME_SOURCE;
|
||||
|
||||
/* some default SDES entries */
|
||||
cname = g_strdup_printf ("user%u@host-%x", g_random_int (), g_random_int ());
|
||||
|
@ -2366,6 +2398,20 @@ gst_rtp_bin_set_property (GObject * object, guint prop_id,
|
|||
case PROP_RTP_PROFILE:
|
||||
rtpbin->rtp_profile = g_value_get_enum (value);
|
||||
break;
|
||||
case PROP_NTP_TIME_SOURCE:{
|
||||
GSList *sessions;
|
||||
GST_RTP_BIN_LOCK (rtpbin);
|
||||
rtpbin->ntp_time_source = g_value_get_enum (value);
|
||||
for (sessions = rtpbin->sessions; sessions;
|
||||
sessions = g_slist_next (sessions)) {
|
||||
GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
|
||||
|
||||
g_object_set (G_OBJECT (session->session),
|
||||
"ntp-time-source", rtpbin->ntp_time_source, NULL);
|
||||
}
|
||||
GST_RTP_BIN_UNLOCK (rtpbin);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -2431,6 +2477,9 @@ gst_rtp_bin_get_property (GObject * object, guint prop_id,
|
|||
case PROP_RTP_PROFILE:
|
||||
g_value_set_enum (value, rtpbin->rtp_profile);
|
||||
break;
|
||||
case PROP_NTP_TIME_SOURCE:
|
||||
g_value_set_enum (value, rtpbin->ntp_time_source);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
#include "rtpsession.h"
|
||||
#include "gstrtpsession.h"
|
||||
#include "rtpjitterbuffer.h"
|
||||
|
||||
#define GST_TYPE_RTP_BIN \
|
||||
|
@ -63,6 +64,7 @@ struct _GstRtpBin {
|
|||
RTPJitterBufferMode buffer_mode;
|
||||
gboolean buffering;
|
||||
gboolean use_pipeline_clock;
|
||||
GstRtpNtpTimeSource ntp_time_source;
|
||||
gboolean send_sync_event;
|
||||
GstClockTime buffer_start;
|
||||
gboolean do_retransmission;
|
||||
|
|
|
@ -122,6 +122,26 @@
|
|||
GST_DEBUG_CATEGORY_STATIC (gst_rtp_session_debug);
|
||||
#define GST_CAT_DEFAULT gst_rtp_session_debug
|
||||
|
||||
GType
|
||||
gst_rtp_ntp_time_source_get_type (void)
|
||||
{
|
||||
static GType type = 0;
|
||||
static const GEnumValue values[] = {
|
||||
{GST_RTP_NTP_TIME_SOURCE_NTP, "NTP time based on realtime clock", "ntp"},
|
||||
{GST_RTP_NTP_TIME_SOURCE_UNIX, "UNIX time based on realtime clock", "unix"},
|
||||
{GST_RTP_NTP_TIME_SOURCE_RUNNING_TIME,
|
||||
"Running time based on pipeline clock",
|
||||
"running-time"},
|
||||
{GST_RTP_NTP_TIME_SOURCE_CLOCK_TIME, "Pipeline clock time", "clock-time"},
|
||||
{0, NULL, NULL},
|
||||
};
|
||||
|
||||
if (!type) {
|
||||
type = g_enum_register_static ("GstRtpNtpTimeSource", values);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/* sink pads */
|
||||
static GstStaticPadTemplate rtpsession_recv_rtp_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("recv_rtp_sink",
|
||||
|
@ -202,6 +222,7 @@ enum
|
|||
#define DEFAULT_RTCP_MIN_INTERVAL (RTP_STATS_MIN_INTERVAL * GST_SECOND)
|
||||
#define DEFAULT_PROBATION RTP_DEFAULT_PROBATION
|
||||
#define DEFAULT_RTP_PROFILE GST_RTP_PROFILE_AVP
|
||||
#define DEFAULT_NTP_TIME_SOURCE GST_RTP_NTP_TIME_SOURCE_NTP
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -218,7 +239,8 @@ enum
|
|||
PROP_RTCP_MIN_INTERVAL,
|
||||
PROP_PROBATION,
|
||||
PROP_STATS,
|
||||
PROP_RTP_PROFILE
|
||||
PROP_RTP_PROFILE,
|
||||
PROP_NTP_TIME_SOURCE
|
||||
};
|
||||
|
||||
#define GST_RTP_SESSION_GET_PRIVATE(obj) \
|
||||
|
@ -251,6 +273,7 @@ struct _GstRtpSessionPrivate
|
|||
GstClockTime send_latency;
|
||||
|
||||
gboolean use_pipeline_clock;
|
||||
GstRtpNtpTimeSource ntp_time_source;
|
||||
|
||||
guint rtx_count;
|
||||
};
|
||||
|
@ -611,9 +634,10 @@ gst_rtp_session_class_init (GstRtpSessionClass * klass)
|
|||
|
||||
g_object_class_install_property (gobject_class, PROP_USE_PIPELINE_CLOCK,
|
||||
g_param_spec_boolean ("use-pipeline-clock", "Use pipeline clock",
|
||||
"Use the pipeline running-time to set the NTP time in the RTCP SR messages",
|
||||
"Use the pipeline running-time to set the NTP time in the RTCP SR messages "
|
||||
"(DEPRECATED: Use ntp-source property)",
|
||||
DEFAULT_USE_PIPELINE_CLOCK,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_DEPRECATED));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_RTCP_MIN_INTERVAL,
|
||||
g_param_spec_uint64 ("rtcp-min-interval", "Minimum RTCP interval",
|
||||
|
@ -652,6 +676,12 @@ gst_rtp_session_class_init (GstRtpSessionClass * klass)
|
|||
"RTP profile to use", GST_TYPE_RTP_PROFILE, DEFAULT_RTP_PROFILE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_NTP_TIME_SOURCE,
|
||||
g_param_spec_enum ("ntp-time-source", "NTP Time Source",
|
||||
"NTP time source for RTCP packets",
|
||||
gst_rtp_ntp_time_source_get_type (), DEFAULT_NTP_TIME_SOURCE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gstelement_class->change_state =
|
||||
GST_DEBUG_FUNCPTR (gst_rtp_session_change_state);
|
||||
gstelement_class->request_new_pad =
|
||||
|
@ -727,6 +757,8 @@ gst_rtp_session_init (GstRtpSession * rtpsession)
|
|||
rtpsession->priv->thread_stopped = TRUE;
|
||||
|
||||
rtpsession->priv->rtx_count = 0;
|
||||
|
||||
rtpsession->priv->ntp_time_source = DEFAULT_NTP_TIME_SOURCE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -786,6 +818,9 @@ gst_rtp_session_set_property (GObject * object, guint prop_id,
|
|||
case PROP_RTP_PROFILE:
|
||||
g_object_set_property (G_OBJECT (priv->session), "rtp-profile", value);
|
||||
break;
|
||||
case PROP_NTP_TIME_SOURCE:
|
||||
priv->ntp_time_source = g_value_get_enum (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -846,6 +881,9 @@ gst_rtp_session_get_property (GObject * object, guint prop_id,
|
|||
case PROP_RTP_PROFILE:
|
||||
g_object_get_property (G_OBJECT (priv->session), "rtp-profile", value);
|
||||
break;
|
||||
case PROP_NTP_TIME_SOURCE:
|
||||
g_value_set_enum (value, priv->ntp_time_source);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -884,17 +922,35 @@ get_current_times (GstRtpSession * rtpsession, GstClockTime * running_time,
|
|||
|
||||
if (rtpsession->priv->use_pipeline_clock) {
|
||||
ntpns = rt;
|
||||
/* add constant to convert from 1970 based time to 1900 based time */
|
||||
ntpns += (2208988800LL * GST_SECOND);
|
||||
} else {
|
||||
GTimeVal current;
|
||||
switch (rtpsession->priv->ntp_time_source) {
|
||||
case GST_RTP_NTP_TIME_SOURCE_NTP:
|
||||
case GST_RTP_NTP_TIME_SOURCE_UNIX:{
|
||||
GTimeVal current;
|
||||
|
||||
/* get current NTP time */
|
||||
g_get_current_time (¤t);
|
||||
ntpns = GST_TIMEVAL_TO_TIME (current);
|
||||
/* get current NTP time */
|
||||
g_get_current_time (¤t);
|
||||
ntpns = GST_TIMEVAL_TO_TIME (current);
|
||||
|
||||
/* add constant to convert from 1970 based time to 1900 based time */
|
||||
if (rtpsession->priv->ntp_time_source == GST_RTP_NTP_TIME_SOURCE_NTP)
|
||||
ntpns += (2208988800LL * GST_SECOND);
|
||||
break;
|
||||
}
|
||||
case GST_RTP_NTP_TIME_SOURCE_RUNNING_TIME:
|
||||
ntpns = rt;
|
||||
break;
|
||||
case GST_RTP_NTP_TIME_SOURCE_CLOCK_TIME:
|
||||
ntpns = clock_time;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* add constant to convert from 1970 based time to 1900 based time */
|
||||
ntpns += (2208988800LL * GST_SECOND);
|
||||
|
||||
gst_object_unref (clock);
|
||||
} else {
|
||||
GST_OBJECT_UNLOCK (rtpsession);
|
||||
|
|
|
@ -76,4 +76,13 @@ struct _GstRtpSessionClass {
|
|||
|
||||
GType gst_rtp_session_get_type (void);
|
||||
|
||||
typedef enum {
|
||||
GST_RTP_NTP_TIME_SOURCE_NTP,
|
||||
GST_RTP_NTP_TIME_SOURCE_UNIX,
|
||||
GST_RTP_NTP_TIME_SOURCE_RUNNING_TIME,
|
||||
GST_RTP_NTP_TIME_SOURCE_CLOCK_TIME
|
||||
} GstRtpNtpTimeSource;
|
||||
|
||||
GType gst_rtp_ntp_time_source_get_type (void);
|
||||
|
||||
#endif /* __GST_RTP_SESSION_H__ */
|
||||
|
|
Loading…
Reference in a new issue