rtpbin: add use-pipeline-clock property
authorThijs Vermeir <thijsvermeir@gmail.com>
Thu, 26 Aug 2010 08:58:26 +0000 (10:58 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Mon, 6 Sep 2010 09:01:57 +0000 (11:01 +0200)
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
gst/rtpmanager/gstrtpbin.h
gst/rtpmanager/gstrtpsession.c

index acddd66..a36d8c9 100644 (file)
@@ -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;
index 51a2adc..b64f86e 100644 (file)
@@ -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;
index 9b8bd78..061302c 100644 (file)
@@ -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 (&current);
-    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 (&current);
+      ntpns = GST_TIMEVAL_TO_TIME (current);
+    }
 
     /* add constant to convert from 1970 based time to 1900 based time */
     ntpns += (2208988800LL * GST_SECOND);