From 653b09ca9345e89c1a6d1030de96efb294ecd862 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 7 Oct 2020 16:49:36 -0400 Subject: [PATCH] TT#92250 add `single codec` flag Change-Id: I7c84e1f906fec93ed624d2fb4a4d9e9bfc9b4109 --- README.md | 6 +++ daemon/call_interfaces.c | 3 ++ daemon/codec.c | 19 +++++++ include/call_interfaces.h | 1 + t/auto-daemon-tests.pl | 102 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 131 insertions(+) diff --git a/README.md b/README.md index c92088765..7a40be481 100644 --- a/README.md +++ b/README.md @@ -774,6 +774,12 @@ Optionally included keys are: PCMA. With this flag however, *rtpengine* honours the single accepted codec from the answer and so is able to eliminate PCMA from its own answer as it's not needed. + - `single codec` + + Using this flag in an `answer` message will leave only the first listed codec in place + and will remove all others from the list. Useful for RTP clients which get confused if + more than one codec is listed in an answer. + - `all` Only relevant to the `unblock media` message. Instructs *rtpengine* to remove not only a diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 55e781839..c0fe2f9f5 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -816,6 +816,9 @@ static void call_ng_flags_flags(struct sdp_ng_flags *out, str *s, void *dummy) { case CSH_LOOKUP("symmetric-codecs"): out->symmetric_codecs = 1; break; + case CSH_LOOKUP("single-codec"): + out->single_codec = 1; + break; case CSH_LOOKUP("inject-DTMF"): out->inject_dtmf = 1; break; diff --git a/daemon/codec.c b/daemon/codec.c index 461635605..1f6deec05 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -2572,6 +2572,25 @@ void codec_rtp_payload_types(struct call_media *media, struct call_media *other_ } } + if (flags->opmode == OP_ANSWER && flags->single_codec) { + int have_codec = 0; + for (GList *l = media->codecs_prefs_recv.head; l;) { + struct rtp_payload_type *pt = l->data; + ensure_codec_def(pt, media); + if (pt->codec_def && pt->codec_def->supplemental) { + // leave these alone + l = l->next; + continue; + } + if (!have_codec) { + have_codec = 1; + l = l->next; + continue; + } + l = __delete_receiver_codec(media, l); + } + } + #ifdef WITH_TRANSCODING // add transcode codecs for (GList *l = flags->codec_transcode.head; l; l = l->next) { diff --git a/include/call_interfaces.h b/include/call_interfaces.h index 2673d7a65..1c56168b4 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -80,6 +80,7 @@ struct sdp_ng_flags { always_transcode:1, asymmetric_codecs:1, symmetric_codecs:1, + single_codec:1, inject_dtmf:1, t38_decode:1, t38_force:1, diff --git a/t/auto-daemon-tests.pl b/t/auto-daemon-tests.pl index 8ff73105f..220172f0b 100755 --- a/t/auto-daemon-tests.pl +++ b/t/auto-daemon-tests.pl @@ -1045,6 +1045,108 @@ rcv($sock_a, $port_b, rtpm(96, 1004, 4200, $ssrc, "\xf0\x14\x41\x00\x30\x44\x41\ +new_call; + +offer('multi codec offer/answer', { + ICE => 'remove', + flags => [], + }, < 'remove', + flags => [], + }, < 'remove', + flags => [], + }, < 'remove', + flags => ['single codec'], + }, <