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}