|
|
|
@ -430,6 +430,21 @@ static int __dtmf_payload_type(GHashTable *dtmf_sinks, struct rtp_payload_type * |
|
|
|
return dtmf_payload_type; |
|
|
|
} |
|
|
|
|
|
|
|
static int __unused_pt_number(struct call_media *media, int num) { |
|
|
|
if (num < 0) |
|
|
|
num = 96; // default first dynamic payload type number |
|
|
|
while (1) { |
|
|
|
if (!g_hash_table_lookup(media->codecs_recv, &num)) |
|
|
|
break; // OK |
|
|
|
num++; |
|
|
|
if (num < 96) // if an RFC type was taken already |
|
|
|
num = 96; |
|
|
|
else if (num >= 128) |
|
|
|
return -1; |
|
|
|
} |
|
|
|
return num; |
|
|
|
} |
|
|
|
|
|
|
|
static void __accept_transcode_codecs(struct call_media *receiver, struct call_media *sink) { |
|
|
|
// if the other side is transcoding, we need to accept codecs that were |
|
|
|
// originally offered (recv->send) if we support them, even if the |
|
|
|
@ -440,7 +455,9 @@ static void __accept_transcode_codecs(struct call_media *receiver, struct call_m |
|
|
|
ensure_codec_def(pt, receiver); |
|
|
|
if (!pt->codec_def) |
|
|
|
continue; |
|
|
|
if (g_hash_table_lookup(receiver->codecs_recv, &pt->payload_type)) { |
|
|
|
struct rtp_payload_type *existing_pt |
|
|
|
= g_hash_table_lookup(receiver->codecs_recv, &pt->payload_type); |
|
|
|
if (existing_pt && !rtp_payload_type_cmp_nf(existing_pt, pt)) { |
|
|
|
// already present. |
|
|
|
// to keep the order intact, we seek the list for the position |
|
|
|
// of this codec entry. all newly added codecs must come after |
|
|
|
@ -458,6 +475,28 @@ static void __accept_transcode_codecs(struct call_media *receiver, struct call_m |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
if (existing_pt) { |
|
|
|
// PT collision. We must renumber one of the entries. `pt` is taken |
|
|
|
// from the send list, so the PT should remain the same. Renumber |
|
|
|
// the existing entry. |
|
|
|
int new_pt = __unused_pt_number(receiver, existing_pt->payload_type); |
|
|
|
if (new_pt < 0) { |
|
|
|
ilog(LOG_WARN, "Ran out of RTP payload type numbers while accepting '" |
|
|
|
STR_FORMAT "' due to '" STR_FORMAT "'", |
|
|
|
STR_FMT(&pt->encoding_with_params), |
|
|
|
STR_FMT(&existing_pt->encoding_with_params)); |
|
|
|
continue; |
|
|
|
} |
|
|
|
ilog(LOG_DEBUG, "Renumbering '" STR_FORMAT "' from PT %i to %i due to '" STR_FORMAT "'", |
|
|
|
STR_FMT(&existing_pt->encoding_with_params), |
|
|
|
existing_pt->payload_type, |
|
|
|
new_pt, |
|
|
|
STR_FMT(&pt->encoding_with_params)); |
|
|
|
g_hash_table_steal(receiver->codecs_recv, &existing_pt->payload_type); |
|
|
|
existing_pt->payload_type = new_pt; |
|
|
|
g_hash_table_insert(receiver->codecs_recv, &existing_pt->payload_type, existing_pt); |
|
|
|
} |
|
|
|
|
|
|
|
ilog(LOG_DEBUG, "Accepting offered codec " STR_FORMAT " due to transcoding", |
|
|
|
STR_FMT(&pt->encoding_with_params)); |
|
|
|
MEDIA_SET(receiver, TRANSCODE); |
|
|
|
@ -1996,23 +2035,15 @@ static struct rtp_payload_type *codec_add_payload_type(const str *codec, struct |
|
|
|
if (pt == (void *) 0x1) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
// find an unused payload type number |
|
|
|
if (pt->payload_type < 0) |
|
|
|
pt->payload_type = 96; // default first dynamic payload type number |
|
|
|
while (1) { |
|
|
|
if (!g_hash_table_lookup(media->codecs_recv, &pt->payload_type)) |
|
|
|
break; // OK |
|
|
|
pt->payload_type++; |
|
|
|
if (pt->payload_type < 96) // if an RFC type was taken already |
|
|
|
pt->payload_type = 96; |
|
|
|
else if (pt->payload_type >= 128) { |
|
|
|
ilog(LOG_WARN, "Ran out of RTP payload type numbers while adding codec '" |
|
|
|
STR_FORMAT "' for transcoding", |
|
|
|
STR_FMT(&pt->encoding_with_params)); |
|
|
|
payload_type_free(pt); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
pt->payload_type = __unused_pt_number(media, pt->payload_type); |
|
|
|
if (pt->payload_type < 0) { |
|
|
|
ilog(LOG_WARN, "Ran out of RTP payload type numbers while adding codec '" |
|
|
|
STR_FORMAT "' for transcoding", |
|
|
|
STR_FMT(&pt->encoding_with_params)); |
|
|
|
payload_type_free(pt); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
return pt; |
|
|
|
} |
|
|
|
|
|
|
|
|