MT#55283 add codec_store_merge() and logic

During an offer, we update the codecs from the given list not only on
the side of the offerer, but also on the answerer's side, in order to
perform the codec answer routine during the answer phase. While doing
this, we empty out the existing list of codecs (on both sides) and
repopulate it fresh from the given list.

This can cause problems during a reverse re-invite, when the list of
codecs on the answerer's side already contained the codecs that had been
offered before. When setting up the new re-invite offer, we want to
retain codecs (and their payload types and format parameters) that were
already in place, instead of recreating a new list from scratch.

Improve this by adding a `merge_cs` option to the populating functions,
which points back to the stream_params codec_store. Codecs that would
have been removed from the codec_store during the repopulation are then
moved back into the stream_params codec_store instead. This then allows
the functions adding new codecs to the list (offer/transcode) to
reference these codecs that were previously in place, and so they can be
added back with the same options as they had existed before, instead of
recreating them from scratch.

Change-Id: I53e7ab10e9144a308a5c36be5ebfddd73c212f06
pull/1772/head
Richard Fuchs 2 years ago
parent 83140f60df
commit a1d8bf2590

@ -2424,14 +2424,16 @@ static void codecs_offer(struct call_media *media, struct call_media *other_medi
if (update_answerer) {
// update/create answer/receiver side
ilogs(codec, LOG_DEBUG, "Updating codecs for answerer " STR_FORMAT " #%u",
ilogs(codec, LOG_DEBUG, "Updating offer codecs for answerer " STR_FORMAT " #%u",
STR_FMT(&media->monologue->tag),
media->index);
if (flags && flags->reuse_codec)
codec_store_populate_reuse(&media->codecs, &sp->codecs);
codec_store_populate_reuse(&media->codecs, &sp->codecs,
.merge_cs = &sp->codecs);
else
codec_store_populate(&media->codecs, &sp->codecs,
.allow_asymmetric = !!(flags && flags->allow_asymmetric_codecs));
.allow_asymmetric = !!(flags && flags->allow_asymmetric_codecs),
.merge_cs = &sp->codecs);
}
if (flags) {
codec_store_strip(&media->codecs, &flags->codec_strip, flags->codec_except);

@ -4987,16 +4987,17 @@ void __codec_store_populate_reuse(struct codec_store *dst, struct codec_store *s
pt->payload_type);
}
}
if(dst->codec_prefs.head){
for (GList *l = dst->codec_prefs.head; l;) {
struct rtp_payload_type *pt = l->data;
struct rtp_payload_type *orig_pt = g_hash_table_lookup(src->codecs,
GINT_TO_POINTER(pt->payload_type));
if(!orig_pt){
l = __codec_store_delete_link(l, dst);
}else{
l = l->next;
}
for (GList *l = dst->codec_prefs.head; l;) {
struct rtp_payload_type *pt = l->data;
struct rtp_payload_type *orig_pt = g_hash_table_lookup(src->codecs,
GINT_TO_POINTER(pt->payload_type));
if(!orig_pt){
if (a.merge_cs)
codec_store_add_raw_link(src, rtp_payload_type_dup(pt),
src->codec_prefs.head);
l = __codec_store_delete_link(l, dst);
}else{
l = l->next;
}
}
}
@ -5011,6 +5012,24 @@ void codec_store_check_empty(struct codec_store *dst, struct codec_store *src) {
codec_store_populate(dst, src);
}
static void codec_store_merge(struct codec_store *dst, struct codec_store *src) {
while (src->codec_prefs.length) {
struct rtp_payload_type *pt = g_queue_pop_tail(&src->codec_prefs);
// src codecs take preference over existing entries in dst: if there's
// a collision in payload types, remove the existing entry in dst,
// then replace with the entry from src
struct rtp_payload_type *old_pt = g_hash_table_lookup(dst->codecs,
GINT_TO_POINTER(pt->payload_type));
if (old_pt)
__codec_store_delete_link(old_pt->prefs_link, dst);
codec_store_add_raw_link(dst, pt, dst->codec_prefs.head);
}
codec_store_cleanup(src);
}
void __codec_store_populate(struct codec_store *dst, struct codec_store *src, struct codec_store_args a) {
// start fresh
struct codec_store orig_dst;
@ -5059,7 +5078,10 @@ void __codec_store_populate(struct codec_store *dst, struct codec_store *src, st
codec_store_add_end(dst, pt);
}
codec_store_cleanup(&orig_dst);
if (a.merge_cs)
codec_store_merge(a.merge_cs, &orig_dst);
else
codec_store_cleanup(&orig_dst);
}
void codec_store_strip(struct codec_store *cs, GQueue *strip, GHashTable *except) {

@ -115,6 +115,7 @@ struct codec_store_args {
GHashTable *codec_set;
bool answer_only;
bool allow_asymmetric;
struct codec_store *merge_cs;
};
__attribute__((nonnull(1)))

@ -326,14 +326,13 @@ s=-
t=0 0
a=extmap-allow-mixed
a=msid-semantic: WMS 4d091157-8680-47a2-b124-36b52fefea19
m=audio PORT RTP/AVP 0 8 9 96
m=audio PORT RTP/AVP 126 0 8 9
c=IN IP4 203.0.113.1
a=mid:1
a=rtpmap:126 telephone-event/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:9 G722/8000
a=rtpmap:96 telephone-event/8000
a=fmtp:96 0-15
a=ssrc:572293880 cname:pHBBuw7Qa5BaQ36a
a=msid:4d091157-8680-47a2-b124-36b52fefea19 ed2eaf3a-926c-4c1a-a315-e02458e05292
a=sendrecv
@ -380,14 +379,13 @@ s=-
t=0 0
a=extmap-allow-mixed
a=msid-semantic: WMS 4d091157-8680-47a2-b124-36b52fefea19
m=audio PORT RTP/AVP 0 8 9 96
m=audio PORT RTP/AVP 126 0 8 9
c=IN IP4 203.0.113.1
a=mid:1
a=rtpmap:126 telephone-event/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:9 G722/8000
a=rtpmap:96 telephone-event/8000
a=fmtp:96 0-15
a=ssrc:572293880 cname:pHBBuw7Qa5BaQ36a
a=msid:4d091157-8680-47a2-b124-36b52fefea19 ed2eaf3a-926c-4c1a-a315-e02458e05292
a=sendrecv
@ -10200,6 +10198,7 @@ m=audio PORT RTP/AVP 0 9 101
a=maxptime:20
a=rtpmap:0 PCMU/8000
a=rtpmap:9 G722/8000
a=fmtp:9 bitrate=64
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=sendrecv

Loading…
Cancel
Save