1#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize))]
7pub struct StreamId(pub u8);
8
9const PROGRAM_STREAM_MAP: u8 = 0xBC;
12const PADDING_STREAM: u8 = 0xBE;
13const PRIVATE_STREAM_2: u8 = 0xBF;
14const ECM_STREAM: u8 = 0xF0;
15const EMM_STREAM: u8 = 0xF1;
16const DSMCC_STREAM: u8 = 0xF2;
17const H222_1_TYPE_E: u8 = 0xF8;
18const PROGRAM_STREAM_DIRECTORY: u8 = 0xFF;
19
20impl StreamId {
21 pub const PROGRAM_STREAM_MAP: StreamId = StreamId(PROGRAM_STREAM_MAP);
23 pub const PADDING_STREAM: StreamId = StreamId(PADDING_STREAM);
25 pub const PRIVATE_STREAM_2: StreamId = StreamId(PRIVATE_STREAM_2);
27
28 #[must_use]
32 pub const fn has_optional_header(self) -> bool {
33 !matches!(
34 self.0,
35 PROGRAM_STREAM_MAP
36 | PADDING_STREAM
37 | PRIVATE_STREAM_2
38 | ECM_STREAM
39 | EMM_STREAM
40 | DSMCC_STREAM
41 | H222_1_TYPE_E
42 | PROGRAM_STREAM_DIRECTORY
43 )
44 }
45
46 #[must_use]
48 pub const fn is_audio(self) -> bool {
49 self.0 & 0xE0 == 0xC0
50 }
51
52 #[must_use]
54 pub const fn is_video(self) -> bool {
55 self.0 & 0xF0 == 0xE0
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[test]
64 fn classification() {
65 assert!(StreamId(0xC0).is_audio());
66 assert!(StreamId(0xE0).is_video());
67 assert!(StreamId(0xE0).has_optional_header());
68 assert!(StreamId(0xBD).has_optional_header()); assert!(!StreamId::PADDING_STREAM.has_optional_header());
70 assert!(!StreamId::PROGRAM_STREAM_MAP.has_optional_header());
71 assert!(!StreamId(0xFF).has_optional_header());
72 }
73}