Dear Maintainer, debian/patches/2016_opus_plc.patch (added for #1060275) makes Asterisk drop all audio on a transcoded call leg once the far end switches to a new RTP stream whose sequence numbers start below the old ones. Every frame is then discarded, without a log message, until the new numbers catch up with the old: up to 32767 packets, i.e. up to 11 minutes at 50 packets/s, in practice the rest of the call. This hits any transcoded leg, not only Opus: we found it in Zamfono, a PBX built on Debian's Asterisk packages, with AMR-WB from a mobile carrier (the caller heard nothing after a transfer) and reproduced it with PCMA -> G.722. Carriers and SBCs change the SSRC during early media and on transfers. These upstream reports, both from Debian builds, look like the same thing: https://github.com/asterisk/asterisk/issues/1324 https://community.asterisk.org/t/ssrc-change-bridging/103903 The experimental 22.11.0 release candidate ships the same patch file. Analysis -------- The patch makes ast_translate() (main/translate.c) compare each frame's RTP sequence number with the previous one on the translation path: - A frame up to 32767 behind counts as late and is freed (return NULL). After a new stream starts k numbers lower, the next k frames are all "late". - A new stream up to 32767 ahead makes the loop synthesize that many empty "lost" frames in a single call. Decoders with native PLC (Opus, Speex, iLBC) turn each into a frame of concealment audio, so the next leg gets a burst of up to 11 minutes of audio at once. - At the 65535 -> 0 wrap the gap is computed off by one: frame 0 is dropped as late and nothing is concealed. The late-frame drop runs on every translation path, including those whose decoder has no native PLC, where the patch has nothing to offer. Proposed fix ------------ The attached 2016_opus_plc.patch replaces the current one. It keeps the native PLC that #1060275 asked for: 1. The sequence number logic only runs on translation paths that start with a native-PLC decoder. Other paths never drop frames as late. 2. Gaps of up to 50 packets are still concealed and packets up to 50 behind are still dropped as late. A larger jump either way is taken as a new stream: the path follows its numbering, nothing is synthesized and nothing is dropped. 3. The distance is computed modulo 2^16, which fixes the wrap. 4. ast_debug() lines for concealed gaps, late drops and new streams replace the commented-out NOTICE (which contained a nested comment opener). The second attachment, translate.c-vs-debian.diff, shows the change against translate.c as the current patch leaves it. Testing ------- Built 1:22.10.1+dfsg+~cs6.17.60671434-1 with the revised patch on trixie (amd64). Calls go through Asterisk from a SIPp far end playing crafted RTP to a baresip phone on G.722 (SRTP). Packets that reached the phone, with the current patch / the revised patch / the patch left out: - PCMA, new SSRC 5024 numbers lower: silence after the switch / all / all. - Opus, new SSRC 5000 numbers higher, then another 5000 lower: a burst of 4999 synthesized packets, then silence / all, no burst / all. - Opus, 5 % loss and 4 swapped pairs: 500 of 500 / 500 of 500 / 478 (no PLC). - Opus across 65535 -> 0: 299 of 300 / 300 of 300 / not run. With the revised patch and debug enabled, the loss run logs exactly the 26 concealed frames (22 lost, 4 arriving after their successor) and the 4 late drops. The jump run logs two "new stream" lines and nothing else. I can send the RTP generator and SIPp scenarios if useful. Regards, Lukas Fabrykowski 3angular Solutions GmbH