Unveiling SDP: A Deep Dive into WebRTC's Session Description Protocol

8 min read
October 31, 2023

Over the past couple of years, real-time communication has become an important aspect of enabling remote working and team collaboration. Among the technologies used to enable real-time communication, WebRTC has emerged as the best technology for enabling such communication. However, WebRTC does not work alone, it encompasses several protocols underneath, one of which is SDP.

In this article, we’ll look at what SDP is, how it works in WebRTC, and also go through some tips and best practices when working with it.

Table of Contents

  1. How does SDP work in WebRTC
  2. Common SDP attributes
  3. Session description
  4. Media description
  5. Attributes
  6. Practical usages of SDP which improve the WebRTC experience
  7. Debugging SDP issues
  8. What are the best practices for working with SDP
  9. Wrapping up

How does SDP work in WebRTC

To simplify it, you can think of SDP as the language WebRTC devices speak to one another to facilitate real-time communication between devices with different capabilities or are positioned behind firewalls or NATs. 

The essence of SDP’s operation lies in its offer-and-answer model. An initiating peer creates an SDP offer detailing the media types, codecs, and transport protocols it supports, alongside other vital session information. This offer is then sent to the receiving peer, which responds with an SDP answer, indicating its chosen set of parameters for the session, aligning with the options presented in the offer.

The process of multimedia sessions set up in WebRTC is significantly driven by SDP. As peers exchange SDP messages during the connection setup, they negotiate the essential parameters that govern the session. This negotiation encompasses media formats, transport protocols, and other crucial elements ensuring a robust real-time communication session.

SDP organises structured message exchange, laying down the groundwork for WebRTC peers to agree on a common set of session parameters, thus paving the way for a successful real-time communication channel. 

Common SDP attributes

SDP uses various attributes within the message to describe the media capabilities and session details of a WebRTC device. These attributes are crucial when it comes to negotiating parameters and ensuring effective real-time communication. Let’s have a look at some of the most common SDP attributes.

Session Description

The Session Description Protocol (SDP) is a text-based format that describes the multimedia sessions in WebRTC. It consists of various fields such as:

  • v=: Indicates the version of the SDP protocol being used.
  • o=: States the origin field specifies the username, session ID, session version, and network address of the originator of the session.
  • s=: The session name field.
  • c=*: Includes the connection information, but it’s not needed if included in all media descriptions.
  • t=: Dictates the time the session is active.

By including this information in the SDP offer and answer messages, peers can effectively negotiate the session parameters and establish a successful WebRTC connection.

Media Description

The Media Description in SDP carries vital information about the media streams to be exchanged - it provides a description of the media type, the codecs used, and the transport protocol used.

  • The "m=" line indicates the media name and transport address.
  • The "a=" lines show zero or more media attribute lines

We’ll look at an example in a later section.

Attributes

SDP Attributes provide pivotal information to facilitate multimedia sessions in WebRTC, here are some of the noteworthy attributes:

  • group:BUNDLE

Enables bundling multiple media types over a single UDP/TCP connection, promoting efficient usage of network resources.

  • fingerprint:sha-256

Contains the hash of certificates exchanged during the DTLS handshake, crucial for secure connections.

  • a=setup

Controls the DTLS agent post-ICE connectivity, determining if DTLS operates as client or server with values: `setup:active`, `setup:passive`, and `setup:actpass`.

  • ice-ufrag`, `ice-pwd` and `ice-options

ICE-related configurations with `ice-ufrag` defining the username fragment, `ice-pwd` holding the password for ICE authentication, and `ice-options` dictating ICE gathering nuances.

  • extmap

Defines available header extensions for peer connections in offer or answer messages, enhancing the communication setup.

  • msid

Communicates stream ID and track one is sending to the other party, formatted as `${streamid} ${trackid}`.

  • rtpmap

Maps a particular codec to an RTP Payload Type, essential for media encoding/decoding consistency across the session.

  • rtcp-fb

Located in the media section of SDP, specifies RTCP Feedback messages for a given payload type, aiding in media quality adjustments.

  • ssrc

