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/5999>
This commit is contained in:
Jan Schmidt 2024-01-25 22:25:19 +11:00 committed by Tim-Philipp Müller
parent 600e105e64
commit 3593bf7b99
3 changed files with 29 additions and 0 deletions

View file

@ -4476,6 +4476,8 @@ _create_answer_task (GstWebRTCBin * webrtc, const GstStructure * options,
gst_sdp_media_set_proto (media, "UDP/TLS/RTP/SAVPF");
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)
&& (rtp_trans = _find_transceiver_for_mid (webrtc, mid))) {
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 *
_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
const gchar * _g_checksum_to_webrtc_string (GChecksumType type);
G_GNUC_INTERNAL
void _remove_optional_offer_fields (GstCaps *offer_caps);
G_GNUC_INTERNAL
GstCaps * _rtp_caps_from_media (const GstSDPMedia * media);
G_GNUC_INTERNAL
GstWebRTCKind webrtc_kind_from_caps (const GstCaps * caps);