From 6ab8dc1dea40acea74303f34c257b68637a77674 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sun, 18 Feb 2024 18:30:49 +0100 Subject: [PATCH] SDP: Fix interpretation of number of channels within rtpmap The standard says (RFC 4566 / 8866): "For audio streams, encoding-params indicates the number of audio channels. This parameter is OPTIONAL and may be omitted if the number of channels is one, provided that no additional parameters are needed." This means that the number of channels is 1, if not specified within rtpmap. It does not state that the codec's default value shall be used, nor static payload definition. Addionally the encoder always defines the number of channel. As the encoding-params MAY be omitted, they are added to the rtpmap line, even if the number of channels is 1. --- src/sdp.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/sdp.c b/src/sdp.c index 614b7e6..5420bfd 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -132,10 +132,7 @@ char *osmo_cc_session_gensdp(osmo_cc_session_t *session, int accepted_only) osmo_cc_session_for_each_codec(media->codec_list, codec) { if (accepted_only && !codec->accepted) continue; - strncat_printf(sdp, "a=rtpmap:%u %s/%d", codec->payload_type_local, codec->payload_name, codec->payload_rate); - if (codec->payload_channels >= 2) - strncat_printf(sdp, "/%d", codec->payload_channels); - strncat_printf(sdp, "\r\n"); + strncat_printf(sdp, "a=rtpmap:%u %s/%d/%d\r\n", codec->payload_type_local, codec->payload_name, codec->payload_rate, codec->payload_channels); } if (individual_send_receive) { if (media->send && !media->receive) @@ -499,32 +496,34 @@ struct osmo_cc_session *osmo_cc_session_parsesdp(osmo_cc_session_config_t *conf, break; } LOGP(DLCC, LOGL_DEBUG, " -> (rtpmap) payload type = %d\n", codec->payload_type_remote); - if (!(word = wordsep(&next_word))) - goto rtpmap_done; + if (!(word = wordsep(&next_word))) { +rtpmap_broken: + LOGP(DLCC, LOGL_NOTICE, "Broken 'rtpmap' definition in SDP line %d = '%s' Skipping codec!\n", line_no, line); + osmo_cc_free_codec(codec); + break; + } if ((p = strchr(word, '/'))) *p++ = '\0'; free((char *)codec->payload_name); // in case it is already set above codec->payload_name = strdup(word); LOGP(DLCC, LOGL_DEBUG, " -> (rtpmap) payload name = %s\n", codec->payload_name); if (!(word = p)) - goto rtpmap_done; + goto rtpmap_broken; if ((p = strchr(word, '/'))) *p++ = '\0'; codec->payload_rate = atoi(word); LOGP(DLCC, LOGL_DEBUG, " -> (rtpmap) payload rate = %d\n", codec->payload_rate); if (!(word = p)) { - /* if no channel is given and no default was specified, we must set 1 channel */ - if (!codec->payload_channels) - codec->payload_channels = 1; - goto rtpmap_done; + /* For audio streams, encoding-params indicates the number of audio channels. + * This parameter is OPTIONAL and may be omitted if the number of channels is + * one, provided that no additional parameters are needed. */ + codec->payload_channels = 1; + LOGP(DLCC, LOGL_DEBUG, " -> (rtpmap) payload channels = %d (default)\n", codec->payload_channels); + break; } codec->payload_channels = atoi(word); LOGP(DLCC, LOGL_DEBUG, " -> (rtpmap) payload channels = %d\n", codec->payload_channels); - rtpmap_done: - if (!codec->payload_name || !codec->payload_rate || !codec->payload_channels) { - LOGP(DLCC, LOGL_NOTICE, "Broken 'rtpmap' definition in SDP line %d = '%s' Skipping codec!\n", line_no, line); - osmo_cc_free_codec(codec); - } + break; } break; }