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 e0574bf..ed874e1 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 73f8734..06cfd10 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);