Expand description
RTCP control packets — RFC 3550 §6, spec-complete (not just a happy-path subset).
Typed, symmetric Parse/Serialize
for every RTCP packet type described in the curated spec transcription at
rtcp-packet/docs/rtcp.md (fetched directly from
RFC 3550) — cite that file,
not this doc comment, as the field-semantics oracle.
SenderReport— SR (§6.4.1, PT 200).ReceiverReport— RR (§6.4.2, PT 201).ReportBlock— the 24-byte reception report block shared by SR/RR.SourceDescription/SdesChunk/SdesItem/SdesItemType— SDES (§6.5, PT 202).Bye— BYE (§6.6, PT 203).App— APP (§6.7, PT 204).RtcpPacket/RtcpPacketType— the packet-type dispatch enum.CompoundPacket— §6.1’s compound packet (a sequence of RTCP packets that must begin with SR or RR), with byte-exact round-trip.
Two decode-completeness gaps are documented (not silently glossed over)
in docs/rtcp.md: SR/RR profile-specific extensions and the SDES PRIV
item’s internal prefix/value sub-structure are not separately typed.
RTCP carries no media — this is a standalone wire codec for the RTP
control channel (a companion to the rtp-packet crate), not a hub
Package/Unpackage spoke.
Depends only on broadcast-common. #![no_std] (+ alloc) when the
std feature is disabled.
§Examples
Build a Sender Report with two reception report blocks and round-trip it:
use broadcast_common::{Parse, Serialize};
use rtcp_packet::{ReportBlock, SenderReport};
let sr = SenderReport {
ssrc: 0x1122_3344,
ntp_msw: 0xE0E1_E2E3,
ntp_lsw: 0x1020_3040,
rtp_timestamp: 0x0009_0000,
packet_count: 4321,
octet_count: 999_999,
report_blocks: vec![ReportBlock {
ssrc: 0xAAAA_AAAA,
fraction_lost: 12,
cumulative_lost: -3,
ext_highest_seq: 0x0001_2345,
jitter: 500,
lsr: 0xAABB_CCDD,
dlsr: 0x0000_1000,
}],
};
let mut bytes = vec![0u8; sr.serialized_len()];
sr.serialize_into(&mut bytes).unwrap();
assert_eq!(SenderReport::parse(&bytes).unwrap(), sr);§Runnable examples
Run with cargo run -p rtcp-packet --example <name>.
§build_sender_report
//! Build an RTCP Sender Report with two reception report blocks from typed
//! fields and serialize it to wire bytes — RFC 3550 §6.4.1.
//!
//! Run with `cargo run -p rtcp-packet --example build_sender_report`.
use broadcast_common::Serialize;
use rtcp_packet::{ReportBlock, SenderReport};
fn main() {
let sr = SenderReport {
ssrc: 0x1122_3344,
ntp_msw: 0xE0E1_E2E3,
ntp_lsw: 0x1020_3040,
rtp_timestamp: 0x0009_0000,
packet_count: 4321,
octet_count: 999_999,
report_blocks: vec![
ReportBlock {
ssrc: 0xAAAA_AAAA,
fraction_lost: 12,
cumulative_lost: 17,
ext_highest_seq: 0x0001_2345,
jitter: 500,
lsr: 0xAABB_CCDD,
dlsr: 0x0000_1000,
},
ReportBlock {
ssrc: 0xBBBB_BBBB,
fraction_lost: 0,
cumulative_lost: -3, // negative: duplicates exceeded losses (§6.4.1)
ext_highest_seq: 0x0002_0000,
jitter: 750,
lsr: 0,
dlsr: 0,
},
],
};
let mut bytes = vec![0u8; sr.serialized_len()];
sr.serialize_into(&mut bytes).expect("serialize");
println!("serialized {} bytes:", bytes.len());
println!(
"{}",
bytes
.iter()
.map(|b| format!("{b:02x}"))
.collect::<Vec<_>>()
.join(" ")
);
println!(
"V={} P={} RC={} PT={}",
bytes[0] >> 6,
(bytes[0] >> 5) & 1,
bytes[0] & 0x1F,
bytes[1]
);
}§parse_compound_packet
//! Build a compound RTCP packet (SR followed by an SDES CNAME chunk, the
//! canonical §6.1 "session report" shape), parse it back, and confirm a
//! byte-exact round trip — RFC 3550 §6.1.
//!
//! Run with `cargo run -p rtcp-packet --example parse_compound_packet`.
use broadcast_common::{Parse, Serialize};
use rtcp_packet::{
CompoundPacket, ReportBlock, RtcpPacket, SdesChunk, SdesItem, SdesItemType, SenderReport,
SourceDescription,
};
fn main() {
let sr = SenderReport {
ssrc: 0x1122_3344,
ntp_msw: 0xE1E2_E3E4,
ntp_lsw: 0x5060_7080,
rtp_timestamp: 0x000A_0000,
packet_count: 12345,
octet_count: 6_789_012,
report_blocks: vec![ReportBlock {
ssrc: 0xAAAA_0001,
fraction_lost: 0,
cumulative_lost: 0,
ext_highest_seq: 0x0000_ABCD,
jitter: 111,
lsr: 0x1234_5678,
dlsr: 0x0000_0100,
}],
};
let sdes = SourceDescription {
chunks: vec![SdesChunk {
source: 0x1122_3344, // same SSRC as the SR: one participant, two reports
items: vec![SdesItem {
item_type: SdesItemType::CName,
text: "alice@example.com".to_string(),
}],
}],
};
let compound = CompoundPacket::new(vec![
RtcpPacket::SenderReport(sr),
RtcpPacket::SourceDescription(sdes),
])
.expect("SR-first compound packet");
let mut bytes = vec![0u8; compound.serialized_len()];
compound.serialize_into(&mut bytes).expect("serialize");
println!("serialized {} bytes (SR + SDES)", bytes.len());
let parsed = CompoundPacket::parse(&bytes).expect("parse");
for (i, pkt) in parsed.packets.iter().enumerate() {
println!(" packet {i}: {} ({:?})", pkt.name(), pkt.packet_type());
}
let mut out = vec![0u8; parsed.serialized_len()];
parsed.serialize_into(&mut out).expect("re-serialize");
assert_eq!(out, bytes, "byte-identical round trip");
println!("round trip byte-identical: OK ({} bytes)", out.len());
}Structs§
- App
- RTCP Application-defined packet (RFC 3550 §6.7, PT 204).
- Bye
- RTCP Goodbye (RFC 3550 §6.6, PT 203).
- Common
Header - The 4-byte RTCP common header shared by every packet type (RFC 3550 §6.1).
- Compound
Packet - A compound RTCP packet (RFC 3550 §6.1): a sequence of RTCP packets sent in a single lower-layer datagram. The first packet must be a report (SR or RR); this is validated on both parse and serialize.
- Receiver
Report - RTCP Receiver Report (RFC 3550 §6.4.2, PT 201).
- Report
Block - A reception report block (RFC 3550 §6.4.1, 24 bytes). Carried by both SR and RR, one per reported source.
- Sdes
Chunk - An SDES chunk: an SSRC/CSRC plus its list of items (RFC 3550 §6.5).
- Sdes
Item - A single SDES item: a typed, length-prefixed text field (RFC 3550 §6.5).
- Sender
Report - RTCP Sender Report (RFC 3550 §6.4.1, PT 200).
- Source
Description - RTCP Source Description (RFC 3550 §6.5, PT 202).
Enums§
- Error
- An RTCP packet parse / serialize error.
- Rtcp
Packet - Any single RTCP packet, dispatched by its common-header
PTbyte (RFC 3550 §6). - Rtcp
Packet Type - The RTCP packet type carried in the common header
PTbyte (RFC 3550 §6). - Sdes
Item Type - SDES item type (RFC 3550 §6.5). Byte-valued; type 0 is the item terminator.
Constants§
- APP_
NAME_ LEN - Length of the APP
namefield — 4 ASCII characters (RFC 3550 §6.7). - PT_APP
- Packet type: Application-defined (RFC 3550 §6.7).
- PT_BYE
- Packet type: Goodbye (RFC 3550 §6.6).
- PT_
RECEIVER_ REPORT - Packet type: Receiver Report (RFC 3550 §6.4.2).
- PT_
SENDER_ REPORT - Packet type: Sender Report (RFC 3550 §6.4.1).
- PT_
SOURCE_ DESCRIPTION - Packet type: Source Description (RFC 3550 §6.5).
- REPORT_
BLOCK_ LEN - Length of a single
ReportBlockon the wire (RFC 3550 §6.4.1). - SDES_
CNAME - SDES item type value: CNAME (RFC 3550 §6.5.1).
- SDES_
EMAIL - SDES item type value: EMAIL (RFC 3550 §6.5.3).
- SDES_
LOC - SDES item type value: LOC (RFC 3550 §6.5.5).
- SDES_
NAME - SDES item type value: NAME (RFC 3550 §6.5.2).
- SDES_
NOTE - SDES item type value: NOTE (RFC 3550 §6.5.7).
- SDES_
PHONE - SDES item type value: PHONE (RFC 3550 §6.5.4).
- SDES_
PRIV - SDES item type value: PRIV (RFC 3550 §6.5.8).
- SDES_
TOOL - SDES item type value: TOOL (RFC 3550 §6.5.6).
Type Aliases§
- Result
- Result alias for
rtcp-packetparsing/serialization.