1use crate::rbsp::BitRead;
4use std::fmt;
5
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
9pub enum PrimaryPicType {
10 I = 0,
12 IP = 1,
14 IPB = 2,
16 SI = 3,
18 SISP = 4,
20 ISI = 5,
22 ISIPSP = 6,
24 ISIPSPB = 7,
26}
27
28#[derive(Debug)]
30pub struct PrimaryPicTypeError(pub u8);
31
32impl fmt::Display for PrimaryPicTypeError {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 write!(f, "invalid primary_pic_type value: {}", self.0)
35 }
36}
37
38impl PrimaryPicType {
39 pub fn from_id(id: u8) -> Result<PrimaryPicType, PrimaryPicTypeError> {
40 match id {
41 0 => Ok(PrimaryPicType::I),
42 1 => Ok(PrimaryPicType::IP),
43 2 => Ok(PrimaryPicType::IPB),
44 3 => Ok(PrimaryPicType::SI),
45 4 => Ok(PrimaryPicType::SISP),
46 5 => Ok(PrimaryPicType::ISI),
47 6 => Ok(PrimaryPicType::ISIPSP),
48 7 => Ok(PrimaryPicType::ISIPSPB),
49 _ => Err(PrimaryPicTypeError(id)),
50 }
51 }
52
53 pub fn id(self) -> u8 {
54 self as u8
55 }
56}
57
58#[derive(Clone, Debug, PartialEq, Eq)]
60pub struct AccessUnitDelimiter {
61 pub primary_pic_type: PrimaryPicType,
62}
63
64impl AccessUnitDelimiter {
65 pub fn from_bits<R: BitRead>(mut r: R) -> Result<AccessUnitDelimiter, AudError> {
66 let val: u8 = r.read::<3, _>("primary_pic_type")?;
67 let primary_pic_type =
68 PrimaryPicType::from_id(val).map_err(AudError::InvalidPrimaryPicType)?;
69 r.finish_rbsp()?;
70 Ok(AccessUnitDelimiter { primary_pic_type })
71 }
72}
73
74#[derive(Debug)]
76pub enum AudError {
77 InvalidPrimaryPicType(PrimaryPicTypeError),
78 RbspError(crate::rbsp::BitReaderError),
79}
80
81impl From<crate::rbsp::BitReaderError> for AudError {
82 fn from(e: crate::rbsp::BitReaderError) -> Self {
83 AudError::RbspError(e)
84 }
85}
86
87impl fmt::Display for AudError {
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 match self {
90 AudError::InvalidPrimaryPicType(e) => write!(f, "{}", e),
91 AudError::RbspError(e) => write!(f, "{:?}", e),
92 }
93 }
94}
95
96#[cfg(test)]
97mod test {
98 use super::*;
99 use crate::rbsp::BitReader;
100
101 #[test]
102 fn parse_all_pic_types() {
103 for id in 0u8..=7 {
104 let byte = (id << 5) | 0x10;
106 let data = [byte];
107 let aud = AccessUnitDelimiter::from_bits(BitReader::new(&data[..])).unwrap();
108 assert_eq!(aud.primary_pic_type.id(), id);
109 }
110 }
111
112 #[test]
113 fn parse_ipb() {
114 let data = [0x50u8];
116 let aud = AccessUnitDelimiter::from_bits(BitReader::new(&data[..])).unwrap();
117 assert_eq!(aud.primary_pic_type, PrimaryPicType::IPB);
118 }
119}