mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
webrtcbin: fix pt selection for FEC and RTX when BUNDLE
When we offer bundled media, payload types must be unique across all bundled media, as they will be multiplexed in the same session.
This commit is contained in:
parent
2f907b7e2d
commit
a2779ef366
1 changed files with 47 additions and 5 deletions
|
@ -1946,7 +1946,8 @@ _add_fingerprint_to_media (GstWebRTCDTLSTransport * transport,
|
||||||
static gboolean
|
static gboolean
|
||||||
sdp_media_from_transceiver (GstWebRTCBin * webrtc, GstSDPMedia * media,
|
sdp_media_from_transceiver (GstWebRTCBin * webrtc, GstSDPMedia * media,
|
||||||
GstWebRTCRTPTransceiver * trans, GstWebRTCSDPType type, guint media_idx,
|
GstWebRTCRTPTransceiver * trans, GstWebRTCSDPType type, guint media_idx,
|
||||||
GString * bundled_mids, guint bundle_idx, gboolean bundle_only)
|
GString * bundled_mids, guint bundle_idx, gboolean bundle_only,
|
||||||
|
GArray * reserved_pts)
|
||||||
{
|
{
|
||||||
/* TODO:
|
/* TODO:
|
||||||
* rtp header extensions
|
* rtp header extensions
|
||||||
|
@ -2028,14 +2029,14 @@ sdp_media_from_transceiver (GstWebRTCBin * webrtc, GstSDPMedia * media,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == GST_WEBRTC_SDP_TYPE_OFFER) {
|
if (type == GST_WEBRTC_SDP_TYPE_OFFER) {
|
||||||
GArray *reserved_pts = g_array_new (FALSE, FALSE, sizeof (guint));
|
|
||||||
const GstStructure *s = gst_caps_get_structure (caps, 0);
|
const GstStructure *s = gst_caps_get_structure (caps, 0);
|
||||||
gint clockrate = -1;
|
gint clockrate = -1;
|
||||||
gint rtx_target_pt;
|
gint rtx_target_pt;
|
||||||
gint original_rtx_target_pt; /* Workaround chrome bug: https://bugs.chromium.org/p/webrtc/issues/detail?id=6196 */
|
gint original_rtx_target_pt; /* Workaround chrome bug: https://bugs.chromium.org/p/webrtc/issues/detail?id=6196 */
|
||||||
guint rtx_target_ssrc = -1;
|
guint rtx_target_ssrc = -1;
|
||||||
|
|
||||||
if (gst_structure_get_int (s, "payload", &rtx_target_pt))
|
if (gst_structure_get_int (s, "payload", &rtx_target_pt) &&
|
||||||
|
webrtc->bundle_policy == GST_WEBRTC_BUNDLE_POLICY_NONE)
|
||||||
g_array_append_val (reserved_pts, rtx_target_pt);
|
g_array_append_val (reserved_pts, rtx_target_pt);
|
||||||
|
|
||||||
original_rtx_target_pt = rtx_target_pt;
|
original_rtx_target_pt = rtx_target_pt;
|
||||||
|
@ -2054,7 +2055,6 @@ sdp_media_from_transceiver (GstWebRTCBin * webrtc, GstSDPMedia * media,
|
||||||
if (original_rtx_target_pt != rtx_target_pt)
|
if (original_rtx_target_pt != rtx_target_pt)
|
||||||
_pick_rtx_payload_types (webrtc, WEBRTC_TRANSCEIVER (trans), reserved_pts,
|
_pick_rtx_payload_types (webrtc, WEBRTC_TRANSCEIVER (trans), reserved_pts,
|
||||||
clockrate, original_rtx_target_pt, rtx_target_ssrc, media);
|
clockrate, original_rtx_target_pt, rtx_target_ssrc, media);
|
||||||
g_array_free (reserved_pts, TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_media_add_ssrcs (media, caps, webrtc, WEBRTC_TRANSCEIVER (trans));
|
_media_add_ssrcs (media, caps, webrtc, WEBRTC_TRANSCEIVER (trans));
|
||||||
|
@ -2084,6 +2084,34 @@ sdp_media_from_transceiver (GstWebRTCBin * webrtc, GstSDPMedia * media,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gather_pad_pt (GstWebRTCBinPad * pad, GArray * reserved_pts)
|
||||||
|
{
|
||||||
|
if (pad->received_caps) {
|
||||||
|
GstStructure *s = gst_caps_get_structure (pad->received_caps, 0);
|
||||||
|
gint pt;
|
||||||
|
|
||||||
|
if (gst_structure_get_int (s, "payload", &pt)) {
|
||||||
|
g_array_append_val (reserved_pts, pt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static GArray *
|
||||||
|
gather_reserved_pts (GstWebRTCBin * webrtc)
|
||||||
|
{
|
||||||
|
GstElement *element = GST_ELEMENT (webrtc);
|
||||||
|
GArray *reserved_pts = g_array_new (FALSE, FALSE, sizeof (guint));
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (webrtc);
|
||||||
|
g_list_foreach (element->sinkpads, (GFunc) gather_pad_pt, reserved_pts);
|
||||||
|
g_list_foreach (webrtc->priv->pending_pads, (GFunc) gather_pad_pt,
|
||||||
|
reserved_pts);
|
||||||
|
GST_OBJECT_UNLOCK (webrtc);
|
||||||
|
|
||||||
|
return reserved_pts;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: use the options argument */
|
/* TODO: use the options argument */
|
||||||
static GstSDPMessage *
|
static GstSDPMessage *
|
||||||
_create_offer_task (GstWebRTCBin * webrtc, const GstStructure * options)
|
_create_offer_task (GstWebRTCBin * webrtc, const GstStructure * options)
|
||||||
|
@ -2093,6 +2121,7 @@ _create_offer_task (GstWebRTCBin * webrtc, const GstStructure * options)
|
||||||
GString *bundled_mids = NULL;
|
GString *bundled_mids = NULL;
|
||||||
gchar *bundle_ufrag = NULL;
|
gchar *bundle_ufrag = NULL;
|
||||||
gchar *bundle_pwd = NULL;
|
gchar *bundle_pwd = NULL;
|
||||||
|
GArray *reserved_pts = NULL;
|
||||||
|
|
||||||
gst_sdp_message_new (&ret);
|
gst_sdp_message_new (&ret);
|
||||||
|
|
||||||
|
@ -2115,6 +2144,7 @@ _create_offer_task (GstWebRTCBin * webrtc, const GstStructure * options)
|
||||||
|
|
||||||
if (webrtc->bundle_policy != GST_WEBRTC_BUNDLE_POLICY_NONE) {
|
if (webrtc->bundle_policy != GST_WEBRTC_BUNDLE_POLICY_NONE) {
|
||||||
_generate_ice_credentials (&bundle_ufrag, &bundle_pwd);
|
_generate_ice_credentials (&bundle_ufrag, &bundle_pwd);
|
||||||
|
reserved_pts = gather_reserved_pts (webrtc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* for each rtp transceiver */
|
/* for each rtp transceiver */
|
||||||
|
@ -2136,6 +2166,7 @@ _create_offer_task (GstWebRTCBin * webrtc, const GstStructure * options)
|
||||||
|
|
||||||
/* FIXME: only needed when restarting ICE */
|
/* FIXME: only needed when restarting ICE */
|
||||||
if (webrtc->bundle_policy == GST_WEBRTC_BUNDLE_POLICY_NONE) {
|
if (webrtc->bundle_policy == GST_WEBRTC_BUNDLE_POLICY_NONE) {
|
||||||
|
reserved_pts = g_array_new (FALSE, FALSE, sizeof (guint));
|
||||||
_generate_ice_credentials (&ufrag, &pwd);
|
_generate_ice_credentials (&ufrag, &pwd);
|
||||||
} else {
|
} else {
|
||||||
ufrag = g_strdup (bundle_ufrag);
|
ufrag = g_strdup (bundle_ufrag);
|
||||||
|
@ -2147,8 +2178,11 @@ _create_offer_task (GstWebRTCBin * webrtc, const GstStructure * options)
|
||||||
g_free (ufrag);
|
g_free (ufrag);
|
||||||
g_free (pwd);
|
g_free (pwd);
|
||||||
|
|
||||||
|
g_assert (reserved_pts != NULL);
|
||||||
|
|
||||||
if (sdp_media_from_transceiver (webrtc, &media, trans,
|
if (sdp_media_from_transceiver (webrtc, &media, trans,
|
||||||
GST_WEBRTC_SDP_TYPE_OFFER, i, bundled_mids, 0, bundle_only)) {
|
GST_WEBRTC_SDP_TYPE_OFFER, i, bundled_mids, 0, bundle_only,
|
||||||
|
reserved_pts)) {
|
||||||
if (bundled_mids) {
|
if (bundled_mids) {
|
||||||
const gchar *mid = gst_sdp_media_get_attribute_val (&media, "mid");
|
const gchar *mid = gst_sdp_media_get_attribute_val (&media, "mid");
|
||||||
|
|
||||||
|
@ -2159,6 +2193,14 @@ _create_offer_task (GstWebRTCBin * webrtc, const GstStructure * options)
|
||||||
} else {
|
} else {
|
||||||
gst_sdp_media_uninit (&media);
|
gst_sdp_media_uninit (&media);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (webrtc->bundle_policy == GST_WEBRTC_BUNDLE_POLICY_NONE) {
|
||||||
|
g_array_free (reserved_pts, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (webrtc->bundle_policy != GST_WEBRTC_BUNDLE_POLICY_NONE) {
|
||||||
|
g_array_free (reserved_pts, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add data channel support */
|
/* add data channel support */
|
||||||
|
|
Loading…
Reference in a new issue