rtpbin/session: Allow RTCP sync to happen based on capture time or send time
authorSebastian Dröge <sebastian@centricular.com>
Wed, 16 Sep 2015 17:28:11 +0000 (19:28 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Fri, 25 Sep 2015 21:55:00 +0000 (23:55 +0200)
Send time is the previous behaviour and the default, but there are use cases
where you want to synchronize based on the capture time.

https://bugzilla.gnome.org/show_bug.cgi?id=755125

gst/rtpmanager/gstrtpbin.c
gst/rtpmanager/gstrtpbin.h
gst/rtpmanager/gstrtpsession.c

index 21e1cd8..a65fc7c 100644 (file)
@@ -290,6 +290,7 @@ enum
 #define DEFAULT_DO_RETRANSMISSION    FALSE
 #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
 
 enum
 {
@@ -308,7 +309,8 @@ enum
   PROP_DO_SYNC_EVENT,
   PROP_DO_RETRANSMISSION,
   PROP_RTP_PROFILE,
-  PROP_NTP_TIME_SOURCE
+  PROP_NTP_TIME_SOURCE,
+  PROP_RTCP_SYNC_SEND_TIME
 };
 
 #define GST_RTP_BIN_RTCP_SYNC_TYPE (gst_rtp_bin_rtcp_sync_get_type())
@@ -625,7 +627,8 @@ create_session (GstRtpBin * rtpbin, gint id)
   /* configure SDES items */
   GST_OBJECT_LOCK (rtpbin);
   g_object_set (session, "sdes", rtpbin->sdes, "rtp-profile",
-      rtpbin->rtp_profile, NULL);
+      rtpbin->rtp_profile, "rtcp-sync-send-time", rtpbin->rtcp_sync_send_time,
+      NULL);
   if (rtpbin->use_pipeline_clock)
     g_object_set (session, "use-pipeline-clock", rtpbin->use_pipeline_clock,
         NULL);
@@ -2171,6 +2174,13 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass)
           gst_rtp_ntp_time_source_get_type (), DEFAULT_NTP_TIME_SOURCE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_RTCP_SYNC_SEND_TIME,
+      g_param_spec_boolean ("rtcp-sync-send-time", "RTCP Sync Send Time",
+          "Use send time or capture time for RTCP sync "
+          "(TRUE = send time, FALSE = capture time)",
+          DEFAULT_RTCP_SYNC_SEND_TIME,
+          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);
@@ -2235,6 +2245,7 @@ gst_rtp_bin_init (GstRtpBin * rtpbin)
   rtpbin->do_retransmission = DEFAULT_DO_RETRANSMISSION;
   rtpbin->rtp_profile = DEFAULT_RTP_PROFILE;
   rtpbin->ntp_time_source = DEFAULT_NTP_TIME_SOURCE;
+  rtpbin->rtcp_sync_send_time = DEFAULT_RTCP_SYNC_SEND_TIME;
 
   /* some default SDES entries */
   cname = g_strdup_printf ("user%u@host-%x", g_random_int (), g_random_int ());
@@ -2412,6 +2423,20 @@ gst_rtp_bin_set_property (GObject * object, guint prop_id,
       GST_RTP_BIN_UNLOCK (rtpbin);
       break;
     }
