mp4_atom/moov/trak/mdia/minf/stbl/stsd/h264/
avcc.rs1use crate::*;
2
3#[derive(Debug, Clone, PartialEq, Eq, Default)]
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5pub struct Avcc {
6 pub configuration_version: u8,
7 pub avc_profile_indication: u8,
8 pub profile_compatibility: u8,
9 pub avc_level_indication: u8,
10 pub length_size: u8,
11 pub sequence_parameter_sets: Vec<Vec<u8>>,
12 pub picture_parameter_sets: Vec<Vec<u8>>,
13 pub ext: Option<AvccExt>,
14}
15
16#[derive(Debug, Clone, PartialEq, Eq)]
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19pub struct AvccExt {
20 pub chroma_format: u8,
21 pub bit_depth_luma: u8,
22 pub bit_depth_chroma: u8,
23 pub sequence_parameter_sets_ext: Vec<Vec<u8>>,
24}
25
26impl Default for AvccExt {
27 fn default() -> Self {
28 AvccExt {
29 chroma_format: 1,
30 bit_depth_luma: 8,
31 bit_depth_chroma: 8,
32 sequence_parameter_sets_ext: Vec::new(),
33 }
34 }
35}
36
37impl Avcc {
38 pub fn new(sps: &[u8], pps: &[u8]) -> Result<Self> {
39 if sps.len() < 4 {
40 return Err(Error::OutOfBounds);
41 }
42
43 Ok(Self {
44 configuration_version: 1,
45 avc_profile_indication: sps[1],
46 profile_compatibility: sps[2],
47 avc_level_indication: sps[3],
48 length_size: 4,
49 sequence_parameter_sets: vec![sps.into()],
50 picture_parameter_sets: vec![pps.into()],
51
52 ext: None,
54 })
55 }
56}
57
58impl Atom for Avcc {
59 const KIND: FourCC = FourCC::new(b"avcC");
60
61 fn decode_body<B: Buf>(buf: &mut B) -> Result<Self> {
62 let configuration_version = u8::decode(buf)?;
63 if configuration_version != 1 {
64 return Err(Error::UnknownVersion(configuration_version));
65 }
66 let avc_profile_indication = u8::decode(buf)?;
67 let profile_compatibility = u8::decode(buf)?;
68 let avc_level_indication = u8::decode(buf)?;
69
70 let mut length_size = u8::decode(buf)?;
72 length_size = match length_size {
73 0xfc..=0xff => (length_size & 0x03) + 1,
74 _ => return Err(Error::InvalidSize),
75 };
76
77 let num_of_spss = u8::decode(buf)? & 0x1F;
78 let mut sequence_parameter_sets = Vec::with_capacity(num_of_spss as usize);
79 for _ in 0..num_of_spss {
80 let size = u16::decode(buf)? as usize;
81 let nal = Vec::decode_exact(buf, size)?;
82 sequence_parameter_sets.push(nal);
83 }
84
85 let num_of_ppss = u8::decode(buf)?;
86 let mut picture_parameter_sets = Vec::with_capacity(num_of_ppss as usize);
87 for _ in 0..num_of_ppss {
88 let size = u16::decode(buf)? as usize;
89 let nal = Vec::decode_exact(buf, size)?;
90 picture_parameter_sets.push(nal);
91 }
92
93 let ext = match avc_profile_indication {
94 100 | 110 | 122 | 144 if buf.remaining() > 0 => {
96 let chroma_format = u8::decode(buf)? & 0x3;
97 let bit_depth_luma_minus8 = u8::decode(buf)? & 0x7;
98 let bit_depth_chroma_minus8 = u8::decode(buf)? & 0x7;
99 let num_of_sequence_parameter_set_exts = u8::decode(buf)? as usize;
100 let mut sequence_parameter_sets_ext =
101 Vec::with_capacity(num_of_sequence_parameter_set_exts);
102
103 for _ in 0..num_of_sequence_parameter_set_exts {
104 let size = u16::decode(buf)? as usize;
105 let nal = Vec::decode_exact(buf, size)?;
106 sequence_parameter_sets_ext.push(nal);
107 }
108
109 Some(AvccExt {
110 chroma_format,
111 bit_depth_luma: bit_depth_luma_minus8 + 8,
112 bit_depth_chroma: bit_depth_chroma_minus8 + 8,
113 sequence_parameter_sets_ext,
114 })
115 }
116 _ => None,
117 };
118
119 Ok(Avcc {
120 configuration_version,
121 avc_profile_indication,
122 profile_compatibility,
123 avc_level_indication,
124 length_size,
125 sequence_parameter_sets,
126 picture_parameter_sets,
127 ext,
128 })
129 }
130
131 fn encode_body<B: BufMut>(&self, buf: &mut B) -> Result<()> {
132 self.configuration_version.encode(buf)?;
133 self.avc_profile_indication.encode(buf)?;
134 self.profile_compatibility.encode(buf)?;
135 self.avc_level_indication.encode(buf)?;
136 let length_size = match self.length_size {
137 0 => return Err(Error::InvalidSize),
138 1..=4 => self.length_size - 1,
139 _ => return Err(Error::InvalidSize),
140 };
141 (length_size | 0xFC).encode(buf)?;
142
143 (self.sequence_parameter_sets.len() as u8 | 0xE0).encode(buf)?;
144 for sps in &self.sequence_parameter_sets {
145 (sps.len() as u16).encode(buf)?;
146 sps.encode(buf)?;
147 }
148
149 (self.picture_parameter_sets.len() as u8).encode(buf)?;
150 for pps in &self.picture_parameter_sets {
151 (pps.len() as u16).encode(buf)?;
152 pps.encode(buf)?;
153 }
154
155 if let Some(ext) = &self.ext {
156 ext.chroma_format.encode(buf)?;
157 ext.bit_depth_luma.encode(buf)?;
158 ext.bit_depth_chroma.encode(buf)?;
159 (ext.sequence_parameter_sets_ext.len() as u8).encode(buf)?;
160 for sps in &ext.sequence_parameter_sets_ext {
161 (sps.len() as u16).encode(buf)?;
162 sps.encode(buf)?;
163 }
164 }
165
166 Ok(())
167 }
168}