From 87f7d6b9bf54cc4303e79d0a9d8b8d0a6089d27a Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 7 Jan 2013 15:45:10 +0100 Subject: [PATCH] rtp: include downstream latency in SR calculations When we make a mapping between an RTP timestamp and an NTP timestamp, include the downstream latency applied to the sinks. This makes it possible to have both sinks run with different latencies and still have correct sync on the client. It also is more correct because the RTP timestamp in the SR report will actually correspond more closely to the NTP time it was sent on the server. For pipelines with high latency on the sender side, this actually allows a GStreamer receiver to perform synchronisation instead of dropping the RTCP packets. --- gst/rtpmanager/gstrtpsession.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/gst/rtpmanager/gstrtpsession.c b/gst/rtpmanager/gstrtpsession.c index acd2fdd17e..1e0e0ee88a 100644 --- a/gst/rtpmanager/gstrtpsession.c +++ b/gst/rtpmanager/gstrtpsession.c @@ -242,6 +242,8 @@ struct _GstRtpSessionPrivate /* caps mapping */ GHashTable *ptmap; + GstClockTime send_latency; + gboolean use_pipeline_clock; }; @@ -1712,6 +1714,33 @@ gst_rtp_session_event_send_rtp_sink (GstPad * pad, GstObject * parent, return ret; } +static gboolean +gst_rtp_session_event_send_rtp_src (GstPad * pad, GstObject * parent, + GstEvent * event) +{ + GstRtpSession *rtpsession; + gboolean ret = FALSE; + + rtpsession = GST_RTP_SESSION (parent); + + GST_DEBUG_OBJECT (rtpsession, "received EVENT %s", + GST_EVENT_TYPE_NAME (event)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_LATENCY: + /* save the latency, we need this to know when an RTP packet will be + * rendered by the sink */ + gst_event_parse_latency (event, &rtpsession->priv->send_latency); + + ret = gst_pad_event_default (pad, parent, event); + break; + default: + ret = gst_pad_event_default (pad, parent, event); + break; + } + return ret; +} + static GstCaps * gst_rtp_session_getcaps_send_rtp (GstPad * pad, GstRtpSession * rtpsession, GstCaps * filter) @@ -1829,6 +1858,7 @@ 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; } else { /* no timestamp. */ running_time = -1; @@ -2011,6 +2041,8 @@ create_send_rtp_sink (GstRtpSession * rtpsession) "send_rtp_src"); gst_pad_set_iterate_internal_links_function (rtpsession->send_rtp_src, gst_rtp_session_iterate_internal_links); + gst_pad_set_event_function (rtpsession->send_rtp_src, + gst_rtp_session_event_send_rtp_src); gst_pad_set_active (rtpsession->send_rtp_src, TRUE); gst_element_add_pad (GST_ELEMENT_CAST (rtpsession), rtpsession->send_rtp_src);