From 4b1c49d70ccf6d2fd2ee7d6785e3b9ebcc42d3cc Mon Sep 17 00:00:00 2001 From: Lorenzo Miniero Date: Fri, 28 Feb 2020 18:18:24 +0100 Subject: [PATCH] Remove duplicated codecs when answering SIP call (#1966) --- plugins/janus_sip.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/plugins/janus_sip.c b/plugins/janus_sip.c index 880fd519e2..455a2ed667 100644 --- a/plugins/janus_sip.c +++ b/plugins/janus_sip.c @@ -5512,6 +5512,8 @@ void janus_sip_sdp_process(janus_sip_session *session, janus_sdp *sdp, gboolean char *janus_sip_sdp_manipulate(janus_sip_session *session, janus_sdp *sdp, gboolean answer) { if(!session || !session->stack || !sdp) return NULL; + GHashTable *codecs = NULL; + GList *pts_to_remove = NULL; /* Start replacing stuff */ JANUS_LOG(LOG_VERB, "Setting protocol to %s\n", session->media.require_srtp ? "RTP/SAVP" : "RTP/AVP"); if(sdp->c_addr) { @@ -5561,8 +5563,45 @@ char *janus_sip_sdp_manipulate(janus_sip_session *session, janus_sdp *sdp, gbool } } } + /* If this is an answer, get rid of multiple versions of the same + * codec as well (e.g., video profiles), as that confuses the hell + * out of SOATAG_RTP_SELECT(SOA_RTP_SELECT_COMMON) in nua_respond() */ + if(answer) { + if(codecs == NULL) + codecs = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL); + /* Check all rtpmap attributes */ + int pt = -1; + char codec[50]; + GList *ma = m->attributes; + while(ma) { + janus_sdp_attribute *a = (janus_sdp_attribute *)ma->data; + if(a->name != NULL && a->value != NULL && !strcasecmp(a->name, "rtpmap")) { + if(sscanf(a->value, "%3d %s", &pt, codec) == 2) { + if(g_hash_table_lookup(codecs, codec) != NULL) { + /* We already have a version of this codec, remove the payload type */ + pts_to_remove = g_list_append(pts_to_remove, GINT_TO_POINTER(pt)); + JANUS_LOG(LOG_HUGE, "Removing %d (%s)\n", pt, codec); + } else { + /* Keep track of this codec */ + g_hash_table_insert(codecs, g_strdup(codec), GINT_TO_POINTER(pt)); + } + } + } + ma = ma->next; + } + } temp = temp->next; } + /* If we need to remove some payload types from the SDP, do it now */ + if(pts_to_remove != NULL) { + GList *temp = pts_to_remove; + while(temp) { + int pt = GPOINTER_TO_INT(temp->data); + janus_sdp_remove_payload_type(sdp, pt); + temp = temp->next; + } + g_list_free(pts_to_remove); + } /* Generate a SDP string out of our changes */ return janus_sdp_write(sdp); }