/src/vlc/modules/packetizer/mpeg4audio.h
Line | Count | Source (jump to first uncovered line) |
1 | | /***************************************************************************** |
2 | | * mpeg4audio.h: ISO/IEC 14496-3 audio definitions |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2001-2024 VLC authors, VideoLAN and VideoLabs |
5 | | * |
6 | | * This program is free software; you can redistribute it and/or modify it |
7 | | * under the terms of the GNU Lesser General Public License as published by |
8 | | * the Free Software Foundation; either version 2.1 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * This program is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public License |
17 | | * along with this program; if not, write to the Free Software Foundation, |
18 | | * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. |
19 | | *****************************************************************************/ |
20 | | #include <vlc_bits.h> |
21 | | |
22 | | enum MPEG4_audioObjectType /* ISO/IEC 14496-3:2009 1.5.1 */ |
23 | | { |
24 | | MPEG4_AOT_NULL = 0, |
25 | | MPEG4_AOT_AAC_MAIN = 1, |
26 | | MPEG4_AOT_AAC_LC = 2, |
27 | | MPEG4_AOT_AAC_SSR = 3, |
28 | | MPEG4_AOT_AAC_LTP = 4, |
29 | | MPEG4_AOT_AAC_SBR = 5, |
30 | | MPEG4_AOT_AAC_SC = 6, |
31 | | MPEG4_AOT_TWINVQ = 7, |
32 | | MPEG4_AOT_CELP = 8, |
33 | | MPEG4_AOT_HVXC = 9, |
34 | | MPEG4_AOT_RESERVED10 = 10, |
35 | | MPEG4_AOT_RESERVED11 = 11, |
36 | | MPEG4_AOT_TTSI = 12, |
37 | | MPEG4_AOT_MAIN_SYNTHETIC = 13, |
38 | | MPEG4_AOT_WAVETABLES = 14, |
39 | | MPEG4_AOT_GENERAL_MIDI = 15, |
40 | | MPEG4_AOT_ALGORITHMIC = 16, |
41 | | MPEG4_AOT_ER_AAC_LC = 17, |
42 | | MPEG4_AOT_RESERVED18 = 18, |
43 | | MPEG4_AOT_ER_AAC_LTP = 19, |
44 | | MPEG4_AOT_ER_AAC_SC = 20, |
45 | | MPEG4_AOT_ER_TWINVQ = 21, |
46 | | MPEG4_AOT_ER_BSAC = 22, |
47 | | MPEG4_AOT_ER_AAC_LD = 23, |
48 | | MPEG4_AOT_ER_CELP = 24, |
49 | | MPEG4_AOT_ER_HXVC = 25, |
50 | | MPEG4_AOT_ER_HILN = 26, |
51 | | MPEG4_AOT_ER_Parametric = 27, |
52 | | MPEG4_AOT_SSC = 28, |
53 | | MPEG4_AOT_AAC_PS = 29, |
54 | | MPEG4_AOT_MPEG_SURROUND = 30, |
55 | | MPEG4_AOT_ESCAPE = 31, |
56 | | MPEG4_AOT_LAYER1 = 32, |
57 | | MPEG4_AOT_LAYER2 = 33, |
58 | | MPEG4_AOT_LAYER3 = 34, |
59 | | MPEG4_AOT_DST = 35, |
60 | | MPEG4_AOT_ALS = 36, |
61 | | MPEG4_AOT_SLS = 37, |
62 | | MPEG4_AOT_SLS_NON_CORE = 38, |
63 | | MPEG4_AOT_ER_AAC_ELD = 39, |
64 | | MPEG4_AOT_SMR_SIMPLE = 40, |
65 | | MPEG4_AOT_SMR_MAIN = 41, |
66 | | }; |
67 | | |
68 | | enum |
69 | | { |
70 | | AAC_PROFILE_MAIN = MPEG4_AOT_AAC_MAIN - 1, |
71 | | AAC_PROFILE_LC, |
72 | | AAC_PROFILE_SSR, |
73 | | AAC_PROFILE_LTP, |
74 | | AAC_PROFILE_HE, |
75 | | AAC_PROFILE_LD = MPEG4_AOT_ER_AAC_LD - 1, |
76 | | AAC_PROFILE_HEv2 = MPEG4_AOT_AAC_PS - 1, |
77 | | AAC_PROFILE_ELD = MPEG4_AOT_ER_AAC_ELD - 1, |
78 | | /* Similar shift signaling as avcodec, as signaling should have been |
79 | | done in ADTS header. Values defaults to MPEG4 */ |
80 | | AAC_PROFILE_MPEG2_LC = AAC_PROFILE_LC + 128, |
81 | | AAC_PROFILE_MPEG2_HE = AAC_PROFILE_HE + 128, |
82 | | }; |
83 | | |
84 | | static const uint32_t MPEG4_asc_channelsbyindex[] = |
85 | | { |
86 | | [0] = 0, /* Set later */ |
87 | | |
88 | | [1] = AOUT_CHAN_CENTER, // Mono |
89 | | |
90 | | [2] = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT, // Stereo |
91 | | |
92 | | [3] = AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT, // 2.1ch 3.0 |
93 | | |
94 | | [4] = AOUT_CHAN_CENTER | // 4ch 3.1 |
95 | | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | |
96 | | AOUT_CHAN_REARCENTER, |
97 | | |
98 | | [5] = AOUT_CHAN_CENTER | // 5ch 3.2 |
99 | | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | |
100 | | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT, |
101 | | |
102 | | [6] = AOUT_CHAN_CENTER | // 5.1ch 3.2.1 |
103 | | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | |
104 | | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | |
105 | | AOUT_CHAN_LFE, |
106 | | |
107 | | [7] = AOUT_CHAN_CENTER | // 7.1ch 5.2.1 |
108 | | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | |
109 | | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT | |
110 | | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | |
111 | | AOUT_CHAN_LFE, |
112 | | |
113 | | [8] = 0, |
114 | | }; |
115 | | |
116 | | #define MPEG4_ASC_MAX_INDEXEDPOS ARRAY_SIZE(MPEG4_asc_channelsbyindex) |
117 | | |
118 | | typedef struct |
119 | | { |
120 | | enum MPEG4_audioObjectType i_object_type; |
121 | | unsigned i_samplerate; |
122 | | uint8_t i_channel_configuration; |
123 | | int8_t i_sbr; // 0: no sbr, 1: sbr, -1: unknown |
124 | | int8_t i_ps; // 0: no ps, 1: ps, -1: unknown |
125 | | |
126 | | struct |
127 | | { |
128 | | enum MPEG4_audioObjectType i_object_type; |
129 | | unsigned i_samplerate; |
130 | | uint8_t i_channel_configuration; |
131 | | } extension; |
132 | | |
133 | | /* GASpecific */ |
134 | | unsigned i_frame_length; // 1024 or 960 |
135 | | |
136 | | } MPEG4_asc_t; |
137 | | |
138 | | static inline int MPEG4_read_GAProgramConfigElement(bs_t *s) |
139 | 266 | { |
140 | | /* TODO compute channels count ? */ |
141 | 266 | int i_tag = bs_read(s, 4); |
142 | 266 | if (i_tag != 0x05) |
143 | 37 | return -1; |
144 | 229 | bs_skip(s, 2 + 4); // object type + sampling index |
145 | 229 | int i_num_front = bs_read(s, 4); |
146 | 229 | int i_num_side = bs_read(s, 4); |
147 | 229 | int i_num_back = bs_read(s, 4); |
148 | 229 | int i_num_lfe = bs_read(s, 2); |
149 | 229 | int i_num_assoc_data = bs_read(s, 3); |
150 | 229 | int i_num_valid_cc = bs_read(s, 4); |
151 | | |
152 | 229 | if (bs_read1(s)) |
153 | 50 | bs_skip(s, 4); // mono downmix |
154 | 229 | if (bs_read1(s)) |
155 | 104 | bs_skip(s, 4); // stereo downmix |
156 | 229 | if (bs_read1(s)) |
157 | 52 | bs_skip(s, 2+1); // matrix downmix + pseudo_surround |
158 | | |
159 | 229 | bs_skip(s, i_num_front * (1+4)); |
160 | 229 | bs_skip(s, i_num_side * (1+4)); |
161 | 229 | bs_skip(s, i_num_back * (1+4)); |
162 | 229 | bs_skip(s, i_num_lfe * (4)); |
163 | 229 | bs_skip(s, i_num_assoc_data * (4)); |
164 | 229 | bs_skip(s, i_num_valid_cc * (5)); |
165 | 229 | bs_align(s); |
166 | 229 | int i_comment = bs_read(s, 8); |
167 | 229 | bs_skip(s, i_comment * 8); |
168 | 229 | return 0; |
169 | 266 | } |
170 | | |
171 | | static inline int MPEG4_read_GASpecificConfig(MPEG4_asc_t *p_cfg, bs_t *s) |
172 | 468 | { |
173 | 468 | p_cfg->i_frame_length = bs_read1(s) ? 960 : 1024; |
174 | 468 | if(p_cfg->i_object_type == MPEG4_AOT_ER_AAC_LD) /* 14496-3 4.5.1.1 */ |
175 | 3 | p_cfg->i_frame_length >>= 1; |
176 | 465 | else if(p_cfg->i_object_type == MPEG4_AOT_AAC_SSR) |
177 | 10 | p_cfg->i_frame_length = 256; |
178 | | |
179 | 468 | if (bs_read1(s)) // depend on core coder |
180 | 115 | bs_skip(s, 14); // core coder delay |
181 | | |
182 | 468 | int i_extension_flag = bs_read1(s); |
183 | 468 | if (p_cfg->i_channel_configuration == 0) |
184 | 266 | MPEG4_read_GAProgramConfigElement(s); |
185 | 468 | if (p_cfg->i_object_type == MPEG4_AOT_AAC_SC || |
186 | 468 | p_cfg->i_object_type == MPEG4_AOT_ER_AAC_SC) |
187 | 109 | bs_skip(s, 3); // layer |
188 | | |
189 | 468 | if (i_extension_flag) { |
190 | 126 | if (p_cfg->i_object_type == MPEG4_AOT_ER_BSAC) |
191 | 13 | bs_skip(s, 5 + 11); // numOfSubFrame + layer length |
192 | 126 | if (p_cfg->i_object_type == MPEG4_AOT_ER_AAC_LC || |
193 | 126 | p_cfg->i_object_type == MPEG4_AOT_ER_AAC_LTP || |
194 | 126 | p_cfg->i_object_type == MPEG4_AOT_ER_AAC_SC || |
195 | 126 | p_cfg->i_object_type == MPEG4_AOT_ER_AAC_LD) |
196 | 65 | bs_skip(s, 1+1+1); // ER data : section scale spectral */ |
197 | 126 | if (bs_read1(s)) // extension 3 |
198 | 36 | fprintf(stderr, "MPEG4GASpecificConfig: error 1\n"); |
199 | 126 | } |
200 | 468 | return 0; |
201 | 468 | } |
202 | | |
203 | | static inline int MPEG4_read_ELDSpecificConfig(MPEG4_asc_t *p_cfg, bs_t *s) |
204 | 296 | { |
205 | 296 | p_cfg->i_frame_length = bs_read1(s) ? 480 : 512; |
206 | | |
207 | | /* ELDSpecificConfig Table 4.180 */ |
208 | | |
209 | 296 | bs_skip(s, 3); |
210 | 296 | if(bs_read1(s)) /* ldSbrPresentFlag */ |
211 | 210 | { |
212 | 210 | bs_skip(s, 2); |
213 | | /* ld_sbr_header(channelConfiguration) Table 4.181 */ |
214 | 210 | unsigned numSbrHeader; |
215 | 210 | switch(p_cfg->i_channel_configuration) |
216 | 210 | { |
217 | 13 | case 1: case 2: |
218 | 13 | numSbrHeader = 1; |
219 | 13 | break; |
220 | 6 | case 3: |
221 | 6 | numSbrHeader = 2; |
222 | 6 | break; |
223 | 48 | case 4: case 5: case 6: |
224 | 48 | numSbrHeader = 3; |
225 | 48 | break; |
226 | 68 | case 7: |
227 | 68 | numSbrHeader = 4; |
228 | 68 | break; |
229 | 75 | default: |
230 | 75 | numSbrHeader = 0; |
231 | 75 | break; |
232 | 210 | } |
233 | 651 | for( ; numSbrHeader; numSbrHeader-- ) |
234 | 441 | { |
235 | | /* sbr_header() Table 4.63 */ |
236 | 441 | bs_read(s, 14); |
237 | 441 | bool header_extra_1 = bs_read1(s); |
238 | 441 | bool header_extra_2 = bs_read1(s); |
239 | 441 | if(header_extra_1) |
240 | 236 | bs_read(s, 5); |
241 | 441 | if(header_extra_2) |
242 | 206 | bs_read(s, 6); |
243 | 441 | } |
244 | 210 | } |
245 | | |
246 | 296 | for(unsigned eldExtType = bs_read(s, 4); |
247 | 2.20k | eldExtType != 0x0 /* ELDEXT_TERM */; |
248 | 1.90k | eldExtType = bs_read(s, 4)) |
249 | 1.90k | { |
250 | 1.90k | unsigned eldExtLen = bs_read(s, 4); |
251 | 1.90k | unsigned eldExtLenAdd = 0; |
252 | 1.90k | if(eldExtLen == 15) |
253 | 92 | { |
254 | 92 | eldExtLenAdd = bs_read(s, 8); |
255 | 92 | eldExtLen += eldExtLenAdd; |
256 | 92 | } |
257 | 1.90k | if(eldExtLenAdd == 255) |
258 | 37 | eldExtLen += bs_read(s, 16); |
259 | | /* reserved extensions */ |
260 | 2.32M | for(; eldExtLen; eldExtLen--) |
261 | 2.32M | bs_skip(s, 8); |
262 | 1.90k | } |
263 | | |
264 | 296 | return 0; |
265 | 296 | } |
266 | | |
267 | | static inline enum MPEG4_audioObjectType MPEG4_read_AudioObjectType(bs_t *s) |
268 | 1.09k | { |
269 | 1.09k | int i_type = bs_read(s, 5); |
270 | 1.09k | if (i_type == 31) |
271 | 41 | i_type = 32 + bs_read(s, 6); |
272 | 1.09k | return (enum MPEG4_audioObjectType) i_type; |
273 | 1.09k | } |
274 | | |
275 | | static const int pi_sample_rates[16] = |
276 | | { |
277 | | 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, |
278 | | 16000, 12000, 11025, 8000, 7350, 0, 0, 0 |
279 | | }; |
280 | | |
281 | | static inline unsigned MPEG4_read_AudioSamplerate(bs_t *s) |
282 | 1.07k | { |
283 | 1.07k | int i_index = bs_read(s, 4); |
284 | 1.07k | if (i_index != 0x0f) |
285 | 1.05k | return pi_sample_rates[i_index]; |
286 | 24 | return bs_read(s, 24); |
287 | 1.07k | } |
288 | | |
289 | | static inline int MPEG4_read_AudioSpecificConfig(bs_t *s, MPEG4_asc_t *p_cfg, bool b_withext) |
290 | 789 | { |
291 | 789 | p_cfg->i_object_type = MPEG4_read_AudioObjectType(s); |
292 | 789 | p_cfg->i_samplerate = MPEG4_read_AudioSamplerate(s); |
293 | 789 | p_cfg->i_channel_configuration = bs_read(s, 4); |
294 | | |
295 | 789 | p_cfg->i_sbr = -1; |
296 | 789 | p_cfg->i_ps = -1; |
297 | 789 | p_cfg->extension.i_object_type = MPEG4_AOT_NULL; |
298 | 789 | p_cfg->extension.i_samplerate = 0; |
299 | 789 | p_cfg->extension.i_channel_configuration = 0; |
300 | 789 | p_cfg->i_frame_length = 0; |
301 | | |
302 | 789 | if (p_cfg->i_object_type == MPEG4_AOT_AAC_SBR || |
303 | 789 | p_cfg->i_object_type == MPEG4_AOT_AAC_PS) { |
304 | 269 | p_cfg->i_sbr = 1; |
305 | 269 | if (p_cfg->i_object_type == MPEG4_AOT_AAC_PS) |
306 | 14 | p_cfg->i_ps = 1; |
307 | 269 | p_cfg->extension.i_object_type = MPEG4_AOT_AAC_SBR; |
308 | 269 | p_cfg->extension.i_samplerate = MPEG4_read_AudioSamplerate(s); |
309 | | |
310 | 269 | p_cfg->i_object_type = MPEG4_read_AudioObjectType(s); |
311 | 269 | if(p_cfg->i_object_type == MPEG4_AOT_ER_BSAC) |
312 | 9 | p_cfg->extension.i_channel_configuration = bs_read(s, 4); |
313 | 269 | } |
314 | | |
315 | 789 | switch(p_cfg->i_object_type) |
316 | 789 | { |
317 | 8 | case MPEG4_AOT_AAC_MAIN: |
318 | 91 | case MPEG4_AOT_AAC_LC: |
319 | 101 | case MPEG4_AOT_AAC_SSR: |
320 | 256 | case MPEG4_AOT_AAC_LTP: |
321 | 308 | case MPEG4_AOT_AAC_SC: |
322 | 317 | case MPEG4_AOT_TWINVQ: |
323 | 357 | case MPEG4_AOT_ER_AAC_LC: |
324 | 372 | case MPEG4_AOT_ER_AAC_LTP: |
325 | 429 | case MPEG4_AOT_ER_AAC_SC: |
326 | 447 | case MPEG4_AOT_ER_TWINVQ: |
327 | 465 | case MPEG4_AOT_ER_BSAC: |
328 | 468 | case MPEG4_AOT_ER_AAC_LD: |
329 | 468 | MPEG4_read_GASpecificConfig(p_cfg, s); |
330 | 468 | break; |
331 | 5 | case MPEG4_AOT_CELP: |
332 | | // CelpSpecificConfig(); |
333 | 24 | case MPEG4_AOT_HVXC: |
334 | | // HvxcSpecificConfig(); |
335 | 41 | case MPEG4_AOT_TTSI: |
336 | | // TTSSSpecificConfig(); |
337 | 87 | case MPEG4_AOT_MAIN_SYNTHETIC: |
338 | 127 | case MPEG4_AOT_WAVETABLES: |
339 | 154 | case MPEG4_AOT_GENERAL_MIDI: |
340 | 164 | case MPEG4_AOT_ALGORITHMIC: |
341 | | // StructuredAudioSpecificConfig(); |
342 | 168 | case MPEG4_AOT_ER_CELP: |
343 | | // ERCelpSpecificConfig(); |
344 | 226 | case MPEG4_AOT_ER_HXVC: |
345 | | // ERHvxcSpecificConfig(); |
346 | 241 | case MPEG4_AOT_ER_HILN: |
347 | 247 | case MPEG4_AOT_ER_Parametric: |
348 | | // ParametricSpecificConfig(); |
349 | 270 | case MPEG4_AOT_SSC: |
350 | | // SSCSpecificConfig(); |
351 | 273 | case MPEG4_AOT_LAYER1: |
352 | 281 | case MPEG4_AOT_LAYER2: |
353 | 284 | case MPEG4_AOT_LAYER3: |
354 | | // MPEG_1_2_SpecificConfig(); |
355 | 286 | case MPEG4_AOT_DST: |
356 | | // DSTSpecificConfig(); |
357 | 288 | case MPEG4_AOT_ALS: |
358 | | // ALSSpecificConfig(); |
359 | 291 | case MPEG4_AOT_SLS: |
360 | 293 | case MPEG4_AOT_SLS_NON_CORE: |
361 | | // SLSSpecificConfig(); |
362 | 296 | case MPEG4_AOT_ER_AAC_ELD: |
363 | 296 | MPEG4_read_ELDSpecificConfig(p_cfg, s); |
364 | 296 | break; |
365 | 0 | case MPEG4_AOT_SMR_SIMPLE: |
366 | 0 | case MPEG4_AOT_SMR_MAIN: |
367 | | // SymbolicMusicSpecificConfig(); |
368 | 25 | default: |
369 | | // error |
370 | 25 | return VLC_EGENERIC; |
371 | 789 | } |
372 | | |
373 | 764 | switch(p_cfg->i_object_type) |
374 | 764 | { |
375 | 40 | case MPEG4_AOT_ER_AAC_LC: |
376 | 55 | case MPEG4_AOT_ER_AAC_LTP: |
377 | 112 | case MPEG4_AOT_ER_AAC_SC: |
378 | 130 | case MPEG4_AOT_ER_TWINVQ: |
379 | 148 | case MPEG4_AOT_ER_BSAC: |
380 | 151 | case MPEG4_AOT_ER_AAC_LD: |
381 | 155 | case MPEG4_AOT_ER_CELP: |
382 | 213 | case MPEG4_AOT_ER_HXVC: |
383 | 228 | case MPEG4_AOT_ER_HILN: |
384 | 234 | case MPEG4_AOT_ER_Parametric: |
385 | 237 | case MPEG4_AOT_ER_AAC_ELD: |
386 | 237 | { |
387 | 237 | int epConfig = bs_read(s, 2); |
388 | 237 | if (epConfig == 2 || epConfig == 3) |
389 | | //ErrorProtectionSpecificConfig(); |
390 | 35 | if (epConfig == 3) |
391 | 28 | if (bs_read1(s)) { |
392 | | // TODO : directMapping |
393 | 16 | } |
394 | 237 | break; |
395 | 234 | } |
396 | 527 | default: |
397 | 527 | break; |
398 | 764 | } |
399 | | |
400 | 764 | if (b_withext && p_cfg->extension.i_object_type != MPEG4_AOT_AAC_SBR && |
401 | 764 | !bs_eof(s) && bs_read(s, 11) == 0x2b7) |
402 | 34 | { |
403 | 34 | p_cfg->extension.i_object_type = MPEG4_read_AudioObjectType(s); |
404 | 34 | if (p_cfg->extension.i_object_type == MPEG4_AOT_AAC_SBR) |
405 | 20 | { |
406 | 20 | p_cfg->i_sbr = bs_read1(s); |
407 | 20 | if (p_cfg->i_sbr == 1) { |
408 | 18 | p_cfg->extension.i_samplerate = MPEG4_read_AudioSamplerate(s); |
409 | 18 | if (bs_read(s, 11) == 0x548) |
410 | 14 | p_cfg->i_ps = bs_read1(s); |
411 | 18 | } |
412 | 20 | } |
413 | 14 | else if (p_cfg->extension.i_object_type == MPEG4_AOT_ER_BSAC) |
414 | 2 | { |
415 | 2 | p_cfg->i_sbr = bs_read1(s); |
416 | 2 | if(p_cfg->i_sbr) |
417 | 1 | p_cfg->extension.i_samplerate = MPEG4_read_AudioSamplerate(s); |
418 | 2 | p_cfg->extension.i_channel_configuration = bs_read(s, 4); |
419 | 2 | } |
420 | 34 | } |
421 | | |
422 | | #if 0 |
423 | | static const char *ppsz_otype[] = { |
424 | | "NULL", |
425 | | "AAC Main", "AAC LC", "AAC SSR", "AAC LTP", "SBR", "AAC Scalable", |
426 | | "TwinVQ", |
427 | | "CELP", "HVXC", |
428 | | "Reserved", "Reserved", |
429 | | "TTSI", |
430 | | "Main Synthetic", "Wavetables Synthesis", "General MIDI", |
431 | | "Algorithmic Synthesis and Audio FX", |
432 | | "ER AAC LC", |
433 | | "Reserved", |
434 | | "ER AAC LTP", "ER AAC Scalable", "ER TwinVQ", "ER BSAC", "ER AAC LD", |
435 | | "ER CELP", "ER HVXC", "ER HILN", "ER Parametric", |
436 | | "SSC", |
437 | | "PS", "MPEG Surround", "Escape", |
438 | | "Layer 1", "Layer 2", "Layer 3", |
439 | | "DST", "ALS", "SLS", "SLS non-core", "ELD", |
440 | | "SMR Simple", "SMR Main", |
441 | | }; |
442 | | |
443 | | fprintf(stderr, "MPEG4ReadAudioSpecificInfo: t=%s(%d)f=%d c=%d sbr=%d\n", |
444 | | ppsz_otype[p_cfg->i_object_type], p_cfg->i_object_type, |
445 | | p_cfg->i_samplerate, p_cfg->i_channel, p_cfg->i_sbr); |
446 | | #endif |
447 | 764 | return bs_error(s) ? VLC_EGENERIC : VLC_SUCCESS; |
448 | 764 | } |
449 | | |
450 | | #define MPEG4_STREAM_MAX_EXTRADATA 64 |
451 | | typedef struct |
452 | | { |
453 | | uint8_t i_program; |
454 | | uint8_t i_layer; |
455 | | |
456 | | unsigned i_frame_length; // type 1 |
457 | | uint8_t i_frame_length_type; |
458 | | uint8_t i_frame_length_index; // type 3 4 5 6 7 |
459 | | |
460 | | MPEG4_asc_t cfg; |
461 | | |
462 | | /* Raw configuration */ |
463 | | size_t i_extra; |
464 | | uint8_t extra[MPEG4_STREAM_MAX_EXTRADATA]; |
465 | | |
466 | | } MPEG4_audio_stream_t; |
467 | | |
468 | | #define MPEG4_STREAMMUX_MAX_LAYER 8 |
469 | | #define MPEG4_STREAMMUX_MAX_PROGRAM 16 |
470 | | typedef struct |
471 | | { |
472 | | bool b_same_time_framing; |
473 | | uint8_t i_sub_frames; |
474 | | uint8_t i_programs; |
475 | | |
476 | | uint8_t pi_layers[MPEG4_STREAMMUX_MAX_PROGRAM]; |
477 | | |
478 | | uint8_t pi_stream[MPEG4_STREAMMUX_MAX_PROGRAM][MPEG4_STREAMMUX_MAX_LAYER]; |
479 | | |
480 | | uint8_t i_streams; |
481 | | MPEG4_audio_stream_t stream[MPEG4_STREAMMUX_MAX_PROGRAM*MPEG4_STREAMMUX_MAX_LAYER]; |
482 | | |
483 | | uint32_t i_other_data; |
484 | | int16_t i_crc; /* -1 if not set */ |
485 | | } MPEG4_streammux_config_t; |
486 | | |
487 | | static inline uint32_t MPEG4_LatmGetValue(bs_t *s) |
488 | 0 | { |
489 | 0 | uint32_t v = 0; |
490 | 0 | for (int i = 1 + bs_read(s, 2); i > 0; i--) |
491 | 0 | v = (v << 8) + bs_read(s, 8); |
492 | 0 | return v; |
493 | 0 | } |
494 | | |
495 | | static inline size_t AudioSpecificConfigBitsToBytes(bs_t *s, uint32_t i_bits, uint8_t *p_data) |
496 | 0 | { |
497 | 0 | size_t i_extra = __MIN((i_bits + 7) / 8, MPEG4_STREAM_MAX_EXTRADATA); |
498 | 0 | for (size_t i = 0; i < i_extra; i++) { |
499 | 0 | const uint32_t i_read = __MIN(8, i_bits - 8*i); |
500 | 0 | p_data[i] = bs_read(s, i_read) << (8-i_read); |
501 | 0 | } |
502 | 0 | return i_extra; |
503 | 0 | } |
504 | | |
505 | | static inline int MPEG4_parse_StreamMuxConfig(bs_t *s, MPEG4_streammux_config_t *m) |
506 | 0 | { |
507 | 0 | int i_mux_version; |
508 | 0 | int i_mux_versionA; |
509 | |
|
510 | 0 | i_mux_version = bs_read(s, 1); |
511 | 0 | i_mux_versionA = 0; |
512 | 0 | if (i_mux_version) |
513 | 0 | i_mux_versionA = bs_read(s, 1); |
514 | |
|
515 | 0 | if (i_mux_versionA != 0) /* support only A=0 */ |
516 | 0 | return -1; |
517 | | |
518 | 0 | memset(m, 0, sizeof(*m)); |
519 | |
|
520 | 0 | if (i_mux_versionA == 0) |
521 | 0 | if (i_mux_version == 1) |
522 | 0 | MPEG4_LatmGetValue(s); /* taraBufferFullness */ |
523 | |
|
524 | 0 | if(bs_eof(s)) |
525 | 0 | return -1; |
526 | | |
527 | 0 | m->b_same_time_framing = bs_read1(s); |
528 | 0 | m->i_sub_frames = 1 + bs_read(s, 6); |
529 | 0 | m->i_programs = 1 + bs_read(s, 4); |
530 | |
|
531 | 0 | for (uint8_t i_program = 0; i_program < m->i_programs; i_program++) { |
532 | 0 | if(bs_eof(s)) |
533 | 0 | return -1; |
534 | 0 | m->pi_layers[i_program] = 1+bs_read(s, 3); |
535 | |
|
536 | 0 | for (uint8_t i_layer = 0; i_layer < m->pi_layers[i_program]; i_layer++) { |
537 | 0 | MPEG4_audio_stream_t *st = &m->stream[m->i_streams]; |
538 | 0 | bool b_previous_cfg; |
539 | |
|
540 | 0 | m->pi_stream[i_program][i_layer] = m->i_streams; |
541 | 0 | st->i_program = i_program; |
542 | 0 | st->i_layer = i_layer; |
543 | |
|
544 | 0 | b_previous_cfg = false; |
545 | 0 | if (i_program != 0 || i_layer != 0) |
546 | 0 | b_previous_cfg = bs_read1(s); |
547 | |
|
548 | 0 | if (b_previous_cfg) { |
549 | 0 | assert(m->i_streams > 0); |
550 | 0 | st->cfg = m->stream[m->i_streams-1].cfg; |
551 | 0 | } else { |
552 | 0 | uint32_t asc_size = 0; |
553 | 0 | if(i_mux_version > 0) |
554 | 0 | asc_size = MPEG4_LatmGetValue(s); |
555 | 0 | bs_t asc_bs = *s; |
556 | 0 | MPEG4_read_AudioSpecificConfig(&asc_bs, &st->cfg, i_mux_version > 0); |
557 | 0 | if (i_mux_version == 0) |
558 | 0 | asc_size = bs_pos(&asc_bs) - bs_pos(s); |
559 | 0 | asc_bs = *s; |
560 | 0 | st->i_extra = AudioSpecificConfigBitsToBytes(&asc_bs, asc_size, st->extra); |
561 | 0 | bs_skip(s, asc_size); |
562 | 0 | } |
563 | | |
564 | 0 | st->i_frame_length_type = bs_read(s, 3); |
565 | 0 | switch(st->i_frame_length_type) |
566 | 0 | { |
567 | 0 | case 0: |
568 | 0 | { |
569 | 0 | bs_skip(s, 8); /* latmBufferFullnes */ |
570 | 0 | if (!m->b_same_time_framing) |
571 | 0 | if (st->cfg.i_object_type == MPEG4_AOT_AAC_SC || |
572 | 0 | st->cfg.i_object_type == MPEG4_AOT_CELP || |
573 | 0 | st->cfg.i_object_type == MPEG4_AOT_ER_AAC_SC || |
574 | 0 | st->cfg.i_object_type == MPEG4_AOT_ER_CELP) |
575 | 0 | bs_skip(s, 6); /* eFrameOffset */ |
576 | 0 | break; |
577 | 0 | } |
578 | 0 | case 1: |
579 | 0 | st->i_frame_length = bs_read(s, 9); |
580 | 0 | break; |
581 | 0 | case 3: case 4: case 5: |
582 | 0 | st->i_frame_length_index = bs_read(s, 6); // celp |
583 | 0 | break; |
584 | 0 | case 6: case 7: |
585 | 0 | st->i_frame_length_index = bs_read(s, 1); // hvxc |
586 | 0 | default: |
587 | 0 | break; |
588 | 0 | } |
589 | | /* Next stream */ |
590 | 0 | m->i_streams++; |
591 | 0 | } |
592 | 0 | } |
593 | | |
594 | 0 | if(bs_error(s) || bs_eof(s)) |
595 | 0 | return -1; |
596 | | |
597 | | /* other data */ |
598 | 0 | if (bs_read1(s)) { |
599 | 0 | if (i_mux_version == 1) |
600 | 0 | m->i_other_data = MPEG4_LatmGetValue(s); |
601 | 0 | else { |
602 | 0 | int b_continue; |
603 | 0 | do { |
604 | 0 | b_continue = bs_read1(s); |
605 | 0 | m->i_other_data = (m->i_other_data << 8) + bs_read(s, 8); |
606 | 0 | } while (b_continue); |
607 | 0 | } |
608 | 0 | } |
609 | | |
610 | | /* crc */ |
611 | 0 | m->i_crc = -1; |
612 | 0 | if (bs_read1(s)) |
613 | 0 | m->i_crc = bs_read(s, 8); |
614 | |
|
615 | 0 | return bs_error(s) ? -1 : 0; |
616 | 0 | } |
617 | | |