How WebRTC Implements Video NACK: A Deep Dive into RTP Retransmission
This article provides a comprehensive walkthrough of WebRTC's video sender NACK implementation, covering the underlying ACK/NACK concepts, RFC4585 retransmission types, and the three-step process of storing RTP packets, handling RTCP NACK messages, and retransmitting lost media with priority handling.
This article explains the implementation of NACK on the WebRTC video sending side, based on the master branch code (commit f412945f05ce1ac372a7dad77d85498d23deaae).
Concept Overview
ACK is an acknowledgment that confirms receipt of data, while NACK is a negative acknowledgment that notifies the sender of missing packets. RFC4585 defines two types of retransmission for lost data, and the commonly used RTP packet loss retransmission offers a short recovery cycle with minimal bandwidth impact.
Key Implementation Steps
1. Send RTP packets and store them in the packet_history_ queue
Each time the pacer sends a packet, the media packet is stored in the
packet_history_queue.
<code>ProcessThreadImpl::Process->PacedSender::Process->PacingController::ProcessPackets->PacketRouter::SendPacket->ModuleRtpRtcpImpl2::TrySendPacket->RtpSenderEgress::SendPacket</code>The
RtpPacketHistory::PutRtpPacketmethod stores RTP packets indexed by sequence number.
The queue length is configured via
SetStorePacketsStatus. Video streams are configured in
CreateRtpStreamSenders->SetStorePacketsStatus, and audio streams in
RegisterSenderCongestionControlObjects->SetStorePacketsStatus.
2. Handle received RTCP NACK packets
The call chain is:
<code>RTCPReceiver::HandleNack -> push packet_information->nack_sequence_numbers into loss queue</code>Then
ModuleRtpRtcpImpl::OnReceivedNackupdates RTT and forwards the NACK sequence numbers to
RTPSender::OnReceivedNack.
3. Retransmit RTP packets in response to NACK
RTPSender::OnReceivedNacktriggers retransmission. Three important points:
NackModule2::AddPacketsToNack decides whether a packet should be placed into the NACK queue.
Retransmission modes : either via a separate RTX channel or mixed with regular media; using a dedicated RTX channel is recommended to avoid interference with bitrate estimation and FEC configuration.
RTPSender::ReSendPacket enqueues the retransmitted packet with high priority using
set_packet_typeand the
kRetransmissiontype.
Priority configuration is performed in
GetPriorityForType, which assigns a high priority to retransmission packets, and the packet is then added to the pacer queue by
PacingController::EnqueuePacket.
Tencent Architect
We share technical insights on storage, computing, and access, and explore industry-leading product technologies together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.