Skip to main content

rtc_rtcp/receiver_report/
mod.rs

1#[cfg(test)]
2mod receiver_report_test;
3
4use crate::{header::*, packet::*, reception_report::*, util::*};
5use shared::{
6    error::{Error, Result},
7    marshal::{Marshal, MarshalSize, Unmarshal},
8};
9
10use bytes::{Buf, BufMut, Bytes};
11use std::any::Any;
12use std::fmt;
13
14pub(super) const RR_SSRC_OFFSET: usize = HEADER_LENGTH;
15pub(super) const RR_REPORT_OFFSET: usize = RR_SSRC_OFFSET + SSRC_LENGTH;
16
17/// A ReceiverReport (RR) packet provides reception quality feedback for an RTP stream
18#[derive(Debug, PartialEq, Eq, Default, Clone)]
19pub struct ReceiverReport {
20    /// The synchronization source identifier for the originator of this RR packet.
21    pub ssrc: u32,
22    /// Zero or more reception report blocks depending on the number of other
23    /// sources heard by this sender since the last report. Each reception report
24    /// block conveys statistics on the reception of RTP packets from a
25    /// single synchronization source.
26    pub reports: Vec<ReceptionReport>,
27    /// Extension contains additional, payload-specific information that needs to
28    /// be reported regularly about the receiver.
29    pub profile_extensions: Bytes,
30}
31
32impl fmt::Display for ReceiverReport {
33    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34        let mut out = format!("ReceiverReport from {}\n", self.ssrc);
35        out += "\tSSRC    \tLost\tLastSequence\n";
36        for rep in &self.reports {
37            out += format!(
38                "\t{:x}\t{}/{}\t{}\n",
39                rep.ssrc, rep.fraction_lost, rep.total_lost, rep.last_sequence_number
40            )
41            .as_str();
42        }
43        out += format!("\tProfile Extension Data: {:?}\n", self.profile_extensions).as_str();
44
45        write!(f, "{out}")
46    }
47}
48
49impl Packet for ReceiverReport {
50    /// Header returns the Header associated with this packet.
51    fn header(&self) -> Header {
52        Header {
53            padding: get_padding_size(self.raw_size()) != 0,
54            count: self.reports.len() as u8,
55            packet_type: PacketType::ReceiverReport,
56            length: ((self.marshal_size() / 4) - 1) as u16,
57        }
58    }
59
60    /// destination_ssrc returns an array of SSRC values that this packet refers to.
61    fn destination_ssrc(&self) -> Vec<u32> {
62        self.reports.iter().map(|x| x.ssrc).collect()
63    }
64
65    fn raw_size(&self) -> usize {
66        let mut reps_length = 0;
67        for rep in &self.reports {
68            reps_length += rep.marshal_size();
69        }
70
71        HEADER_LENGTH + SSRC_LENGTH + reps_length + self.profile_extensions.len()
72    }
73
74    fn as_any(&self) -> &dyn Any {
75        self
76    }
77
78    fn equal(&self, other: &dyn Packet) -> bool {
79        other.as_any().downcast_ref::<ReceiverReport>() == Some(self)
80    }
81
82    fn cloned(&self) -> Box<dyn Packet> {
83        Box::new(self.clone())
84    }
85}
86
87impl MarshalSize for ReceiverReport {
88    fn marshal_size(&self) -> usize {
89        let l = self.raw_size();
90        // align to 32-bit boundary
91        l + get_padding_size(l)
92    }
93}
94
95impl Marshal for ReceiverReport {
96    /// marshal_to encodes the packet in binary.
97    fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
98        if self.reports.len() > COUNT_MAX {
99            return Err(Error::TooManyReports);
100        }
101
102        if buf.remaining_mut() < self.marshal_size() {
103            return Err(Error::BufferTooShort);
104        }
105
106        /*
107         *         0                   1                   2                   3
108         *         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
109         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
110         * header |V=2|P|    RC   |   PT=RR=201   |             length            |
111         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
112         *        |                     SSRC of packet sender                     |
113         *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
114         * report |                 SSRC_1 (SSRC of first source)                 |
115         * block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
116         *   1    | fraction lost |       cumulative number of packets lost       |
117         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
118         *        |           extended highest sequence number received           |
119         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
120         *        |                      interarrival jitter                      |
121         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
122         *        |                         last SR (LSR)                         |
123         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
124         *        |                   delay since last SR (DLSR)                  |
125         *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
126         * report |                 SSRC_2 (SSRC of second source)                |
127         * block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
128         *   2    :                               ...                             :
129         *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
130         *        |                  profile-specific extensions                  |
131         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
132         */
133        let h = self.header();
134        let n = h.marshal_to(buf)?;
135        buf = &mut buf[n..];
136
137        buf.put_u32(self.ssrc);
138
139        for report in &self.reports {
140            let n = report.marshal_to(buf)?;
141            buf = &mut buf[n..];
142        }
143
144        buf.put(self.profile_extensions.clone());
145
146        if h.padding {
147            put_padding(buf, self.raw_size());
148        }
149
150        Ok(self.marshal_size())
151    }
152}
153
154impl Unmarshal for ReceiverReport {
155    /// Unmarshal decodes the ReceiverReport from binary
156    fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
157    where
158        Self: Sized,
159        B: Buf,
160    {
161        /*
162         *         0                   1                   2                   3
163         *         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
164         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
165         * header |V=2|P|    RC   |   PT=RR=201   |             length            |
166         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
167         *        |                     SSRC of packet sender                     |
168         *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
169         * report |                 SSRC_1 (SSRC of first source)                 |
170         * block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
171         *   1    | fraction lost |       cumulative number of packets lost       |
172         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
173         *        |           extended highest sequence number received           |
174         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
175         *        |                      interarrival jitter                      |
176         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
177         *        |                         last SR (LSR)                         |
178         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
179         *        |                   delay since last SR (DLSR)                  |
180         *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
181         * report |                 SSRC_2 (SSRC of second source)                |
182         * block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
183         *   2    :                               ...                             :
184         *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
185         *        |                  profile-specific extensions                  |
186         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
187         */
188        let raw_packet_len = raw_packet.remaining();
189        if raw_packet_len < (HEADER_LENGTH + SSRC_LENGTH) {
190            return Err(Error::PacketTooShort);
191        }
192
193        let header = Header::unmarshal(raw_packet)?;
194        if header.packet_type != PacketType::ReceiverReport {
195            return Err(Error::WrongType);
196        }
197
198        let ssrc = raw_packet.get_u32();
199
200        let mut offset = RR_REPORT_OFFSET;
201        let mut reports = Vec::with_capacity(header.count as usize);
202        for _ in 0..header.count {
203            if offset + RECEPTION_REPORT_LENGTH > raw_packet_len {
204                return Err(Error::PacketTooShort);
205            }
206            let reception_report = ReceptionReport::unmarshal(raw_packet)?;
207            reports.push(reception_report);
208            offset += RECEPTION_REPORT_LENGTH;
209        }
210        let profile_extensions = raw_packet.copy_to_bytes(raw_packet.remaining());
211        /*
212        if header.padding && raw_packet.has_remaining() {
213            raw_packet.advance(raw_packet.remaining());
214        }
215         */
216
217        Ok(ReceiverReport {
218            ssrc,
219            reports,
220            profile_extensions,
221        })
222    }
223}