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