From 0c819d2f313749dc49feeb35e436449748c6775b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 11 Apr 2022 19:25:43 +0300 Subject: [PATCH] rtpbin/rtpjitterbuffer: Allow syncing to an SR without CNAME if the CNAME is already known The RTCP SR packet might be without SDES in case of a reduced-size RTCP packet. For syncing purposes the CNAME is needed but it might be known already from an earlier RTCP packet or out of band, via the SDP for example. Part-of: --- .../gst-plugins-good/gst/rtpmanager/gstrtpbin.c | 17 +++++++++++++++++ .../gst/rtpmanager/gstrtpjitterbuffer.c | 13 +++++++++++++ 2 files changed, 30 insertions(+) diff --git a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.c b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.c index e0574bf4b4..ed874e1316 100644 --- a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.c +++ b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.c @@ -1761,6 +1761,8 @@ gst_rtp_bin_handle_sync (GstElement * jitterbuffer, GstStructure * s, return; } + cname = gst_structure_get_string (s, "cname"); + /* if the jitterbuffer directly got the NTP timestamp then don't work * through the RTCP SR, otherwise extract it from there */ if (gst_structure_get_uint64 (s, "inband-ntpnstime", &inband_ntpnstime) @@ -1797,6 +1799,9 @@ gst_rtp_bin_handle_sync (GstElement * jitterbuffer, GstStructure * s, gst_rtcp_buffer_map (buffer, GST_MAP_READ, &rtcp); GST_RTCP_BUFFER_FOR_PACKETS (more, &rtcp, &packet) { + if (have_sr && (cname || have_sdes)) + break; + /* first packet must be SR or RR or else the validate would have failed */ switch (gst_rtcp_packet_get_type (&packet)) { case GST_RTCP_TYPE_SR: @@ -1818,6 +1823,18 @@ gst_rtp_bin_handle_sync (GstElement * jitterbuffer, GstStructure * s, continue; have_sr = TRUE; + + /* If we already have the CNAME don't require parsing SDES */ + if (cname) { + GST_RTP_BIN_LOCK (bin); + /* associate the stream to CNAME */ + gst_rtp_bin_associate (bin, stream, strlen (cname), + (const guint8 *) cname, ntpnstime, extrtptime, base_rtptime, + base_time, clock_rate, clock_base); + GST_RTP_BIN_UNLOCK (bin); + break; + } + break; case GST_RTCP_TYPE_SDES: { diff --git a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpjitterbuffer.c b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpjitterbuffer.c index 73f873439f..06cfd10b47 100644 --- a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpjitterbuffer.c +++ b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpjitterbuffer.c @@ -406,6 +406,7 @@ struct _GstRtpJitterBufferPrivate GstClockTime peer_latency; guint64 ext_rtptime; GstBuffer *last_sr; + guint32 last_sr_ssrc; /* some accounting */ guint64 num_pushed; @@ -4579,15 +4580,26 @@ do_handle_sync (GstRtpJitterBuffer * jitterbuffer) GST_DEBUG_OBJECT (jitterbuffer, "keeping RTCP packet for later"); } else if (valid) { GstStructure *s; + GList *l; s = gst_structure_new ("application/x-rtp-sync", "base-rtptime", G_TYPE_UINT64, base_rtptime, "base-time", G_TYPE_UINT64, base_time, "clock-rate", G_TYPE_UINT, clock_rate, "clock-base", G_TYPE_UINT64, clock_base, + "ssrc", G_TYPE_UINT, priv->last_sr_ssrc, "sr-ext-rtptime", G_TYPE_UINT64, ext_rtptime, "sr-buffer", GST_TYPE_BUFFER, priv->last_sr, NULL); + for (l = priv->cname_ssrc_mappings; l; l = l->next) { + const CNameSSRCMapping *map = l->data; + + if (map->ssrc == priv->last_ssrc) { + gst_structure_set (s, "cname", G_TYPE_STRING, map->cname, NULL); + break; + } + } + GST_DEBUG_OBJECT (jitterbuffer, "signaling sync"); gst_buffer_replace (&priv->last_sr, NULL); JBUF_UNLOCK (priv); @@ -4700,6 +4712,7 @@ gst_rtp_jitter_buffer_chain_rtcp (GstPad * pad, GstObject * parent, priv->ext_rtptime = ext_rtptime; gst_buffer_replace (&priv->last_sr, buffer); + priv->last_sr_ssrc = ssrc; do_handle_sync (jitterbuffer); -- 2.34.1