SDP has been a frequent topic, both here on webrtcHacks as well as in the discussion about the standard itself. Modifying the SDP in arcane ways is referred to as SDP munging. This post gives an introduction into what SDP munging is, why its done and why it should not be done. This is not a guide to SDP munging.
A minimal recap of SDP in WebRTC 1.0
Although WebRTC 1.0 exposes an API to handle and transmit local audio, video and/or data to a remote WebRTC peer, the information exchange unit is the Session Description Protocol (SDP). This basically means that, whichever operation is locally executed, a SDP must be transmitted to the other party (or let the other party generate such a SDP representing our local operations) and “apply” it into its RTCPeerConnection by means of setRemoteDescription(). webrtcHacks has a line-by-line SDP guide and is a good reference in addition to the spec to follow along.
What SDP does
A WebRTC SDP conveys information regarding all the communication layers, including:
- ICE parameters – for establishing a network path between both peers in the multimedia session with optional ICE candidates (can be sent later)
- DTLS parameters – used to perform a DTLS handshake and exchange the SRTP keys to be used for audio and video, and/or establishing the encrypted transport on which DataChannel messages will be exchanged
- RTP parameters – specify what the peer is willing to send and receive from the other peer
What is SDP Munging?
SDP munging refers to the process of changing the SDP manually as opposed to letting the WebRTC API’s do it. For example, one common form of munging is adding or removing lines to remove codecs or change their priority. The apprtc demo application still contains some examples of that.
When looking at WebRTC, there are two places where one can munge the SDP:
1 2 3 4 5 6 7 |
pc.createOffer() .then((offer => { // SDP munging option before setLocalDescription pc.setLocalDescription(offer); // SDP munging option during signaling // send offer to other peer }) |
Let’s look at this in more detail.
Munging before setLocalDescription
The SDP can be changed either before setLocalDescription or when it is being signalled to the remote peer (or server). On the other end the same modifications after possible after pc.createAnswer.
According to the specification, munging between createOffer and setLocalDescription (the first form above) is not allowed and would result in an InvalidModificationError.
Why is this illegal? Modifying SDP here is very challenging for the browsers. They would have to interpret the changes made to the SDP and guess the intent. A specification that stated what values are allowed to change and which ones you cannot change (e.g. allowing JavaScript to change ICE ufrag/pwd would be bad) would be a a nightmare to follow. It is more practical to just not allow it.
In fact, since you’re not allowed to change the SDP here, recent versions of Chrome and Firefox actually allow calling setLocalDescription without parameters. When you do this the browser will use the last created offer or answer as a default parameter automatically . While this is certainly the way forward, it is not available everywhere so it is better to wait a bit.
Munging during signaling
The second form of munging takes place during signaling. This is not prohibited as WebRTC doesn’t define how signaling happens. One can build creative hacks like what I did in simulcast playground with this munging methodology. This can happen either in the local client, the signaling server or the remote client.
This is still a valid way of working with SDP offers and answers and it won’t go away. However, be aware that you are still on your own if something breaks.
Do we still need SDP munging?
Discussions to forbid SDP munging have been ongoing since 2016 (Tsahi wrote a great blog post back in 2016; the advice is still very relevant). Progress has been slow toward achieving a SDP-free WebRTC, but there has been some activity here. Some use-cases, such as modifying the bandwidth using SDP munging are now solved with the object-oriented approach from ORTC (see the sample).
However, there are quite a number of things that still require SDP munging. For example, to play stereo sound from Freeswitch one has to munge the local (from the browser) SDP and include stereo=1 in the opus fmtp line. As documented in this bug, requiring an SDP munge to play stereo is not very obvious, so this took quite some time and effort to figure out.
Another major use-case for SDP munging is simulcast. The procedure for that has been virtually unchanged since I wrote the Hangouts analysis post back in 2014.
While Chrome has added APIs for enabling simulcast without SDP munging, they are not working for cases where the remote end sends the offer. Also, Chrome decided to not include SSRCs in the SDP in that case which caused quite some concern among SFU developers and probably continues to hinder adoption.
How often is SDP munging used?
chromestatus is a great source of answers to such questions. There is a counter for RTCLocalSdpModification which is a nicer term for the first form of SDP munging (which is the variant that can be measured in Chrome):
Chrome added this metric in March 2018 and it shipped in the stable release in June 2018. You can see it started at around 0.04% of the pageloads. It has since increased to 0.06% of pageloads and just jumped to 0.075% in the last week. It is hard to say what percentage of peer connections uses SDP munging but given that getUserMedia is done on 0.07% of the pageloads, the percentage could be quite high. We will see the first results of specifically measuring simulcast-munging in a few weeks.
SDP Munging begone!
And yet… SDP munging has to go away in the long run. There is a Chrome issue tracking the deprecation and removal but it is unlikely to happen soon. Much before this, in Chrome 82, chrome://webrtc-internals will detect and mark modifications before setLocalDescription , doing a simple string comparison.
This allows you to check your application, review the cases where you do munge SDP and check if there are alternatives that should be used instead. If you are using SDP munging in a case that isn’t possible without it please leave a comment. This twitter thread already contrains some good answers.
Mind you: If the bad trend in the RTCLocalSdpModification graph has not changed in six months, I am going to add some 😱 emojis…
{“author”: “Philipp Hancke“}
Maktech says
We are currently using VP8 for software encoding. What we are seeing is our bitrate starts extremely low and ramps over time (up to a minute or two) to get to a reasonable level (5 Mbps to 10Mbps) for our demos.
Using SDP munging can we control that start bitrate and ramp duration?
With our H264 hardware encoding we were setting the google-x-start-bitrate and google-x-max-bitrate.
Do these work with software encoding?
Philipp Hancke says
using SDP munging to attempt tweaking this is generally a bad idea (but the API has no actual knobs for things like start bitrate, only maxBitrate). You might want to check if this caused by not using transport-cc for bandwidth estimation instead, slow ramp-up typically happens with REMB.
anand says
sir, how can we include temporal scalability in vp8?