rtc_rtcp/transport_feedbacks/transport_layer_nack/
mod.rs1#[cfg(test)]
2mod transport_layer_nack_test;
3
4use crate::{header::*, packet::*, util::*};
5use shared::{
6 error::{Error, Result},
7 marshal::{Marshal, MarshalSize, Unmarshal},
8};
9
10use bytes::{Buf, BufMut};
11use std::any::Any;
12use std::fmt;
13
14type PacketBitmap = u16;
17
18#[derive(Debug, PartialEq, Eq, Default, Clone, Copy)]
21pub struct NackPair {
22 pub packet_id: u16,
24 pub lost_packets: PacketBitmap,
26}
27
28pub struct NackIterator {
30 packet_id: u16,
31 bitfield: PacketBitmap,
32 has_yielded_packet_id: bool,
33}
34
35impl Iterator for NackIterator {
36 type Item = u16;
37
38 fn next(&mut self) -> Option<Self::Item> {
39 if !self.has_yielded_packet_id {
40 self.has_yielded_packet_id = true;
41
42 Some(self.packet_id)
43 } else {
44 let mut i = 0;
45
46 while self.bitfield != 0 {
47 if (self.bitfield & (1 << i)) != 0 {
48 self.bitfield &= !(1 << i);
49
50 return Some(self.packet_id.wrapping_add(i + 1));
51 }
52
53 i += 1;
54 }
55
56 None
57 }
58 }
59}
60
61impl NackPair {
62 pub fn new(seq: u16) -> Self {
64 Self {
65 packet_id: seq,
66 lost_packets: Default::default(),
67 }
68 }
69
70 pub fn packet_list(&self) -> Vec<u16> {
72 self.into_iter().collect()
73 }
74
75 pub fn range<F>(&self, f: F)
79 where
80 F: Fn(u16) -> bool,
81 {
82 for packet_id in self.into_iter() {
83 if !f(packet_id) {
84 return;
85 }
86 }
87 }
88}
89
90impl IntoIterator for NackPair {
92 type Item = u16;
93
94 type IntoIter = NackIterator;
95
96 fn into_iter(self) -> Self::IntoIter {
97 NackIterator {
98 packet_id: self.packet_id,
99 bitfield: self.lost_packets,
100 has_yielded_packet_id: false,
101 }
102 }
103}
104
105const TLN_LENGTH: usize = 2;
106const NACK_OFFSET: usize = 8;
107
108const NACK_MIN_OCTET_COUNT: usize = 12;
113
114#[derive(Debug, PartialEq, Eq, Default, Clone)]
121pub struct TransportLayerNack {
122 pub sender_ssrc: u32,
124 pub media_ssrc: u32,
126
127 pub nacks: Vec<NackPair>,
129}
130
131impl fmt::Display for TransportLayerNack {
132 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133 let mut out = format!("TransportLayerNack from {:x}\n", self.sender_ssrc);
134 out += format!("\tMedia Ssrc {:x}\n", self.media_ssrc).as_str();
135 out += "\tID\tLostPackets\n";
136 for nack in &self.nacks {
137 out += format!("\t{}\t{:b}\n", nack.packet_id, nack.lost_packets).as_str();
138 }
139 write!(f, "{out}")
140 }
141}
142
143impl Packet for TransportLayerNack {
144 fn header(&self) -> Header {
146 Header {
147 padding: get_padding_size(self.raw_size()) != 0,
148 count: FORMAT_TLN,
149 packet_type: PacketType::TransportSpecificFeedback,
150 length: ((self.marshal_size() / 4) - 1) as u16,
151 }
152 }
153
154 fn destination_ssrc(&self) -> Vec<u32> {
156 vec![self.media_ssrc]
157 }
158
159 fn raw_size(&self) -> usize {
160 HEADER_LENGTH + NACK_OFFSET + self.nacks.len() * 4
161 }
162
163 fn as_any(&self) -> &dyn Any {
164 self
165 }
166
167 fn equal(&self, other: &dyn Packet) -> bool {
168 other.as_any().downcast_ref::<TransportLayerNack>() == Some(self)
169 }
170
171 fn cloned(&self) -> Box<dyn Packet> {
172 Box::new(self.clone())
173 }
174}
175
176impl MarshalSize for TransportLayerNack {
177 fn marshal_size(&self) -> usize {
178 let l = self.raw_size();
179 l + get_padding_size(l)
181 }
182}
183
184impl Marshal for TransportLayerNack {
185 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
187 if self.nacks.len() + TLN_LENGTH > u8::MAX as usize {
188 return Err(Error::TooManyReports);
189 }
190 if buf.remaining_mut() < self.marshal_size() {
191 return Err(Error::BufferTooShort);
192 }
193
194 let h = self.header();
195 let n = h.marshal_to(buf)?;
196 buf = &mut buf[n..];
197
198 buf.put_u32(self.sender_ssrc);
199 buf.put_u32(self.media_ssrc);
200
201 for i in 0..self.nacks.len() {
202 buf.put_u16(self.nacks[i].packet_id);
203 buf.put_u16(self.nacks[i].lost_packets);
204 }
205
206 if h.padding {
207 put_padding(buf, self.raw_size());
208 }
209
210 Ok(self.marshal_size())
211 }
212}
213
214impl Unmarshal for TransportLayerNack {
215 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
217 where
218 Self: Sized,
219 B: Buf,
220 {
221 let raw_packet_len = raw_packet.remaining();
222 if raw_packet_len < (HEADER_LENGTH + NACK_MIN_OCTET_COUNT) {
223 return Err(Error::PacketTooShort);
224 }
225
226 let h = Header::unmarshal(raw_packet)?;
227
228 if raw_packet_len < (HEADER_LENGTH + 4 * (h.length as usize)) {
229 return Err(Error::PacketTooShort);
230 }
231
232 if h.packet_type != PacketType::TransportSpecificFeedback || h.count != FORMAT_TLN {
233 return Err(Error::WrongType);
234 }
235
236 let sender_ssrc = raw_packet.get_u32();
237 let media_ssrc = raw_packet.get_u32();
238
239 let mut nacks = vec![];
240 for _i in 0..(h.length as i32 - NACK_OFFSET as i32 / 4) {
241 nacks.push(NackPair {
242 packet_id: raw_packet.get_u16(),
243 lost_packets: raw_packet.get_u16(),
244 });
245 }
246
247 if
248 raw_packet.has_remaining() {
250 raw_packet.advance(raw_packet.remaining());
251 }
252
253 Ok(TransportLayerNack {
254 sender_ssrc,
255 media_ssrc,
256 nacks,
257 })
258 }
259}
260
261pub fn nack_pairs_from_sequence_numbers(seq_nos: &[u16]) -> Vec<NackPair> {
265 if seq_nos.is_empty() {
266 return vec![];
267 }
268
269 let mut nack_pair = NackPair::new(seq_nos[0]);
270 let mut pairs = vec![];
271
272 for &seq in seq_nos.iter().skip(1) {
273 if seq == nack_pair.packet_id {
274 continue;
275 }
276 if seq <= nack_pair.packet_id || seq > nack_pair.packet_id.saturating_add(16) {
277 pairs.push(nack_pair);
278 nack_pair = NackPair::new(seq);
279 continue;
280 }
281
282 nack_pair.lost_packets |= 1 << (seq - nack_pair.packet_id - 1);
284 }
285
286 pairs.push(nack_pair);
287
288 pairs
289}