rtp_parse/rtcp/rtcp_sr.rs
1use parsely_rs::*;
2use std::fmt::Debug;
3
4use super::{
5 rtcp_header::RtcpHeader, rtcp_report_block::RtcpReportBlock, rtcp_sender_info::RtcpSenderInfo,
6};
7
8/// https://datatracker.ietf.org/doc/html/rfc3550#section-6.4.1
9/// 0 1 2 3
10/// 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
11/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
12/// header |V=2|P| RC | PT=SR=200 | length |
13/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
14/// | SSRC of sender |
15/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
16/// sender | NTP timestamp, most significant word |
17/// info +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
18/// | NTP timestamp, least significant word |
19/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20/// | RTP timestamp |
21/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
22/// | sender's packet count |
23/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24/// | sender's octet count |
25/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
26/// report | SSRC_1 (SSRC of first source) |
27/// block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
28/// 1 | fraction lost | cumulative number of packets lost |
29/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
30/// | extended highest sequence number received |
31/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32/// | interarrival jitter |
33/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34/// | last SR (LSR) |
35/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36/// | delay since last SR (DLSR) |
37/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
38/// report | SSRC_2 (SSRC of second source) |
39/// block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40/// 2 : ... :
41/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
42/// | profile-specific extensions |
43/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44#[derive(Debug, PartialEq, Eq, ParselyRead, ParselyWrite)]
45#[parsely_read(required_context("rtcp_header: RtcpHeader"))]
46pub struct RtcpSrPacket {
47 #[parsely_read(assign_from = "rtcp_header")]
48 #[parsely_write(sync_with(
49 "self.payload_length_bytes()",
50 "self.report_blocks.len().try_into()"
51 ))]
52 pub header: RtcpHeader,
53 pub sender_ssrc: u32,
54 pub sender_info: RtcpSenderInfo,
55 #[parsely_read(count = "header.report_count.into()")]
56 pub report_blocks: Vec<RtcpReportBlock>,
57}
58
59impl RtcpSrPacket {
60 pub const PT: u8 = 200;
61
62 pub fn payload_length_bytes(&self) -> u16 {
63 (RtcpSenderInfo::SIZE_BYTES + self.report_blocks.len() * RtcpReportBlock::SIZE_BYTES) as u16
64 }
65}