rtcp/transport_feedbacks/transport_layer_nack/
mod.rs1#[cfg(test)]
2mod transport_layer_nack_test;
3
4use std::any::Any;
5use std::fmt;
6
7use bytes::{Buf, BufMut};
8use util::marshal::{Marshal, MarshalSize, Unmarshal};
9
10use crate::error::Error;
11use crate::header::*;
12use crate::packet::*;
13use crate::util::*;
14
15type PacketBitmap = u16;
18
19#[derive(Debug, PartialEq, Eq, Default, Clone, Copy)]
22pub struct NackPair {
23 pub packet_id: u16,
25 pub lost_packets: PacketBitmap,
27}
28
29pub 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 {
63 Self {
64 packet_id: seq,
65 lost_packets: Default::default(),
66 }
67 }
68
69 pub fn packet_list(&self) -> Vec<u16> {
71 self.into_iter().collect()
72 }
73
74 pub fn range<F>(&self, f: F)
75 where
76 F: Fn(u16) -> bool,
77 {
78 for packet_id in self.into_iter() {
79 if !f(packet_id) {
80 return;
81 }
82 }
83 }
84}
85
86impl IntoIterator for NackPair {
88 type Item = u16;
89
90 type IntoIter = NackIterator;
91
92 fn into_iter(self) -> Self::IntoIter {
93 NackIterator {
94 packet_id: self.packet_id,
95 bitfield: self.lost_packets,
96 has_yielded_packet_id: false,
97 }
98 }
99}
100
101const TLN_LENGTH: usize = 2;
102const NACK_OFFSET: usize = 8;
103
104#[derive(Debug, PartialEq, Eq, Default, Clone)]
111pub struct TransportLayerNack {
112 pub sender_ssrc: u32,
114 pub media_ssrc: u32,
116
117 pub nacks: Vec<NackPair>,
118}
119
120impl fmt::Display for TransportLayerNack {
121 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122 let mut out = format!("TransportLayerNack from {:x}\n", self.sender_ssrc);
123 out += format!("\tMedia Ssrc {:x}\n", self.media_ssrc).as_str();
124 out += "\tID\tLostPackets\n";
125 for nack in &self.nacks {
126 out += format!("\t{}\t{:b}\n", nack.packet_id, nack.lost_packets).as_str();
127 }
128 write!(f, "{out}")
129 }
130}
131
132impl Packet for TransportLayerNack {
133 fn header(&self) -> Header {
135 Header {
136 padding: get_padding_size(self.raw_size()) != 0,
137 count: FORMAT_TLN,
138 packet_type: PacketType::TransportSpecificFeedback,
139 length: ((self.marshal_size() / 4) - 1) as u16,
140 }
141 }
142
143 fn destination_ssrc(&self) -> Vec<u32> {
145 vec![self.media_ssrc]
146 }
147
148 fn raw_size(&self) -> usize {
149 HEADER_LENGTH + NACK_OFFSET + self.nacks.len() * 4
150 }
151
152 fn as_any(&self) -> &(dyn Any + Send + Sync) {
153 self
154 }
155
156 fn equal(&self, other: &(dyn Packet + Send + Sync)) -> bool {
157 other.as_any().downcast_ref::<TransportLayerNack>() == Some(self)
158 }
159
160 fn cloned(&self) -> Box<dyn Packet + Send + Sync> {
161 Box::new(self.clone())
162 }
163}
164
165impl MarshalSize for TransportLayerNack {
166 fn marshal_size(&self) -> usize {
167 let l = self.raw_size();
168 l + get_padding_size(l)
170 }
171}
172
173impl Marshal for TransportLayerNack {
174 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize, util::Error> {
176 if self.nacks.len() + TLN_LENGTH > u8::MAX as usize {
177 return Err(Error::TooManyReports.into());
178 }
179 if buf.remaining_mut() < self.marshal_size() {
180 return Err(Error::BufferTooShort.into());
181 }
182
183 let h = self.header();
184 let n = h.marshal_to(buf)?;
185 buf = &mut buf[n..];
186
187 buf.put_u32(self.sender_ssrc);
188 buf.put_u32(self.media_ssrc);
189
190 for i in 0..self.nacks.len() {
191 buf.put_u16(self.nacks[i].packet_id);
192 buf.put_u16(self.nacks[i].lost_packets);
193 }
194
195 if h.padding {
196 put_padding(buf, self.raw_size());
197 }
198
199 Ok(self.marshal_size())
200 }
201}
202
203impl Unmarshal for TransportLayerNack {
204 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self, util::Error>
206 where
207 Self: Sized,
208 B: Buf,
209 {
210 let raw_packet_len = raw_packet.remaining();
211 if raw_packet_len < (HEADER_LENGTH + SSRC_LENGTH) {
212 return Err(Error::PacketTooShort.into());
213 }
214
215 let h = Header::unmarshal(raw_packet)?;
216
217 if raw_packet_len < (HEADER_LENGTH + (4 * h.length) as usize) {
218 return Err(Error::PacketTooShort.into());
219 }
220
221 if h.packet_type != PacketType::TransportSpecificFeedback || h.count != FORMAT_TLN {
222 return Err(Error::WrongType.into());
223 }
224
225 let sender_ssrc = raw_packet.get_u32();
226 let media_ssrc = raw_packet.get_u32();
227
228 let mut nacks = vec![];
229 for _i in 0..(h.length as i32 - NACK_OFFSET as i32 / 4) {
230 nacks.push(NackPair {
231 packet_id: raw_packet.get_u16(),
232 lost_packets: raw_packet.get_u16(),
233 });
234 }
235
236 if
237 raw_packet.has_remaining() {
239 raw_packet.advance(raw_packet.remaining());
240 }
241
242 Ok(TransportLayerNack {
243 sender_ssrc,
244 media_ssrc,
245 nacks,
246 })
247 }
248}
249
250pub fn nack_pairs_from_sequence_numbers(seq_nos: &[u16]) -> Vec<NackPair> {
251 if seq_nos.is_empty() {
252 return vec![];
253 }
254
255 let mut nack_pair = NackPair::new(seq_nos[0]);
256 let mut pairs = vec![];
257
258 for &seq in seq_nos.iter().skip(1) {
259 if seq == nack_pair.packet_id {
260 continue;
261 }
262 if seq <= nack_pair.packet_id || seq > nack_pair.packet_id.saturating_add(16) {
263 pairs.push(nack_pair);
264 nack_pair = NackPair::new(seq);
265 continue;
266 }
267
268 nack_pair.lost_packets |= 1 << (seq - nack_pair.packet_id - 1);
270 }
271
272 pairs.push(nack_pair);
273
274 pairs
275}