For the last few months I, along with Ben Ford, have been working on improving the user experience side of the WebRTC support in Asterisk. When one thinks of user experience the first thing that comes to mind is usually a user interface but in this context I’m referring to underlying technology. Ben has been tackling the problem of packet retransmission which improves the experience by reducing the freezing and stuttering of video. I’ve been working on bitrate control which is a way of controlling the sender’s bitrate to fit within the bandwidth available on the receiver. Let’s dive into what this has entailed.
Receiver estimated maximum bitrate, or remb for short, is a draft created by Google as a transport congestion control mechanism. While other RFCs and specs exist to do this the support is nowhere near as widespread as remb. It was chosen specifically for this reason, to allow the most number of people to benefit from the work. In the future, though, the additional specs may be implemented to improve things even further.
Let’s jump into how remb works! The receiver of a video stream determines what it thinks its maximum available bandwidth is based on the traffic it receives and then sends this information as an RTCP message to the sender. This is done every few seconds which allows the sender to adjust its encoding parameters to try to fit within the available bandwidth. Since Asterisk just acts as a forwarder of video we don’t need to go to the extent of calculating outright what the maximum available bandwidth is and enforcing encoding parameters. This simplified things a little bit.
To support remb an existing frame type called AST_FRAME_RTCP was leveraged for both the reception and sending of remb. When the res_rtp_asterisk module receives remb information it creates an Asterisk frame (just like as if it had received DTMF or audio/video), populates it with the information from the RTCP message, and raises it. The message then goes through the core and is handled by whatever may be handling the channel at that time. For outgoing the AST_FRAME_RTCP frame is provided to res_rtp_asterisk which examines the frame, constructs the remb RTCP message, and sends it. This gives a good amount of control over things.
In the case of a direct call Asterisk can just act as a forwarder of this frame, just like for audio or video. We receive remb information on one side and send it out the other without changing the values. This requires no configuration and happens automatically.
In the case of a multiparty conference we can’t just forward. A stream may be going to multiple channels each providing their own remb information. Sending all of these back would confuse the sender and result in a bad experience as it switched its encoding around. Instead what the bridge_softmix module does is combine all the remb information into a single message based on configuration. The three options for configuration are: lowest, highest, and average. The “lowest” option will pass through the message with the lowest available bandwidth. The “highest” option will pass through the message with the highest available bandwidth. The “average” option creates a new message with the average of all.
If you would like to leverage this new remb support in the SFU you will need to use the latest version of Asterisk as of this writing, 15.4.0, and set the “remb_send_interval” and “remb_behavior” options. The “remb_send_interval” option sets the frequency at which a remb message is generated and sent, with 1000ms being a reasonable amount. If you experience any problems please file an issue so we can continue to improve this functionality.