]>
Commit | Line | Data |
---|---|---|
1 | use nihav_core::codecs::{DecoderResult, DecoderError}; | |
2 | use nihav_core::io::bitreader::*; | |
3 | use std::fmt; | |
4 | ||
5 | #[allow(non_camel_case_types)] | |
6 | #[derive(Clone,Copy,PartialEq)] | |
7 | pub enum M4AType { | |
8 | None, | |
9 | Main, | |
10 | LC, | |
11 | SSR, | |
12 | LTP, | |
13 | SBR, | |
14 | Scalable, | |
15 | TwinVQ, | |
16 | CELP, | |
17 | HVXC, | |
18 | TTSI, | |
19 | MainSynth, | |
20 | WavetableSynth, | |
21 | GeneralMIDI, | |
22 | Algorithmic, | |
23 | ER_AAC_LC, | |
24 | ER_AAC_LTP, | |
25 | ER_AAC_Scalable, | |
26 | ER_TwinVQ, | |
27 | ER_BSAC, | |
28 | ER_AAC_LD, | |
29 | ER_CELP, | |
30 | ER_HVXC, | |
31 | ER_HILN, | |
32 | ER_Parametric, | |
33 | SSC, | |
34 | PS, | |
35 | MPEGSurround, | |
36 | Layer1, | |
37 | Layer2, | |
38 | Layer3, | |
39 | DST, | |
40 | ALS, | |
41 | SLS, | |
42 | SLSNonCore, | |
43 | ER_AAC_ELD, | |
44 | SMRSimple, | |
45 | SMRMain, | |
46 | Reserved, | |
47 | Unknown, | |
48 | } | |
49 | ||
50 | const M4A_TYPES: &[M4AType] = &[ | |
51 | M4AType::None, M4AType::Main, M4AType::LC, M4AType::SSR, | |
52 | M4AType::LTP, M4AType::SBR, M4AType::Scalable, M4AType::TwinVQ, | |
53 | M4AType::CELP, M4AType::HVXC, M4AType::Reserved, M4AType::Reserved, | |
54 | M4AType::TTSI, M4AType::MainSynth, M4AType::WavetableSynth, M4AType::GeneralMIDI, | |
55 | M4AType::Algorithmic, M4AType::ER_AAC_LC, M4AType::Reserved, M4AType::ER_AAC_LTP, | |
56 | M4AType::ER_AAC_Scalable, M4AType::ER_TwinVQ, M4AType::ER_BSAC, M4AType::ER_AAC_LD, | |
57 | M4AType::ER_CELP, M4AType::ER_HVXC, M4AType::ER_HILN, M4AType::ER_Parametric, | |
58 | M4AType::SSC, M4AType::PS, M4AType::MPEGSurround, M4AType::Reserved /*escape*/, | |
59 | M4AType::Layer1, M4AType::Layer2, M4AType::Layer3, M4AType::DST, | |
60 | M4AType::ALS, M4AType::SLS, M4AType::SLSNonCore, M4AType::ER_AAC_ELD, | |
61 | M4AType::SMRSimple, M4AType::SMRMain, | |
62 | ]; | |
63 | const M4A_TYPE_NAMES: &[&str] = &[ | |
64 | "None", "AAC Main", "AAC LC", "AAC SSR", "AAC LTP", "SBR", "AAC Scalable", "TwinVQ", "CELP", "HVXC", | |
65 | /*"(reserved10)", "(reserved11)", */ "TTSI", | |
66 | "Main synthetic", "Wavetable synthesis", "General MIDI", "Algorithmic Synthesis and Audio FX", | |
67 | "ER AAC LC", /*"(reserved18)",*/ "ER AAC LTP", "ER AAC Scalable", "ER TwinVQ", "ER BSAC", "ER AAC LD", | |
68 | "ER CELP", "ER HVXC", "ER HILN", "ER Parametric", "SSC", "PS", "MPEG Surround", /*"(escape)",*/ | |
69 | "Layer-1", "Layer-2", "Layer-3", "DST", "ALS", "SLS", "SLS non-core", "ER AAC ELD", "SMR Simple", "SMR Main", | |
70 | "(reserved)", "(unknown)", | |
71 | ]; | |
72 | ||
73 | impl fmt::Display for M4AType { | |
74 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
75 | write!(f, "{}", M4A_TYPE_NAMES[*self as usize]) | |
76 | } | |
77 | } | |
78 | ||
79 | const AAC_SAMPLE_RATES: [u32; 16] = [ | |
80 | 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, | |
81 | 16000, 12000, 11025, 8000, 7350, 0, 0, 0 | |
82 | ]; | |
83 | ||
84 | const AAC_CHANNELS: [usize; 8] = [ 0, 1, 2, 3, 4, 5, 6, 8 ]; | |
85 | ||
86 | pub struct M4AInfo { | |
87 | pub otype: M4AType, | |
88 | pub srate: u32, | |
89 | pub channels: usize, | |
90 | pub samples: usize, | |
91 | pub sbr_ps_info: Option<(u32, usize)>, | |
92 | pub sbr_present: bool, | |
93 | pub ps_present: bool, | |
94 | } | |
95 | ||
96 | impl M4AInfo { | |
97 | pub fn new() -> Self { | |
98 | Self { | |
99 | otype: M4AType::None, | |
100 | srate: 0, | |
101 | channels: 0, | |
102 | samples: 0, | |
103 | sbr_ps_info: Option::None, | |
104 | sbr_present: false, | |
105 | ps_present: false, | |
106 | } | |
107 | } | |
108 | fn read_object_type(br: &mut BitReader) -> DecoderResult<M4AType> { | |
109 | let otypeidx; | |
110 | if br.peek(5) == 31 { | |
111 | br.skip(5)?; | |
112 | otypeidx = (br.read(6)? as usize) + 32; | |
113 | } else { | |
114 | otypeidx = br.read(5)? as usize; | |
115 | } | |
116 | if otypeidx >= M4A_TYPES.len() { | |
117 | Ok(M4AType::Unknown) | |
118 | } else { | |
119 | Ok(M4A_TYPES[otypeidx]) | |
120 | } | |
121 | } | |
122 | fn read_sampling_frequency(br: &mut BitReader) -> DecoderResult<u32> { | |
123 | if br.peek(4) == 15 { | |
124 | let srate = br.read(24)?; | |
125 | Ok(srate) | |
126 | } else { | |
127 | let srate_idx = br.read(4)? as usize; | |
128 | Ok(AAC_SAMPLE_RATES[srate_idx]) | |
129 | } | |
130 | } | |
131 | fn read_channel_config(br: &mut BitReader) -> DecoderResult<usize> { | |
132 | let chidx = br.read(4)? as usize; | |
133 | if chidx < AAC_CHANNELS.len() { | |
134 | Ok(AAC_CHANNELS[chidx]) | |
135 | } else { | |
136 | Ok(chidx) | |
137 | } | |
138 | } | |
139 | pub fn read(&mut self, src: &[u8]) -> DecoderResult<()> { | |
140 | let mut br = BitReader::new(src, BitReaderMode::BE); | |
141 | self.otype = Self::read_object_type(&mut br)?; | |
142 | self.srate = Self::read_sampling_frequency(&mut br)?; | |
143 | validate!(self.srate > 0); | |
144 | self.channels = Self::read_channel_config(&mut br)?; | |
145 | ||
146 | if (self.otype == M4AType::SBR) || (self.otype == M4AType::PS) { | |
147 | let ext_srate = Self::read_sampling_frequency(&mut br)?; | |
148 | self.otype = Self::read_object_type(&mut br)?; | |
149 | let ext_chans; | |
150 | if self.otype == M4AType::ER_BSAC { | |
151 | ext_chans = Self::read_channel_config(&mut br)?; | |
152 | } else { | |
153 | ext_chans = 0; | |
154 | } | |
155 | self.sbr_ps_info = Some((ext_srate, ext_chans)); | |
156 | } | |
157 | ||
158 | match self.otype { | |
159 | M4AType::Main | M4AType::LC | M4AType::SSR | M4AType::Scalable | M4AType::TwinVQ | | |
160 | M4AType::ER_AAC_LC | M4AType::ER_AAC_LTP | M4AType::ER_AAC_Scalable | M4AType::ER_TwinVQ | | |
161 | M4AType::ER_BSAC | M4AType::ER_AAC_LD => { | |
162 | // GASpecificConfig | |
163 | let short_frame = br.read_bool()?; | |
164 | self.samples = if short_frame { 960 } else { 1024 }; | |
165 | let depends_on_core = br.read_bool()?; | |
166 | if depends_on_core { | |
167 | let _delay = br.read(14)?; | |
168 | } | |
169 | let extension_flag = br.read_bool()?; | |
170 | if self.channels == 0 { | |
171 | unimplemented!("program config element"); | |
172 | } | |
173 | if (self.otype == M4AType::Scalable) || (self.otype == M4AType::ER_AAC_Scalable) { | |
174 | let _layer = br.read(3)?; | |
175 | } | |
176 | if extension_flag { | |
177 | if self.otype == M4AType::ER_BSAC { | |
178 | let _num_subframes = br.read(5)? as usize; | |
179 | let _layer_length = br.read(11)?; | |
180 | } | |
181 | if (self.otype == M4AType::ER_AAC_LC) || | |
182 | (self.otype == M4AType::ER_AAC_LTP) || | |
183 | (self.otype == M4AType::ER_AAC_Scalable) || | |
184 | (self.otype == M4AType::ER_AAC_LD) { | |
185 | let _section_data_resilience = br.read_bool()?; | |
186 | let _scalefactors_resilience = br.read_bool()?; | |
187 | let _spectral_data_resilience = br.read_bool()?; | |
188 | } | |
189 | let extension_flag3 = br.read_bool()?; | |
190 | if extension_flag3 { | |
191 | unimplemented!("version3 extensions"); | |
192 | } | |
193 | } | |
194 | }, | |
195 | M4AType::CELP => { unimplemented!("CELP config"); }, | |
196 | M4AType::HVXC => { unimplemented!("HVXC config"); }, | |
197 | M4AType::TTSI => { unimplemented!("TTS config"); }, | |
198 | M4AType::MainSynth | M4AType::WavetableSynth | M4AType::GeneralMIDI | M4AType::Algorithmic => { unimplemented!("structured audio config"); }, | |
199 | M4AType::ER_CELP => { unimplemented!("ER CELP config"); }, | |
200 | M4AType::ER_HVXC => { unimplemented!("ER HVXC config"); }, | |
201 | M4AType::ER_HILN | M4AType::ER_Parametric => { unimplemented!("parametric config"); }, | |
202 | M4AType::SSC => { unimplemented!("SSC config"); }, | |
203 | M4AType::MPEGSurround => { | |
204 | br.skip(1)?; // sacPayloadEmbedding | |
205 | unimplemented!("MPEG Surround config"); | |
206 | }, | |
207 | M4AType::Layer1 | M4AType::Layer2 | M4AType::Layer3 => { unimplemented!("MPEG Layer 1/2/3 config"); }, | |
208 | M4AType::DST => { unimplemented!("DST config"); }, | |
209 | M4AType::ALS => { | |
210 | br.skip(5)?; // fillBits | |
211 | unimplemented!("ALS config"); | |
212 | }, | |
213 | M4AType::SLS | M4AType::SLSNonCore => { unimplemented!("SLS config"); }, | |
214 | M4AType::ER_AAC_ELD => { unimplemented!("ELD config"); }, | |
215 | M4AType::SMRSimple | M4AType::SMRMain => { unimplemented!("symbolic music config"); }, | |
216 | _ => {}, | |
217 | }; | |
218 | match self.otype { | |
219 | M4AType::ER_AAC_LC | M4AType::ER_AAC_LTP | M4AType::ER_AAC_Scalable | M4AType::ER_TwinVQ | | |
220 | M4AType::ER_BSAC | M4AType::ER_AAC_LD | M4AType::ER_CELP | M4AType::ER_HVXC | | |
221 | M4AType::ER_HILN | M4AType::ER_Parametric | M4AType::ER_AAC_ELD => { | |
222 | let ep_config = br.read(2)?; | |
223 | if (ep_config == 2) || (ep_config == 3) { | |
224 | unimplemented!("error protection config"); | |
225 | } | |
226 | if ep_config == 3 { | |
227 | let direct_mapping = br.read_bool()?; | |
228 | validate!(direct_mapping); | |
229 | } | |
230 | }, | |
231 | _ => {}, | |
232 | }; | |
233 | if self.sbr_ps_info.is_some() && (br.left() >= 16) { | |
234 | let sync = br.read(11)?; | |
235 | if sync == 0x2B7 { | |
236 | let ext_otype = Self::read_object_type(&mut br)?; | |
237 | if ext_otype == M4AType::SBR { | |
238 | self.sbr_present = br.read_bool()?; | |
239 | if self.sbr_present { | |
240 | let _ext_srate = Self::read_sampling_frequency(&mut br)?; | |
241 | if br.left() >= 12 { | |
242 | let sync = br.read(11)?; | |
243 | if sync == 0x548 { | |
244 | self.ps_present = br.read_bool()?; | |
245 | } | |
246 | } | |
247 | } | |
248 | } | |
249 | if ext_otype == M4AType::PS { | |
250 | self.sbr_present = br.read_bool()?; | |
251 | if self.sbr_present { | |
252 | let _ext_srate = Self::read_sampling_frequency(&mut br)?; | |
253 | } | |
254 | let _ext_channels = br.read(4)?; | |
255 | } | |
256 | } | |
257 | } | |
258 | ||
259 | Ok(()) | |
260 | } | |
261 | } | |
262 | ||
263 | impl fmt::Display for M4AInfo { | |
264 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
265 | write!(f, "MPEG 4 Audio {}, {} Hz, {} channels, {} samples per frame", | |
266 | self.otype, self.srate, self.channels, self.samples) | |
267 | } | |
268 | } | |
269 |