1use crate::packet::frame_count;
9use crate::{Error, Result};
10
11pub(crate) fn samples_per_frame(toc: u8, fs: i32) -> i32 {
13 if toc & 0x80 != 0 {
14 let a = ((toc >> 3) & 0x3) as i32;
15 (fs << a) / 400
16 } else if toc & 0x60 == 0x60 {
17 if toc & 0x08 != 0 { fs / 50 } else { fs / 100 }
18 } else {
19 let a = ((toc >> 3) & 0x3) as i32;
20 if a == 3 {
21 fs * 60 / 1000
22 } else {
23 (fs << a) / 100
24 }
25 }
26}
27
28fn parse_size(data: &[u8]) -> (i32, i32) {
33 if data.is_empty() {
34 (-1, -1)
35 } else if data[0] < 252 {
36 (1, data[0] as i32)
37 } else if data.len() < 2 {
38 (-1, -1)
39 } else {
40 (2, data[1] as i32 * 4 + data[0] as i32)
41 }
42}
43
44fn encode_size(size: i32, out: &mut Vec<u8>) {
45 if size < 252 {
46 out.push(size as u8);
47 } else {
48 let b0 = 252 + (size & 0x3);
49 out.push(b0 as u8);
50 out.push(((size - b0) >> 2) as u8);
51 }
52}
53
54pub(crate) const MAX_FRAMES: usize = 48;
57
58const _: () = assert!(5760 / 120 == MAX_FRAMES);
61
62#[derive(Clone, Copy)]
65pub(crate) struct FrameList<T: Copy> {
66 items: [T; MAX_FRAMES],
67 len: usize,
68}
69
70impl<T: Copy + Default> FrameList<T> {
71 fn new() -> Self {
72 Self {
73 items: [T::default(); MAX_FRAMES],
74 len: 0,
75 }
76 }
77
78 fn push(&mut self, item: T) {
81 self.items[self.len] = item;
82 self.len += 1;
83 }
84
85 fn clear(&mut self) {
86 self.len = 0;
87 }
88}
89
90impl<T: Copy> std::ops::Deref for FrameList<T> {
91 type Target = [T];
92
93 fn deref(&self) -> &[T] {
94 &self.items[..self.len]
95 }
96}
97
98pub(crate) fn parse_packet(
101 data: &[u8],
102 self_delimited: bool,
103) -> Result<(u8, FrameList<&[u8]>, usize)> {
104 if data.is_empty() {
105 return Err(Error::InvalidPacket("invalid packet"));
106 }
107 let framesize = samples_per_frame(data[0], 48000);
108 let toc = data[0];
109 let mut pos = 1usize; let mut len = data.len() as i32 - 1;
111 let mut cbr = false;
112 let mut last_size = len;
113 let mut sizes = FrameList::<i32>::new();
114
115 let count: usize = match toc & 0x3 {
116 0 => 1,
117 1 => {
118 cbr = true;
119 if !self_delimited {
120 if len & 1 != 0 {
121 return Err(Error::InvalidPacket("invalid packet"));
122 }
123 last_size = len / 2;
124 sizes.push(last_size);
125 }
126 2
127 }
128 2 => {
129 let (bytes, sz) = parse_size(&data[pos..]);
130 if bytes < 0 {
131 return Err(Error::InvalidPacket("invalid packet"));
132 }
133 len -= bytes;
134 if sz < 0 || sz > len {
135 return Err(Error::InvalidPacket("invalid packet"));
136 }
137 pos += bytes as usize;
138 sizes.push(sz);
139 last_size = len - sz;
140 2
141 }
142 _ => {
143 if len < 1 {
144 return Err(Error::InvalidPacket("invalid packet"));
145 }
146 let ch = data[pos];
147 pos += 1;
148 len -= 1;
149 let count = (ch & 0x3f) as usize;
150 if count == 0 || framesize * count as i32 > 5760 {
151 return Err(Error::InvalidPacket("invalid packet"));
152 }
153 if ch & 0x40 != 0 {
154 loop {
156 if len <= 0 {
157 return Err(Error::InvalidPacket("invalid packet"));
158 }
159 let p = data[pos];
160 pos += 1;
161 len -= 1;
162 let tmp = if p == 255 { 254 } else { p as i32 };
163 len -= tmp;
164 if p != 255 {
165 break;
166 }
167 }
168 }
169 if len < 0 {
170 return Err(Error::InvalidPacket("invalid packet"));
171 }
172 cbr = ch & 0x80 == 0;
173 if !cbr {
174 last_size = len;
175 for _ in 0..count - 1 {
176 let (bytes, sz) = parse_size(&data[pos..]);
177 if bytes < 0 {
178 return Err(Error::InvalidPacket("invalid packet"));
179 }
180 len -= bytes;
181 if sz < 0 || sz > len {
182 return Err(Error::InvalidPacket("invalid packet"));
183 }
184 pos += bytes as usize;
185 sizes.push(sz);
186 last_size -= bytes + sz;
187 }
188 if last_size < 0 {
189 return Err(Error::InvalidPacket("invalid packet"));
190 }
191 } else if !self_delimited {
192 last_size = len / count as i32;
193 if last_size * count as i32 != len {
194 return Err(Error::InvalidPacket("invalid packet"));
195 }
196 for _ in 0..count - 1 {
197 sizes.push(last_size);
198 }
199 }
200 count
201 }
202 };
203
204 if self_delimited {
205 let (bytes, sz) = parse_size(&data[pos..]);
206 if bytes < 0 {
207 return Err(Error::InvalidPacket("invalid packet"));
208 }
209 len -= bytes;
210 if sz < 0 || sz > len {
211 return Err(Error::InvalidPacket("invalid packet"));
212 }
213 pos += bytes as usize;
214 if cbr {
215 if sz * count as i32 > len {
216 return Err(Error::InvalidPacket("invalid packet"));
217 }
218 sizes.clear();
219 for _ in 0..count - 1 {
220 sizes.push(sz);
221 }
222 sizes.push(sz);
223 } else {
224 if bytes + sz > last_size {
225 return Err(Error::InvalidPacket("invalid packet"));
226 }
227 sizes.push(sz);
228 }
229 } else {
230 if last_size > 1275 {
231 return Err(Error::InvalidPacket("invalid packet"));
232 }
233 sizes.push(last_size);
234 }
235
236 let mut frames = FrameList::new();
238 let mut off = pos;
239 for &s in sizes.iter() {
240 if off + s as usize > data.len() {
241 return Err(Error::InvalidPacket("invalid packet"));
242 }
243 frames.push(&data[off..off + s as usize]);
244 off += s as usize;
245 }
246 let packet_offset = off; Ok((toc, frames, packet_offset))
248}
249
250pub(crate) fn take_self_delimited_into(data: &[u8], out: &mut Vec<u8>) -> Result<usize> {
263 let (toc, frames, consumed) = parse_packet(data, true)?;
264 out.clear();
265 emit_packet(toc, frames.iter().copied(), None, false, out)?;
266 Ok(consumed)
267}
268
269#[derive(Default)]
272pub struct Repacketizer {
273 toc: u8,
274 framesize: i32,
275 frames: Vec<Vec<u8>>,
276 spare: Vec<Vec<u8>>,
281}
282
283impl std::fmt::Debug for Repacketizer {
286 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
287 f.debug_struct("Repacketizer")
288 .field("nb_frames", &self.frames.len())
289 .field("toc", &format_args!("{:#04x}", self.toc))
290 .field("framesize", &self.framesize)
291 .field("bytes", &self.frames.iter().map(Vec::len).sum::<usize>())
292 .finish()
293 }
294}
295
296impl Repacketizer {
297 pub fn new() -> Self {
299 Repacketizer::default()
300 }
301
302 pub fn clear(&mut self) {
308 self.spare.append(&mut self.frames);
309 self.toc = 0;
310 self.framesize = 0;
311 }
312
313 pub fn nb_frames(&self) -> usize {
318 self.frames.len()
319 }
320
321 pub fn cat(&mut self, data: &[u8]) -> Result<()> {
324 self.cat_impl(data, false)
325 }
326
327 fn cat_impl(&mut self, data: &[u8], self_delimited: bool) -> Result<()> {
328 if data.is_empty() {
329 return Err(Error::InvalidPacket("cat: the packet is empty"));
330 }
331 if self.frames.is_empty() {
332 self.toc = data[0];
333 self.framesize = samples_per_frame(data[0], 8000);
334 } else if self.toc & 0xfc != data[0] & 0xfc {
335 return Err(Error::InvalidPacket("toc mismatch"));
336 }
337 let curr = frame_count(data)?;
338 if (curr + self.frames.len()) as i32 * self.framesize > 960 {
339 return Err(Error::InvalidPacket("packet exceeds 120 ms"));
340 }
341 let (_toc, frames, _off) = parse_packet(data, self_delimited)?;
342 for &f in frames.iter() {
343 let mut frame = self.spare.pop().unwrap_or_default();
344 frame.clear();
345 frame.extend_from_slice(f);
346 self.frames.push(frame);
347 }
348 Ok(())
349 }
350
351 pub fn out_range(&self, begin: usize, end: usize) -> Result<Vec<u8>> {
353 self.out_range_impl(begin, end, None)
354 }
355
356 pub fn out(&self) -> Result<Vec<u8>> {
358 self.out_range_impl(0, self.frames.len(), None)
359 }
360
361 pub fn out_into(&self, out: &mut Vec<u8>) -> Result<()> {
367 self.out_range_full(0, self.frames.len(), None, false, out)
368 }
369
370 pub fn out_range_into(&self, begin: usize, end: usize, out: &mut Vec<u8>) -> Result<()> {
372 self.out_range_full(begin, end, None, false, out)
373 }
374
375 pub fn out_self_delimited_into(&self, out: &mut Vec<u8>) -> Result<()> {
377 self.out_range_full(0, self.frames.len(), None, true, out)
378 }
379
380 pub(crate) fn out_range_impl(
383 &self,
384 begin: usize,
385 end: usize,
386 pad_to: Option<usize>,
387 ) -> Result<Vec<u8>> {
388 let mut out = Vec::new();
389 self.out_range_full(begin, end, pad_to, false, &mut out)?;
390 Ok(out)
391 }
392
393 pub fn out_self_delimited(&self) -> Result<Vec<u8>> {
396 let mut out = Vec::new();
397 self.out_range_full(0, self.frames.len(), None, true, &mut out)?;
398 Ok(out)
399 }
400
401 fn out_range_full(
402 &self,
403 begin: usize,
404 end: usize,
405 pad_to: Option<usize>,
406 self_delimited: bool,
407 out: &mut Vec<u8>,
408 ) -> Result<()> {
409 if begin >= end || end > self.frames.len() {
410 return Err(Error::InvalidArgument(
411 "frame range must satisfy begin < end <= nb_frames",
412 ));
413 }
414 emit_packet(
415 self.toc,
416 self.frames[begin..end].iter().map(Vec::as_slice),
417 pad_to,
418 self_delimited,
419 out,
420 )
421 }
422}
423
424fn emit_packet<'f>(
432 toc: u8,
433 frames: impl ExactSizeIterator<Item = &'f [u8]> + Clone,
434 pad_to: Option<usize>,
435 self_delimited: bool,
436 out: &mut Vec<u8>,
437) -> Result<()> {
438 let count = frames.len();
439 if count == 0 {
440 return Err(Error::InvalidArgument("a packet needs at least one frame"));
441 }
442 let lens = || frames.clone().map(<[u8]>::len);
443 let first_len = lens().next().unwrap_or(0);
444 let last_len = lens().last().unwrap_or(0);
445 let vbr = lens().any(|l| l != first_len);
446 let start = out.len();
447
448 if count == 1 {
449 out.push(toc & 0xfc); } else if count == 2 && !vbr {
451 out.push((toc & 0xfc) | 0x1); } else if count == 2 {
453 out.push((toc & 0xfc) | 0x2); encode_size(first_len as i32, out);
455 }
456
457 if count > 2 || pad_to.is_some() {
458 out.truncate(start);
462 out.push((toc & 0xfc) | 0x3);
463 out.push(if vbr {
464 (count as u8) | 0x80
465 } else {
466 count as u8
467 });
468 let mut tot = 2usize;
470 if vbr {
471 for l in lens().take(count - 1) {
472 tot += 1 + usize::from(l >= 252) + l;
473 }
474 tot += last_len;
475 } else {
476 tot += count * first_len;
477 }
478 let pad_amount = pad_to.map(|n| n.saturating_sub(tot)).unwrap_or(0);
479 if pad_amount != 0 {
480 out[start + 1] |= 0x40; let nb_255s = (pad_amount - 1) / 255;
482 out.extend(std::iter::repeat_n(255u8, nb_255s));
483 out.push((pad_amount - 255 * nb_255s - 1) as u8);
484 }
485 if vbr {
486 for l in lens().take(count - 1) {
487 encode_size(l as i32, out);
488 }
489 }
490 if self_delimited {
491 encode_size(last_len as i32, out);
492 }
493 for f in frames.clone() {
494 out.extend_from_slice(f);
495 }
496 if let Some(n) = pad_to {
497 while out.len() - start < n {
498 out.push(0);
499 }
500 }
501 return Ok(());
502 }
503
504 if self_delimited {
505 encode_size(last_len as i32, out);
506 }
507 for f in frames.clone() {
508 out.extend_from_slice(f);
509 }
510 Ok(())
511}
512
513pub fn pad_packet(packet: &mut Vec<u8>, new_len: usize) -> Result<()> {
517 if packet.is_empty() {
518 return Err(Error::InvalidArgument("pad_packet: the packet is empty"));
519 }
520 if packet.len() == new_len {
521 return Ok(());
522 }
523 if packet.len() > new_len {
524 return Err(Error::InvalidArgument(
525 "pad_packet: new_len is smaller than the packet",
526 ));
527 }
528 let mut rp = Repacketizer::new();
529 rp.cat(packet)?;
530 let padded = rp.out_range_impl(0, rp.nb_frames(), Some(new_len))?;
531 *packet = padded;
532 Ok(())
533}
534
535pub fn unpad_packet(packet: &[u8]) -> Result<Vec<u8>> {
537 if packet.is_empty() {
538 return Err(Error::InvalidArgument("unpad_packet: the packet is empty"));
539 }
540 let mut rp = Repacketizer::new();
541 rp.cat(packet)?;
542 rp.out_range_impl(0, rp.nb_frames(), None)
543}
544
545#[cfg(test)]
546mod tests {
547 use super::*;
548
549 #[test]
552 fn split_merge_roundtrip() {
553 let toc = 12u8 << 3;
555 let mut pkt = vec![toc | 0x3, 3 | 0x80]; let f0 = vec![0xAAu8; 3];
557 let f1 = vec![0xBBu8; 5];
558 let f2 = vec![0xCCu8; 4];
559 encode_size(3, &mut pkt);
560 encode_size(5, &mut pkt);
561 pkt.extend_from_slice(&f0);
562 pkt.extend_from_slice(&f1);
563 pkt.extend_from_slice(&f2);
564
565 let mut rp = Repacketizer::new();
566 rp.cat(&pkt).unwrap();
567 assert_eq!(rp.nb_frames(), 3);
568 assert_eq!(rp.out().unwrap(), pkt);
570 let s0 = rp.out_range(0, 1).unwrap();
572 assert_eq!(s0[0] & 0x3, 0);
573 assert_eq!(&s0[1..], &f0[..]);
574 let s1 = rp.out_range(1, 2).unwrap();
575 assert_eq!(&s1[1..], &f1[..]);
576 }
577
578 #[test]
582 fn take_self_delimited_matches_the_repacketizer() {
583 let toc = 12u8 << 3; let cases: &[&[usize]] = &[&[3], &[4, 4], &[3, 5], &[4, 4, 4], &[3, 5, 4], &[300, 2]];
585 for lens in cases {
586 let mut rp = Repacketizer::new();
587 for (i, &l) in lens.iter().enumerate() {
588 let mut pkt = vec![toc];
589 pkt.extend(std::iter::repeat_n(i as u8 + 1, l));
590 rp.cat(&pkt).unwrap();
591 }
592 let mut sd = rp.out_self_delimited().unwrap();
593 let trailer = [0xEEu8; 7]; sd.extend_from_slice(&trailer);
595
596 let mut out = vec![0xFF; 3];
597 let consumed = take_self_delimited_into(&sd, &mut out).unwrap();
598 assert_eq!(consumed, sd.len() - trailer.len(), "lens {lens:?}");
599 assert_eq!(out, rp.out().unwrap(), "lens {lens:?}");
600 }
601 }
602
603 #[test]
604 fn pad_unpad_identity() {
605 let toc = 8u8 << 3; let mut pkt = vec![toc];
607 pkt.extend_from_slice(&[1, 2, 3, 4, 5]);
608 let orig = pkt.clone();
609 pad_packet(&mut pkt, orig.len() + 10).unwrap();
610 assert_eq!(pkt.len(), orig.len() + 10);
611 let back = unpad_packet(&pkt).unwrap();
612 let (_t, f, _) = parse_packet(&back, false).unwrap();
614 assert_eq!(f[0], &orig[1..]);
615 }
616
617 #[test]
618 fn cbr_merge_code1() {
619 let toc = 8u8 << 3;
621 let p = vec![toc, 9, 9, 9]; let mut rp = Repacketizer::new();
623 rp.cat(&p).unwrap();
624 rp.cat(&p).unwrap();
625 let out = rp.out().unwrap();
626 assert_eq!(out[0] & 0x3, 1); assert_eq!(rp.nb_frames(), 2);
628 }
629}
630
631#[cfg(test)]
632mod sd_tests {
633 use super::*;
634 #[test]
635 fn self_delimited_roundtrip() {
636 let toc = 12u8 << 3;
638 let mut rp = Repacketizer::new();
639 let mut p = vec![toc | 0x3, 3 | 0x80];
640 encode_size(3, &mut p);
641 encode_size(5, &mut p);
642 p.extend_from_slice(&[1u8; 3]);
643 p.extend_from_slice(&[2u8; 5]);
644 p.extend_from_slice(&[3u8; 4]);
645 rp.cat(&p).unwrap();
646 let sd = rp.out_self_delimited().unwrap();
647 let mut stream = sd.clone();
649 stream.extend_from_slice(&[0xEE; 7]);
650 let (t, frames, off) = parse_packet(&stream, true).unwrap();
651 assert_eq!(t, toc | 0x3);
652 assert_eq!(frames.len(), 3);
653 assert_eq!(frames[0], &[1, 1, 1]);
654 assert_eq!(frames[2], &[3, 3, 3, 3]);
655 assert_eq!(off, sd.len()); }
657}