mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-03 14:08:56 +00:00
webrtc: add all SSRC attributes getting CAPS for a PT
The transport stream only returned the CAPS for the first matching PT entry from the `ptmap`. Other SSRC with the same PT where not included. For a stream which bundled multiple audio streams for instance, only the first SSRC was knowed to the SSRC demux and downstream elements. This commit adds all the `ssrc-` attributes from the matching PT entries. The RTP jitter buffer can now find the CNAME corresponding its SSRC even if it was not the first to be registered for a particular PT. The RTP PT demux removes `ssrc-*` attributes cooresponding to other SSRCs before pushing SSRC specific CAPS to downstream elements. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6119>
This commit is contained in:
parent
d83184cf9a
commit
7d5bb1ea7a
3 changed files with 57 additions and 6 deletions
|
@ -5122,6 +5122,8 @@ _set_internal_rtpbin_element_props_from_stream (GstWebRTCBin * webrtc,
|
|||
|
||||
GST_LOG_OBJECT (stream, "setting rtx mapping: %s -> %u", apt, rtx_pt[i]);
|
||||
gst_structure_set (pt_map, apt, G_TYPE_UINT, rtx_pt[i], NULL);
|
||||
|
||||
gst_caps_unref (rtx_caps);
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (stream, "setting payload map on %" GST_PTR_FORMAT " : %"
|
||||
|
@ -7446,8 +7448,7 @@ on_rtpbin_request_pt_map (GstElement * rtpbin, guint session_id, guint pt,
|
|||
if (!stream)
|
||||
goto unknown_session;
|
||||
|
||||
if ((ret = transport_stream_get_caps_for_pt (stream, pt)))
|
||||
gst_caps_ref (ret);
|
||||
ret = transport_stream_get_caps_for_pt (stream, pt);
|
||||
|
||||
GST_DEBUG_OBJECT (webrtc, "Found caps %" GST_PTR_FORMAT " for pt %d in "
|
||||
"session %d", ret, pt, session_id);
|
||||
|
|
|
@ -47,15 +47,37 @@ enum
|
|||
GstCaps *
|
||||
transport_stream_get_caps_for_pt (TransportStream * stream, guint pt)
|
||||
{
|
||||
guint i, len;
|
||||
GstCaps *ret = NULL;
|
||||
GstStructure *ret_s, *item_s;
|
||||
guint i, len, si, slen;
|
||||
const gchar *field_name;
|
||||
|
||||
len = stream->ptmap->len;
|
||||
for (i = 0; i < len; i++) {
|
||||
PtMapItem *item = &g_array_index (stream->ptmap, PtMapItem, i);
|
||||
if (item->pt == pt)
|
||||
return item->caps;
|
||||
if (item->pt == pt) {
|
||||
if (item->caps) {
|
||||
if (ret == NULL) {
|
||||
ret = gst_caps_copy (item->caps);
|
||||
ret_s = gst_caps_get_structure (ret, 0);
|
||||
} else {
|
||||
/* Append the "ssrc-*" fields for current PT entry to ret */
|
||||
item_s = gst_caps_get_structure (item->caps, 0);
|
||||
slen = gst_structure_n_fields (item_s);
|
||||
for (si = 0; si < slen; ++si) {
|
||||
field_name = gst_structure_nth_field_name (item_s, si);
|
||||
if (!g_str_has_prefix (field_name, "ssrc-"))
|
||||
continue;
|
||||
|
||||
gst_structure_set (ret_s, field_name, G_TYPE_STRING,
|
||||
gst_structure_get_string (item_s, field_name), NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -312,6 +312,29 @@ gst_rtp_pt_demux_finalize (GObject * object)
|
|||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/* Removes "ssrc-*" attributes matching other SSRCs. */
|
||||
static gboolean
|
||||
_filter_ssrc (GQuark field_id, GValue * value, gpointer ssrc)
|
||||
{
|
||||
const gchar *field_name = g_quark_to_string (field_id);
|
||||
|
||||
if (!g_str_has_prefix (field_name, "ssrc-"))
|
||||
return TRUE;
|
||||
|
||||
gchar *endptr;
|
||||
guint32 field_ssrc = g_ascii_strtoll (field_name + 5, &endptr, 10);
|
||||
|
||||
if (!endptr || *endptr != '-')
|
||||
return TRUE;
|
||||
|
||||
/* Found a valid "ssrc-*" */
|
||||
if (field_ssrc != *(guint32 *) ssrc)
|
||||
/* Not the expected SSRC => remove this field */
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_rtp_pt_demux_get_caps (GstRtpPtDemux * rtpdemux, guint pt)
|
||||
{
|
||||
|
@ -349,7 +372,12 @@ gst_rtp_pt_demux_get_caps (GstRtpPtDemux * rtpdemux, guint pt)
|
|||
}
|
||||
|
||||
if (caps != NULL) {
|
||||
GstStructure *s;
|
||||
|
||||
caps = gst_caps_make_writable (caps);
|
||||
s = gst_caps_get_structure (caps, 0);
|
||||
gst_structure_filter_and_map_in_place (s, _filter_ssrc, &ssrc);
|
||||
|
||||
gst_caps_set_simple (caps, "payload", G_TYPE_INT, pt, NULL);
|
||||
if (have_ssrc)
|
||||
gst_caps_set_simple (caps, "ssrc", G_TYPE_UINT, ssrc, NULL);
|
||||
|
|
Loading…
Reference in a new issue