commit 17725bcc9caabe33769cf2f8763a4b7c0f4e575b Author: Alex Hermann Date: Fri Apr 15 12:26:01 2022 +0200 rtp_engine: Clear all "old" payload types when receiving a re-INVITE When receiving a re-invite, Asterisk would effectively merge the newly negotiated codecs into the "current" codecs list. This would overwrite existing payload types, but would never remove the deprectated ones. The result is that if a codec moved to a higher PT, it would never be used by Asterisk, as it keeps using the lowest PT ever seen for the codec, even if this wasn't in the latest negotiation. With this change, all payload types that are not in the new negotiation will be removed from the final list of allowed PT's/codecs. This fixes https://issues.asterisk.org/jira/browse/ASTERISK-27056 diff --git a/main/rtp_engine.c b/main/rtp_engine.c index f51e55eb6a..23bdc35127 100644 --- a/main/rtp_engine.c +++ b/main/rtp_engine.c @@ -734,16 +734,19 @@ void ast_rtp_codecs_payloads_copy(struct ast_rtp_codecs *src, struct ast_rtp_cod for (i = 0; i < AST_VECTOR_SIZE(&src->payloads); i++) { struct ast_rtp_payload_type *type; + if (i < AST_VECTOR_SIZE(&dest->payloads)) { + ao2_t_cleanup(AST_VECTOR_GET(&dest->payloads, i), "cleaning up payload type about to be replaced"); + } + type = AST_VECTOR_GET(&src->payloads, i); if (!type) { + AST_VECTOR_REPLACE(&dest->payloads, i, NULL); continue; } - if (i < AST_VECTOR_SIZE(&dest->payloads)) { - ao2_t_cleanup(AST_VECTOR_GET(&dest->payloads, i), "cleaning up vector element about to be replaced"); - } + ast_debug(2, "Copying payload %d (%p) from %p to %p\n", i, type, src, dest); - ao2_bump(type); + ao2_t_bump(type, "copying payload type"); if (AST_VECTOR_REPLACE(&dest->payloads, i, type)) { ao2_cleanup(type); } else if (instance && instance->engine && instance->engine->payload_set) { @@ -752,6 +755,16 @@ void ast_rtp_codecs_payloads_copy(struct ast_rtp_codecs *src, struct ast_rtp_cod ao2_unlock(instance); } } + // Clear remaining payloads in dest + for (; i < AST_VECTOR_SIZE(&dest->payloads); i++) { + struct ast_rtp_payload_type *type; + + type = AST_VECTOR_GET(&dest->payloads, i); + if (type) { + ao2_t_ref(type, -1, "cleaning up obsoleted payload type"); + AST_VECTOR_REPLACE(&dest->payloads, i, NULL); + } + } dest->framing = src->framing; ast_rwlock_unlock(&src->codecs_lock); ast_rwlock_unlock(&dest->codecs_lock);