MT#55283 preserve supplemental codecs in publish mode

Add RED (RFC 2198) codec definition to codeclib as a supplemental codec.
Modify codec_store_accept_one() to preserve supplemental codecs whose
clock rate matches the accepted primary codec. Skip supplemental codecs
in codec_store_is_full_answer() since they are optional in SDP answers.

Closes #2100

Change-Id: Ie81f45091c5d3dc55e20896d5a6e7a8361fda2f4
master
Orgad Shaneh 3 days ago committed by Richard Fuchs
parent 1a832a8af3
commit b87ae58036

@ -6095,7 +6095,8 @@ int codec_store_accept_one(struct codec_store *cs, const str_q *accept, bool acc
return -1;
}
// delete all codecs except the accepted one
// delete all codecs except the accepted one, preserving supplemental codecs
// that match the accepted codec's clock rate
__auto_type link = cs->codec_prefs.head;
while (link) {
rtp_payload_type *pt = link->data;
@ -6103,6 +6104,13 @@ int codec_store_accept_one(struct codec_store *cs, const str_q *accept, bool acc
link = link->next;
continue;
}
ensure_codec_def(pt, cs->media);
if (pt->codec_def && pt->codec_def->supplemental
&& pt->clock_rate == accept_pt->clock_rate)
{
link = link->next;
continue;
}
link = __codec_store_delete_link(link, cs);
}
@ -6445,6 +6453,8 @@ void codec_store_synthesise(struct codec_store *dst, struct codec_store *opposit
bool codec_store_is_full_answer(const struct codec_store *src, const struct codec_store *dst) {
for (auto_iter(l, src->codec_prefs.head); l; l = l->next) {
const rtp_payload_type *src_pt = l->data;
if (src_pt->codec_def && src_pt->codec_def->supplemental)
continue;
const rtp_payload_type *dst_pt = t_hash_table_lookup(dst->codecs,
GINT_TO_POINTER(src_pt->payload_type));
if (!dst_pt || !rtp_payload_type_eq_compat(src_pt, dst_pt)) {

@ -784,6 +784,18 @@ static struct codec_def_s __codec_defs[] = {
.format_cmp = format_cmp_ignore,
.codec_type = &codec_type_cn,
},
{
.rtpname = "red",
.avcodec_id = -1,
.packetizer = packetizer_passthrough,
.media_type = MT_AUDIO,
.supplemental = 1,
.default_clockrate = 8000,
.default_channels = 1,
.format_cmp = format_cmp_ignore,
.support_encoding = 1,
.support_decoding = 1,
},
{
.rtpname = "G726-16",
.avcodec_id = AV_CODEC_ID_ADPCM_G726,

@ -4716,5 +4716,137 @@ a=sendrecv
a=rtcp:PORT
SDP
# publish with RED supplemental codec preserved alongside primary codec
($sock_a, $sock_b) =
new_call([qw(198.51.100.14 6160)], [qw(198.51.100.14 6162)]);
($port_a) = publish('publish w RED supplemental',
{ codec => { accept => ['any'] } }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio 6160 RTP/AVP 8 97 101
c=IN IP4 198.51.100.14
a=sendonly
a=rtpmap:97 RED/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
----------------------------------
v=0
o=- SDP_VERSION IN IP4 203.0.113.1
s=RTPE_VERSION
t=0 0
m=audio PORT RTP/AVP 8 97 101
c=IN IP4 203.0.113.1
a=rtpmap:8 PCMA/8000
a=rtpmap:97 RED/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=recvonly
a=rtcp:PORT
SDP
snd($sock_a, $port_a, rtp(8, 2000, 4000, 0x3456, "\x00" x 160));
($ftr, $ttr, undef, undef, undef, $port_b) = subscribe_request('publish w RED supplemental',
{ 'from-tag' => ft() }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio PORT RTP/AVP 8 97 101
c=IN IP4 203.0.113.1
a=rtpmap:8 PCMA/8000
a=rtpmap:97 RED/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=sendonly
a=rtcp:PORT
SDP
is $ftr, ft(), 'from-tag matches';
subscribe_answer('publish w RED supplemental',
{ 'to-tag' => $ttr }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio 6162 RTP/AVP 8
c=IN IP4 198.51.100.14
a=recvonly
SDP
snd($sock_a, $port_a, rtp(8, 2001, 4160, 0x3456, "\x00" x 160));
rcv($sock_b, $port_b, rtpm(8, 2001, 4160, 0x3456, "\x00" x 160));
# publish with mixed-clockrate supplementals: only matching clockrate kept
($sock_a, $sock_b) =
new_call([qw(198.51.100.14 6164)], [qw(198.51.100.14 6166)]);
($port_a) = publish('publish supplemental clockrate filter',
{ codec => { accept => ['any'] } }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio 6164 RTP/AVP 8 96 97 101 110
c=IN IP4 198.51.100.14
a=sendonly
a=rtpmap:96 RED/8000
a=rtpmap:97 RED/48000
a=rtpmap:101 telephone-event/8000
a=rtpmap:110 telephone-event/48000
----------------------------------
v=0
o=- SDP_VERSION IN IP4 203.0.113.1
s=RTPE_VERSION
t=0 0
m=audio PORT RTP/AVP 8 96 101
c=IN IP4 203.0.113.1
a=rtpmap:8 PCMA/8000
a=rtpmap:96 RED/8000
a=rtpmap:101 telephone-event/8000
a=recvonly
a=rtcp:PORT
SDP
($ftr, $ttr, undef, undef, undef, $port_b) = subscribe_request('publish supplemental clockrate filter',
{ 'from-tag' => ft() }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio PORT RTP/AVP 8 96 101
c=IN IP4 203.0.113.1
a=rtpmap:8 PCMA/8000
a=rtpmap:96 RED/8000
a=rtpmap:101 telephone-event/8000
a=sendonly
a=rtcp:PORT
SDP
is $ftr, ft(), 'from-tag matches';
subscribe_answer('publish supplemental clockrate filter',
{ 'to-tag' => $ttr }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio 6166 RTP/AVP 8
c=IN IP4 198.51.100.14
a=recvonly
SDP
snd($sock_a, $port_a, rtp(8, 2000, 4000, 0x3456, "\x00" x 160));
rcv($sock_b, $port_b, rtpm(8, 2000, 4000, 0x3456, "\x00" x 160));
done_testing();
#done_testing;NGCP::Rtpengine::AutoTest::terminate('f00');exit;

@ -1706,12 +1706,13 @@ class TestVideoroom(unittest.TestCase):
"o=- \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"s=rtpengine.*?\r\n"
"t=0 0\r\n"
"m=audio \\d+ UDP/TLS/RTP/SAVPF 111\r\n"
"m=audio \\d+ UDP/TLS/RTP/SAVPF 111 110\r\n"
"c=IN IP4 203.0.113.1\r\n"
"a=mid:0\r\n"
"a=rtpmap:111 opus/48000/2\r\n"
"a=fmtp:111 useinbandfec=1; minptime=10\r\n"
"a=rtcp-fb:111 transport-cc\r\n"
"a=rtpmap:110 telephone-event/48000\r\n"
"a=extmap-allow-mixed\r\n"
"a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n"
"a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n" # noqa: E501
@ -1730,7 +1731,7 @@ class TestVideoroom(unittest.TestCase):
"a=ice-options:trickle\r\n"
"a=candidate:.{16} 1 UDP 2130706431 203.0.113.1 \\d+ typ host\r\n" # noqa: E501
"a=end-of-candidates\r\n"
"m=video \\d+ UDP/TLS/RTP/SAVPF 96\r\n"
"m=video \\d+ UDP/TLS/RTP/SAVPF 96 124\r\n"
"c=IN IP4 203.0.113.1\r\n"
"a=mid:1\r\n"
"a=rtpmap:96 VP8/90000\r\n"
@ -1739,6 +1740,7 @@ class TestVideoroom(unittest.TestCase):
"a=rtcp-fb:96 ccm fir\r\n"
"a=rtcp-fb:96 nack\r\n"
"a=rtcp-fb:96 nack pli\r\n"
"a=rtpmap:124 red/90000\r\n"
"a=extmap-allow-mixed\r\n"
"a=extmap:14 urn:ietf:params:rtp-hdrext:toffset\r\n"
"a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n" # noqa: E501
@ -1831,12 +1833,13 @@ class TestVideoroom(unittest.TestCase):
"s=-\r\n"
"t=0 0\r\n"
"a=msid-semantic: WMS hJifdaJwqEqHxSG0pVbs1DrLAwiHqz7fKlqC\r\n"
"m=audio \\d+ UDP/TLS/RTP/SAVPF 111\r\n"
"m=audio \\d+ UDP/TLS/RTP/SAVPF 111 110\r\n"
"c=IN IP4 203.0.113.1\r\n"
"a=mid:1\r\n"
"a=rtpmap:111 opus/48000/2\r\n"
"a=fmtp:111 useinbandfec=1; minptime=10\r\n"
"a=rtcp-fb:111 transport-cc\r\n"
"a=rtpmap:110 telephone-event/48000\r\n"
"a=extmap-allow-mixed\r\n"
"a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n"
"a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n" # noqa: E501
@ -1859,7 +1862,7 @@ class TestVideoroom(unittest.TestCase):
"a=ice-options:trickle\r\n"
"a=candidate:.{16} 1 UDP 2130706431 203.0.113.1 \\d+ typ host\r\n" # noqa: E501
"a=end-of-candidates\r\n"
"m=video \\d+ UDP/TLS/RTP/SAVPF 96\r\n"
"m=video \\d+ UDP/TLS/RTP/SAVPF 96 124\r\n"
"c=IN IP4 203.0.113.1\r\n"
"a=mid:2\r\n"
"a=rtpmap:96 VP8/90000\r\n"
@ -1868,6 +1871,7 @@ class TestVideoroom(unittest.TestCase):
"a=rtcp-fb:96 ccm fir\r\n"
"a=rtcp-fb:96 nack\r\n"
"a=rtcp-fb:96 nack pli\r\n"
"a=rtpmap:124 red/90000\r\n"
"a=extmap-allow-mixed\r\n"
"a=extmap:14 urn:ietf:params:rtp-hdrext:toffset\r\n"
"a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n" # noqa: E501

Loading…
Cancel
Save