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}
26impl<'buf> TryFrom<&'buf [u8]> for AvcDecoderConfigurationRecord<'buf> {
27 type Error = AvccError;
28
29 fn try_from(data: &'buf [u8]) -> Result<Self, Self::Error> {
30 let avcc = AvcDecoderConfigurationRecord { data };
31 avcc.ck(Self::MIN_CONF_SIZE)?;
33 if avcc.configuration_version() != 1 {
34 return Err(AvccError::UnsupportedConfigurationVersion(
37 avcc.configuration_version(),
38 ));
39 }
40 let mut len = avcc.seq_param_sets_end()?;
44
45 avcc.ck(len + 1)?;
46 let mut num_pps = data[len];
47 len += 1;
48 while num_pps > 0 {
49 avcc.ck(len + 2)?;
50 let pps_len = (u16::from(data[len]) << 8 | u16::from(data[len + 1])) as usize;
51 len += 2;
52 avcc.ck(len + pps_len)?;
53 len += pps_len;
54 num_pps -= 1;
55 }
56
57 Ok(avcc)
58 }
59}
60impl<'buf> AvcDecoderConfigurationRecord<'buf> {
61 const MIN_CONF_SIZE: usize = 6;
62
63 fn seq_param_sets_end(&self) -> Result<usize, AvccError> {
64 let mut num_sps = self.num_of_sequence_parameter_sets();
65 let mut len = Self::MIN_CONF_SIZE;
66 while num_sps > 0 {
67 self.ck(len + 2)?;
68 let sps_len = (u16::from(self.data[len]) << 8 | u16::from(self.data[len + 1])) as usize;
69 len += 2;
70 self.ck(len + sps_len)?;
71 len += sps_len;
72 num_sps -= 1;
73 }
74 Ok(len)
75 }
76 fn ck(&self, len: usize) -> Result<(), AvccError> {
77 if self.data.len() < len {
78 Err(AvccError::NotEnoughData {
79 expected: len,
80 actual: self.data.len(),
81 })
82 } else {
83 Ok(())
84 }
85 }
86 pub fn configuration_version(&self) -> u8 {
87 self.data[0]
88 }
89 pub fn num_of_sequence_parameter_sets(&self) -> usize {
90 (self.data[5] & 0b0001_1111) as usize
91 }
92 pub fn avc_profile_indication(&self) -> ProfileIdc {
93 self.data[1].into()
94 }
95 pub fn profile_compatibility(&self) -> ConstraintFlags {
96 self.data[2].into()
97 }
98 pub fn avc_level_indication(&self) -> Level {
99 Level::from_constraint_flags_and_level_idc(self.profile_compatibility(), self.data[3])
100 }
101 pub fn length_size_minus_one(&self) -> u8 {
104 self.data[4] & 0b0000_0011
105 }
106 pub fn sequence_parameter_sets(
107 &self,
108 ) -> impl Iterator<Item = Result<&'buf [u8], ParamSetError>> {
109 let num = self.num_of_sequence_parameter_sets();
110 let data = &self.data[Self::MIN_CONF_SIZE..];
111 ParamSetIter::new(data, UnitType::SeqParameterSet).take(num)
112 }
113 pub fn picture_parameter_sets(
114 &self,
115 ) -> impl Iterator<Item = Result<&'buf [u8], ParamSetError>> + 'buf {
116 let offset = self.seq_param_sets_end().unwrap();
117 let num = self.data[offset];
118 let data = &self.data[offset + 1..];
119 ParamSetIter::new(data, UnitType::PicParameterSet).take(num as usize)
120 }
121
122 pub fn create_context(&self) -> Result<Context, AvccError> {
128 let mut ctx = Context::new();
129 for sps in self.sequence_parameter_sets() {
130 let sps = sps.map_err(AvccError::ParamSet)?;
131 let sps = RefNal::new(&sps[..], &[], true);
132 let sps = crate::nal::sps::SeqParameterSet::from_bits(sps.rbsp_bits())
133 .map_err(AvccError::Sps)?;
134 ctx.put_seq_param_set(sps);
135 }
136 for pps in self.picture_parameter_sets() {
137 let pps = pps.map_err(AvccError::ParamSet)?;
138 let pps = RefNal::new(&pps[..], &[], true);
139 let pps = crate::nal::pps::PicParameterSet::from_bits(&ctx, pps.rbsp_bits())
140 .map_err(AvccError::Pps)?;
141 ctx.put_pic_param_set(pps);
142 }
143 Ok(ctx)
144 }
145}
146
147#[derive(Debug)]
148pub enum ParamSetError {
149 NalHeader(NalHeaderError),
150 IncorrectNalType {
151 expected: UnitType,
152 actual: UnitType,
153 },
154 IncompatibleSps(SeqParameterSet),
157}
158
159struct ParamSetIter<'buf>(&'buf [u8], UnitType);
160
161impl<'buf> ParamSetIter<'buf> {
162 pub fn new(buf: &'buf [u8], unit_type: UnitType) -> ParamSetIter<'buf> {
163 ParamSetIter(buf, unit_type)
164 }
165}
166impl<'buf> Iterator for ParamSetIter<'buf> {
167 type Item = Result<&'buf [u8], ParamSetError>;
168
169 fn next(&mut self) -> Option<Self::Item> {
170 if self.0.is_empty() {
171 None
172 } else {
173 let len = u16::from(self.0[0]) << 8 | u16::from(self.0[1]);
174 let data = &self.0[2..];
175 let res = match NalHeader::new(data[0]) {
176 Ok(nal_header) => {
177 if nal_header.nal_unit_type() == self.1 {
178 let (data, remainder) = data.split_at(len as usize);
179 self.0 = remainder;
180 Ok(data)
181 } else {
182 Err(ParamSetError::IncorrectNalType {
183 expected: self.1,
184 actual: nal_header.nal_unit_type(),
185 })
186 }
187 }
188 Err(err) => Err(ParamSetError::NalHeader(err)),
189 };
190 Some(res)
191 }
192 }
193}
194
195#[cfg(test)]
196mod test {
197 use super::*;
198 use crate::nal::pps::PicParamSetId;
199 use crate::nal::sps::SeqParamSetId;
200 use hex_literal::*;
201
202 #[test]
203 fn it_works() {
204 let avcc_data = hex!("0142c01e ffe10020 6742c01e b91061ff 78088000 00030080 00001971 3006d600 daf7bdc0 7c2211a8 01000468 de3c80");
205 let avcc = AvcDecoderConfigurationRecord::try_from(&avcc_data[..]).unwrap();
206 assert_eq!(1, avcc.configuration_version());
207 assert_eq!(1, avcc.num_of_sequence_parameter_sets());
208 assert_eq!(ProfileIdc::from(66), avcc.avc_profile_indication());
209 let flags = avcc.profile_compatibility();
210 assert!(flags.flag0());
211 assert!(flags.flag1());
212 assert!(!flags.flag2());
213 assert!(!flags.flag3());
214 assert!(!flags.flag4());
215 assert!(!flags.flag5());
216 let ctx = avcc.create_context().unwrap();
217 let sps = ctx
218 .sps_by_id(SeqParamSetId::from_u32(0).unwrap())
219 .expect("missing sps");
220 assert_eq!(avcc.avc_level_indication(), sps.level());
221 assert_eq!(avcc.avc_profile_indication(), sps.profile_idc);
222 assert_eq!(
223 SeqParamSetId::from_u32(0).unwrap(),
224 sps.seq_parameter_set_id
225 );
226 let _pps = ctx
227 .pps_by_id(PicParamSetId::from_u32(0).unwrap())
228 .expect("missing pps");
229 }
230 #[test]
231 fn sps_with_emulation_protection() {
232 let avcc_data = hex!(
234 "014d401e ffe10017 674d401e 9a660a0f
235 ff350101 01400000 fa000003 01f40101
236 000468ee 3c80"
237 );
238 let avcc = AvcDecoderConfigurationRecord::try_from(&avcc_data[..]).unwrap();
239 let _sps_data = avcc.sequence_parameter_sets().next().unwrap().unwrap();
240 let ctx = avcc.create_context().unwrap();
241 let _sps = ctx
242 .sps_by_id(SeqParamSetId::from_u32(0).unwrap())
243 .expect("missing sps");
244 }
245}