From 51020549f0f9fc8964b1aab1fe657f2caff2a515 Mon Sep 17 00:00:00 2001 From: Thijs Vermeir Date: Thu, 26 Aug 2010 10:58:26 +0200 Subject: [PATCH] rtpbin: add use-pipeline-clock property With this property RTCP SR NTP times can be based on the system clock (maybe synced with ntpd) or the current pipeline clock. https://bugzilla.gnome.org/show_bug.cgi?id=627796 --- gst/rtpmanager/gstrtpbin.c | 31 ++++++++++++++++++++++++++++--- gst/rtpmanager/gstrtpbin.h | 1 + gst/rtpmanager/gstrtpsession.c | 28 ++++++++++++++++++++++++---- 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/gst/rtpmanager/gstrtpbin.c b/gst/rtpmanager/gstrtpbin.c index acddd66..a36d8c9 100644 --- a/gst/rtpmanager/gstrtpbin.c +++ b/gst/rtpmanager/gstrtpbin.c @@ -232,12 +232,13 @@ enum LAST_SIGNAL }; -#define DEFAULT_LATENCY_MS 200 +#define DEFAULT_LATENCY_MS 200 #define DEFAULT_SDES NULL #define DEFAULT_DO_LOST FALSE #define DEFAULT_IGNORE_PT FALSE #define DEFAULT_AUTOREMOVE FALSE #define DEFAULT_BUFFER_MODE RTP_JITTER_BUFFER_MODE_SLAVE +#define DEFAULT_USE_PIPELINE_CLOCK FALSE enum { @@ -248,6 +249,7 @@ enum PROP_IGNORE_PT, PROP_AUTOREMOVE, PROP_BUFFER_MODE, + PROP_USE_PIPELINE_CLOCK, PROP_LAST }; @@ -529,7 +531,8 @@ create_session (GstRtpBin * rtpbin, gint id) /* configure SDES items */ GST_OBJECT_LOCK (rtpbin); - g_object_set (session, "sdes", rtpbin->sdes, NULL); + g_object_set (session, "sdes", rtpbin->sdes, "use-pipeline-clock", + rtpbin->use_pipeline_clock, NULL); GST_OBJECT_UNLOCK (rtpbin); /* provide clock_rate to the session manager when needed */ @@ -1530,7 +1533,6 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass) "Send an event downstream when a packet is lost", DEFAULT_DO_LOST, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_AUTOREMOVE, g_param_spec_boolean ("autoremove", "Auto Remove", "Automatically remove timed out sources", DEFAULT_AUTOREMOVE, @@ -1540,6 +1542,12 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass) g_param_spec_boolean ("ignore_pt", "Ignore PT", "Do not demultiplex based on PT values", DEFAULT_IGNORE_PT, G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_USE_PIPELINE_CLOCK, + g_param_spec_boolean ("use-pipeline-clock", "Use pipeline clock", + "Use the pipeline clock to set the NTP time in the RTCP SR messages", + DEFAULT_AUTOREMOVE, G_PARAM_READWRITE)); + /** * GstRtpBin::buffer-mode: * @@ -1582,6 +1590,7 @@ gst_rtp_bin_init (GstRtpBin * rtpbin, GstRtpBinClass * klass) rtpbin->ignore_pt = DEFAULT_IGNORE_PT; rtpbin->priv->autoremove = DEFAULT_AUTOREMOVE; rtpbin->buffer_mode = DEFAULT_BUFFER_MODE; + rtpbin->use_pipeline_clock = DEFAULT_USE_PIPELINE_CLOCK; /* some default SDES entries */ str = g_strdup_printf ("%s@%s", g_get_user_name (), g_get_host_name ()); @@ -1695,6 +1704,19 @@ gst_rtp_bin_set_property (GObject * object, guint prop_id, case PROP_AUTOREMOVE: rtpbin->priv->autoremove = g_value_get_boolean (value); break; + case PROP_USE_PIPELINE_CLOCK: + { + GSList *sessions; + GST_RTP_BIN_LOCK (rtpbin); + rtpbin->use_pipeline_clock = g_value_get_boolean (value); + for (sessions = rtpbin->sessions; sessions; + sessions = g_slist_next (sessions)) { + g_object_set (G_OBJECT (sessions->data), "use-pipeline-clock", + rtpbin->use_pipeline_clock, NULL); + } + GST_RTP_BIN_UNLOCK (rtpbin); + } + break; case PROP_BUFFER_MODE: GST_RTP_BIN_LOCK (rtpbin); rtpbin->buffer_mode = g_value_get_enum (value); @@ -1739,6 +1761,9 @@ gst_rtp_bin_get_property (GObject * object, guint prop_id, case PROP_BUFFER_MODE: g_value_set_enum (value, rtpbin->buffer_mode); break; + case PROP_USE_PIPELINE_CLOCK: + g_value_set_boolean (value, rtpbin->use_pipeline_clock); + 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 51a2adc..b64f86e 100644 --- a/gst/rtpmanager/gstrtpbin.h +++ b/gst/rtpmanager/gstrtpbin.h @@ -51,6 +51,7 @@ struct _GstRtpBin { gboolean ignore_pt; RTPJitterBufferMode buffer_mode; gboolean buffering; + gboolean use_pipeline_clock; GstClockTime buffer_start; /* a list of session */ GSList *sessions; diff --git a/gst/rtpmanager/gstrtpsession.c b/gst/rtpmanager/gstrtpsession.c index 9b8bd78..061302c 100644 --- a/gst/rtpmanager/gstrtpsession.c +++ b/gst/rtpmanager/gstrtpsession.c @@ -198,6 +198,7 @@ enum #define DEFAULT_SDES NULL #define DEFAULT_NUM_SOURCES 0 #define DEFAULT_NUM_ACTIVE_SOURCES 0 +#define DEFAULT_USE_PIPELINE_CLOCK FALSE enum { @@ -211,6 +212,7 @@ enum PROP_NUM_SOURCES, PROP_NUM_ACTIVE_SOURCES, PROP_INTERNAL_SESSION, + PROP_USE_PIPELINE_CLOCK, PROP_LAST }; @@ -238,6 +240,7 @@ struct _GstRtpSessionPrivate /* NTP base time */ guint64 ntpnsbase; + gboolean use_pipeline_clock; }; /* callbacks to handle actions from the session manager */ @@ -572,6 +575,11 @@ gst_rtp_session_class_init (GstRtpSessionClass * klass) "The internal RTPSession object", RTP_TYPE_SESSION, G_PARAM_READABLE)); + g_object_class_install_property (gobject_class, PROP_USE_PIPELINE_CLOCK, + g_param_spec_boolean ("use-pipeline-clock", "Use pipeline clock", + "Use the pipeline clock to set the NTP time in the RTCP SR messages", + DEFAULT_USE_PIPELINE_CLOCK, G_PARAM_READWRITE)); + gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_session_change_state); gstelement_class->request_new_pad = @@ -592,6 +600,7 @@ gst_rtp_session_init (GstRtpSession * rtpsession, GstRtpSessionClass * klass) rtpsession->priv->lock = g_mutex_new (); rtpsession->priv->sysclock = gst_system_clock_obtain (); rtpsession->priv->session = rtp_session_new (); + rtpsession->priv->use_pipeline_clock = DEFAULT_USE_PIPELINE_CLOCK; /* configure callbacks */ rtp_session_set_callbacks (rtpsession->priv->session, &callbacks, rtpsession); @@ -682,6 +691,9 @@ gst_rtp_session_set_property (GObject * object, guint prop_id, case PROP_SDES: rtp_session_set_sdes_struct (priv->session, g_value_get_boxed (value)); break; + case PROP_USE_PIPELINE_CLOCK: + priv->use_pipeline_clock = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -731,6 +743,9 @@ gst_rtp_session_get_property (GObject * object, guint prop_id, case PROP_INTERNAL_SESSION: g_value_set_object (value, priv->session); break; + case PROP_USE_PIPELINE_CLOCK: + g_value_set_boolean (value, priv->use_pipeline_clock); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -744,7 +759,6 @@ get_current_times (GstRtpSession * rtpsession, GstClockTime * running_time, guint64 ntpns; GstClock *clock; GstClockTime base_time, rt; - GTimeVal current; GST_OBJECT_LOCK (rtpsession); if ((clock = GST_ELEMENT_CLOCK (rtpsession))) { @@ -752,9 +766,15 @@ get_current_times (GstRtpSession * rtpsession, GstClockTime * running_time, gst_object_ref (clock); GST_OBJECT_UNLOCK (rtpsession); - /* get current NTP time */ - g_get_current_time (¤t); - ntpns = GST_TIMEVAL_TO_TIME (current); + if (rtpsession->priv->use_pipeline_clock) { + ntpns = gst_clock_get_time (clock); + } else { + GTimeVal 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 */ ntpns += (2208988800LL * GST_SECOND); -- 2.7.4