Browse Source

TT#92250 split up __accept_transcode_codecs

Change-Id: I52b602961c2e60f5e73576bcea8e9af47528111a
pull/1164/head
Richard Fuchs 5 years ago
parent
commit
a02134cd06
1 changed files with 99 additions and 86 deletions
  1. +99
    -86
      daemon/codec.c

+ 99
- 86
daemon/codec.c View File

@ -655,101 +655,114 @@ static int __check_receiver_codecs(struct call_media *receiver, struct call_medi
return ret;
}
static void __accept_transcode_codecs(struct call_media *receiver, struct call_media *sink,
const struct sdp_ng_flags *flags, int accept_only_tc)
static void __accept_pt(struct call_media *receiver, struct call_media *sink, int payload_type,
int fallback_type, int accept_only_tc, GList **insert_pos)
{
// if the other side is transcoding, we need to accept codecs that were
// originally offered (recv->send) if we support them, even if the
// response (sink->send) doesn't include them
GList *insert_pos = NULL;
for (GList *l = receiver->codecs_prefs_send.head; l; l = l->next) {
struct rtp_payload_type *pt = l->data;
ensure_codec_def(pt, receiver);
if (!pt->codec_def)
continue;
if (accept_only_tc && !pt->for_transcoding)
continue;
//ilog(LOG_DEBUG, "XXXXXXXXXXX accept codec " STR_FORMAT " flag %i", STR_FMT(&pt->encoding_with_params), pt->for_transcoding);
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
// this entry.
if (!insert_pos)
insert_pos = receiver->codecs_prefs_recv.head;
while (insert_pos) {
if (!insert_pos->next)
break; // end of list - we insert everything after
struct rtp_payload_type *test_pt = insert_pos->data;
if (test_pt->payload_type == pt->payload_type)
break;
insert_pos = insert_pos->next;
}
continue;
}
struct rtp_payload_type *pt = g_hash_table_lookup(receiver->codecs_send, &payload_type);
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, sink, existing_pt);
if (new_pt < 0) {
ilogs(codec, 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;
}
ilogs(codec, 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);
// fallback PT in case the codec handler is a dummy or a passthrough
// or some other internal problem
if (!pt && fallback_type != -1)
pt = g_hash_table_lookup(receiver->codecs_send, &fallback_type);
if (!pt)
return;
ensure_codec_def(pt, receiver);
if (!pt->codec_def)
return;
if (accept_only_tc && !pt->for_transcoding)
return;
//ilog(LOG_DEBUG, "XXXXXXXXXXX accept codec " STR_FORMAT " flag %i", STR_FMT(&pt->encoding_with_params), pt->for_transcoding);
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
// this entry.
if (!*insert_pos)
*insert_pos = receiver->codecs_prefs_recv.head;
while (*insert_pos) {
if (!(*insert_pos)->next)
break; // end of list - we insert everything after
struct rtp_payload_type *test_pt = (*insert_pos)->data;
if (test_pt->payload_type == pt->payload_type)
break;
*insert_pos = (*insert_pos)->next;
}
return;
}
//ilog(LOG_DEBUG, "XXXXXXXXXXXXX offered codec %i", pt->for_transcoding);
ilogs(codec, LOG_DEBUG, "Accepting offered codec " STR_FORMAT " due to transcoding",
STR_FMT(&pt->encoding_with_params));
MEDIA_SET(receiver, TRANSCODE);
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, sink, existing_pt);
if (new_pt < 0) {
ilogs(codec, 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));
return;
}
ilogs(codec, 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, "XXXXXXXXXXXXX offered codec %i", pt->for_transcoding);
ilogs(codec, LOG_DEBUG, "Accepting offered codec " STR_FORMAT " due to transcoding",
STR_FMT(&pt->encoding_with_params));
MEDIA_SET(receiver, TRANSCODE);
// we need a new pt entry
pt = __rtp_payload_type_copy(pt);
pt->for_transcoding = 1;
codec_touched(pt, receiver);
// this somewhat duplicates __rtp_payload_type_add_recv
g_hash_table_insert(receiver->codecs_recv, &pt->payload_type, pt);
__rtp_payload_type_add_name(receiver->codec_names_recv, pt);
// we need a new pt entry
pt = __rtp_payload_type_copy(pt);
pt->for_transcoding = 1;
codec_touched(pt, receiver);
// this somewhat duplicates __rtp_payload_type_add_recv
g_hash_table_insert(receiver->codecs_recv, &pt->payload_type, pt);
__rtp_payload_type_add_name(receiver->codec_names_recv, pt);
// keep supplemental codecs last
ensure_codec_def(pt, receiver);
if (!pt->codec_def || !pt->codec_def->supplemental) {
while (insert_pos) {
struct rtp_payload_type *ipt = insert_pos->data;
ensure_codec_def(ipt, receiver);
if (!ipt->codec_def || !ipt->codec_def->supplemental)
break;
insert_pos = insert_pos->prev;
}
}
else {
if (!insert_pos)
insert_pos = receiver->codecs_prefs_recv.tail;
// keep supplemental codecs last
ensure_codec_def(pt, receiver);
if (!pt->codec_def || !pt->codec_def->supplemental) {
while (*insert_pos) {
struct rtp_payload_type *ipt = (*insert_pos)->data;
ensure_codec_def(ipt, receiver);
if (!ipt->codec_def || !ipt->codec_def->supplemental)
break;
*insert_pos = (*insert_pos)->prev;
}
}
else {
if (!*insert_pos)
*insert_pos = receiver->codecs_prefs_recv.tail;
}
if (!insert_pos) {
g_queue_push_head(&receiver->codecs_prefs_recv, pt);
insert_pos = receiver->codecs_prefs_recv.head;
}
else {
g_queue_insert_after(&receiver->codecs_prefs_recv, insert_pos, pt);
insert_pos = insert_pos->next;
}
if (!*insert_pos) {
g_queue_push_head(&receiver->codecs_prefs_recv, pt);
*insert_pos = receiver->codecs_prefs_recv.head;
}
else {
g_queue_insert_after(&receiver->codecs_prefs_recv, *insert_pos, pt);
*insert_pos = (*insert_pos)->next;
}
}
static void __accept_transcode_codecs(struct call_media *receiver, struct call_media *sink,
const struct sdp_ng_flags *flags, int accept_only_tc)
{
// if the other side is transcoding, we need to accept codecs that were
// originally offered (recv->send) if we support them, even if the
// response (sink->send) doesn't include them
GList *insert_pos = NULL;
for (GList *l = receiver->codecs_prefs_send.head; l; l = l->next) {
struct rtp_payload_type *pt = l->data;
__accept_pt(receiver, sink, pt->payload_type, -1, accept_only_tc, &insert_pos);
}
__single_codec(receiver, flags);


Loading…
Cancel
Save