Stands for Synchronisation Source, a 32-bit random value indicating media sent from a specific source in RTP connection, formatted as `a=ssrc:<ssrc-id> cname: <cname-id>’.

These are the important attributes that tell us a lot about the media being negotiated and used for a session. I hope you have understood how to read SDP and its components.

We’ll cover a few examples in the next section. 

Practical usages of SDP which improve the WebRTC experience

Simulcast

Simulcast is a vital enhancement in WebRTC, that allows the same video stream to be transmitted at multiple resolutions and bit rates. This way, the receiver can then select the most suitable stream based on your available bandwidth and device capabilities through SDP. 

It leverages additional SDP attributes such as: 

  • `a=simulcast`, 
  • `a=rid`, and 
  • `a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id`. 

The `a=simulcast` attribute indicates the number of simulcast RTP streams and potential alternative formats for each stream, which are identified using the RID identifier (rid-id).

Example of an SDP offer using simulcast:

m=video 49300 RTP/AVP 97 98 99
a=rtpmap:97 H264/90000
a=rtpmap:98 H264/90000
a=rtpmap:99 VP8/90000
a=fmtp:97 profile-level-id=42c01f;max-fs=3600;max-mbps=108000
a=fmtp:98 profile-level-id=42c00b;max-fs=240;max-mbps=3600
a=fmtp:99 max-fs=240; max-fr=30
a=rid:1 send pt=97;max-width=1280;max-height=720
a=rid:2 send pt=98;max-width=320;max-height=180
a=rid:3 send pt=99;max-width=320;max-height=180
a=rid:4 recv pt=97
a=simulcast:send 1;2,3 recv 4
a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id

Legacy Simulcast

Legacy Simulcast is the older way of implementing simulcast, as adopted by Firefox. It utilises explicitly defined `ssrc` and `ssrc-group` attributes in SDP along with `rid` attributes. Legacy Simulcast forms a relationship among several `ssrc`s of an RTP session, defining the sending RTP packets on defined `ssrc`s only, which the answering peer connection must understand.

Example of an SDP offer generated with Legacy Simulcast enabled:

a=simulcast:send r1;r0 a=ssrc:4264196019 cname:{816fd64c-ca90-417c-a2b7-72c7c36a6500}
a=ssrc:2642934809 cname:{816fd64c-ca90-417c-a2b7-72c7c36a6500}
a=ssrc:764299737 cname:{816fd64c-ca90-417c-a2b7-72c7c36a6500}
a=ssrc:3939469720 cname:{816fd64c-ca90-417c-a2b7-72c7c36a6500}
a=ssrc-group:FID 4264196019 2642934809
a=ssrc-group:FID 764299737 3939469720

Perfect Negotiation

Perfect negotiation is an advanced process in WebRTC that makes it possible to effectively and completely separate the negotiation process from the rest of the application’s logic. The main aim of this process is to avoid the collision of SDP offers from both sides.

Negotiation is an inherently asymmetric process, meaning one side needs to be the ‘caller’ while other peers serve as the ‘callee‘. A perfect negotiation process smoothly removes this difference by separating it into independent negotiation logic, this way, your application does not have to care which end of the connection it is. 

The implementation involves a handler on `pc.onnegotiationneeded`, which triggers `pc.setLocalDescription()` without first generating the offer. This approach solves the problem of generating multiple SDP offers unnecessarily for a peer connection.

Example of Perfect Negotiation handling in WebRTC

The code snippet below manages the initiation of a negotiation process when it's needed. When the onnegotiationneeded event is fired, it attempts to set a local description, send it to the signaling server, and handle any errors that might occur in this process. 

The makingOffer flag is used to ensure that only one side is making the offer to avoid negotiation collisions. Additionally, there is an oniceconnectionstatechange event handler set up to restart the ICE process if the connection fails, which is part of ensuring the robustness of the connection setup.

let makingOffer = false;
pc.onnegotiationneeded = async () => {
  try {
    makingOffer = true;
    await pc.setLocalDescription();
    signaler.send({ description: pc.localDescription });
  } catch (err) {
    console.error(err);
  } finally {
    makingOffer = false;
  }
};
pc.oniceconnectionstatechange = () => {
  if (pc.iceConnectionState === "failed") {
    pc.restartIce();
  }
};

The code snippet below will handle incoming messages from the signaling server, which could be either session descriptions or ICE candidates. It uses the ignoreOffer flag along with checking the polite flag and the current signaling state to decide whether to ignore the incoming offer and avoid a collision in the negotiation process.

If the incoming message is a session description, it sets the remote description, and if it's an offer, sets a local description and sends it back to the signaling server. If the incoming message is an ICE candidate, it attempts to add the candidate to the RTCPeerConnection.

let ignoreOffer = false;
signaler.onmessage = async ({ data: { description, candidate } }) => {
  try {
    if (description) {
      const offerCollision =
        description.type === "offer" &&
        (makingOffer || pc.signalingState !== "stable");
      ignoreOffer = !polite && offerCollision;
      if (ignoreOffer) {
        return;
      }
      await pc.setRemoteDescription(description);
      if (description.type === "offer") {
        await pc.setLocalDescription();
        signaler.send({ description: pc.localDescription });
      }
    } else if (candidate) {
      try {
        await pc.addIceCandidate(candidate);
      } catch (err) {
        if (!ignoreOffer) {
          throw err;
        }
      }
    }
  } catch (err) {
    console.error(err);
  }
};

This arrangement ensures a more predictable reaction to error-related occurrences during the negotiation process, aiding the establishment of optimal media capabilities.

Debugging SDP issues

When working with SDP, it's essential to have the right tools to help you debug issues more efficiently. While there aren't many tools available specifically for SDP, a few SDP parsers can be used to make SDP strings more readable. Some of these tools include:

  1. SDP Transform: A JavaScript library that provides functions for parsing, modifying, and generating SDP strings.
  2. SDP Visualiser: A tool that allows you to visualise and analyse SDP files, making it easier to understand their structure and content.
  3. SDP Parser Libraries: There are several SDP parser libraries available for different programming languages, such as JavaScript and Go. These libraries can help you work with SDP in your preferred language, making it easier to debug and troubleshoot issues.

What are the best practices for working with SDP?

To ensure optimal performance and compatibility when working with SDP, consider the following best practices:

Although it’s not a comprehensive list, these best practices can help you build a more reliable and performant WebRTC implementation.

Wrapping up

SDP plays a crucial role in WebRTC by enabling seamless interactions between diverse devices, even when barriers like firewalls or NATs exist. Understanding how SDP works within WebRTC and following the recommended practices can fuel a sturdier and more efficient WebRTC setup. 

By embracing the insights and guidelines shared in this article, you're well on your way to fine-tuning your WebRTC setup, ensuring its harmonious function across various browsers and platforms.

Discover how Digital Samba can elevate your real-time communication experience by leveraging the power of SDP and WebRTC, explore our solutions today!

Request a free consultation
Elevate your real-time communication experience by leveraging the power of SDP and WebRTC
Get a consultation
 

Get Email Notifications