I have been using Janus as a WebRTC server with the SIP plugin. My setup is pretty simple, client establishes a WebRTC session with Janus which in turn establishes a SIP session with my SIP server. It’s Audio only. I was checking the SDP and nackCount and realized there’s no nack negotiation or actual NACK packets initiated from Janus. How do I configure Janus to both negotiate and use NACK.
I tried customizing the SDP on the client side to insert NACK negotiation rtcp-fb lines for every audio codec negotiated, but nothing changed. Janus just relays the SIP ANSWER received from the SIP server which of course doesn’t contain any NACK related stuff and it nevers requests any retransmissions.
Browsers don’t negotiate NACK support for audio, but even if they did, Janus would terminate and handle it at the WebRTC level, and not forward NACK requests on the SIP side. REMB should already be relayed instead. Closing as not a code issue: discussion can continue on the group, if needed.
@lorenzo Following up on your reply in the github issue, this is not the behavior I’m experiencing at all. It seems JANUS is completely ignoring both NACK and REMB (neither relaying them nor handling them on the WebRTC level). I did a basic test using tc to simulate aggressive packet loss and initiated a session both on Google Meet and with Janus. The Googe Meet session as apparent from chrome://webrtc-internals, utilizes NACK (both nack count and number of retransmitted packets increases) while Janus doesn’t.
To take a step back, the main motive here is making sure to deliver the best experience under poor network conditions. Currently I’m using OPUS codec with FEC which seems to improve things but there’s still huge chunks of audio completely gone when experiencing burst packet loss. If you think there’s a better approach possible with Janus or something I’m missing your recommendations are very welcome.
As I said on Github, it’s the browsers that by default don’t negotiate NACKs for audio, which is why by default we don’t either, and that’s true for all plugins, not just the SIP one. I guess Meet forces NACKs for audio too by munging the SDP or something like that. I can’t remember if we have fences in the code that still prevent audio NACKs, though. For bursts of packet loss, browsers usually perform packet-loss concealment (PLC) whn FEC on its own is not enough.
Hmmm, my experiment included modifying the SDP to negotiate NACK on the INVITE to Janus. Is that normally not enough to overcome the issue of browsers not negotiating by default?
That depends what you mean by modifying the SDP; you need to edit SDPs before a call to setLocalDescription to make sure browsers do NACK themselves, otherwise it’s useless. Then it’s a matter of seeing what Janus returns back. You should check what appears in the SDP offer and answer that Janus sees on the WebRTC side, and what the Admin API says with respect to NACK support in the audio medium.
You’re using \n instead of \r\n, and that’s broken SDP already. That said, you’re not negotiating NACK at all, that way: I don’t see rtx payload types being offered. No idea why you’re adding REMB and transport-cc too, which have nothing to do with NACK, or pli, which only makes sense for video.
@lorenzo Thanks for your feedback. I re-read the RFC and made some changes. Now I’m facing the following error (on Chrome): “Failed to execute ‘setLocalDescription’ on ‘RTCPeerConnection’: Failed to parse SessionDescription. Encountered webrtc error in janus”. Here’s the local SDP:
I can see that there’s someone else that’s facing the same issue but I couldn’t progress any further. Do you mind taking a quick look on the SDP and letting me know if I missed something.
Yeah, which is what I told you about browsers not negotiating it. There may be ways to force it, though (maybe by munging both local and remote SDP, before setLocalDescription and setRemoteDescription?), especially if you say Meet does use them.
That turned out to be an overlook by me, they use it in their video stream only. Sorry about that. Thank you for your help.
Looking at the bigger picture my initial goal is to mitigate burst packet loss as much as possible. Are you aware of any other measures I could try, other than NACK. (I’m using OPUS with FEC, CBR and a JitterBuffer)
But is this a custom client? That is, not a browser? Then you could look into how to use Packet Loss Concealment (PLC) in Opus to smoothen out losses. Check the libopus documentation for more info.
It’s not a custom client sadly (for now at least). Janus is relaying media directly to an Asterisk server which is supposed to have its own PLC implementation. I’ll look more into optimizing that. Thanks a lot for your support