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: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2132>
This commit is contained in:
Sebastian Dröge 2022-04-11 19:25:43 +03:00 committed by GStreamer Marge Bot
parent cbaac3cdba
commit 0c819d2f31
2 changed files with 30 additions and 0 deletions

View 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:
{

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