1use crate::nal::sps::{ConstraintFlags, Level, ProfileIdc, SeqParameterSet};
6use crate::nal::{pps, sps, Nal, NalHeader, NalHeaderError, RefNal, UnitType};
7use crate::Context;
8use std::convert::TryFrom;
9
10#[derive(Debug)]
11pub enum AvccError {
12 NotEnoughData {
13 expected: usize,
14 actual: usize,
15 },
16 UnsupportedConfigurationVersion(u8),
18 ParamSet(ParamSetError),
19 Sps(sps::SpsError),
20 Pps(pps::PpsError),
21}
22
23pub struct AvcDecoderConfigurationRecord<'buf> {
24 data: &'buf [u8],
25 extension_offset: Option<usize>,
27}
28impl<'buf> TryFrom<&'buf [u8]> for AvcDecoderConfigurationRecord<'buf> {
29 type Error = AvccError;
30
31 fn try_from(data: &'buf [u8]) -> Result<Self, Self::Error> {
32 let avcc = AvcDecoderConfigurationRecord {
33 data,
34 extension_offset: None,
35 };
36 avcc.ck(Self::MIN_CONF_SIZE)?;
38 if avcc.configuration_version() != 1 {
39 return Err(AvccError::UnsupportedConfigurationVersion(
42 avcc.configuration_version(),
43 ));
44 }
45 let mut len = avcc.seq_param_sets_end()?;
49
50 avcc.ck(len + 1)?;
51 let mut num_pps = data[len];
52 len += 1;
53 while num_pps > 0 {
54 avcc.ck(len + 2)?;
55 let pps_len = (u16::from(data[len]) << 8 | u16::from(data[len + 1])) as usize;
56 len += 2;
57 avcc.ck(len + pps_len)?;
58 len += pps_len;
59 num_pps -= 1;
60 }
61
62 let extension_offset = if avcc.avc_profile_indication().has_chroma_info()
66 && data.len() > len
67 {
68 let ext_start = len;
69 avcc.ck(len + 4)?;
70 len += 3; let num_sps_ext = data[len] as usize;
72 len += 1;
73 for _ in 0..num_sps_ext {
74 avcc.ck(len + 2)?;
75 let sps_ext_len = (u16::from(data[len]) << 8 | u16::from(data[len + 1])) as usize;
76 len += 2;
77 avcc.ck(len + sps_ext_len)?;
78 len += sps_ext_len;
79 }
80 Some(ext_start)
81 } else {
82 None
83 };
84
85 Ok(AvcDecoderConfigurationRecord {
86 data,
87 extension_offset,
88 })
89 }
90}
91impl<'buf> AvcDecoderConfigurationRecord<'buf> {
92 const MIN_CONF_SIZE: usize = 6;
93
94 fn seq_param_sets_end(&self) -> Result<usize, AvccError> {
95 let mut num_sps = self.num_of_sequence_parameter_sets();
96 let mut len = Self::MIN_CONF_SIZE;
97 while num_sps > 0 {
98 self.ck(len + 2)?;
99 let sps_len = (u16::from(self.data[len]) << 8 | u16::from(self.data[len + 1])) as usize;
100 len += 2;
101 self.ck(len + sps_len)?;
102 len += sps_len;
103 num_sps -= 1;
104 }
105 Ok(len)
106 }
107 fn ck(&self, len: usize) -> Result<(), AvccError> {
108 if self.data.len() < len {
109 Err(AvccError::NotEnoughData {
110 expected: len,
111 actual: self.data.len(),
112 })
113 } else {
114 Ok(())
115 }
116 }
117 pub fn configuration_version(&self) -> u8 {
118 self.data[0]
119 }
120 pub fn num_of_sequence_parameter_sets(&self) -> usize {
121 (self.data[5] & 0b0001_1111) as usize
122 }
123 pub fn avc_profile_indication(&self) -> ProfileIdc {
124 self.data[1].into()
125 }
126 pub fn profile_compatibility(&self) -> ConstraintFlags {
127 self.data[2].into()
128 }
129 pub fn avc_level_indication(&self) -> Level {
130 Level::from_constraint_flags_and_level_idc(self.profile_compatibility(), self.data[3])
131 }
132 pub fn length_size_minus_one(&self) -> u8 {
135 self.data[4] & 0b0000_0011
136 }
137 pub fn sequence_parameter_sets(
138 &self,
139 ) -> impl Iterator<Item = Result<&'buf [u8], ParamSetError>> {
140 let num = self.num_of_sequence_parameter_sets();
141 let data = &self.data[Self::MIN_CONF_SIZE..];
142 ParamSetIter::new(data, UnitType::SeqParameterSet).take(num)
143 }
144 pub fn chroma_format(&self) -> Option<u8> {
146 self.extension_offset
147 .map(|off| self.data[off] & 0b0000_0011)
148 }
149 pub fn bit_depth_luma_minus8(&self) -> Option<u8> {
151 self.extension_offset
152 .map(|off| self.data[off + 1] & 0b0000_0111)
153 }
154 pub fn bit_depth_chroma_minus8(&self) -> Option<u8> {
156 self.extension_offset
157 .map(|off| self.data[off + 2] & 0b0000_0111)
158 }
159 pub fn sequence_parameter_set_extensions(
160 &self,
161 ) -> impl Iterator<Item = Result<&'buf [u8], ParamSetError>> + 'buf {
162 let (data, num) = if let Some(off) = self.extension_offset {
163 let num = self.data[off + 3] as usize;
164 (&self.data[off + 4..], num)
165 } else {
166 (&self.data[..0], 0)
167 };
168 ParamSetIter::new(data, UnitType::SeqParameterSetExtension).take(num)
169 }
170 pub fn picture_parameter_sets(
171 &self,
172 ) -> impl Iterator<Item = Result<&'buf [u8], ParamSetError>> + 'buf {
173 let offset = self.seq_param_sets_end().unwrap();
174 let num = self.data[offset];
175 let data = &self.data[offset + 1..];
176 ParamSetIter::new(data, UnitType::PicParameterSet).take(num as usize)
177 }
178
179 pub fn create_context(&self) -> Result<Context, AvccError> {
185 let mut ctx = Context::new();
186 for sps in self.sequence_parameter_sets() {
187 let sps = sps.map_err(AvccError::ParamSet)?;
188 let sps = RefNal::new(&sps[..], &[], true);
189 let sps = crate::nal::sps::SeqParameterSet::from_bits(sps.rbsp_bits())
190 .map_err(AvccError::Sps)?;
191 ctx.put_seq_param_set(sps);
192 }
193 for pps in self.picture_parameter_sets() {
194 let pps = pps.map_err(AvccError::ParamSet)?;
195 let pps = RefNal::new(&pps[..], &[], true);
196 let pps = crate::nal::pps::PicParameterSet::from_bits(&ctx, pps.rbsp_bits())
197 .map_err(AvccError::Pps)?;
198 ctx.put_pic_param_set(pps);
199 }
200 Ok(ctx)
201 }
202}
203
204#[derive(Debug)]
205pub enum ParamSetError {
206 NalHeader(NalHeaderError),
207 IncorrectNalType {
208 expected: UnitType,
209 actual: UnitType,
210 },
211 IncompatibleSps(SeqParameterSet),
214}
215
216struct ParamSetIter<'buf>(&'buf [u8], UnitType);
217
218impl<'buf> ParamSetIter<'buf> {
219 pub fn new(buf: &'buf [u8], unit_type: UnitType) -> ParamSetIter<'buf> {
220 ParamSetIter(buf, unit_type)
221 }
222}
223impl<'buf> Iterator for ParamSetIter<'buf> {
224 type Item = Result<&'buf [u8], ParamSetError>;
225
226 fn next(&mut self) -> Option<Self::Item> {
227 if self.0.is_empty() {
228 None
229 } else {
230 let len = u16::from(self.0[0]) << 8 | u16::from(self.0[1]);
231 let data = &self.0[2..];
232 let res = match NalHeader::new(data[0]) {
233 Ok(nal_header) => {
234 if nal_header.nal_unit_type() == self.1 {
235 let (data, remainder) = data.split_at(len as usize);
236 self.0 = remainder;
237 Ok(data)
238 } else {
239 Err(ParamSetError::IncorrectNalType {
240 expected: self.1,
241 actual: nal_header.nal_unit_type(),
242 })
243 }
244 }
245 Err(err) => Err(ParamSetError::NalHeader(err)),
246 };
247 Some(res)
248 }
249 }
250}
251
252#[cfg(test)]
253mod test {
254 use super::*;
255 use crate::nal::pps::PicParamSetId;
256 use crate::nal::sps::SeqParamSetId;
257 use hex_literal::*;
258
259 #[test]
260 fn it_works() {
261 let avcc_data = hex!("0142c01e ffe10020 6742c01e b91061ff 78088000 00030080 00001971 3006d600 daf7bdc0 7c2211a8 01000468 de3c80");
262 let avcc = AvcDecoderConfigurationRecord::try_from(&avcc_data[..]).unwrap();
263 assert_eq!(1, avcc.configuration_version());
264 assert_eq!(1, avcc.num_of_sequence_parameter_sets());
265 assert_eq!(ProfileIdc::from(66), avcc.avc_profile_indication());
266 let flags = avcc.profile_compatibility();
267 assert!(flags.flag0());
268 assert!(flags.flag1());
269 assert!(!flags.flag2());
270 assert!(!flags.flag3());
271 assert!(!flags.flag4());
272 assert!(!flags.flag5());
273 assert_eq!(avcc.chroma_format(), None);
275 assert_eq!(avcc.bit_depth_luma_minus8(), None);
276 assert_eq!(avcc.bit_depth_chroma_minus8(), None);
277 assert_eq!(avcc.sequence_parameter_set_extensions().count(), 0);
278 let ctx = avcc.create_context().unwrap();
279 let sps = ctx
280 .sps_by_id(SeqParamSetId::from_u32(0).unwrap())
281 .expect("missing sps");
282 assert_eq!(avcc.avc_level_indication(), sps.level());
283 assert_eq!(avcc.avc_profile_indication(), sps.profile_idc);
284 assert_eq!(
285 SeqParamSetId::from_u32(0).unwrap(),
286 sps.seq_parameter_set_id
287 );
288 let _pps = ctx
289 .pps_by_id(PicParamSetId::from_u32(0).unwrap())
290 .expect("missing pps");
291 }
292 #[test]
293 fn high_profile_extension_fields() {
294 let sps_nalu = hex!("6764001e acd940a0 2ff96100 00030001 00000300 3c9c5802 d0000bb8 00004e20 6e200000 10000003 00010000 03000321");
301 let pps_nalu = hex!("68eb e3cb 22c0");
302 let mut avcc_data: Vec<u8> = Vec::new();
303 avcc_data.extend_from_slice(&[0x01, 0x64, 0x00, 0x1e, 0xff]);
305 avcc_data.push(0xe1);
307 avcc_data.extend_from_slice(&(sps_nalu.len() as u16).to_be_bytes());
308 avcc_data.extend_from_slice(&sps_nalu);
309 avcc_data.push(0x01);
311 avcc_data.extend_from_slice(&(pps_nalu.len() as u16).to_be_bytes());
312 avcc_data.extend_from_slice(&pps_nalu);
313 avcc_data.extend_from_slice(&[0xfd, 0xf8, 0xf8, 0x00]);
315
316 let avcc = AvcDecoderConfigurationRecord::try_from(&avcc_data[..]).unwrap();
317 assert_eq!(avcc.avc_profile_indication(), ProfileIdc::from(100));
318 assert_eq!(avcc.chroma_format(), Some(1));
319 assert_eq!(avcc.bit_depth_luma_minus8(), Some(0));
320 assert_eq!(avcc.bit_depth_chroma_minus8(), Some(0));
321 assert_eq!(avcc.sequence_parameter_set_extensions().count(), 0);
322 }
323 #[test]
324 fn high_profile_without_extension() {
325 let sps_nalu = hex!("6764001e acd940a0 2ff96100 00030001 00000300 3c9c5802 d0000bb8 00004e20 6e200000 10000003 00010000 03000321");
327 let pps_nalu = hex!("68eb e3cb 22c0");
328 let mut avcc_data: Vec<u8> = Vec::new();
329 avcc_data.extend_from_slice(&[0x01, 0x64, 0x00, 0x1e, 0xff]);
330 avcc_data.push(0xe1);
331 avcc_data.extend_from_slice(&(sps_nalu.len() as u16).to_be_bytes());
332 avcc_data.extend_from_slice(&sps_nalu);
333 avcc_data.push(0x01);
334 avcc_data.extend_from_slice(&(pps_nalu.len() as u16).to_be_bytes());
335 avcc_data.extend_from_slice(&pps_nalu);
336 let avcc = AvcDecoderConfigurationRecord::try_from(&avcc_data[..]).unwrap();
339 assert_eq!(avcc.avc_profile_indication(), ProfileIdc::from(100));
340 assert_eq!(avcc.chroma_format(), None);
341 assert_eq!(avcc.bit_depth_luma_minus8(), None);
342 assert_eq!(avcc.bit_depth_chroma_minus8(), None);
343 }
344 #[test]
345 fn sps_with_emulation_protection() {
346 let avcc_data = hex!(
348 "014d401e ffe10017 674d401e 9a660a0f
349 ff350101 01400000 fa000003 01f40101
350 000468ee 3c80"
351 );
352 let avcc = AvcDecoderConfigurationRecord::try_from(&avcc_data[..]).unwrap();
353 let _sps_data = avcc.sequence_parameter_sets().next().unwrap().unwrap();
354 let ctx = avcc.create_context().unwrap();
355 let _sps = ctx
356 .sps_by_id(SeqParamSetId::from_u32(0).unwrap())
357 .expect("missing sps");
358 }
359}