rtpbin/session: Allow RTCP sync to happen based on capture time or send time

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
This commit is contained in:
Sebastian Dröge 2015-09-16 19:28:11 +02:00
parent 4dade84258
commit a0ae6b5b5a
3 changed files with 51 additions and 4 deletions

View 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;

View 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;

View 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;