rtpbin/rtpjitterbuffer: Allow syncing to an SR without CNAME if the CNAME is already...
authorSebastian Dröge <sebastian@centricular.com>
Mon, 11 Apr 2022 16:25:43 +0000 (19:25 +0300)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 20 Apr 2022 14:40:25 +0000 (14:40 +0000)
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: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2132>

subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.c
subprojects/gst-plugins-good/gst/rtpmanager/gstrtpjitterbuffer.c

index e0574bf4b4b94f19ea47cd00d2560383c1245354..ed874e1316922544eef9c0b32f5efef8adc70a35 100644 (file)
@@ -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:
       {
index 73f873439f5b7e7e9d2ffedb70c384cc7721b6f9..06cfd10b47500a7b8518a19e4f670aa4bebb80dc 100644 (file)
@@ -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);