1use crate::Error;
9pub fn samples_per_frame(toc: u8, fs: i32) -> i32 {
11 if toc & 0x80 != 0 {
12 let a = ((toc >> 3) & 0x3) as i32;
13 (fs << a) / 400
14 } else if toc & 0x60 == 0x60 {
15 if toc & 0x08 != 0 { fs / 50 } else { fs / 100 }
16 } else {
17 let a = ((toc >> 3) & 0x3) as i32;
18 if a == 3 {
19 fs * 60 / 1000
20 } else {
21 (fs << a) / 100
22 }
23 }
24}
25
26pub fn nb_frames(packet: &[u8]) -> Result<i32, Error> {
33 if packet.is_empty() {
34 return Err(Error::BadArg("bad arg"));
35 }
36 match packet[0] & 0x3 {
37 0 => Ok(1),
38 3 => {
39 if packet.len() < 2 {
40 Err(Error::InvalidPacket("invalid packet"))
41 } else {
42 Ok((packet[1] & 0x3f) as i32)
43 }
44 }
45 _ => Ok(2),
46 }
47}
48
49fn parse_size(data: &[u8]) -> (i32, i32) {
50 if data.is_empty() {
52 (-1, -1)
53 } else if data[0] < 252 {
54 (1, data[0] as i32)
55 } else if data.len() < 2 {
56 (-1, -1)
57 } else {
58 (2, data[1] as i32 * 4 + data[0] as i32)
59 }
60}
61
62#[cfg(test)]
63fn encode_size(size: i32, out: &mut Vec<u8>) {
64 if size < 252 {
65 out.push(size as u8);
66 } else {
67 let b0 = 252 + (size & 0x3);
68 out.push(b0 as u8);
69 out.push(((size - b0) >> 2) as u8);
70 }
71}
72
73const MAX_FRAMES: usize = 48;
75
76const TOO_SMALL: Error = Error::BufferTooSmall("output buffer too small for packet");
77
78struct Cursor<'a> {
80 buf: &'a mut [u8],
81 pos: usize,
82}
83
84impl Cursor<'_> {
85 fn put(&mut self, b: u8) -> Result<(), Error> {
86 *self.buf.get_mut(self.pos).ok_or(TOO_SMALL)? = b;
87 self.pos += 1;
88 Ok(())
89 }
90
91 fn put_all(&mut self, src: &[u8]) -> Result<(), Error> {
92 let end = self.pos + src.len();
93 self.buf
94 .get_mut(self.pos..end)
95 .ok_or(TOO_SMALL)?
96 .copy_from_slice(src);
97 self.pos = end;
98 Ok(())
99 }
100
101 fn put_size(&mut self, size: usize) -> Result<(), Error> {
103 if size < 252 {
104 self.put(size as u8)
105 } else {
106 let b0 = 252 + (size & 0x3);
107 self.put(b0 as u8)?;
108 self.put(((size - b0) >> 2) as u8)
109 }
110 }
111}
112
113#[derive(Clone, Copy)]
115struct SizeList {
116 v: [i32; MAX_FRAMES],
117 n: usize,
118}
119
120impl SizeList {
121 const fn new() -> Self {
122 Self {
123 v: [0; MAX_FRAMES],
124 n: 0,
125 }
126 }
127
128 fn push(&mut self, size: i32) -> Result<(), Error> {
129 *self
130 .v
131 .get_mut(self.n)
132 .ok_or(Error::InvalidPacket("invalid packet"))? = size;
133 self.n += 1;
134 Ok(())
135 }
136
137 fn clear(&mut self) {
138 self.n = 0;
139 }
140
141 fn as_slice(&self) -> &[i32] {
142 &self.v[..self.n]
143 }
144}
145
146pub(crate) struct Frames {
148 pub(crate) toc: u8,
149 pub(crate) count: usize,
150 pub(crate) ranges: [(usize, usize); MAX_FRAMES],
151 pub(crate) end: usize,
152}
153
154impl Frames {
155 pub(crate) fn ranges(&self) -> &[(usize, usize)] {
156 &self.ranges[..self.count]
157 }
158}
159
160#[allow(clippy::type_complexity)]
163pub fn parse_packet(
169 data: &[u8],
170 self_delimited: bool,
171) -> Result<(u8, Vec<(usize, usize)>, usize), Error> {
172 let f = parse_frames(data, self_delimited)?;
173 Ok((f.toc, f.ranges().to_vec(), f.end))
174}
175
176pub(crate) fn parse_frames(data: &[u8], self_delimited: bool) -> Result<Frames, Error> {
178 if data.is_empty() {
179 return Err(Error::InvalidPacket("invalid packet"));
180 }
181 let framesize = samples_per_frame(data[0], 48000);
182 let toc = data[0];
183 let mut pos = 1usize; let mut len = data.len() as i32 - 1;
185 let mut cbr = false;
186 let mut last_size = len;
187 let mut sizes = SizeList::new();
188
189 let count: usize = match toc & 0x3 {
190 0 => 1,
191 1 => {
192 cbr = true;
193 if !self_delimited {
194 if len & 1 != 0 {
195 return Err(Error::InvalidPacket("invalid packet"));
196 }
197 last_size = len / 2;
198 sizes.push(last_size)?;
199 }
200 2
201 }
202 2 => {
203 let (bytes, sz) = parse_size(&data[pos..]);
204 if bytes < 0 {
205 return Err(Error::InvalidPacket("invalid packet"));
206 }
207 len -= bytes;
208 if sz < 0 || sz > len {
209 return Err(Error::InvalidPacket("invalid packet"));
210 }
211 pos += bytes as usize;
212 sizes.push(sz)?;
213 last_size = len - sz;
214 2
215 }
216 _ => {
217 if len < 1 {
218 return Err(Error::InvalidPacket("invalid packet"));
219 }
220 let ch = data[pos];
221 pos += 1;
222 len -= 1;
223 let count = (ch & 0x3f) as usize;
224 if count == 0 || framesize * count as i32 > 5760 {
225 return Err(Error::InvalidPacket("invalid packet"));
226 }
227 if ch & 0x40 != 0 {
228 loop {
230 if len <= 0 {
231 return Err(Error::InvalidPacket("invalid packet"));
232 }
233 let p = data[pos];
234 pos += 1;
235 len -= 1;
236 let tmp = if p == 255 { 254 } else { p as i32 };
237 len -= tmp;
238 if p != 255 {
239 break;
240 }
241 }
242 }
243 if len < 0 {
244 return Err(Error::InvalidPacket("invalid packet"));
245 }
246 cbr = ch & 0x80 == 0;
247 if !cbr {
248 last_size = len;
249 for _ in 0..count - 1 {
250 let (bytes, sz) = parse_size(&data[pos..]);
251 if bytes < 0 {
252 return Err(Error::InvalidPacket("invalid packet"));
253 }
254 len -= bytes;
255 if sz < 0 || sz > len {
256 return Err(Error::InvalidPacket("invalid packet"));
257 }
258 pos += bytes as usize;
259 sizes.push(sz)?;
260 last_size -= bytes + sz;
261 }
262 if last_size < 0 {
263 return Err(Error::InvalidPacket("invalid packet"));
264 }
265 } else if !self_delimited {
266 last_size = len / count as i32;
267 if last_size * count as i32 != len {
268 return Err(Error::InvalidPacket("invalid packet"));
269 }
270 for _ in 0..count - 1 {
271 sizes.push(last_size)?;
272 }
273 }
274 count
275 }
276 };
277
278 if self_delimited {
279 let (bytes, sz) = parse_size(&data[pos..]);
280 if bytes < 0 {
281 return Err(Error::InvalidPacket("invalid packet"));
282 }
283 len -= bytes;
284 if sz < 0 || sz > len {
285 return Err(Error::InvalidPacket("invalid packet"));
286 }
287 pos += bytes as usize;
288 if cbr {
289 if sz * count as i32 > len {
290 return Err(Error::InvalidPacket("invalid packet"));
291 }
292 sizes.clear();
293 for _ in 0..count - 1 {
294 sizes.push(sz)?;
295 }
296 sizes.push(sz)?;
297 } else {
298 if bytes + sz > last_size {
299 return Err(Error::InvalidPacket("invalid packet"));
300 }
301 sizes.push(sz)?;
302 }
303 } else {
304 if last_size > 1275 {
305 return Err(Error::InvalidPacket("invalid packet"));
306 }
307 sizes.push(last_size)?;
308 }
309
310 let mut ranges = [(0usize, 0usize); MAX_FRAMES];
312 let mut off = pos;
313 for (slot, &s) in ranges.iter_mut().zip(sizes.as_slice()) {
314 if off + s as usize > data.len() {
315 return Err(Error::InvalidPacket("invalid packet"));
316 }
317 *slot = (off, s as usize);
318 off += s as usize;
319 }
320 Ok(Frames {
322 toc,
323 count: sizes.as_slice().len(),
324 ranges,
325 end: off,
326 })
327}
328
329#[derive(Default)]
336pub struct Repacketizer {
337 toc: u8,
338 framesize: i32,
339 data: Vec<u8>,
340 frames: Vec<(usize, usize)>,
342}
343
344impl Repacketizer {
345 pub fn new() -> Self {
347 Self::default()
348 }
349
350 pub fn reset(&mut self) {
352 self.data.clear();
353 self.frames.clear();
354 }
355
356 pub fn nb_frames(&self) -> usize {
358 self.frames.len()
359 }
360
361 fn frame(&self, i: usize) -> &[u8] {
362 let (start, len) = self.frames[i];
363 &self.data[start..start + len]
364 }
365
366 pub fn cat(&mut self, data: &[u8]) -> Result<(), Error> {
374 self.cat_impl(data, false)
375 }
376
377 fn cat_impl(&mut self, data: &[u8], self_delimited: bool) -> Result<(), Error> {
378 if data.is_empty() {
379 return Err(Error::InvalidPacket("invalid packet"));
380 }
381 if self.frames.is_empty() {
382 self.toc = data[0];
383 self.framesize = samples_per_frame(data[0], 8000);
384 } else if self.toc & 0xfc != data[0] & 0xfc {
385 return Err(Error::InvalidPacket("toc mismatch"));
386 }
387 let curr = nb_frames(data)?;
388 if curr < 1 {
389 return Err(Error::InvalidPacket("invalid packet"));
390 }
391 if (curr as usize + self.frames.len()) as i32 * self.framesize > 960 {
392 return Err(Error::InvalidPacket("packet exceeds 120 ms"));
393 }
394 let parsed = parse_frames(data, self_delimited)?;
395 for &(o, l) in parsed.ranges() {
396 self.frames.push((self.data.len(), l));
397 self.data.extend_from_slice(&data[o..o + l]);
398 }
399 Ok(())
400 }
401
402 pub fn out_range(&self, begin: usize, end: usize) -> Result<Vec<u8>, Error> {
408 self.out_vec(begin, end, None, false)
409 }
410
411 pub fn out(&self) -> Result<Vec<u8>, Error> {
417 self.out_vec(0, self.frames.len(), None, false)
418 }
419
420 pub fn out_into(&self, out: &mut [u8]) -> Result<usize, Error> {
428 self.write_range(0, self.frames.len(), None, false, out)
429 }
430
431 pub fn out_range_into(&self, begin: usize, end: usize, out: &mut [u8]) -> Result<usize, Error> {
439 self.write_range(begin, end, None, false, out)
440 }
441
442 pub(crate) fn out_padded_into(&self, pad_to: usize, out: &mut [u8]) -> Result<usize, Error> {
445 self.write_range(0, self.frames.len(), Some(pad_to), false, out)
446 }
447
448 pub fn out_self_delimited(&self) -> Result<Vec<u8>, Error> {
455 self.out_vec(0, self.frames.len(), None, true)
456 }
457
458 fn out_vec(
460 &self,
461 begin: usize,
462 end: usize,
463 pad_to: Option<usize>,
464 self_delimited: bool,
465 ) -> Result<Vec<u8>, Error> {
466 if begin >= end || end > self.frames.len() {
467 return Err(Error::BadArg("bad arg"));
468 }
469 let payload: usize = self.frames[begin..end].iter().map(|&(_, l)| l).sum();
470 let bound = 2 + 2 * (end - begin + 1) + payload + pad_to.map_or(0, |n| n + n / 255 + 1);
473 let mut out = vec![0u8; bound];
474 let n = self.write_range(begin, end, pad_to, self_delimited, &mut out)?;
475 out.truncate(n);
476 Ok(out)
477 }
478
479 fn write_range(
481 &self,
482 begin: usize,
483 end: usize,
484 pad_to: Option<usize>,
485 self_delimited: bool,
486 out: &mut [u8],
487 ) -> Result<usize, Error> {
488 if begin >= end || end > self.frames.len() {
489 return Err(Error::BadArg("bad arg"));
490 }
491 let count = end - begin;
492 let lens = &self.frames[begin..end];
493 let len = |i: usize| lens[i].1;
494 let mut w = Cursor { buf: out, pos: 0 };
495
496 if count > 2 || pad_to.is_some() {
497 let vbr = lens.iter().any(|&(_, l)| l != len(0));
499 w.put((self.toc & 0xfc) | 0x3)?;
500 w.put(count as u8 | if vbr { 0x80 } else { 0 })?;
501 let mut tot = 2usize;
503 if vbr {
504 for &(_, l) in &lens[..count - 1] {
505 tot += 1 + usize::from(l >= 252) + l;
506 }
507 tot += len(count - 1);
508 } else {
509 tot += count * len(0);
510 }
511 let pad_amount = pad_to.map_or(0, |n| n.saturating_sub(tot));
512 if pad_amount != 0 {
513 w.buf[1] |= 0x40; let nb_255s = (pad_amount - 1) / 255;
515 for _ in 0..nb_255s {
516 w.put(255)?;
517 }
518 w.put((pad_amount - 255 * nb_255s - 1) as u8)?;
519 }
520 if vbr {
521 for &(_, l) in &lens[..count - 1] {
522 w.put_size(l)?;
523 }
524 }
525 } else if count == 1 {
526 w.put(self.toc & 0xfc)?; } else if len(0) == len(1) {
528 w.put((self.toc & 0xfc) | 0x1)?; } else {
530 w.put((self.toc & 0xfc) | 0x2)?; w.put_size(len(0))?;
532 }
533 if self_delimited {
534 w.put_size(len(count - 1))?;
535 }
536 for i in begin..end {
537 w.put_all(self.frame(i))?;
538 }
539 if let Some(n) = pad_to {
540 while w.pos < n {
541 w.put(0)?;
542 }
543 }
544 Ok(w.pos)
545 }
546}
547
548pub fn pad_packet(packet: &mut Vec<u8>, new_len: usize) -> Result<(), Error> {
557 if packet.is_empty() {
558 return Err(Error::BadArg("bad arg"));
559 }
560 if packet.len() == new_len {
561 return Ok(());
562 }
563 if packet.len() > new_len {
564 return Err(Error::BadArg("bad arg"));
565 }
566 let mut rp = Repacketizer::new();
567 rp.cat(packet)?;
568 let padded = rp.out_vec(0, rp.nb_frames(), Some(new_len), false)?;
569 *packet = padded;
570 Ok(())
571}
572
573pub fn unpad_packet(packet: &[u8]) -> Result<Vec<u8>, Error> {
580 if packet.is_empty() {
581 return Err(Error::BadArg("bad arg"));
582 }
583 let mut rp = Repacketizer::new();
584 rp.cat(packet)?;
585 rp.out()
586}
587
588#[cfg(test)]
589mod tests {
590 use super::*;
591
592 #[test]
595 fn split_merge_roundtrip() {
596 let toc = 12u8 << 3;
598 let mut pkt = vec![toc | 0x3, 3 | 0x80]; let f0 = vec![0xAAu8; 3];
600 let f1 = vec![0xBBu8; 5];
601 let f2 = vec![0xCCu8; 4];
602 encode_size(3, &mut pkt);
603 encode_size(5, &mut pkt);
604 pkt.extend_from_slice(&f0);
605 pkt.extend_from_slice(&f1);
606 pkt.extend_from_slice(&f2);
607
608 let mut rp = Repacketizer::new();
609 rp.cat(&pkt).unwrap();
610 assert_eq!(rp.nb_frames(), 3);
611 assert_eq!(rp.out().unwrap(), pkt);
613 let s0 = rp.out_range(0, 1).unwrap();
615 assert_eq!(s0[0] & 0x3, 0);
616 assert_eq!(&s0[1..], &f0[..]);
617 let s1 = rp.out_range(1, 2).unwrap();
618 assert_eq!(&s1[1..], &f1[..]);
619 }
620
621 #[test]
622 fn pad_unpad_identity() {
623 let toc = 8u8 << 3; let mut pkt = vec![toc];
625 pkt.extend_from_slice(&[1, 2, 3, 4, 5]);
626 let orig = pkt.clone();
627 pad_packet(&mut pkt, orig.len() + 10).unwrap();
628 assert_eq!(pkt.len(), orig.len() + 10);
629 let back = unpad_packet(&pkt).unwrap();
630 let (_t, f, _) = parse_packet(&back, false).unwrap();
632 assert_eq!(&back[f[0].0..f[0].0 + f[0].1], &orig[1..]);
633 }
634
635 #[test]
636 fn cbr_merge_code1() {
637 let toc = 8u8 << 3;
639 let p = vec![toc, 9, 9, 9]; let mut rp = Repacketizer::new();
641 rp.cat(&p).unwrap();
642 rp.cat(&p).unwrap();
643 let out = rp.out().unwrap();
644 assert_eq!(out[0] & 0x3, 1); assert_eq!(rp.nb_frames(), 2);
646 }
647}
648
649#[cfg(test)]
650mod sd_tests {
651 use super::*;
652 #[test]
653 fn self_delimited_roundtrip() {
654 let toc = 12u8 << 3;
656 let mut rp = Repacketizer::new();
657 let mut p = vec![toc | 0x3, 3 | 0x80];
658 encode_size(3, &mut p);
659 encode_size(5, &mut p);
660 p.extend_from_slice(&[1u8; 3]);
661 p.extend_from_slice(&[2u8; 5]);
662 p.extend_from_slice(&[3u8; 4]);
663 rp.cat(&p).unwrap();
664 let sd = rp.out_self_delimited().unwrap();
665 let mut stream = sd.clone();
667 stream.extend_from_slice(&[0xEE; 7]);
668 let (t, frames, off) = parse_packet(&stream, true).unwrap();
669 assert_eq!(t, toc | 0x3);
670 assert_eq!(frames.len(), 3);
671 assert_eq!(&stream[frames[0].0..frames[0].0 + frames[0].1], &[1, 1, 1]);
672 assert_eq!(
673 &stream[frames[2].0..frames[2].0 + frames[2].1],
674 &[3, 3, 3, 3]
675 );
676 assert_eq!(off, sd.len()); }
678}