Skip to content
File

Blob: firmware/vendor/str0m/src/rtp/rtcp/nack.rs

rust157 lines
1use super::extend_u16;
2use super::{FeedbackMessageType, ReportList, RtcpHeader, RtcpPacket, SeqNo};
3use super::{RtcpType, Ssrc, TransportType};
4 
5use super::list::private::WordSized;
6 
7/// A NACK entry indiciating packets missing.
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct Nack {
10 /// Sender of this feedback. Mostly irrelevant, but part of RTCP packets.
11 pub sender_ssrc: Ssrc,
12 /// The SSRC this nack reports missing packets for.
13 pub ssrc: Ssrc,
14 /// The missing nack. This can be multiple segments.
15 pub reports: ReportList<NackEntry>,
16}
17 
18/// A range of sequence numbers missing.
19#[allow(missing_docs)]
20#[derive(Debug, PartialEq, Eq, Default, Clone, Copy)]
21pub struct NackEntry {
22 pub pid: u16,
23 pub blp: u16,
24}
25 
26impl RtcpPacket for Nack {
27 fn header(&self) -> RtcpHeader {
28 RtcpHeader {
29 rtcp_type: RtcpType::TransportLayerFeedback,
30 feedback_message_type: FeedbackMessageType::TransportFeedback(TransportType::Nack),
31 words_less_one: (self.length_words() - 1) as u16,
32 }
33 }
34 
35 fn length_words(&self) -> usize {
36 // header
37 // sender SSRC
38 // media SSRC
39 // 1 word per NackPair
40 1 + 2 + self.reports.len()
41 }
42 
43 fn write_to(&self, buf: &mut [u8]) -> usize {
44 self.header().write_to(&mut buf[..4]);
45 buf[4..8].copy_from_slice(&self.sender_ssrc.to_be_bytes());
46 buf[8..12].copy_from_slice(&self.ssrc.to_be_bytes());
47 let mut buf = &mut buf[12..];
48 for r in &self.reports {
49 buf[0..2].copy_from_slice(&r.pid.to_be_bytes());
50 buf[2..4].copy_from_slice(&r.blp.to_be_bytes());
51 buf = &mut buf[4..];
52 }
53 self.length_words() * 4
54 }
55}
56 
57impl WordSized for NackEntry {
58 fn word_size(&self) -> usize {
59 1
60 }
61}
62 
63impl<'a> TryFrom<&'a [u8]> for Nack {
64 type Error = &'static str;
65 
66 fn try_from(buf: &'a [u8]) -> Result<Self, Self::Error> {
67 if buf.len() < 12 {
68 return Err("Nack less than 12 bytes");
69 }
70 
71 let sender_ssrc = u32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]).into();
72 let ssrc = u32::from_be_bytes([buf[4], buf[5], buf[6], buf[7]]).into();
73 
74 let mut reports = ReportList::new();
75 
76 let mut buf = &buf[8..];
77 let count = buf.len() / 4;
78 let max = count.min(31);
79 
80 for _ in 0..max {
81 let pid = u16::from_be_bytes([buf[0], buf[1]]);
82 let blp = u16::from_be_bytes([buf[2], buf[3]]);
83 reports.push(NackEntry { pid, blp });
84 buf = &buf[4..];
85 }
86 
87 Ok(Nack {
88 sender_ssrc,
89 ssrc,
90 reports,
91 })
92 }
93}
94 
95impl NackEntry {
96 /// Iterator over sequence numbers missing.
97 ///
98 /// The given sequence number is used to interpret ROC.
99 pub fn into_iter(self, seq_no: SeqNo) -> impl Iterator<Item = SeqNo> {
100 NackEntryIterator(self, 0, seq_no)
101 }
102}
103 
104pub struct NackEntryIterator(NackEntry, u16, SeqNo);
105 
106impl Iterator for NackEntryIterator {
107 type Item = SeqNo;
108 
109 fn next(&mut self) -> Option<Self::Item> {
110 let seq_16 = if self.1 == 0 {
111 self.1 += 1;
112 self.0.pid
113 } else {
114 loop {
115 if self.1 >= 17 {
116 return None;
117 }
118 let i = self.1 - 1;
119 self.1 += 1;
120 if 1 << i & self.0.blp > 0 {
121 break self.0.pid.wrapping_add(self.1 - 1);
122 }
123 }
124 };
125 let l = extend_u16(Some(*self.2), seq_16);
126 Some(l.into())
127 }
128}
129 
130#[cfg(test)]
131mod test {
132 use super::*;
133 
134 #[test]
135 fn nack_entry_iter() {
136 // 196_618
137 let seq_no: SeqNo = (65_536_u64 * 3 + 10).into();
138 
139 // 196_508
140 let pid = (65_536_u32 - 100) as u16;
141 
142 println!("{seq_no:?} {pid:?}");
143 
144 // 196_509, 196_512, 196_524
145 let blp = 0b1000_0000_0000_1001;
146 
147 let entry = NackEntry { pid, blp };
148 
149 let nacks: Vec<_> = entry.into_iter(seq_no).collect();
150 
151 assert_eq!(
152 nacks,
153 vec![196508.into(), 196509.into(), 196512.into(), 196524.into()]
154 );
155 }
156}