How are retransmissions implemented in WebRTC



These mechanisms can be combined depending on the network conditions and can also be tuned for specific cases like scalable video as described in [2]. In Chrome the retransmissions are implemented for both audio and video but by default it is only enabled for video.

This post is about the retransmissions approach, specifically about when to ask for a retransmission and when not to do it.

Disclaimer: Please report any mistake/inaccuracy in this post and I will fix it asap for future reference. BTW this post is not about rtx "encapsulation" vs the legacy way of sending retransmissions but I'm happy to talk about that in twitter :)

Implementation in the RTP Receiver Side

The RTP receiver side is the one requesting the retransmission sending a NACK RTCP packet when it detects a missing packet.

But... should I request for retransmissions immediately after detecting a gap in the sequence numbers?  Google implementation does that plus also have a periodic timer to keep requesting them.

And... for how long should I keep requesting the retransmission? Chrome keeps requesting the retransmission of a specific packet unless the sequence number is "more than 10000 old", the number of missing packets in the list is larger than 1000, you asked for the same packet 10 times already or you have a new decodable full frame (no packet is missing for any other frame it depends on).

This is the Google implementation of WebRTC (and the same code is copied into Firefox and Safari) transcribed as pseudocode:

Implementation in the RTP Sender Side

The RTP sender side is the one receiving the retransmission requests (NACKs) and resending the lost packets if possible.

The main question here is if I should obey all the retransmission requests or not.  The way this is implemented in Google's WebRTC implementation right now is this one:
  1. Keep a copy of the packets sent in the last 1000 msecs (the "history").
  2. When a NACK is received try to send the packets requests if we still have them in the history.
  3. But... (
    • Ignore the request if the packet has been resent in the last RTT msecs.
    • Ignore the request if we are sending too many retransmissions.  There is a rate limiter (retransmission_rate_limiter) that is apparently configured to the whole channel bandwidth estimation.
    • If pacing is enabled insert this packet in the queue with normal priority.


  1. great post man!
    Have a question. I'm searching the google code for the audio jitter buffer and not the video jitter buffer .
    I want to make some tests and wrap this thing in my app.
    do you know where i can start from?

    1. It is here, but don't expect it to be easy to reuse in your app, it probably has many dependencies with rest of webrtc codebase:


    Virtual Edge

  3. Thank you for the post.

    A typical video stream has about 100 packets per second. Packet age of 10,000 is about 100 seconds old and 1,000 nack queue length is equal to at least 10 seconds. Is there a use case where 100 or 10 seconds old packets are still useful? Why don't they use 1 second limit as in the receiver side?

    Why do they keep a list of keyframes and not just the most recent one?

    I think they also check for the first packet in a keyframe and not if we got all the frame parts:
    bool is_keyframe =
    packet.is_first_packet_in_frame && packet.frameType == kVideoFrameKey;

    Seems like the webrtc source has moved:



  5. Thanks very much for this post! I'm currently implementing retransmissons for aiortc, my Python implementation of WebRTC and it answers a number of questions I had.


Post a Comment

Popular posts from this blog

Bandwidth Estimation in WebRTC (and the new Sender Side BWE)

Controlling bandwidth usage in WebRTC (and how googSuspendBelowMinBitrate works)

Using DSCP for WebRTC packet marking and prioritization