1use alloc::vec::Vec;
10
11#[derive(Debug, Default)]
18pub struct PesAssembler {
19 buf: Vec<u8>,
20 started: bool,
21}
22
23impl PesAssembler {
24 #[must_use]
26 pub fn new() -> Self {
27 Self::default()
28 }
29
30 #[must_use]
35 pub fn feed(&mut self, payload_unit_start: bool, payload: &[u8]) -> Option<Vec<u8>> {
36 if payload_unit_start {
37 let completed = if self.started && !self.buf.is_empty() {
38 Some(core::mem::take(&mut self.buf))
39 } else {
40 None
41 };
42 self.started = true;
43 self.buf.extend_from_slice(payload);
44 completed
45 } else {
46 if self.started {
48 self.buf.extend_from_slice(payload);
49 }
50 None
51 }
52 }
53
54 #[must_use]
56 pub fn flush(&mut self) -> Option<Vec<u8>> {
57 self.started = false;
58 if self.buf.is_empty() {
59 None
60 } else {
61 Some(core::mem::take(&mut self.buf))
62 }
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69 use crate::PesPacket;
70
71 #[test]
72 fn reassembles_across_packets_and_flushes() {
73 let mut a = PesAssembler::new();
74 assert_eq!(
76 a.feed(true, &[0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x80]),
77 None
78 );
79 assert_eq!(
80 a.feed(false, &[0x80, 0x05, 0x21, 0x00, 0x01, 0x00, 0x01]),
81 None
82 );
83 assert_eq!(a.feed(false, &[0xAA, 0xBB]), None);
84 let first = a
86 .feed(
87 true,
88 &[0x00, 0x00, 0x01, 0xC0, 0x00, 0x00, 0x80, 0x00, 0x00, 0x11],
89 )
90 .expect("first PES emitted on next unit start");
91 let p1 = PesPacket::parse(&first).unwrap();
92 assert!(p1.stream_id.is_video());
93 assert_eq!(p1.payload, &[0xAA, 0xBB]);
94 let second = a.flush().expect("second PES flushed");
96 let p2 = PesPacket::parse(&second).unwrap();
97 assert!(p2.stream_id.is_audio());
98 assert!(a.flush().is_none());
99 }
100
101 #[test]
102 fn ignores_continuation_before_first_start() {
103 let mut a = PesAssembler::new();
104 assert_eq!(a.feed(false, &[0xDE, 0xAD]), None); assert!(a.flush().is_none());
106 }
107}