1use crate::prelude::*;
4use crate::{utils::u32_from_be_bytes, RtcpParseError};
5
6use super::{pad_to_4bytes, u16_from_be_bytes, xr_offset_sequence, RtcpPacketWriter, XrBlock};
7
8#[derive(Debug)]
10pub struct Rle<'a> {
11 pub(crate) block: XrBlock<'a>,
12}
13
14impl<'a> Rle<'a> {
15 pub fn parse(data: &'a [u8]) -> Result<Self, RtcpParseError> {
17 let block = XrBlock::parse(data)?;
18 if block.length() < 12 {
19 return Err(RtcpParseError::Truncated {
20 expected: 12,
21 actual: block.length(),
22 });
23 }
24 let ret = Self { block };
25 Ok(ret)
26 }
27
28 pub fn thinning(&self) -> u8 {
31 self.block.data[1] & 0x0f
32 }
33
34 pub fn media_ssrc(&self) -> u32 {
36 u32_from_be_bytes(&self.block.data[4..8])
37 }
38
39 pub fn begin(&self) -> u16 {
42 u16_from_be_bytes(&self.block.data[8..10])
43 }
44
45 pub fn end(&self) -> u16 {
48 u16_from_be_bytes(&self.block.data[10..12])
49 }
50
51 pub fn sequence_iter(&self) -> impl Iterator<Item = u16> + '_ {
53 RleSequenceIter {
54 rle: self,
55 block_iter: RleBlockIter {
56 rle: self,
57 block_offset: 12,
58 },
59 chunk_iter: None,
60 seq_offset: self.begin(),
61 }
62 }
63
64 pub fn chunk_iter(&self) -> impl Iterator<Item = RleChunk> + '_ {
66 RleBlockIter {
67 rle: self,
68 block_offset: 12,
69 }
70 }
71
72 pub fn builder() -> RleBuilder {
74 RleBuilder::default()
75 }
76}
77
78#[derive(Debug)]
79struct RleBlockIter<'a> {
80 rle: &'a Rle<'a>,
81 block_offset: usize,
83}
84
85impl Iterator for RleBlockIter<'_> {
86 type Item = RleChunk;
87
88 fn next(&mut self) -> Option<Self::Item> {
89 if self.block_offset + 2 >= self.rle.block.length() {
90 return None;
91 }
92 let chunk = RleChunk::parse(&self.rle.block.data[self.block_offset..self.block_offset + 2]);
93 self.block_offset += 2;
94 Some(chunk)
95 }
96}
97
98pub struct RleSequenceIter<'a> {
99 rle: &'a Rle<'a>,
100 block_iter: RleBlockIter<'a>,
101 chunk_iter: Option<RleChunkIter>,
102 seq_offset: u16,
103}
104
105impl Iterator for RleSequenceIter<'_> {
106 type Item = u16;
107
108 fn next(&mut self) -> Option<Self::Item> {
109 loop {
110 if let Some(it) = self.chunk_iter.as_mut() {
111 let ret = it.next();
112 if ret.is_none() {
113 let len = it.length() as u16;
114 let diff = 2u16.pow(self.rle.thinning() as u32).wrapping_mul(len);
115 self.seq_offset = self.seq_offset.wrapping_add(diff);
116 self.chunk_iter = None;
117 } else {
118 return ret.and_then(|seq| {
119 xr_offset_sequence(
120 seq,
121 self.seq_offset,
122 self.rle.end(),
123 self.rle.thinning(),
124 )
125 });
126 }
127 }
128 let chunk = self.block_iter.next()?;
129 self.chunk_iter = Some(chunk.iter());
130 }
131 }
132}
133
134#[derive(Debug, Copy, Clone, PartialEq, Eq)]
136pub enum RleChunk {
137 RunLength(u16),
139 SkipLength(u16),
141 BitVector(u16),
144 Null,
146}
147
148impl RleChunk {
149 fn parse(data: &[u8]) -> Self {
150 let value = u16_from_be_bytes(data);
151 if value == 0 {
152 return Self::Null;
153 }
154 if (value & 0x8000) == 0x8000 {
155 Self::BitVector(value & !0x8000)
156 } else if (value & 0x4000) == 0x4000 {
157 Self::RunLength(value & !0xc000)
158 } else {
159 Self::SkipLength(value & !0xc000)
160 }
161 }
162
163 fn length(&self) -> usize {
164 match self {
165 Self::Null => 0,
166 Self::BitVector(_) => 15,
167 Self::SkipLength(rle) | Self::RunLength(rle) => (rle & !0xc000) as usize,
168 }
169 }
170
171 fn iter(&self) -> RleChunkIter {
172 RleChunkIter {
173 chunk: *self,
174 chunk_offset: 0,
175 }
176 }
177
178 fn write_into(&self, buf: &mut [u8]) {
179 match self {
180 Self::Null => {
181 buf[0] = 0x0;
182 buf[1] = 0x0;
183 }
184 Self::RunLength(rle) => {
185 buf[..2].copy_from_slice(&((rle & !0xc000) | 0x4000).to_be_bytes())
186 }
187 Self::SkipLength(rle) => buf[..2].copy_from_slice(&(rle & !0xc000).to_be_bytes()),
188 Self::BitVector(vector) => buf[..2].copy_from_slice(&(vector | 0x8000).to_be_bytes()),
189 }
190 }
191}
192
193#[derive(Debug)]
194struct RleChunkIter {
195 chunk: RleChunk,
196 chunk_offset: u16,
197}
198
199impl Iterator for RleChunkIter {
200 type Item = u16;
201
202 fn next(&mut self) -> Option<Self::Item> {
203 match self.chunk {
204 RleChunk::Null | RleChunk::SkipLength(_) => None,
205 RleChunk::BitVector(vector) => {
206 while self.chunk_offset < 15 {
207 let value = (vector & !0x8000) >> (14 - self.chunk_offset) & 0x1;
208 if value > 0 {
209 break;
210 }
211 self.chunk_offset += 1
212 }
213 if self.chunk_offset >= 15 {
214 None
215 } else {
216 let ret = self.chunk_offset;
217 self.chunk_offset += 1;
218 Some(ret)
219 }
220 }
221 RleChunk::RunLength(rlen) => {
222 let rlen = rlen & !0xc000;
223 if self.chunk_offset < rlen {
224 let ret = self.chunk_offset;
225 self.chunk_offset += 1;
226 Some(ret)
227 } else {
228 None
229 }
230 }
231 }
232 }
233}
234
235impl RleChunkIter {
236 fn length(&self) -> usize {
237 self.chunk.length()
238 }
239}
240
241#[derive(Debug, Default)]
242pub struct RleBuilder {
243 block_type: u8,
244 media_ssrc: u32,
245 begin: u16,
246 end: u16,
247 chunks: Vec<RleChunk>,
248 thinning: u8,
249}
250
251impl RleBuilder {
252 pub fn block_type(mut self, block_type: u8) -> Self {
253 self.block_type = block_type;
254 self
255 }
256
257 pub fn ssrc(mut self, ssrc: u32) -> Self {
258 self.media_ssrc = ssrc;
259 self
260 }
261
262 pub fn begin(mut self, begin: u16) -> Self {
263 self.begin = begin;
264 self
265 }
266
267 pub fn end(mut self, end: u16) -> Self {
268 self.end = end;
269 self
270 }
271
272 pub fn thinning(mut self, thinning: u8) -> Self {
273 self.thinning = thinning;
274 self
275 }
276
277 pub fn add_chunk(mut self, chunk: RleChunk) -> Self {
278 self.chunks.push(chunk);
279 self
280 }
281}
282
283impl XrBlockBuilder<'_> for RleBuilder {
284 fn type_specific_byte(&self) -> u8 {
285 self.thinning & 0xf
286 }
287}
288
289impl RtcpPacketWriter for RleBuilder {
290 fn calculate_size(&self) -> Result<usize, crate::RtcpWriteError> {
291 Ok(12 + pad_to_4bytes(self.chunks.len() * 2))
292 }
293
294 fn write_into_unchecked(&self, buf: &mut [u8]) -> usize {
295 self.write_header_unchecked(
296 buf,
297 self.block_type,
298 (pad_to_4bytes(self.chunks.len() * 2) / 4) as u16 + 2,
299 );
300 buf[4..8].copy_from_slice(&self.media_ssrc.to_be_bytes());
301 buf[8..10].copy_from_slice(&self.begin.to_be_bytes());
302 buf[10..12].copy_from_slice(&self.end.to_be_bytes());
303 let mut idx = 12;
304 for chunk in self.chunks.iter() {
305 chunk.write_into(&mut buf[idx..idx + 2]);
306 idx += 2;
307 }
308 if idx % 4 != 0 {
309 RleChunk::Null.write_into(&mut buf[idx..idx + 2]);
310 idx += 2;
311 }
312 idx
313 }
314
315 fn get_padding(&self) -> Option<u8> {
316 None
317 }
318}
319
320#[cfg(test)]
321mod tests {
322 use super::*;
323
324 #[test]
325 fn bit_chunk_iter() {
326 let chunk = RleChunk::BitVector(0b1011_0100_0111_1001);
327 assert_eq!(chunk.length(), 15);
328 let sequences = chunk.iter().collect::<Vec<_>>();
329 let expected = vec![1, 2, 4, 8, 9, 10, 11, 14];
330 assert_eq!(sequences, expected);
331 }
332
333 #[test]
334 fn bit_chunk_iter_single_value() {
335 for i in 0..14 {
336 let chunk = RleChunk::BitVector(0x8000 | (0x1 << i));
337 assert_eq!(chunk.length(), 15);
338 let sequences = chunk.iter().collect::<Vec<_>>();
339 let expected = vec![14 - i];
340 assert_eq!(sequences, expected);
341 }
342 }
343
344 #[test]
345 fn null_chunk_iter() {
346 let chunk = RleChunk::Null;
347 assert_eq!(chunk.length(), 0);
348 assert_eq!(chunk.iter().next(), None);
349 }
350
351 #[test]
352 fn skip_chunk_iter() {
353 let chunk = RleChunk::SkipLength(29);
354 assert_eq!(chunk.length(), 29);
355 assert_eq!(chunk.iter().next(), None);
356 }
357
358 #[test]
359 fn run_chunk_iter() {
360 let chunk = RleChunk::RunLength(18);
361 assert_eq!(chunk.length(), 18);
362 let expected = (0..18).collect::<Vec<_>>();
363 let sequences = chunk.iter().collect::<Vec<_>>();
364 assert_eq!(sequences, expected);
365 }
366
367 #[test]
368 fn rle_builder_vector_larger_than_sequence_range() {
369 let builder = Rle::builder()
370 .block_type(0x48)
371 .ssrc(0x1357_9864)
372 .begin(u16::MAX - 3)
373 .end(4)
374 .thinning(0)
375 .add_chunk(RleChunk::BitVector(0b0111_1111_1111_1111));
376 let len = builder.calculate_size().unwrap();
377 let mut buf = vec![0; len];
378 builder.write_into_unchecked(&mut buf);
379 println!("{buf:x?}");
380
381 let rle = Rle::parse(&buf).unwrap();
382 assert_eq!(rle.media_ssrc(), 0x1357_9864);
383 assert_eq!(rle.thinning(), 0);
384 assert_eq!(rle.begin(), u16::MAX - 3);
385 assert_eq!(rle.end(), 4);
386 let expected = (u16::MAX - 3..=u16::MAX).chain(0..4).collect::<Vec<_>>();
387 let sequence = rle.sequence_iter().collect::<Vec<_>>();
388 assert_eq!(sequence, expected);
389 }
390}