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