RTCP control¶
Relay - rtcp
REL-04 - status: review - audio, video
RTCP feedback/control packets on the call media path: a standard Sender Report (PT 200) plus two WhatsApp compact reports (PT 208, PT 209), and the rule for classifying a received packet as RTP or RTCP on a shared port.
RTCP shares the media 5-tuple with RTP and is protected as SRTCP (see
srtp-hop-by-hop). Every packet uses RTP version 2 (top two
bits of byte 0 = 0b10) and an 8-byte fixed header: version/padding/count,
payload type, big-endian 16-bit length. length MUST be packet size in
32-bit words minus one. All multi-byte integers are big-endian.
Sender Report (PT 200). 28-byte cleartext. RC MUST be 0 (no reception report blocks). Layout:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1 0|0|0 0 0 0 0| PT = 200 | length = 6 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| sender SSRC |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| NTP timestamp, seconds (since 1900) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| NTP timestamp, fraction |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RTP timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| sender's packet count |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| sender's octet count |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- byte 0 MUST be
0x80; byte 1 MUST be200;lengthMUST be6. sender SSRCMUST be the sender's own SSRC (see ssrc).- NTP timestamp encodes wall-clock send time as 64-bit NTP: high 32 bits =
(floor(now_ms / 1000) + 2208988800) mod 2^32; low 32 bits =floor((now_ms mod 1000) / 1000 * 2^32). RTP timestampMUST correspond to the same instant as the NTP timestamp, in the sender stream's clock units.sender's packet count/sender's octet countMUST be the total RTP data packets / payload octets transmitted since stream start.
Compact report (PT 208). 12-byte cleartext binding local to remote source:
0 1 2 3
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1 0|0|0 0 0 0 1| PT = 208 | length = 2 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| local SSRC |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| remote SSRC |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- byte 0 MUST be
0x81; byte 1 MUST be208;lengthMUST be2. - First SSRC word MUST be local source; second MUST be remote source.
Compact report (PT 209). 8-byte cleartext, local source only, pre-speech:
0 1 2 3
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1 0|0|0 0 0 0 1| PT = 209 | length = 1 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| local SSRC |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- byte 0 MUST be
0x81; byte 1 MUST be209;lengthMUST be1.
On-the-wire size with SRTCP. SRTCP appends a 14-byte authenticated trailer (E-flag/index word plus auth tag): PT 208 = 26 bytes, PT 209 = 22 bytes, Sender Report = 42 bytes on the wire.
Classification (RTP vs. RTCP). On a shared port, a receiver MUST treat a packet as RTCP only if ALL hold, else as RTP:
- length >= 22 bytes (8-byte header + 14-byte SRTCP trailer);
- version bits (top two bits of byte 0) == 2;
- byte 1 as unsigned 8-bit >= 64.
WhatsApp RTP sets the extension bit (X=1, byte 0 0x90) and a 7-bit payload
type in the low bits of byte 1: a receiver MUST NOT classify a packet as RTCP
when byte 0's extension bit is set and the low 7 bits of byte 1 equal the Opus
RTP payload type. The RTCP payload type is the full byte 1; sender SSRC is
bytes 4..8.
Requires: srtp-hop-by-hop, ssrc, rtp-framing
Implemented by
| Flavor | Status | Source | Notes |
|---|---|---|---|
whatsapp-rust |
working | history - blame - commits 674e851 |
— |
zapo-caller |
working | — | origin of the rtcp.ts implementation this is ported from |
Annotation wacrg:REL-04 — a flavor marks its implementation site in source with this comment; a script clones the source, finds it, and attaches the commit blame/permalink.
Contributors
| Contributor | Role |
|---|---|
| wrote initial spec |
protocol history / diff - blame
Open questions - Trigger conditions and cadence for emitting PT 208 vs PT 209, and how often Sender Reports are sent. - Semantics consumed by the peer/relay from the PT 208/209 compact reports beyond the SSRC binding.
References - RFC 3550 — RTP/RTCP - RFC 3711 — SRTP/SRTCP
Changelog¶
- 2026-06-21 — Initial spec entry.