From a02134cd06a98240ce324e5efcf6a2223e7173a0 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 17 Dec 2020 15:04:35 -0500 Subject: [PATCH] TT#92250 split up __accept_transcode_codecs Change-Id: I52b602961c2e60f5e73576bcea8e9af47528111a --- daemon/codec.c | 185 ++++++++++++++++++++++++++----------------------- 1 file changed, 99 insertions(+), 86 deletions(-) diff --git a/daemon/codec.c b/daemon/codec.c index 3491fa70f..a7dae5e6e 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -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);