1pub fn samples_per_frame(toc: u8, fs: i32) -> i32 {
10 if toc & 0x80 != 0 {
11 let a = ((toc >> 3) & 0x3) as i32;
12 (fs << a) / 400
13 } else if toc & 0x60 == 0x60 {
14 if toc & 0x08 != 0 {
15 fs / 50
16 } else {
17 fs / 100
18 }
19 } else {
20 let a = ((toc >> 3) & 0x3) as i32;
21 if a == 3 {
22 fs * 60 / 1000
23 } else {
24 (fs << a) / 100
25 }
26 }
27}
28
29pub fn nb_frames(packet: &[u8]) -> Result<i32, &'static str> {
31 if packet.is_empty() {
32 return Err("bad arg");
33 }
34 match packet[0] & 0x3 {
35 0 => Ok(1),
36 3 => {
37 if packet.len() < 2 {
38 Err("invalid packet")
39 } else {
40 Ok((packet[1] & 0x3f) as i32)
41 }
42 }
43 _ => Ok(2),
44 }
45}
46
47fn parse_size(data: &[u8]) -> (i32, i32) {
48 if data.is_empty() {
50 (-1, -1)
51 } else if data[0] < 252 {
52 (1, data[0] as i32)
53 } else if data.len() < 2 {
54 (-1, -1)
55 } else {
56 (2, data[1] as i32 * 4 + data[0] as i32)
57 }
58}
59
60fn encode_size(size: i32, out: &mut Vec<u8>) {
61 if size < 252 {
62 out.push(size as u8);
63 } else {
64 let b0 = 252 + (size & 0x3);
65 out.push(b0 as u8);
66 out.push(((size - b0) >> 2) as u8);
67 }
68}
69
70#[allow(clippy::type_complexity)]
73pub fn parse_packet(
74 data: &[u8],
75 self_delimited: bool,
76) -> Result<(u8, Vec<(usize, usize)>, usize), &'static str> {
77 if data.is_empty() {
78 return Err("invalid packet");
79 }
80 let framesize = samples_per_frame(data[0], 48000);
81 let toc = data[0];
82 let mut pos = 1usize; let mut len = data.len() as i32 - 1;
84 let mut cbr = false;
85 let mut last_size = len;
86 let mut sizes: Vec<i32> = Vec::new();
87
88 let count: usize = match toc & 0x3 {
89 0 => 1,
90 1 => {
91 cbr = true;
92 if !self_delimited {
93 if len & 1 != 0 {
94 return Err("invalid packet");
95 }
96 last_size = len / 2;
97 sizes.push(last_size);
98 }
99 2
100 }
101 2 => {
102 let (bytes, sz) = parse_size(&data[pos..]);
103 if bytes < 0 {
104 return Err("invalid packet");
105 }
106 len -= bytes;
107 if sz < 0 || sz > len {
108 return Err("invalid packet");
109 }
110 pos += bytes as usize;
111 sizes.push(sz);
112 last_size = len - sz;
113 2
114 }
115 _ => {
116 if len < 1 {
117 return Err("invalid packet");
118 }
119 let ch = data[pos];
120 pos += 1;
121 len -= 1;
122 let count = (ch & 0x3f) as usize;
123 if count == 0 || framesize * count as i32 > 5760 {
124 return Err("invalid packet");
125 }
126 if ch & 0x40 != 0 {
127 loop {
129 if len <= 0 {
130 return Err("invalid packet");
131 }
132 let p = data[pos];
133 pos += 1;
134 len -= 1;
135 let tmp = if p == 255 { 254 } else { p as i32 };
136 len -= tmp;
137 if p != 255 {
138 break;
139 }
140 }
141 }
142 if len < 0 {
143 return Err("invalid packet");
144 }
145 cbr = ch & 0x80 == 0;
146 if !cbr {
147 last_size = len;
148 for _ in 0..count - 1 {
149 let (bytes, sz) = parse_size(&data[pos..]);
150 if bytes < 0 {
151 return Err("invalid packet");
152 }
153 len -= bytes;
154 if sz < 0 || sz > len {
155 return Err("invalid packet");
156 }
157 pos += bytes as usize;
158 sizes.push(sz);
159 last_size -= bytes + sz;
160 }
161 if last_size < 0 {
162 return Err("invalid packet");
163 }
164 } else if !self_delimited {
165 last_size = len / count as i32;
166 if last_size * count as i32 != len {
167 return Err("invalid packet");
168 }
169 for _ in 0..count - 1 {
170 sizes.push(last_size);
171 }
172 }
173 count
174 }
175 };
176
177 if self_delimited {
178 let (bytes, sz) = parse_size(&data[pos..]);
179 if bytes < 0 {
180 return Err("invalid packet");
181 }
182 len -= bytes;
183 if sz < 0 || sz > len {
184 return Err("invalid packet");
185 }
186 pos += bytes as usize;
187 if cbr {
188 if sz * count as i32 > len {
189 return Err("invalid packet");
190 }
191 sizes.clear();
192 for _ in 0..count - 1 {
193 sizes.push(sz);
194 }
195 sizes.push(sz);
196 } else {
197 if bytes + sz > last_size {
198 return Err("invalid packet");
199 }
200 sizes.push(sz);
201 }
202 } else {
203 if last_size > 1275 {
204 return Err("invalid packet");
205 }
206 sizes.push(last_size);
207 }
208
209 let mut frames = Vec::with_capacity(count);
211 let mut off = pos;
212 for &s in &sizes {
213 if off + s as usize > data.len() {
214 return Err("invalid packet");
215 }
216 frames.push((off, s as usize));
217 off += s as usize;
218 }
219 let packet_offset = off; Ok((toc, frames, packet_offset))
221}
222
223#[derive(Default)]
226pub struct Repacketizer {
227 toc: u8,
228 framesize: i32,
229 frames: Vec<Vec<u8>>,
230}
231
232impl Repacketizer {
233 pub fn new() -> Self {
234 Repacketizer::default()
235 }
236
237 pub fn nb_frames(&self) -> usize {
238 self.frames.len()
239 }
240
241 pub fn cat(&mut self, data: &[u8]) -> Result<(), &'static str> {
244 self.cat_impl(data, false)
245 }
246
247 fn cat_impl(&mut self, data: &[u8], self_delimited: bool) -> Result<(), &'static str> {
248 if data.is_empty() {
249 return Err("invalid packet");
250 }
251 if self.frames.is_empty() {
252 self.toc = data[0];
253 self.framesize = samples_per_frame(data[0], 8000);
254 } else if self.toc & 0xfc != data[0] & 0xfc {
255 return Err("toc mismatch");
256 }
257 let curr = nb_frames(data)?;
258 if curr < 1 {
259 return Err("invalid packet");
260 }
261 if (curr as usize + self.frames.len()) as i32 * self.framesize > 960 {
262 return Err("packet exceeds 120 ms");
263 }
264 let (_toc, ranges, _off) = parse_packet(data, self_delimited)?;
265 for (o, l) in ranges {
266 self.frames.push(data[o..o + l].to_vec());
267 }
268 Ok(())
269 }
270
271 pub fn out_range(&self, begin: usize, end: usize) -> Result<Vec<u8>, &'static str> {
273 self.out_range_impl(begin, end, None)
274 }
275
276 pub fn out(&self) -> Result<Vec<u8>, &'static str> {
278 self.out_range_impl(0, self.frames.len(), None)
279 }
280
281 fn out_range_impl(
282 &self,
283 begin: usize,
284 end: usize,
285 pad_to: Option<usize>,
286 ) -> Result<Vec<u8>, &'static str> {
287 self.out_range_full(begin, end, pad_to, false)
288 }
289
290 pub fn out_self_delimited(&self) -> Result<Vec<u8>, &'static str> {
293 self.out_range_full(0, self.frames.len(), None, true)
294 }
295
296 fn out_range_full(
297 &self,
298 begin: usize,
299 end: usize,
300 pad_to: Option<usize>,
301 self_delimited: bool,
302 ) -> Result<Vec<u8>, &'static str> {
303 if begin >= end || end > self.frames.len() {
304 return Err("bad arg");
305 }
306 let count = end - begin;
307 let lens: Vec<usize> = self.frames[begin..end].iter().map(|f| f.len()).collect();
308 let mut out: Vec<u8> = Vec::new();
309
310 if count == 1 {
311 out.push(self.toc & 0xfc); } else if count == 2 && lens[0] == lens[1] {
313 out.push((self.toc & 0xfc) | 0x1); } else if count == 2 {
315 out.push((self.toc & 0xfc) | 0x2); encode_size(lens[0] as i32, &mut out);
317 }
318
319 let want_pad = pad_to.is_some();
320 if count > 2 || (want_pad && count <= 2) {
321 out.clear();
323 let vbr = lens.iter().any(|&l| l != lens[0]);
324 if vbr {
325 out.push((self.toc & 0xfc) | 0x3);
326 out.push((count as u8) | 0x80);
327 } else {
328 out.push((self.toc & 0xfc) | 0x3);
329 out.push(count as u8);
330 }
331 let mut tot = 2usize;
333 if vbr {
334 for &l in lens.iter().take(count - 1) {
335 tot += 1 + usize::from(l >= 252) + l;
336 }
337 tot += lens[count - 1];
338 } else {
339 tot += count * lens[0];
340 }
341 let pad_amount = pad_to.map(|n| n.saturating_sub(tot)).unwrap_or(0);
342 if pad_amount != 0 {
343 out[1] |= 0x40; let nb_255s = (pad_amount - 1) / 255;
345 for _ in 0..nb_255s {
346 out.push(255);
347 }
348 out.push((pad_amount - 255 * nb_255s - 1) as u8);
349 }
350 if vbr {
351 for &l in lens.iter().take(count - 1) {
352 encode_size(l as i32, &mut out);
353 }
354 }
355 if self_delimited {
356 encode_size(lens[count - 1] as i32, &mut out);
357 }
358 for f in &self.frames[begin..end] {
359 out.extend_from_slice(f);
360 }
361 if let Some(n) = pad_to {
362 while out.len() < n {
363 out.push(0);
364 }
365 }
366 return Ok(out);
367 }
368
369 if self_delimited {
370 encode_size(lens[count - 1] as i32, &mut out);
371 }
372 for f in &self.frames[begin..end] {
373 out.extend_from_slice(f);
374 }
375 Ok(out)
376 }
377}
378
379pub fn pad_packet(packet: &mut Vec<u8>, new_len: usize) -> Result<(), &'static str> {
383 if packet.is_empty() {
384 return Err("bad arg");
385 }
386 if packet.len() == new_len {
387 return Ok(());
388 }
389 if packet.len() > new_len {
390 return Err("bad arg");
391 }
392 let mut rp = Repacketizer::new();
393 rp.cat(packet)?;
394 let padded = rp.out_range_impl(0, rp.nb_frames(), Some(new_len))?;
395 *packet = padded;
396 Ok(())
397}
398
399pub fn unpad_packet(packet: &[u8]) -> Result<Vec<u8>, &'static str> {
401 if packet.is_empty() {
402 return Err("bad arg");
403 }
404 let mut rp = Repacketizer::new();
405 rp.cat(packet)?;
406 rp.out_range_impl(0, rp.nb_frames(), None)
407}
408
409#[cfg(test)]
410mod tests {
411 use super::*;
412
413 #[test]
416 fn split_merge_roundtrip() {
417 let toc = 12u8 << 3;
419 let mut pkt = vec![toc | 0x3, 3 | 0x80]; let f0 = vec![0xAAu8; 3];
421 let f1 = vec![0xBBu8; 5];
422 let f2 = vec![0xCCu8; 4];
423 encode_size(3, &mut pkt);
424 encode_size(5, &mut pkt);
425 pkt.extend_from_slice(&f0);
426 pkt.extend_from_slice(&f1);
427 pkt.extend_from_slice(&f2);
428
429 let mut rp = Repacketizer::new();
430 rp.cat(&pkt).unwrap();
431 assert_eq!(rp.nb_frames(), 3);
432 assert_eq!(rp.out().unwrap(), pkt);
434 let s0 = rp.out_range(0, 1).unwrap();
436 assert_eq!(s0[0] & 0x3, 0);
437 assert_eq!(&s0[1..], &f0[..]);
438 let s1 = rp.out_range(1, 2).unwrap();
439 assert_eq!(&s1[1..], &f1[..]);
440 }
441
442 #[test]
443 fn pad_unpad_identity() {
444 let toc = 8u8 << 3; let mut pkt = vec![toc];
446 pkt.extend_from_slice(&[1, 2, 3, 4, 5]);
447 let orig = pkt.clone();
448 pad_packet(&mut pkt, orig.len() + 10).unwrap();
449 assert_eq!(pkt.len(), orig.len() + 10);
450 let back = unpad_packet(&pkt).unwrap();
451 let (_t, f, _) = parse_packet(&back, false).unwrap();
453 assert_eq!(&back[f[0].0..f[0].0 + f[0].1], &orig[1..]);
454 }
455
456 #[test]
457 fn cbr_merge_code1() {
458 let toc = 8u8 << 3;
460 let p = vec![toc, 9, 9, 9]; let mut rp = Repacketizer::new();
462 rp.cat(&p).unwrap();
463 rp.cat(&p).unwrap();
464 let out = rp.out().unwrap();
465 assert_eq!(out[0] & 0x3, 1); assert_eq!(rp.nb_frames(), 2);
467 }
468}
469
470#[cfg(test)]
471mod sd_tests {
472 use super::*;
473 #[test]
474 fn self_delimited_roundtrip() {
475 let toc = 12u8 << 3;
477 let mut rp = Repacketizer::new();
478 let mut p = vec![toc | 0x3, 3 | 0x80];
479 encode_size(3, &mut p); encode_size(5, &mut p);
480 p.extend_from_slice(&[1u8;3]); p.extend_from_slice(&[2u8;5]); p.extend_from_slice(&[3u8;4]);
481 rp.cat(&p).unwrap();
482 let sd = rp.out_self_delimited().unwrap();
483 let mut stream = sd.clone(); stream.extend_from_slice(&[0xEE;7]);
485 let (t, frames, off) = parse_packet(&stream, true).unwrap();
486 assert_eq!(t, toc | 0x3);
487 assert_eq!(frames.len(), 3);
488 assert_eq!(&stream[frames[0].0..frames[0].0+frames[0].1], &[1,1,1]);
489 assert_eq!(&stream[frames[2].0..frames[2].0+frames[2].1], &[3,3,3,3]);
490 assert_eq!(off, sd.len()); }
492}