+    case PROP_RTCP_SYNC_SEND_TIME:{
+      GSList *sessions;
+      GST_RTP_BIN_LOCK (rtpbin);
+      rtpbin->rtcp_sync_send_time = g_value_get_boolean (value);
+      for (sessions = rtpbin->sessions; sessions;
+          sessions = g_slist_next (sessions)) {
+        GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
+
+        g_object_set (G_OBJECT (session->session),
+            "rtcp-sync-send-time", rtpbin->rtcp_sync_send_time, NULL);
+      }
+      GST_RTP_BIN_UNLOCK (rtpbin);
+      break;
+    }
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -2480,6 +2505,9 @@ gst_rtp_bin_get_property (GObject * object, guint prop_id,
     case PROP_NTP_TIME_SOURCE:
       g_value_set_enum (value, rtpbin->ntp_time_source);
       break;
+    case PROP_RTCP_SYNC_SEND_TIME:
+      g_value_set_boolean (value, rtpbin->rtcp_sync_send_time);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
index 87c1fad..41ab38c 100644 (file)
@@ -69,6 +69,7 @@ struct _GstRtpBin {
   GstClockTime    buffer_start;
   gboolean        do_retransmission;
   GstRTPProfile   rtp_profile;
+  gboolean        rtcp_sync_send_time;
 
   /* a list of session */
   GSList         *sessions;
index 2604c61..844a75f 100644 (file)
@@ -223,6 +223,7 @@ enum
 #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
+#define DEFAULT_RTCP_SYNC_SEND_TIME  TRUE
 
 enum
 {
@@ -240,7 +241,8 @@ enum
   PROP_PROBATION,
   PROP_STATS,
   PROP_RTP_PROFILE,
-  PROP_NTP_TIME_SOURCE
+  PROP_NTP_TIME_SOURCE,
+  PROP_RTCP_SYNC_SEND_TIME
 };
 
 #define GST_RTP_SESSION_GET_PRIVATE(obj)  \
@@ -274,6 +276,7 @@ struct _GstRtpSessionPrivate
 
   gboolean use_pipeline_clock;
   GstRtpNtpTimeSource ntp_time_source;
+  gboolean rtcp_sync_send_time;
 
   guint rtx_count;
 };
@@ -682,6 +685,13 @@ gst_rtp_session_class_init (GstRtpSessionClass * klass)
           gst_rtp_ntp_time_source_get_type (), DEFAULT_NTP_TIME_SOURCE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_RTCP_SYNC_SEND_TIME,
+      g_param_spec_boolean ("rtcp-sync-send-time", "RTCP Sync Send Time",
+          "Use send time or capture time for RTCP sync "
+          "(TRUE = send time, FALSE = capture time)",
+          DEFAULT_RTCP_SYNC_SEND_TIME,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_rtp_session_change_state);
   gstelement_class->request_new_pad =
@@ -726,6 +736,7 @@ gst_rtp_session_init (GstRtpSession * rtpsession)
   rtpsession->priv->sysclock = gst_system_clock_obtain ();
   rtpsession->priv->session = rtp_session_new ();
   rtpsession->priv->use_pipeline_clock = DEFAULT_USE_PIPELINE_CLOCK;
+  rtpsession->priv->rtcp_sync_send_time = DEFAULT_RTCP_SYNC_SEND_TIME;
 
   /* configure callbacks */
   rtp_session_set_callbacks (rtpsession->priv->session, &callbacks, rtpsession);
@@ -821,6 +832,9 @@ gst_rtp_session_set_property (GObject * object, guint prop_id,
     case PROP_NTP_TIME_SOURCE:
       priv->ntp_time_source = g_value_get_enum (value);
       break;
+    case PROP_RTCP_SYNC_SEND_TIME:
+      priv->rtcp_sync_send_time = g_value_get_boolean (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -884,6 +898,9 @@ gst_rtp_session_get_property (GObject * object, guint prop_id,
     case PROP_NTP_TIME_SOURCE:
       g_value_set_enum (value, priv->ntp_time_source);
       break;
+    case PROP_RTCP_SYNC_SEND_TIME:
+      g_value_set_boolean (value, priv->rtcp_sync_send_time);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -2174,7 +2191,8 @@ gst_rtp_session_chain_send_rtp_common (GstRtpSession * rtpsession,
     running_time =
         gst_segment_to_running_time (&rtpsession->send_rtp_seg, GST_FORMAT_TIME,
         timestamp);
-    running_time += priv->send_latency;
+    if (priv->rtcp_sync_send_time)
+      running_time += priv->send_latency;
   } else {
     /* no timestamp. */
     running_time = -1;