Opus PLC or FEC not working?

Hi,

In our configuration, we use the Asterisk confbridge with SIP and Opus codec. Clients connect to Janus over WebRTC and then Janus uses SIP to connect to the Asterisk. All Janus is doing is forwarding RTP packets between the client and Asterisk.

We are noticing that if you induce packet loss in the RTP packets to Asterisk (even a small amount), the audio quality significantly deteriorates compared to when clients connect directly to each other over WebRTC (same packet loss) and use an SDP with same properties. The SDP offer sent to Asterisk and answer received both have useinbandfec=1. When there is RTP packet loss to Asterisk, it sounds like a crackling sound for the packets lost. It’s almost like the PLC is not working in Asterisk or it’s not using the FEC sent by the clients. Note: there is no packet loss for any packets sent from Asterisk (only 1 way so we can control this test). This is a link to a short sound recording of how it sounds: asterisk_sound_packet_loss.mp3 - Google Drive

Below are the configurations we use. Does anyone have any idea on why there is this audio quality degradation in Asterisk? It seems like there is some misconfiguration.

Thanks,
Terry

sip.conf
—————
allow=opus
jbenable=yes
jbforce=yes
jbimpl=adaptive
jbmaxsize=300
jbresyncthreshold=1000

codec.conf
—————
[opus]
type=opus
fec=yes
dtx=yes
max_playback_rate=16000 ; Limit the maximum playback rate on the encoder
packet_loss=30
max_bandwidth=wide
cbr=no
signal=voice

You need to also specify an expected packet_loss in the opus configuration. Also, might want to try lowering the max_bandwidth to at most “medium”.

More info can be found on the Asterisk blog: configuring-opus-encoder-asterisk and asterisk-opus-packet-loss-fec

Thanks for the response.

I had actually tried all those blog post configurations before I posted. Through further experimentation, I did discover that much of the distortions are coming from dtx=yes. Turning dtx=no improved the quality quite a bit, but still some noticeable distortions even at low packet loss rates (e.g. 5%, 10%). Chrome Opus encoder does 20% FEC, which was the input source for this test. It may have something to do with how Asterisk does PLC as well. I didn’t see any settings to tune that.

Does dtx attribute conflict with another setting? These results are all based on latest Asterisk version 18.2.1.

Not strictly speaking that I am aware of.

DTX is encoder side only, and means less packets are sent when silence is encountered (probably better stated as when the encoder produces packet data below a specified threshold). The decoder (receiving side) might interpret this as packet loss. I’m not entirely sure how Asterisk would handle this, but my guess is that if the packets are ordered correctly it won’t necessarily view this as packet loss. Could be though that because a jitter buffer is being used that the timing of such packets is enough to make it so Asterisk itself drops the packet (meaning it was unable to insert the packet into the jitter buffer). That said I can see a path for Asterisk in which DTX could make things worse.

You might try disabling the jitter buffer, or increasing its size (give more time for late packets) when DTX is enabled to see if that helps.

There is no configuration setting per se to “tune” PLC when using the codec opus for Asterisk. Opus itself has native PLC handling within the decoder that it employs depending on its current operating mode. For Asterisk part, opus’s native PLC is used when fec is disabled, and packet loss is encountered. However, if fec is enabled then that is used instead when packet loss is encountered, and the next packet contains fec data.

And to the last point the quality may also depend on the type of packet loss. fec can only attempt to rebuild the last packet lost. If you have 2 or more packets lost in a row then you’ll always be missing some audio and will hear “clicks” and “pops”. However, seemingly if fec is working correctly and you lost every other packet (technically a 50% loss) the audio should theoretically be “decent”.

Maybe try some of the following in various combinations:

Disable the jitter buffer, or increase the max size
Disable fec and use only native PLC
Try tweaking the expected packet_loss configuration setting

Hi,

Thanks for the suggestions.

These are my results:

  1. Disable the jitter buffer, or increase the max size
    Disabling the jitter buffer seems to make it worse, perhaps because there was some jitter at times. I tried increasing the jitter buffer size, but that made no difference. I did make one observation. If you use an adaptive jitter buffer, there were times that the first 5 seconds of the call or so were very garbled (even with no induced packet loss), but then recovered. I thought it had something to do with target_extra so increased that to 100 (default 40), but that made no difference. So, in summary, the jitterbuffer is necessary and it needs to be fixed (rather than adaptive) for best results.

  2. Disable fec and use only native PLC
    This was noticeably worse when packet loss was induced, even at packet loss rates of 5-10%.

  3. Try tweaking the expected packet_loss configuration setting
    This didn’t make any noticeable difference either way. Tried going to 60% and low as 30%, but no noticeable improvement. Doesn’t this parameter control the FEC that Asterisk to use when sending outbound packets to the client? If so, I wouldn’t expect any difference here because I was inducing packet loss only from the client to Asterisk.

Why is FEC and PLC mutually exclusive? If you start to lose consecutive packets, I would think it would be useful to play the previous packet (perhaps at a lower volume) rather than nothing as that would create the pop and click sounds.

Thanks,
Terry

I think given the fact that disabling fec makes things worse seems to indicate it is at least working in some capacity when it is enabled.

It’s possible some improvement could be made to the actual code, but it’s also possible it’s currently working the best it can with the given data. For instance, 5-10% packet loss may not be considered a lot in some scenarios, but for others it could be considered a lot (given say over different time intervals).

Yep, my bad you are correct here. I got confused about how it’s used. So there is no reason to alter this setting for decoding as it’s not used there.

If I implied this I believe I was wrong about that too. Asterisk’s codec_opus module is just a thin layer over the actual opus library. For the most part it just passes along configuration settings and packets to the underlying library. If fec is not enabled then the opus library attempts native PLC for missing packets. If fec is enabled then the opus library will attempt to use a subsequent frame’s fec data to rebuild the missing packet. However, if fec is enabled, but the subsequent frame does not contain fec data then I believe it falls back to native PLC.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.