mp4_atom/moov/trak/mdia/minf/stbl/stsd/h264/
avc1.rs

1use crate::*;
2
3#[derive(Debug, Clone, PartialEq, Eq, Default)]
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5pub struct Avc1 {
6    pub visual: Visual,
7    pub avcc: Avcc,
8    pub btrt: Option<Btrt>,
9    pub colr: Option<Colr>,
10    pub pasp: Option<Pasp>,
11    pub taic: Option<Taic>,
12}
13
14impl Atom for Avc1 {
15    const KIND: FourCC = FourCC::new(b"avc1");
16
17    fn decode_body<B: Buf>(buf: &mut B) -> Result<Self> {
18        let visual = Visual::decode(buf)?;
19
20        let mut avcc = None;
21        let mut btrt = None;
22        let mut colr = None;
23        let mut pasp = None;
24        let mut taic = None;
25        while let Some(atom) = Any::decode_maybe(buf)? {
26            match atom {
27                Any::Avcc(atom) => avcc = atom.into(),
28                Any::Btrt(atom) => btrt = atom.into(),
29                Any::Colr(atom) => colr = atom.into(),
30                Any::Pasp(atom) => pasp = atom.into(),
31                Any::Taic(atom) => taic = atom.into(),
32                _ => tracing::warn!("unknown atom: {:?}", atom),
33            }
34        }
35
36        Ok(Avc1 {
37            visual,
38            avcc: avcc.ok_or(Error::MissingBox(Avcc::KIND))?,
39            btrt,
40            colr,
41            pasp,
42            taic,
43        })
44    }
45
46    fn encode_body<B: BufMut>(&self, buf: &mut B) -> Result<()> {
47        self.visual.encode(buf)?;
48        self.avcc.encode(buf)?;
49        if self.btrt.is_some() {
50            self.btrt.encode(buf)?;
51        }
52        if self.colr.is_some() {
53            self.colr.encode(buf)?;
54        }
55        if self.pasp.is_some() {
56            self.pasp.encode(buf)?;
57        }
58        if self.taic.is_some() {
59            self.taic.encode(buf)?
60        }
61        Ok(())
62    }
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68
69    #[test]
70    fn test_avc1() {
71        let expected = Avc1 {
72            visual: Visual {
73                data_reference_index: 1,
74                width: 320,
75                height: 240,
76                horizresolution: 0x48.into(),
77                vertresolution: 0x48.into(),
78                frame_count: 1,
79                compressor: "ya boy".into(),
80                depth: 24,
81            },
82            avcc: Avcc {
83                configuration_version: 1,
84                avc_profile_indication: 100,
85                profile_compatibility: 0,
86                avc_level_indication: 13,
87                length_size: 4,
88                sequence_parameter_sets: vec![vec![
89                    0x67, 0x64, 0x00, 0x0D, 0xAC, 0xD9, 0x41, 0x41, 0xFA, 0x10, 0x00, 0x00, 0x03,
90                    0x00, 0x10, 0x00, 0x00, 0x03, 0x03, 0x20, 0xF1, 0x42, 0x99, 0x60,
91                ]],
92                picture_parameter_sets: vec![vec![0x68, 0xEB, 0xE3, 0xCB, 0x22, 0xC0]],
93                ..Default::default()
94            },
95            btrt: None,
96            colr: None,
97            pasp: None,
98            taic: None,
99        };
100        let mut buf = Vec::new();
101        expected.encode(&mut buf).unwrap();
102
103        let mut buf = buf.as_ref();
104        let decoded = Avc1::decode(&mut buf).unwrap();
105        assert_eq!(decoded, expected);
106    }
107
108    #[test]
109    fn test_avc1_with_extras() {
110        let expected = Avc1 {
111            visual: Visual {
112                data_reference_index: 1,
113                width: 320,
114                height: 240,
115                horizresolution: 0x48.into(),
116                vertresolution: 0x48.into(),
117                frame_count: 1,
118                compressor: "they".into(),
119                depth: 24,
120            },
121            avcc: Avcc {
122                configuration_version: 1,
123                avc_profile_indication: 100,
124                profile_compatibility: 0,
125                avc_level_indication: 13,
126                length_size: 4,
127                sequence_parameter_sets: vec![vec![
128                    0x67, 0x64, 0x00, 0x0D, 0xAC, 0xD9, 0x41, 0x41, 0xFA, 0x10, 0x00, 0x00, 0x03,
129                    0x00, 0x10, 0x00, 0x00, 0x03, 0x03, 0x20, 0xF1, 0x42, 0x99, 0x60,
130                ]],
131                picture_parameter_sets: vec![vec![0x68, 0xEB, 0xE3, 0xCB, 0x22, 0xC0]],
132                ..Default::default()
133            },
134            btrt: Some(Btrt {
135                buffer_size_db: 14075,
136                max_bitrate: 374288,
137                avg_bitrate: 240976,
138            }),
139            colr: Some(Colr::default()),
140            pasp: Some(Pasp {
141                h_spacing: 4,
142                v_spacing: 3,
143            }),
144            taic: Some(Taic {
145                time_uncertainty: u64::MAX,
146                clock_resolution: 1000,
147                clock_drift_rate: i32::MAX,
148                clock_type: ClockType::CanSync,
149            }),
150        };
151        let mut buf = Vec::new();
152        expected.encode(&mut buf).unwrap();
153
154        let mut buf = buf.as_ref();
155        let decoded = Avc1::decode(&mut buf).unwrap();
156        assert_eq!(decoded, expected);
157    }
158}