webrtcbin: Improve SDP intersection for Opus

Remove optional sprop-stereo and sprop-maxcapture fields from Opus
remote offer caps before intersecting with local codec preferences.

According to https://datatracker.ietf.org/doc/html/rfc7587#section-7.1
those fields are sender-only informative, and don't affect
interoperability.

Fixes cases where the webrtc media will end up receive-only if the
local side wants to send stereo but the remote is sending mono, or
vice versa.

There may be other fields in other codecs, so the implementation
anticipates needing to add further fields and codecs in the future.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5993>
This commit is contained in:
Jan Schmidt 2024-01-25 22:25:19 +11:00 committed by GStreamer Marge Bot
parent 9afab6107f
commit ef71c1319a
3 changed files with 29 additions and 0 deletions

View file

@ -4542,6 +4542,8 @@ _create_answer_task (GstWebRTCBin * webrtc, const GstStructure * options,
gst_sdp_media_set_proto (media, "UDP/TLS/RTP/SAVPF"); gst_sdp_media_set_proto (media, "UDP/TLS/RTP/SAVPF");
offer_caps = _rtp_caps_from_media (offer_media); offer_caps = _rtp_caps_from_media (offer_media);
_remove_optional_offer_fields (offer_caps);
if (last_answer && i < gst_sdp_message_medias_len (last_answer) if (last_answer && i < gst_sdp_message_medias_len (last_answer)
&& (rtp_trans = _find_transceiver_for_mid (webrtc, mid))) { && (rtp_trans = _find_transceiver_for_mid (webrtc, mid))) {
const GstSDPMedia *last_media = const GstSDPMedia *last_media =

View file

@ -170,6 +170,31 @@ _g_checksum_to_webrtc_string (GChecksumType type)
} }
} }
void
_remove_optional_offer_fields (GstCaps * offer_caps)
{
int i;
for (i = 0; i < gst_caps_get_size (offer_caps); i++) {
GstStructure *s = gst_caps_get_structure (offer_caps, i);
const gchar *mtype = gst_structure_get_string (s, "media");
const gchar *encoding_name = gst_structure_get_string (s, "encoding-name");
if (mtype == NULL || encoding_name == NULL) {
continue;
}
/* Special cases for different codecs - sender-only fields
* that we don't need to care about for SDP intersection */
if (g_str_equal (mtype, "audio")) {
if (g_str_equal (encoding_name, "OPUS")) {
gst_structure_remove_fields (s, "sprop-stereo", "sprop-maxcapturerate",
NULL);
}
}
}
}
GstCaps * GstCaps *
_rtp_caps_from_media (const GstSDPMedia * media) _rtp_caps_from_media (const GstSDPMedia * media)
{ {

View file

@ -63,6 +63,8 @@ const gchar * _enum_value_to_string (GType type, guint val
G_GNUC_INTERNAL G_GNUC_INTERNAL
const gchar * _g_checksum_to_webrtc_string (GChecksumType type); const gchar * _g_checksum_to_webrtc_string (GChecksumType type);
G_GNUC_INTERNAL G_GNUC_INTERNAL
void _remove_optional_offer_fields (GstCaps *offer_caps);
G_GNUC_INTERNAL
GstCaps * _rtp_caps_from_media (const GstSDPMedia * media); GstCaps * _rtp_caps_from_media (const GstSDPMedia * media);
G_GNUC_INTERNAL G_GNUC_INTERNAL
GstWebRTCKind webrtc_kind_from_caps (const GstCaps * caps); GstWebRTCKind webrtc_kind_from_caps (const GstCaps * caps);