From 06f90deb5f1cbf2a726c591ccc44d441a9903808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 7 Apr 2022 19:36:25 +0300 Subject: [PATCH] sdp: Parse the RFC5576 Source-specific media SDP attributes into caps The format of the caps fields is ssrc-(SSRC_VALUE)-(ATTRIBUTE_NAME)=(ATTRIBUTE_VALUE) . Parsing of the attributes from the caps into the SDP is not implemented as this depends not only a single stream's caps but on the whole rtpbin configuration. Part-of: --- .../gst-libs/gst/sdp/gstsdpmessage.c | 76 ++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c b/subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c index 2fb6d68ffa..9ad2aec26d 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c @@ -3583,7 +3583,7 @@ gst_sdp_media_caps_adjust_h264 (GstCaps * caps) * * a=fmtp:(payload) (param)[=(value)];... * - * Note that the extmap attribute is set only by gst_sdp_media_attributes_to_caps(). + * Note that the extmap, ssrc and rid attributes are set only by gst_sdp_media_attributes_to_caps(). * * Returns: a #GstCaps, or %NULL if an error happened * @@ -4216,6 +4216,8 @@ sdp_add_attributes_to_caps (GArray * attributes, GstCaps * caps) continue; if (!strcmp (key, "extmap")) continue; + if (!strcmp (key, "ssrc")) + continue; if (!strcmp (key, "rid")) continue; @@ -4343,6 +4345,73 @@ gst_sdp_media_add_extmap_attributes (GArray * attributes, GstCaps * caps) return GST_SDP_OK; } +/* parses Source-specific media SDP attributes (RFC5576) into caps */ +static GstSDPResult +gst_sdp_media_add_ssrc_attributes (GArray * attributes, GstCaps * caps) +{ + gchar *p, *tmp, *to_free; + guint i; + GstStructure *s; + + g_return_val_if_fail (attributes != NULL, GST_SDP_EINVAL); + g_return_val_if_fail (caps != NULL && GST_IS_CAPS (caps), GST_SDP_EINVAL); + + s = gst_caps_get_structure (caps, 0); + + for (i = 0; i < attributes->len; i++) { + const gchar *value; + GstSDPAttribute *attr; + guint32 ssrc; + gchar *ssrc_val, *ssrc_attr; + gchar *key; + + attr = &g_array_index (attributes, GstSDPAttribute, i); + if (strcmp (attr->key, "ssrc") != 0) + continue; + + value = attr->value; + + /* p is now of the format ssrc attribute[:value] */ + to_free = p = g_strdup (value); + + ssrc = strtoul (p, &tmp, 10); + if (*tmp != ' ') { + GST_ERROR ("Invalid ssrc attribute '%s'", to_free); + goto next; + } + + /* At the space */ + p = tmp; + + SKIP_SPACES (p); + + tmp = strstr (p, ":"); + if (tmp == NULL) { + ssrc_attr = tmp; + ssrc_val = (gchar *) ""; + } else { + ssrc_attr = p; + *tmp = '\0'; + p = tmp + 1; + ssrc_val = p; + } + + if (ssrc_attr == NULL || *ssrc_attr == '\0') { + GST_ERROR ("Invalid ssrc attribute '%s'", to_free); + goto next; + } + + key = g_strdup_printf ("ssrc-%u-%s", ssrc, ssrc_attr); + gst_structure_set (s, key, G_TYPE_STRING, ssrc_val, NULL); + GST_DEBUG ("adding caps: %s=%s", key, ssrc_val); + g_free (key); + + next: + g_free (to_free); + } + return GST_SDP_OK; +} + /* parses RID SDP attributes (RFC8851) into caps */ static GstSDPResult gst_sdp_media_add_rid_attributes (GArray * attributes, GstCaps * caps) @@ -4551,6 +4620,11 @@ gst_sdp_media_attributes_to_caps (const GstSDPMedia * media, GstCaps * caps) res = gst_sdp_media_add_extmap_attributes (media->attributes, caps); } + if (res == GST_SDP_OK) { + /* parse media ssrc field */ + res = gst_sdp_media_add_ssrc_attributes (media->attributes, caps); + } + if (res == GST_SDP_OK) { /* parse media rid fields */ res = gst_sdp_media_add_rid_attributes (media->attributes, caps);