rtcp_types/xr/
duplicate_rle.rs1use crate::prelude::*;
4use crate::xr::rle::{Rle, RleBuilder, RleChunk};
5use crate::xr::{XrBlockBuilder, XrBlockParser, XrBlockStaticType};
6use crate::{RtcpParseError, RtcpWriteError};
7
8#[derive(Debug)]
10pub struct DuplicateRle<'a> {
11 rle: Rle<'a>,
12}
13
14impl XrBlockStaticType for DuplicateRle<'_> {
15 const BLOCK_TYPE: u8 = 0x2;
16}
17
18impl<'a> XrBlockParser<'a> for DuplicateRle<'a> {
19 fn parse(data: &'a [u8]) -> Result<Self, RtcpParseError> {
20 let rle = Rle::parse(data)?;
21 let ret = Self { rle };
22 Ok(ret)
23 }
24
25 #[inline(always)]
26 fn header_data(&self) -> [u8; 4] {
27 self.rle.block.header_data()
28 }
29}
30
31impl DuplicateRle<'_> {
32 pub fn thinning(&self) -> u8 {
35 self.rle.thinning()
36 }
37
38 pub fn media_ssrc(&self) -> u32 {
40 self.rle.media_ssrc()
41 }
42
43 pub fn begin(&self) -> u16 {
46 self.rle.begin()
47 }
48
49 pub fn end(&self) -> u16 {
52 self.rle.end()
53 }
54
55 pub fn sequence_iter(&self) -> impl Iterator<Item = u16> + '_ {
57 self.rle.sequence_iter()
58 }
59
60 pub fn chunk_iter(&self) -> impl Iterator<Item = RleChunk> + '_ {
65 self.rle.chunk_iter()
66 }
67
68 pub fn builder() -> DuplicateRleBuilder {
70 let mut builder = DuplicateRleBuilder {
71 rle: Rle::builder(),
72 };
73 builder.rle = builder.rle.block_type(Self::BLOCK_TYPE);
74 builder
75 }
76}
77
78#[derive(Debug, Default)]
80pub struct DuplicateRleBuilder {
81 rle: RleBuilder,
82}
83
84impl DuplicateRleBuilder {
85 pub fn ssrc(mut self, ssrc: u32) -> Self {
87 self.rle = self.rle.ssrc(ssrc);
88 self
89 }
90
91 pub fn begin(mut self, begin: u16) -> Self {
93 self.rle = self.rle.begin(begin);
94 self
95 }
96
97 pub fn end(mut self, end: u16) -> Self {
99 self.rle = self.rle.end(end);
100 self
101 }
102
103 pub fn thinning(mut self, thinning: u8) -> Self {
107 assert!(thinning <= 0xf);
108 self.rle = self.rle.thinning(thinning);
109 self
110 }
111
112 pub fn add_chunk(mut self, chunk: RleChunk) -> Self {
114 self.rle = self.rle.add_chunk(chunk);
115 self
116 }
117}
118
119impl XrBlockBuilder<'_> for DuplicateRleBuilder {
120 fn type_specific_byte(&self) -> u8 {
121 self.rle.type_specific_byte()
122 }
123}
124
125impl RtcpPacketWriter for DuplicateRleBuilder {
126 fn calculate_size(&self) -> Result<usize, RtcpWriteError> {
127 self.rle.calculate_size()
128 }
129
130 fn write_into_unchecked(&self, buf: &mut [u8]) -> usize {
131 self.rle.write_into_unchecked(buf)
132 }
133
134 fn get_padding(&self) -> Option<u8> {
135 None
136 }
137}
138
139#[cfg(test)]
140mod tests {
141 use super::*;
142
143 #[test]
144 fn duplicate_rle_builder_wraparound() {
145 let builder = DuplicateRle::builder()
146 .ssrc(0x1357_9864)
147 .begin(u16::MAX - 51)
148 .end(50)
149 .thinning(1)
150 .add_chunk(RleChunk::RunLength(51));
151 let len = builder.calculate_size().unwrap();
152 let mut buf = vec![0; len];
153 builder.write_into_unchecked(&mut buf);
154 println!("{buf:x?}");
155
156 let rle = DuplicateRle::parse(&buf).unwrap();
157 assert_eq!(rle.media_ssrc(), 0x1357_9864);
158 assert_eq!(rle.thinning(), 1);
159 assert_eq!(rle.begin(), u16::MAX - 51);
160 assert_eq!(rle.end(), 50);
161 let expected = (u16::MAX - 51..u16::MAX)
162 .chain(0..50)
163 .filter(|x| x % 2 == 0)
164 .collect::<Vec<_>>();
165 let sequence = rle.sequence_iter().collect::<Vec<_>>();
166 assert_eq!(sequence, expected);
167 }
168}