1 /******************************************************************************
2 * *
3 * Copyright (C) 2018 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 #include <string.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include "ixheaacd_sbr_common.h"
24 #include <ixheaacd_type_def.h>
25 #include <ixheaacd_type_def.h>
26 #include "ixheaacd_constants.h"
27 #include <ixheaacd_basic_ops32.h>
28 #include <ixheaacd_basic_ops16.h>
29 #include <ixheaacd_basic_ops40.h>
30 #include "ixheaacd_basic_ops.h"
31
32 #include "ixheaacd_error_standards.h"
33 #include "ixheaacd_apicmd_standards.h"
34 #include "ixheaacd_aac_config.h"
35 #include "ixheaacd_api_defs.h"
36
37 #include "ixheaacd_definitions.h"
38 #include "ixheaacd_error_codes.h"
39 #include "ixheaacd_bitbuffer.h"
40
41 #include "ixheaacd_audioobjtypes.h"
42 #include "ixheaacd_sbrdecsettings.h"
43 #include "ixheaacd_memory_standards.h"
44
45 #include "ixheaacd_bitbuffer.h"
46 #include "ixheaacd_adts.h"
47 #include "ixheaacd_defines.h"
48 #include <ixheaacd_aac_rom.h>
49
50 #include "ixheaacd_sbr_scale.h"
51 #include "ixheaacd_lpp_tran.h"
52 #include "ixheaacd_env_extr_part.h"
53 #include <ixheaacd_sbr_rom.h>
54
55 #include "ixheaacd_hybrid.h"
56 #include "ixheaacd_ps_dec.h"
57 #include "ixheaacd_ps_bitdec.h"
58
59 #include "ixheaacd_pulsedata.h"
60
61 #include "ixheaacd_pns.h"
62 #include "ixheaacd_drc_data_struct.h"
63
64 #include "ixheaacd_lt_predict.h"
65
66 #include "ixheaacd_channelinfo.h"
67 #include "ixheaacd_drc_dec.h"
68 #include "ixheaacd_sbr_const.h"
69 #include "ixheaacd_sbrdecoder.h"
70 #include "ixheaacd_env_extr.h"
71 #include "ixheaacd_common_rom.h"
72 #include "ixheaacd_freq_sca.h"
73 #include "ixheaacd_qmf_dec.h"
74 #include "ixheaacd_env_calc.h"
75
76 #include "ixheaacd_pvc_dec.h"
77 #include "ixheaacd_sbr_dec.h"
78 #include "ixheaacd_block.h"
79 #include "ixheaacd_channel.h"
80
81 #include "ixheaacd_audioobjtypes.h"
82 #include "ixheaacd_latmdemux.h"
83
84 #include "ixheaacd_aacdec.h"
85 #include "ixheaacd_mps_polyphase.h"
86 #include "ixheaacd_config.h"
87 #include "ixheaacd_mps_dec.h"
88 #include "ixheaacd_struct_def.h"
89 #include "ixheaacd_headerdecode.h"
90 #include "ixheaacd_adts_crc_check.h"
91
92 #include "ixheaacd_multichannel.h"
93 #include "ixheaacd_ver_number.h"
94
95 #include "ixheaacd_interface.h"
96 #include "ixheaacd_info.h"
97
98 #include "ixheaacd_config.h"
99
100 #include "ixheaacd_struct.h"
101 #include "ixheaacd_cnst.h"
102 #include "ixheaacd_mps_polyphase.h"
103 #include "ixheaacd_tns_usac.h"
104 #include "ixheaacd_acelp_info.h"
105
106 #include "ixheaacd_main.h"
107 #include "ixheaacd_arith_dec.h"
108 #include "ixheaacd_create.h"
109 #include "ixheaacd_function_selector.h"
110
111 #define MAX_TRACKS_PER_LAYER 50
112
113 #define ALIGN_SIZE64(x) ((((x) + 7) >> 3) << 3)
114
115 #define IA_ENHAACPDEC_NUM_MEMTABS (4)
116
117 #define NUM_AAC_TABLES 8
118
119 #define IXHEAACD_CCE_DEC_INFO_MEM_SIZE (610)
120 #define IXHEAACD_CCE_DEC_INFO_MEM_SIZE_8 (IXHEAACD_CCE_DEC_INFO_MEM_SIZE + 8)
121
ixheaacd_dec_mem_api(ia_exhaacplus_dec_api_struct * p_obj_exhaacplus_dec,WORD32 i_cmd,WORD32 i_idx,VOID * pv_value)122 IA_ERRORCODE ixheaacd_dec_mem_api(
123 ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec, WORD32 i_cmd,
124 WORD32 i_idx, VOID *pv_value) {
125 pUWORD32 pui_value = pv_value;
126
127 if (i_idx < 0 || i_idx >= IA_ENHAACPDEC_NUM_MEMTABS) {
128 return IA_ENHAACPLUS_DEC_API_FATAL_INVALID_MEMTAB_INDEX;
129 }
130
131 if (i_cmd == IA_API_CMD_SET_MEM_PTR) {
132 if (pv_value == 0) {
133 return (IA_ENHAACPLUS_DEC_API_FATAL_MEM_ALLOC);
134 }
135 if (((SIZE_T)pv_value %
136 p_obj_exhaacplus_dec->p_mem_info_aac[i_idx].ui_alignment) != 0) {
137 return (IA_ENHAACPLUS_DEC_API_FATAL_MEM_ALIGN);
138 }
139 p_obj_exhaacplus_dec->pp_mem_aac[i_idx] = pv_value;
140 memset(p_obj_exhaacplus_dec->pp_mem_aac[i_idx], 0,
141 p_obj_exhaacplus_dec->p_mem_info_aac[i_idx].ui_size);
142
143 if (i_idx == IA_ENHAACPLUS_DEC_PERSIST_IDX) {
144 pUWORD8 p_temp = pv_value;
145 UWORD32 *meminfo =
146 (UWORD32 *)p_obj_exhaacplus_dec->p_mem_info_aac + i_idx;
147 UWORD32 pers_size = meminfo[0];
148 p_temp = p_temp + pers_size -
149 (sizeof(ia_dec_data_struct) +
150 sizeof(ia_audio_specific_config_struct) + (8300));
151 p_obj_exhaacplus_dec->p_state_aac = pv_value;
152
153 p_obj_exhaacplus_dec->p_state_aac->pstr_dec_data = p_temp;
154 p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config =
155 p_temp + sizeof(ia_dec_data_struct);
156 p_obj_exhaacplus_dec->p_state_aac->header_ptr =
157 p_temp + sizeof(ia_dec_data_struct) +
158 sizeof(ia_audio_specific_config_struct);
159 }
160
161 } else {
162 UWORD32 *meminfo =
163 (UWORD32 *)(p_obj_exhaacplus_dec->p_mem_info_aac + i_idx);
164 *pui_value = *(meminfo + (i_cmd - IA_API_CMD_GET_MEM_INFO_SIZE));
165 }
166
167 return IA_NO_ERROR;
168 }
169
170 static PLATFORM_INLINE VOID
ixheaacd_init_sbr_tables(ia_sbr_tables_struct * ptr_sbr_tables)171 ixheaacd_init_sbr_tables(ia_sbr_tables_struct *ptr_sbr_tables) {
172 ptr_sbr_tables->env_calc_tables_ptr =
173 (ia_env_calc_tables_struct *)&ixheaacd_aac_dec_env_calc_tables;
174 ptr_sbr_tables->qmf_dec_tables_ptr =
175 (ia_qmf_dec_tables_struct *)&ixheaacd_aac_qmf_dec_tables;
176 ptr_sbr_tables->env_extr_tables_ptr =
177 (ia_env_extr_tables_struct *)&ixheaacd_aac_dec_env_extr_tables;
178 ptr_sbr_tables->ps_tables_ptr =
179 (ia_ps_tables_struct *)&ixheaacd_aac_dec_ps_tables;
180 }
181
ixheaacd_updatebytesconsumed(ia_aac_dec_state_struct * p_state_enhaacplus_dec,struct ia_bit_buf_struct * it_bit_buff)182 VOID ixheaacd_updatebytesconsumed(
183 ia_aac_dec_state_struct *p_state_enhaacplus_dec,
184 struct ia_bit_buf_struct *it_bit_buff) {
185 p_state_enhaacplus_dec->i_bytes_consumed =
186 (it_bit_buff->ptr_read_next - it_bit_buff->ptr_bit_buf_base);
187 if ((p_state_enhaacplus_dec->i_bytes_consumed == 0) &&
188 (it_bit_buff->cnt_bits == 0)) {
189 p_state_enhaacplus_dec->i_bytes_consumed =
190 p_state_enhaacplus_dec->ui_in_bytes;
191 }
192 if (it_bit_buff->cnt_bits < 0) {
193 p_state_enhaacplus_dec->i_bytes_consumed = 0;
194 p_state_enhaacplus_dec->ui_out_bytes = 0;
195 p_state_enhaacplus_dec->b_n_raw_data_blk = 0;
196 }
197 }
198
ixheaacd_readifadts(ia_aac_dec_state_struct * p_state_enhaacplus_dec,struct ia_bit_buf_struct * it_bit_buff,ia_adts_header_struct * adts)199 WORD32 ixheaacd_readifadts(ia_aac_dec_state_struct *p_state_enhaacplus_dec,
200 struct ia_bit_buf_struct *it_bit_buff,
201 ia_adts_header_struct *adts) {
202 WORD error;
203
204 if ((error = ixheaacd_find_syncword(adts, it_bit_buff)) != 0) {
205 ixheaacd_updatebytesconsumed(p_state_enhaacplus_dec, it_bit_buff);
206 return IA_ENHAACPLUS_DEC_EXE_NONFATAL_ADTS_SYNC_LOST;
207 }
208 if ((error = ixheaacd_check_if_adts(
209 adts, it_bit_buff,
210 p_state_enhaacplus_dec->p_config->ui_max_channels)) != 0) {
211 p_state_enhaacplus_dec->i_bytes_consumed = 1;
212
213 if (it_bit_buff->cnt_bits < 0) {
214 p_state_enhaacplus_dec->i_bytes_consumed = 0;
215 p_state_enhaacplus_dec->ui_out_bytes = 0;
216 error = IA_ENHAACPLUS_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES;
217 return error;
218 }
219 return IA_ENHAACPLUS_DEC_EXE_NONFATAL_ADTS_SYNC_LOST;
220 }
221 p_state_enhaacplus_dec->b_n_raw_data_blk =
222 (WORD8)(adts->no_raw_data_blocks + 1);
223 return 0;
224 }
225
ixheaacd_allocate_aac_scr(ia_aac_dec_scratch_struct * aac_scratch_struct,VOID * base_scratch_ptr,VOID * output_ptr,WORD channel,WORD max_channel,WORD32 audio_object_type)226 static VOID ixheaacd_allocate_aac_scr(
227 ia_aac_dec_scratch_struct *aac_scratch_struct, VOID *base_scratch_ptr,
228 VOID *output_ptr, WORD channel, WORD max_channel,
229 WORD32 audio_object_type) {
230 aac_scratch_struct->base_scr_8k = base_scratch_ptr;
231 aac_scratch_struct->extra_scr_4k[1] = (WORD8 *)base_scratch_ptr;
232 if (channel == 1) {
233 aac_scratch_struct->extra_scr_4k[0] =
234 (WORD8 *)base_scratch_ptr + (IXHEAACD_CCE_DEC_INFO_MEM_SIZE_8 * 1024) +
235 (4 * 1024);
236 } else {
237 aac_scratch_struct->extra_scr_4k[0] = output_ptr;
238
239 if (max_channel > 2) {
240 aac_scratch_struct->extra_scr_4k[0] =
241 (WORD8 *)base_scratch_ptr +
242 (IXHEAACD_CCE_DEC_INFO_MEM_SIZE_8 * 1024) + (8 * 1024);
243 }
244 }
245
246 aac_scratch_struct->extra_scr_4k[2] =
247 (WORD8 *)base_scratch_ptr + (IXHEAACD_CCE_DEC_INFO_MEM_SIZE_8 * 1024) +
248 (46 * 1024);
249
250 if (audio_object_type == AOT_ER_AAC_ELD ||
251 audio_object_type == AOT_ER_AAC_LD) {
252 aac_scratch_struct->extra_scr_4k[0] =
253 (WORD8 *)base_scratch_ptr + (IXHEAACD_CCE_DEC_INFO_MEM_SIZE_8 * 1024) +
254 (4 * 1024);
255
256 aac_scratch_struct->extra_scr_4k[2] =
257 (WORD8 *)base_scratch_ptr + (IXHEAACD_CCE_DEC_INFO_MEM_SIZE_8 * 1024) +
258 (46 * 1024);
259
260 aac_scratch_struct->extra_scr_4k[3] =
261 (WORD8 *)base_scratch_ptr + (IXHEAACD_CCE_DEC_INFO_MEM_SIZE_8 * 1024) +
262 (54 * 1024);
263 }
264 if ((audio_object_type == AOT_ER_AAC_LD) ||
265 (audio_object_type == AOT_AAC_LTP)) {
266 aac_scratch_struct->in_data =
267 (WORD32 *)((WORD8 *)base_scratch_ptr +
268 (IXHEAACD_CCE_DEC_INFO_MEM_SIZE_8 * 1024) + (62 * 1024) +
269 (4 * 16));
270 aac_scratch_struct->out_data =
271 (WORD32 *)((WORD8 *)base_scratch_ptr +
272 (IXHEAACD_CCE_DEC_INFO_MEM_SIZE_8 * 1024) + (56 * 1024) +
273 (4 * 16));
274 }
275 }
276
ixheaacd_allocate_sbr_scr(ia_sbr_scr_struct * sbr_scratch_struct,VOID * base_scratch_ptr,VOID * output_ptr,WORD total_elements,WORD ch_fac,WORD32 audio_object_type)277 VOID ixheaacd_allocate_sbr_scr(ia_sbr_scr_struct *sbr_scratch_struct,
278 VOID *base_scratch_ptr, VOID *output_ptr,
279 WORD total_elements, WORD ch_fac,
280 WORD32 audio_object_type) {
281 WORD32 temp = 0;
282 sbr_scratch_struct->ptr_work_buf_core = base_scratch_ptr;
283 sbr_scratch_struct->ptr_work_buf = (WORD8 *)base_scratch_ptr + (18 * 1024);
284
285 if (total_elements > 1) {
286 sbr_scratch_struct->extra_scr_1k[0] =
287 (WORD8 *)base_scratch_ptr + (18 * 1024);
288
289 sbr_scratch_struct->extra_scr_1k[1] =
290 (WORD8 *)base_scratch_ptr + (19 * 1024);
291 }
292
293 else {
294 if (ch_fac == 1) {
295 temp = 2;
296 } else {
297 temp = 4;
298 }
299
300 if (audio_object_type != AOT_ER_AAC_ELD) {
301 sbr_scratch_struct->extra_scr_1k[0] = (WORD8 *)output_ptr + (temp * 1024);
302
303 sbr_scratch_struct->extra_scr_1k[1] =
304 (WORD8 *)base_scratch_ptr + (18 * 1024);
305 } else {
306 sbr_scratch_struct->extra_scr_1k[0] =
307 (WORD8 *)base_scratch_ptr + (18 * 1024);
308
309 sbr_scratch_struct->extra_scr_1k[1] =
310 (WORD8 *)base_scratch_ptr + (19 * 1024);
311 }
312 }
313 }
314
ixheaacd_dec_api(pVOID p_ia_enhaacplus_dec_obj,WORD32 i_cmd,WORD32 i_idx,pVOID pv_value)315 IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_enhaacplus_dec_obj, WORD32 i_cmd,
316 WORD32 i_idx, pVOID pv_value) {
317 ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec = p_ia_enhaacplus_dec_obj;
318 pUWORD32 pui_value = pv_value;
319 pWORD32 pui_value_signed = pv_value;
320 pWORD8 pb_value = pv_value;
321 pVOID *pp_value = (pVOID *)pv_value;
322
323 if ((i_cmd != IA_API_CMD_GET_API_SIZE) &&
324 (i_cmd != IA_API_CMD_GET_LIB_ID_STRINGS)) {
325 if (p_ia_enhaacplus_dec_obj == 0) {
326 return (IA_ENHAACPLUS_DEC_API_FATAL_MEM_ALLOC);
327 }
328 if (((SIZE_T)p_ia_enhaacplus_dec_obj & 3) != 0) {
329 return (IA_ENHAACPLUS_DEC_API_FATAL_MEM_ALIGN);
330 }
331 }
332
333 switch (i_cmd) {
334 case IA_API_CMD_GET_MEM_INFO_SIZE:
335 case IA_API_CMD_GET_MEM_INFO_ALIGNMENT:
336 case IA_API_CMD_GET_MEM_INFO_TYPE:
337 case IA_API_CMD_SET_MEM_PTR: {
338 return ixheaacd_dec_mem_api(p_ia_enhaacplus_dec_obj, i_cmd, i_idx,
339 pv_value);
340 }
341
342 case IA_API_CMD_GET_TABLE_INFO_SIZE:
343 case IA_API_CMD_GET_TABLE_INFO_ALIGNMENT:
344 case IA_API_CMD_SET_TABLE_PTR:
345 case IA_API_CMD_GET_TABLE_PTR: {
346 return ixheaacd_dec_table_api(p_ia_enhaacplus_dec_obj, i_cmd, i_idx,
347 pv_value);
348 }
349 };
350
351 switch (i_cmd) {
352 case IA_API_CMD_GET_LIB_ID_STRINGS: {
353 WORD8 *i1_ver;
354 WORD8 ver_char;
355
356 if (i_idx == IA_CMD_TYPE_LIB_NAME)
357 i1_ver = (WORD8 *)LIBNAME;
358 else if (i_idx == IA_CMD_TYPE_LIB_VERSION)
359 i1_ver = (WORD8 *)xHE_AAC_DEC_ITTIAM_VER;
360 else
361 return IA_ENHAACPLUS_DEC_API_FATAL_INVALID_LIB_ID_STRINGS_IDX;
362
363 ver_char = *i1_ver++;
364
365 for (; ver_char != '\0';) {
366 if (ver_char != '$') {
367 *pb_value++ = ver_char;
368 }
369 ver_char = *i1_ver++;
370 }
371 *pb_value = ver_char;
372
373 break;
374 }
375 case IA_API_CMD_GET_API_SIZE: {
376 *pui_value = sizeof(ia_exhaacplus_dec_api_struct);
377 break;
378 }
379 case IA_API_CMD_INIT: {
380 switch (i_idx) {
381 case IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS: {
382 memset(p_obj_exhaacplus_dec, 0, sizeof(*p_obj_exhaacplus_dec));
383 p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz = 16;
384 p_obj_exhaacplus_dec->aac_config.flag_downmix = 0;
385 p_obj_exhaacplus_dec->aac_config.flag_08khz_out = 0;
386 p_obj_exhaacplus_dec->aac_config.flag_16khz_out = 0;
387 p_obj_exhaacplus_dec->aac_config.flag_to_stereo = 0;
388 p_obj_exhaacplus_dec->aac_config.down_sample_flag = 0;
389 p_obj_exhaacplus_dec->aac_config.header_dec_done = 0;
390 p_obj_exhaacplus_dec->aac_config.frame_status = 1;
391 p_obj_exhaacplus_dec->aac_config.ui_mp4_flag = 0;
392 p_obj_exhaacplus_dec->aac_config.ui_disable_sync = 0;
393 p_obj_exhaacplus_dec->aac_config.ui_auto_sbr_upsample = 1;
394 p_obj_exhaacplus_dec->aac_config.ui_samp_freq = 0;
395 p_obj_exhaacplus_dec->aac_config.ui_channel_mode = 3;
396 p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 0;
397 p_obj_exhaacplus_dec->aac_config.ui_effect_type = 0;
398 p_obj_exhaacplus_dec->aac_config.ui_target_loudness = -24;
399 p_obj_exhaacplus_dec->aac_config.ui_loud_norm_flag = 0;
400 p_obj_exhaacplus_dec->aac_config.ui_pce_found_in_hdr = 0;
401 p_obj_exhaacplus_dec->aac_config.loas_present = 0;
402 p_obj_exhaacplus_dec->aac_config.ld_decoder = 0;
403 p_obj_exhaacplus_dec->aac_config.ui_drc_enable = 1;
404 p_obj_exhaacplus_dec->aac_config.ui_drc_boost = 0;
405 p_obj_exhaacplus_dec->aac_config.ui_drc_cut = 0;
406 p_obj_exhaacplus_dec->aac_config.ui_drc_target_level = 108;
407 p_obj_exhaacplus_dec->aac_config.ui_drc_set = 0;
408 p_obj_exhaacplus_dec->aac_config.ui_flush_cmd = 0;
409
410 p_obj_exhaacplus_dec->aac_config.ui_max_channels = 6;
411
412 p_obj_exhaacplus_dec->aac_config.ui_coupling_channel = 0;
413 p_obj_exhaacplus_dec->aac_config.downmix = 0;
414 p_obj_exhaacplus_dec->aac_config.ui_n_channels = 2;
415 p_obj_exhaacplus_dec->aac_config.i_channel_mask = 3;
416
417 {
418 ia_aac_dec_tables_struct *pstr_aac_tables =
419 &p_obj_exhaacplus_dec->aac_tables;
420 pstr_aac_tables->pstr_huffmann_tables =
421 (ia_aac_dec_huffman_tables_struct
422 *)&ixheaacd_aac_huffmann_tables;
423 pstr_aac_tables->pstr_block_tables =
424 (ia_aac_dec_block_tables_struct *)&ixheaacd_aac_block_tables;
425 pstr_aac_tables->pstr_imdct_tables =
426 (ia_aac_dec_imdct_tables_struct *)&ixheaacd_imdct_tables;
427
428 ixheaacd_huff_tables_create(pstr_aac_tables);
429 }
430 ixheaacd_init_sbr_tables(&p_obj_exhaacplus_dec->str_sbr_tables);
431 p_obj_exhaacplus_dec->common_tables =
432 (ixheaacd_misc_tables *)&ixheaacd_str_fft_n_transcendent_tables;
433 p_obj_exhaacplus_dec->aac_config.ui_qmf_bands = 64;
434
435 break;
436 }
437 case IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS: {
438 ixheaacd_fill_aac_mem_tables(p_obj_exhaacplus_dec);
439 break;
440 }
441 case IA_CMD_TYPE_INIT_PROCESS: {
442 WORD32 err_code = 0;
443 err_code = ixheaacd_dec_init(p_obj_exhaacplus_dec);
444 if (err_code != 0) {
445 p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed =
446 p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes;
447 }
448 return err_code;
449 break;
450 }
451 case IA_CMD_TYPE_INIT_DONE_QUERY: {
452 if (p_obj_exhaacplus_dec->p_state_aac->ui_init_done == 1) {
453 *pui_value = 1;
454 } else {
455 *pui_value = 0;
456 }
457 break;
458 }
459
460 case IA_CMD_TYPE_GA_HDR: {
461 return ixheaacd_decoder_2_ga_hdr(p_obj_exhaacplus_dec);
462 break;
463 }
464
465 case IA_CMD_TYPE_FLUSH_MEM: {
466 return ixheaacd_decoder_flush_api(p_obj_exhaacplus_dec);
467 break;
468 }
469
470 default: {
471 return IA_ENHAACPLUS_DEC_API_NONFATAL_CMD_TYPE_NOT_SUPPORTED;
472 }
473 };
474 break;
475 }
476 case IA_API_CMD_SET_CONFIG_PARAM: {
477 switch (i_idx) {
478 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ: {
479 if ((*pui_value < 8000) || (*pui_value > 96000)) {
480 return (IA_ENHAACPLUS_DEC_CONFIG_FATAL_INVALID_SAMPLE_RATE);
481 }
482 p_obj_exhaacplus_dec->aac_config.ui_samp_freq = *pui_value;
483 break;
484 }
485 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ: {
486 if ((*pui_value != 16) && (*pui_value != 24)) {
487 p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz = 16;
488 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_PCM_WDSZ);
489 }
490 p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz = *pui_value;
491 break;
492 }
493 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_DOWNMIX: {
494 if ((*pui_value != 1) && (*pui_value != 0)) {
495 p_obj_exhaacplus_dec->aac_config.flag_downmix = 0;
496 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_DOWNMIX);
497 }
498 p_obj_exhaacplus_dec->aac_config.flag_downmix = *pui_value;
499 p_obj_exhaacplus_dec->aac_config.downmix = *pui_value;
500 break;
501 }
502
503 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_TOSTEREO: {
504 if ((*pui_value != 1) && (*pui_value != 0)) {
505 p_obj_exhaacplus_dec->aac_config.flag_to_stereo = 1;
506 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_TOSTEREO);
507 }
508 p_obj_exhaacplus_dec->aac_config.flag_to_stereo = *pui_value;
509 break;
510 }
511 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_DSAMPLE: {
512 if ((*pui_value != 1) && (*pui_value != 0)) {
513 p_obj_exhaacplus_dec->aac_config.down_sample_flag = 0;
514 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_DSAMPLE);
515 }
516 p_obj_exhaacplus_dec->aac_config.down_sample_flag = *pui_value;
517 break;
518 }
519
520 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_FRAMEOK: {
521 if ((*pui_value != 1) && (*pui_value != 0)) {
522 p_obj_exhaacplus_dec->aac_config.frame_status = 1;
523 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_FRAMEOK);
524 }
525 p_obj_exhaacplus_dec->aac_config.frame_status = *pui_value;
526 break;
527 }
528
529 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4: {
530 if ((*pui_value != 1) && (*pui_value != 0)) {
531 p_obj_exhaacplus_dec->aac_config.ui_mp4_flag = 0;
532 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_MP4FLAG);
533 }
534 p_obj_exhaacplus_dec->aac_config.ui_mp4_flag = *pui_value;
535 break;
536 }
537 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISLOAS: {
538 if ((*pui_value != 1) && (*pui_value != 0)) {
539 p_obj_exhaacplus_dec->aac_config.loas_present = 0;
540 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_LOASFLAG);
541 }
542 p_obj_exhaacplus_dec->aac_config.loas_present = *pui_value;
543 break;
544 }
545 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE: {
546 if ((*pui_value != 1) && (*pui_value != 0)) {
547 p_obj_exhaacplus_dec->aac_config.ui_drc_enable = 0;
548 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_DRCFLAG);
549 }
550 p_obj_exhaacplus_dec->aac_config.ui_drc_enable = *pui_value;
551 break;
552 }
553 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT: {
554 p_obj_exhaacplus_dec->aac_config.ui_drc_set = 1;
555 if (*pui_value > 127) {
556 p_obj_exhaacplus_dec->aac_config.ui_drc_cut = 0;
557 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_DRC_CUT);
558 }
559 p_obj_exhaacplus_dec->aac_config.ui_drc_cut =
560 (WORD32)((*pui_value / 127.0) * 100);
561 break;
562 }
563
564 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST: {
565 p_obj_exhaacplus_dec->aac_config.ui_drc_set = 1;
566 if (*pui_value > 127) {
567 p_obj_exhaacplus_dec->aac_config.ui_drc_boost = 0;
568 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_DRC_BOOST);
569 }
570 p_obj_exhaacplus_dec->aac_config.ui_drc_boost =
571 (WORD32)((*pui_value / 127.0) * 100);
572 break;
573 }
574
575 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL: {
576 p_obj_exhaacplus_dec->aac_config.ui_drc_set = 1;
577 if (*pui_value > 127) {
578 p_obj_exhaacplus_dec->aac_config.ui_drc_target_level = 108;
579 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_DRC_TARGET);
580 }
581 p_obj_exhaacplus_dec->aac_config.ui_drc_target_level = *pui_value;
582 break;
583 }
584 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP: {
585 p_obj_exhaacplus_dec->aac_config.ui_drc_set = 1;
586 if ((*pui_value != 1) && (*pui_value != 0)) {
587 p_obj_exhaacplus_dec->aac_config.ui_drc_heavy_comp = 0;
588 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_DRCFLAG);
589 }
590 p_obj_exhaacplus_dec->aac_config.ui_drc_heavy_comp = *pui_value;
591 break;
592 }
593 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_DISABLE_SYNC: {
594 if ((*pui_value != 1) && (*pui_value != 0)) {
595 p_obj_exhaacplus_dec->aac_config.ui_disable_sync = 0;
596 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_SYNCFLAG);
597 }
598 p_obj_exhaacplus_dec->aac_config.ui_disable_sync = *pui_value;
599 break;
600 }
601 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_AUTO_SBR_UPSAMPLE: {
602 if ((*pui_value != 1) && (*pui_value != 0)) {
603 p_obj_exhaacplus_dec->aac_config.ui_auto_sbr_upsample = 0;
604 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_SBRUPFLAG);
605 }
606 p_obj_exhaacplus_dec->aac_config.ui_auto_sbr_upsample = *pui_value;
607 break;
608 }
609 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_MAX_CHANNEL: {
610 if (*pui_value > 8) {
611 p_obj_exhaacplus_dec->aac_config.ui_max_channels = 8;
612 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_MAX_CHANNEL);
613 }
614 if (*pui_value < 2) {
615 p_obj_exhaacplus_dec->aac_config.ui_max_channels = 2;
616 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_MAX_CHANNEL);
617 }
618 p_obj_exhaacplus_dec->aac_config.ui_max_channels = *pui_value;
619 break;
620 }
621 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_FRAMESIZE: {
622 if (*pui_value == 1) {
623 p_obj_exhaacplus_dec->aac_config.framesize_480 = 1;
624 } else if (*pui_value == 0) {
625 p_obj_exhaacplus_dec->aac_config.framesize_480 = 0;
626 } else {
627 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_FRAMSZ);
628 }
629 break;
630 }
631
632 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_LD_TESTING: {
633 if (*pui_value == 1) {
634 p_obj_exhaacplus_dec->aac_config.ld_decoder = 1;
635 } else if (*pui_value == 0) {
636 p_obj_exhaacplus_dec->aac_config.ld_decoder = 0;
637 } else {
638 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_LD_CONFIG);
639 }
640 break;
641 }
642
643 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_ELD_SBR_PRESENT: {
644 if (*pui_value == 1) {
645 p_obj_exhaacplus_dec->aac_config.eld_sbr_present = 1;
646 } else if (*pui_value == 0) {
647 p_obj_exhaacplus_dec->aac_config.eld_sbr_present = 0;
648 } else {
649 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_ELDSBR);
650 }
651 break;
652 }
653 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_COUP_CHANNEL: {
654 if (*pui_value > 16) {
655 p_obj_exhaacplus_dec->aac_config.ui_coupling_channel = 1;
656 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_COUP_CHANNEL);
657 }
658 p_obj_exhaacplus_dec->aac_config.ui_coupling_channel = *pui_value;
659 break;
660 }
661
662 case IA_ENHAACPLUS_DEC_CONFIG_PARAM_DOWNMIX_STEREO: {
663 if ((*pui_value != 1) && (*pui_value != 0)) {
664 p_obj_exhaacplus_dec->aac_config.downmix = 0;
665 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_DOWNMIX);
666 }
667 p_obj_exhaacplus_dec->aac_config.downmix = *pui_value;
668 break;
669 }
670
671 case IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE: {
672 if (((*pui_value_signed) > 8) || ((*pui_value_signed) < -1)) {
673 p_obj_exhaacplus_dec->aac_config.ui_effect_type = -1;
674 return (IA_ENHAACPLUS_DEC_CONFIG_NON_FATAL_INVALID_EFFECT_TYPE);
675 }
676 p_obj_exhaacplus_dec->aac_config.ui_effect_type = *pui_value_signed;
677 break;
678 }
679 case IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS: {
680 if (*pui_value_signed >= 0) {
681 p_obj_exhaacplus_dec->aac_config.ui_loud_norm_flag = 1;
682 }
683 *pui_value_signed = -(*pui_value_signed >> 2);
684 if (((*pui_value_signed) > 0) || ((*pui_value_signed) < -63)) {
685 p_obj_exhaacplus_dec->aac_config.ui_target_loudness = 0;
686 return (IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_TARGET_LOUDNESS);
687 }
688 p_obj_exhaacplus_dec->aac_config.ui_target_loudness =
689 *pui_value_signed;
690 break;
691 }
692 default: { return IA_ENHAACPLUS_DEC_API_FATAL_INVALID_CONFIG_PARAM; }
693 }
694 break;
695 }
696
697 case IA_API_CMD_GET_CONFIG_PARAM: {
698 UWORD32 i;
699 WORD32 *pvalue =
700 (WORD32 *)(&p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz);
701
702 if (i_idx >= 0 && i_idx <= 8) {
703 *pui_value = pvalue[i_idx];
704 } else if (IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR == i_idx) {
705 ia_audio_specific_config_struct *ptr_audio_specific_config =
706 ((ia_audio_specific_config_struct *)
707 p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config);
708
709 for (i = 0; i < ptr_audio_specific_config->str_usac_config
710 .str_usac_dec_config.num_config_extensions;
711 i++) {
712 pp_value[i] = ptr_audio_specific_config->str_usac_config
713 .str_usac_dec_config.usac_cfg_ext_info_buf[i];
714 }
715
716 for (i = 0; i < ptr_audio_specific_config->str_usac_config
717 .str_usac_dec_config.num_elements;
718 i++) {
719 if (ptr_audio_specific_config->str_usac_config.str_usac_dec_config
720 .usac_ext_ele_payload_present[i]) {
721 pp_value[i + 16] =
722 ptr_audio_specific_config->str_usac_config.str_usac_dec_config
723 .usac_ext_ele_payload_buf[i];
724 }
725 }
726 } else if (IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES == i_idx) {
727 WORD32 *ptri_value = (WORD32 *)pv_value;
728 ia_audio_specific_config_struct *ptr_audio_specific_config =
729 ((ia_audio_specific_config_struct *)
730 p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config);
731 for (i = 0; i < ptr_audio_specific_config->str_usac_config
732 .str_usac_dec_config.num_config_extensions;
733 i++) {
734 ptri_value[i] = ptr_audio_specific_config->str_usac_config
735 .str_usac_dec_config.usac_cfg_ext_info_len[i];
736 }
737 for (i = 0; i < ptr_audio_specific_config->str_usac_config
738 .str_usac_dec_config.num_elements;
739 i++) {
740 ptri_value[i + 16] =
741 ptr_audio_specific_config->str_usac_config.str_usac_dec_config
742 .usac_ext_ele_payload_len[i];
743 }
744
745 } else if (IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE == i_idx) {
746 UWORD32 *ptri_value = (UWORD32 *)pv_value;
747 ia_audio_specific_config_struct *ptr_audio_specific_config =
748 ((ia_audio_specific_config_struct *)
749 p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config);
750 *ptri_value = ptr_audio_specific_config->str_usac_config
751 .str_usac_dec_config.num_elements;
752
753 } else if (IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT == i_idx) {
754 UWORD32 *ptri_value = (UWORD32 *)pv_value;
755 ia_audio_specific_config_struct *ptr_audio_specific_config =
756 ((ia_audio_specific_config_struct *)
757 p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config);
758 *ptri_value = ptr_audio_specific_config->str_usac_config
759 .str_usac_dec_config.num_config_extensions;
760 } else if (IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN == i_idx) {
761 UWORD32 *ptri_value = (UWORD32 *)pv_value;
762 ia_audio_specific_config_struct *ptr_audio_specific_config =
763 ((ia_audio_specific_config_struct *)
764 p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config);
765 *ptri_value = ptr_audio_specific_config->str_usac_config
766 .str_usac_dec_config.usac_ext_gain_payload_len;
767 } else if (IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF == i_idx) {
768 ia_audio_specific_config_struct *ptr_audio_specific_config =
769 ((ia_audio_specific_config_struct *)
770 p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config);
771 *pp_value = ptr_audio_specific_config->str_usac_config
772 .str_usac_dec_config.usac_ext_gain_payload_buf;
773 } else {
774 return IA_ENHAACPLUS_DEC_API_FATAL_INVALID_CONFIG_PARAM;
775 }
776 break;
777 }
778
779 case IA_API_CMD_GET_MEMTABS_SIZE: {
780 *pui_value = (sizeof(ia_mem_info_struct) + sizeof(pVOID *)) *
781 (IA_ENHAACPDEC_NUM_MEMTABS);
782 break;
783 }
784 case IA_API_CMD_SET_MEMTABS_PTR: {
785 if (pv_value == NULL) return IA_ENHAACPLUS_DEC_API_FATAL_MEM_ALLOC;
786 memset(pv_value, 0, (sizeof(ia_mem_info_struct) + sizeof(pVOID *)) *
787 (IA_ENHAACPDEC_NUM_MEMTABS));
788
789 p_obj_exhaacplus_dec->p_mem_info_aac = pv_value;
790 p_obj_exhaacplus_dec->pp_mem_aac =
791 (pVOID *)((WORD8 *)pv_value +
792 sizeof(ia_mem_info_struct) * IA_ENHAACPDEC_NUM_MEMTABS);
793
794 break;
795 }
796 case IA_API_CMD_GET_N_MEMTABS: {
797 *pui_value = IA_ENHAACPDEC_NUM_MEMTABS;
798 break;
799 }
800
801 case IA_API_CMD_GET_N_TABLES: {
802 *pui_value = NUM_AAC_TABLES;
803 break;
804 }
805 case IA_API_CMD_EXECUTE: {
806 switch (i_idx) {
807 case IA_CMD_TYPE_DO_EXECUTE: {
808 WORD32 err_code = 0;
809 if (!p_obj_exhaacplus_dec->p_state_aac->ui_init_done) {
810 err_code = IA_FATAL_ERROR;
811 } else {
812 err_code = ixheaacd_dec_execute(p_obj_exhaacplus_dec);
813 }
814 if (err_code != IA_NO_ERROR) {
815 p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed =
816 p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes;
817 }
818 return err_code;
819 break;
820 }
821 case IA_CMD_TYPE_DONE_QUERY: {
822 if (p_obj_exhaacplus_dec->p_state_aac->ui_input_over == 1) {
823 *pui_value = 1;
824 } else {
825 *pui_value = 0;
826 }
827
828 break;
829 }
830 default: { return IA_ENHAACPLUS_DEC_API_FATAL_INVALID_EXECUTE_TYPE; }
831 };
832 break;
833 }
834 case IA_API_CMD_GET_CURIDX_INPUT_BUF: {
835 *pui_value = p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed;
836 break;
837 }
838 case IA_API_CMD_SET_INPUT_BYTES: {
839 p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes = *pui_value;
840 break;
841 }
842 case IA_API_CMD_GET_OUTPUT_BYTES: {
843 *pui_value = p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes;
844 break;
845 }
846 case IA_API_CMD_INPUT_OVER: {
847 p_obj_exhaacplus_dec->p_state_aac->ui_input_over = 1;
848 break;
849 }
850 default: { return IA_ENHAACPLUS_DEC_API_FATAL_INVALID_CMD; }
851 };
852 return IA_NO_ERROR;
853 }
854
ixheaacd_decoder_2_ga_hdr(ia_exhaacplus_dec_api_struct * p_obj_exhaacplus_dec)855 IA_ERRORCODE ixheaacd_decoder_2_ga_hdr(
856 ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec) {
857 if (p_obj_exhaacplus_dec->aac_config.ui_flush_cmd == 0) {
858 p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz = 16;
859 p_obj_exhaacplus_dec->aac_config.flag_downmix = 0;
860 p_obj_exhaacplus_dec->aac_config.flag_08khz_out = 0;
861 p_obj_exhaacplus_dec->aac_config.flag_16khz_out = 0;
862 p_obj_exhaacplus_dec->aac_config.flag_to_stereo = 0;
863 p_obj_exhaacplus_dec->aac_config.down_sample_flag = 0;
864 p_obj_exhaacplus_dec->aac_config.header_dec_done = 0;
865 p_obj_exhaacplus_dec->aac_config.frame_status = 1;
866 p_obj_exhaacplus_dec->aac_config.ui_mp4_flag = 1;
867 p_obj_exhaacplus_dec->aac_config.ui_disable_sync = 0;
868 p_obj_exhaacplus_dec->aac_config.ui_auto_sbr_upsample = 1;
869 p_obj_exhaacplus_dec->aac_config.ui_samp_freq = 0;
870 p_obj_exhaacplus_dec->aac_config.ui_channel_mode = 3;
871 p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 2;
872 p_obj_exhaacplus_dec->aac_config.ui_pce_found_in_hdr = 0;
873 p_obj_exhaacplus_dec->aac_config.loas_present = 0;
874
875 p_obj_exhaacplus_dec->aac_config.ui_drc_enable = 1;
876 p_obj_exhaacplus_dec->aac_config.ui_drc_boost = 0;
877 p_obj_exhaacplus_dec->aac_config.ui_drc_cut = 0;
878 p_obj_exhaacplus_dec->aac_config.ui_drc_target_level = 108;
879 p_obj_exhaacplus_dec->aac_config.ui_drc_set = 0;
880 p_obj_exhaacplus_dec->aac_config.ui_flush_cmd = 1;
881
882 p_obj_exhaacplus_dec->aac_config.ui_max_channels = 6;
883
884 p_obj_exhaacplus_dec->aac_config.ui_coupling_channel = 0;
885 p_obj_exhaacplus_dec->aac_config.downmix = 0;
886
887 {
888 ia_aac_dec_tables_struct *pstr_aac_tables =
889 &p_obj_exhaacplus_dec->aac_tables;
890 pstr_aac_tables->pstr_huffmann_tables =
891 (ia_aac_dec_huffman_tables_struct *)&ixheaacd_aac_huffmann_tables;
892 pstr_aac_tables->pstr_block_tables =
893 (ia_aac_dec_block_tables_struct *)&ixheaacd_aac_block_tables;
894 pstr_aac_tables->pstr_imdct_tables =
895 (ia_aac_dec_imdct_tables_struct *)&ixheaacd_imdct_tables;
896
897 ixheaacd_huff_tables_create(pstr_aac_tables);
898 }
899 ixheaacd_init_sbr_tables(&p_obj_exhaacplus_dec->str_sbr_tables);
900 p_obj_exhaacplus_dec->common_tables =
901 (ixheaacd_misc_tables *)&ixheaacd_str_fft_n_transcendent_tables;
902 p_obj_exhaacplus_dec->aac_config.ui_qmf_bands = 64;
903 p_obj_exhaacplus_dec->p_state_aac->ui_init_done = 0;
904
905 return ixheaacd_dec_init(p_obj_exhaacplus_dec);
906 } else {
907 p_obj_exhaacplus_dec->aac_config.ui_flush_cmd = 0;
908 return ixheaacd_dec_init(p_obj_exhaacplus_dec);
909 }
910 }
911
ixheaacd_decoder_flush_api(ia_exhaacplus_dec_api_struct * p_obj_exhaacplus_dec)912 IA_ERRORCODE ixheaacd_decoder_flush_api(
913 ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec) {
914 UWORD8 *header_temp_ptr;
915 WORD32 header_length;
916 if (p_obj_exhaacplus_dec->aac_config.ui_flush_cmd == 0) {
917 header_temp_ptr = p_obj_exhaacplus_dec->p_state_aac->header_ptr;
918 header_length = p_obj_exhaacplus_dec->p_state_aac->header_length;
919 memset(p_obj_exhaacplus_dec->p_state_aac, 0,
920 sizeof(ia_aac_dec_state_struct));
921 {
922 pUWORD8 p_temp = (pUWORD8)p_obj_exhaacplus_dec->p_state_aac;
923 UWORD32 *meminfo = (UWORD32 *)p_obj_exhaacplus_dec->p_mem_info_aac;
924 UWORD32 pers_size = meminfo[0];
925 p_temp = p_temp + pers_size -
926 (sizeof(ia_dec_data_struct) +
927 sizeof(ia_audio_specific_config_struct) + (8300));
928
929 p_obj_exhaacplus_dec->p_state_aac->pstr_dec_data = p_temp;
930 p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config =
931 p_temp + sizeof(ia_dec_data_struct);
932 p_obj_exhaacplus_dec->p_state_aac->header_ptr =
933 p_temp + sizeof(ia_dec_data_struct) +
934 sizeof(ia_audio_specific_config_struct);
935 }
936 memset(&(p_obj_exhaacplus_dec->aac_config), 0,
937 sizeof(ia_aac_dec_config_struct));
938
939 p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz = 16;
940 p_obj_exhaacplus_dec->aac_config.flag_downmix = 0;
941 p_obj_exhaacplus_dec->aac_config.flag_08khz_out = 0;
942 p_obj_exhaacplus_dec->aac_config.flag_16khz_out = 0;
943 p_obj_exhaacplus_dec->aac_config.flag_to_stereo = 0;
944 p_obj_exhaacplus_dec->aac_config.down_sample_flag = 0;
945 p_obj_exhaacplus_dec->aac_config.header_dec_done = 0;
946 p_obj_exhaacplus_dec->aac_config.frame_status = 1;
947 p_obj_exhaacplus_dec->aac_config.ui_mp4_flag = 1;
948 p_obj_exhaacplus_dec->aac_config.ui_disable_sync = 0;
949 p_obj_exhaacplus_dec->aac_config.ui_auto_sbr_upsample = 1;
950 p_obj_exhaacplus_dec->aac_config.ui_samp_freq = 0;
951 p_obj_exhaacplus_dec->aac_config.ui_channel_mode = 3;
952 p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 2;
953 p_obj_exhaacplus_dec->aac_config.ui_pce_found_in_hdr = 0;
954 p_obj_exhaacplus_dec->aac_config.loas_present = 0;
955
956 p_obj_exhaacplus_dec->aac_config.ui_drc_enable = 1;
957 p_obj_exhaacplus_dec->aac_config.ui_drc_boost = 0;
958 p_obj_exhaacplus_dec->aac_config.ui_drc_cut = 0;
959 p_obj_exhaacplus_dec->aac_config.ui_drc_target_level = 108;
960 p_obj_exhaacplus_dec->aac_config.ui_drc_set = 0;
961 p_obj_exhaacplus_dec->aac_config.ui_flush_cmd = 1;
962
963 p_obj_exhaacplus_dec->aac_config.ui_max_channels = 6;
964
965 p_obj_exhaacplus_dec->aac_config.ui_coupling_channel = 0;
966 p_obj_exhaacplus_dec->aac_config.downmix = 0;
967
968 {
969 ia_aac_dec_tables_struct *pstr_aac_tables =
970 &p_obj_exhaacplus_dec->aac_tables;
971 pstr_aac_tables->pstr_huffmann_tables =
972 (ia_aac_dec_huffman_tables_struct *)&ixheaacd_aac_huffmann_tables;
973 pstr_aac_tables->pstr_block_tables =
974 (ia_aac_dec_block_tables_struct *)&ixheaacd_aac_block_tables;
975 pstr_aac_tables->pstr_imdct_tables =
976 (ia_aac_dec_imdct_tables_struct *)&ixheaacd_imdct_tables;
977
978 ixheaacd_huff_tables_create(pstr_aac_tables);
979 }
980 ixheaacd_init_sbr_tables(&p_obj_exhaacplus_dec->str_sbr_tables);
981 p_obj_exhaacplus_dec->common_tables =
982 (ixheaacd_misc_tables *)&ixheaacd_str_fft_n_transcendent_tables;
983 p_obj_exhaacplus_dec->aac_config.ui_qmf_bands = 64;
984 p_obj_exhaacplus_dec->p_state_aac->header_ptr = header_temp_ptr;
985 p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes = header_length;
986 p_obj_exhaacplus_dec->p_state_aac->header_length = header_length;
987
988 return ixheaacd_dec_init(p_obj_exhaacplus_dec);
989
990 } else {
991 p_obj_exhaacplus_dec->aac_config.ui_flush_cmd = 0;
992 return ixheaacd_dec_init(p_obj_exhaacplus_dec);
993 }
994 }
995
996 static PLATFORM_INLINE WORD32
ixheaacd_persistent_buffer_sizes(WORD32 num_channel)997 ixheaacd_persistent_buffer_sizes(WORD32 num_channel) {
998 WORD32 size_buffers = 0;
999
1000 WORD32 temp;
1001 WORD32 max_channels;
1002
1003 size_buffers += 4 * 512 * num_channel * sizeof(WORD32);
1004
1005 size_buffers += (ltp_buffer_size * num_channel * sizeof(WORD16));
1006
1007 if (num_channel > 2) {
1008 max_channels = MAX_BS_ELEMENT;
1009 } else {
1010 max_channels = 2;
1011 }
1012 size_buffers +=
1013 (max_channels)*2 * ALIGN_SIZE64(sizeof(ia_aac_dec_sbr_bitstream_struct));
1014
1015 size_buffers += ALIGN_SIZE64(MAXSBRBYTES) * num_channel * sizeof(WORD8);
1016
1017 size_buffers += num_channel *
1018 (QMF_FILTER_STATE_ANA_SIZE + 2 * NO_ANALYSIS_CHANNELS) *
1019 sizeof(WORD16);
1020
1021 size_buffers += num_channel *
1022 (QMF_FILTER_STATE_ANA_SIZE + 2 * NO_ANALYSIS_CHANNELS) *
1023 sizeof(WORD32);
1024
1025 size_buffers += num_channel *
1026 (QMF_FILTER_STATE_SYN_SIZE + 2 * NO_SYNTHESIS_CHANNELS) *
1027 sizeof(WORD16);
1028
1029 size_buffers += num_channel *
1030 (QMF_FILTER_STATE_SYN_SIZE + 2 * NO_SYNTHESIS_CHANNELS) *
1031 sizeof(WORD32);
1032
1033 if (num_channel <= 2) {
1034 size_buffers +=
1035 num_channel * 2 * MAX_OV_COLS * NO_SYNTHESIS_CHANNELS * sizeof(WORD32);
1036 } else {
1037 size_buffers +=
1038 num_channel * MAX_OV_COLS * NO_SYNTHESIS_CHANNELS * sizeof(WORD32);
1039 }
1040
1041 size_buffers +=
1042 LPC_ORDER * num_channel * NO_ANALYSIS_CHANNELS * sizeof(WORD32);
1043
1044 if (num_channel <= 2) {
1045 size_buffers +=
1046 LPC_ORDER * num_channel * NO_ANALYSIS_CHANNELS * sizeof(WORD32);
1047 }
1048
1049 size_buffers += num_channel * 3 * MAX_FREQ_COEFFS * sizeof(WORD16);
1050
1051 temp = sizeof(ia_freq_band_data_struct) +
1052 sizeof(ia_sbr_prev_frame_data_struct) + sizeof(ia_sbr_channel_struct) +
1053 sizeof(ia_sbr_header_data_struct);
1054 size_buffers += num_channel * ALIGN_SIZE64(temp);
1055
1056 size_buffers += MAX_BS_ELEMENT * sizeof(ixheaac_drc_bs_data_struct *);
1057
1058 if (num_channel <= 2) {
1059 size_buffers += sizeof(ia_ps_dec_struct);
1060 }
1061
1062 {
1063 WORD32 temp_size = 0;
1064 size_buffers +=
1065 MAXNRSBRCHANNELS * (sizeof(ia_sbr_frame_info_data_struct) +
1066 MAX_FREQ_COEFFS * sizeof(WORD32) * 2 + 8);
1067 temp_size += sizeof(ia_pvc_data_struct);
1068 temp_size += sizeof(ia_esbr_hbe_txposer_struct) * 2;
1069 temp_size += (MAX_HBE_PERSISTENT_SIZE * 2);
1070 temp_size += (MAX_QMF_BUF_LEN * 2 * 2 * sizeof(FLOAT32 *));
1071 temp_size += (MAX_QMF_BUF_LEN * MAX_QMF_BUF_LEN * 2 * 2 * sizeof(FLOAT32));
1072 size_buffers += temp_size * num_channel;
1073 }
1074
1075 return (size_buffers);
1076 }
1077
ixheaacd_fill_aac_mem_tables(ia_exhaacplus_dec_api_struct * p_obj_exhaacplus_dec)1078 IA_ERRORCODE ixheaacd_fill_aac_mem_tables(
1079 ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec) {
1080 ia_mem_info_struct *p_mem_info_aac;
1081
1082 WORD32 num_channels;
1083 WORD32 channels;
1084 WORD32 buffer_size;
1085
1086 if (p_obj_exhaacplus_dec->aac_config.ui_max_channels > 2) {
1087 num_channels = (p_obj_exhaacplus_dec->aac_config.ui_max_channels + 1);
1088 } else
1089
1090 {
1091 num_channels = p_obj_exhaacplus_dec->aac_config.ui_max_channels;
1092 }
1093
1094 channels = num_channels;
1095 buffer_size = ixheaacd_persistent_buffer_sizes(num_channels);
1096
1097 {
1098 p_mem_info_aac =
1099 &p_obj_exhaacplus_dec->p_mem_info_aac[IA_ENHAACPLUS_DEC_PERSIST_IDX];
1100 p_mem_info_aac->ui_size =
1101 sizeof(ia_aac_dec_state_struct) +
1102 channels * sizeof(struct ia_aac_persistent_struct) +
1103
1104 buffer_size + channels * ixheaacd_getsize_sbr_persistent() +
1105 channels * 16;
1106
1107 p_mem_info_aac->ui_size += sizeof(ia_dec_data_struct);
1108 p_mem_info_aac->ui_size += sizeof(ia_audio_specific_config_struct);
1109 p_mem_info_aac->ui_size += 8300;
1110
1111 p_mem_info_aac->ui_alignment = 8;
1112 p_mem_info_aac->ui_type = IA_MEMTYPE_PERSIST;
1113 }
1114
1115 {
1116 p_mem_info_aac =
1117 &p_obj_exhaacplus_dec->p_mem_info_aac[IA_ENHAACPLUS_DEC_SCRATCH_IDX];
1118
1119 {
1120 if (num_channels > 2) {
1121 WORD32 other_scr1;
1122 WORD32 other_scr2 = 0;
1123
1124 p_mem_info_aac->ui_size =
1125 2 * sizeof(WORD32) * IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME;
1126
1127 other_scr2 = 2 * sizeof(WORD32) * IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME;
1128
1129 other_scr1 = (4 * 1024);
1130
1131 if (MAX_CC_CHANNEL_NUM > 0) {
1132 other_scr1 +=
1133 sizeof(WORD16) * IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME * 2;
1134 other_scr1 += (4 * 1024);
1135
1136 other_scr1 += 4 * 12;
1137 }
1138
1139 p_mem_info_aac->ui_size += max(other_scr1, other_scr2);
1140
1141 } else {
1142 p_mem_info_aac->ui_size =
1143 2 * sizeof(WORD32) * IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME;
1144
1145 p_mem_info_aac->ui_size +=
1146 2 * sizeof(WORD32) * IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME;
1147
1148 p_mem_info_aac->ui_size +=
1149 sizeof(WORD32) * IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME;
1150 p_mem_info_aac->ui_size += 4 * 12;
1151
1152 p_mem_info_aac->ui_size +=
1153 ((IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME << 1) * sizeof(WORD32));
1154 p_mem_info_aac->ui_size +=
1155 ((IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME << 1) * sizeof(WORD32));
1156 p_mem_info_aac->ui_size +=
1157 2 * (sizeof(ia_sbr_frame_info_data_struct) + 232);
1158 }
1159 }
1160
1161 p_mem_info_aac->ui_size += 2200000 + 2048;
1162 p_mem_info_aac->ui_alignment = 8;
1163 p_mem_info_aac->ui_type = IA_MEMTYPE_SCRATCH;
1164 }
1165 {
1166 p_mem_info_aac =
1167 &p_obj_exhaacplus_dec->p_mem_info_aac[IA_ENHAACPLUS_DEC_INPUT_IDX];
1168
1169 p_mem_info_aac->ui_size = 8 * 1024 + 11;
1170
1171 p_mem_info_aac->ui_alignment = 8;
1172 p_mem_info_aac->ui_type = IA_MEMTYPE_INPUT;
1173 }
1174 {
1175 p_mem_info_aac =
1176 &p_obj_exhaacplus_dec->p_mem_info_aac[IA_ENHAACPLUS_DEC_OUTPUT_IDX];
1177 p_mem_info_aac->ui_size = num_channels * IA_ENHAACPLUS_DEC_OUT_BUF_SIZE;
1178 p_mem_info_aac->ui_alignment = 8;
1179 p_mem_info_aac->ui_type = IA_MEMTYPE_OUTPUT;
1180 }
1181 return IA_NO_ERROR;
1182 }
1183
ixheaacd_dec_table_api(ia_exhaacplus_dec_api_struct * p_obj_exhaacplus_dec,WORD32 i_cmd,WORD32 i_idx,pVOID pv_value)1184 IA_ERRORCODE ixheaacd_dec_table_api(
1185 ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec, WORD32 i_cmd,
1186 WORD32 i_idx, pVOID pv_value) {
1187 pUWORD32 pui_value = pv_value;
1188 pUWORD32 *p_pui_value = pv_value;
1189 SIZE_T ui_get_vals[5];
1190
1191 pVOID *table_ptrs[8];
1192 UWORD32 table_sizes[8] = {sizeof(ixheaacd_aac_huffmann_tables),
1193 sizeof(ixheaacd_aac_block_tables),
1194 sizeof(ixheaacd_imdct_tables),
1195 sizeof(ixheaacd_str_fft_n_transcendent_tables),
1196 sizeof(ixheaacd_aac_dec_env_calc_tables),
1197 sizeof(ixheaacd_aac_qmf_dec_tables),
1198 sizeof(ixheaacd_aac_dec_env_extr_tables),
1199 sizeof(ixheaacd_aac_dec_ps_tables)};
1200
1201 table_ptrs[0] =
1202 (pVOID *)&(p_obj_exhaacplus_dec->aac_tables.pstr_huffmann_tables);
1203 table_ptrs[1] =
1204 (pVOID *)&(p_obj_exhaacplus_dec->aac_tables.pstr_block_tables);
1205 table_ptrs[2] =
1206 (pVOID *)&(p_obj_exhaacplus_dec->aac_tables.pstr_imdct_tables);
1207 table_ptrs[3] = (pVOID *)&(p_obj_exhaacplus_dec->common_tables);
1208 table_ptrs[4] =
1209 (pVOID *)&p_obj_exhaacplus_dec->str_sbr_tables.env_calc_tables_ptr;
1210 table_ptrs[5] =
1211 (pVOID *)&p_obj_exhaacplus_dec->str_sbr_tables.qmf_dec_tables_ptr;
1212 table_ptrs[6] =
1213 (pVOID *)&p_obj_exhaacplus_dec->str_sbr_tables.env_extr_tables_ptr;
1214 table_ptrs[7] = (pVOID *)&p_obj_exhaacplus_dec->str_sbr_tables.ps_tables_ptr;
1215
1216 if (i_idx < 0 || i_idx >= NUM_AAC_TABLES) {
1217 return IA_ENHAACPLUS_DEC_API_FATAL_INVALID_MEMTAB_INDEX;
1218 }
1219
1220 ui_get_vals[0] = table_sizes[i_idx];
1221 ui_get_vals[1] = 4;
1222 ui_get_vals[4] = (SIZE_T)(*table_ptrs[i_idx]);
1223
1224 if (i_cmd == IA_API_CMD_SET_TABLE_PTR) {
1225 if (pv_value == 0) {
1226 return (IA_ENHAACPLUS_DEC_API_FATAL_MEM_ALLOC);
1227 }
1228 if (((SIZE_T)pv_value) & 3) {
1229 return IA_ENHAACPLUS_DEC_API_FATAL_MEM_ALIGN;
1230 }
1231
1232 *table_ptrs[i_idx] = pv_value;
1233
1234 if (i_idx == 0) {
1235 ixheaacd_huff_tables_create(&p_obj_exhaacplus_dec->aac_tables);
1236 }
1237
1238 }
1239
1240 else if (i_cmd == IA_API_CMD_GET_TABLE_PTR) {
1241 *p_pui_value = (UWORD32 *)((SIZE_T)(
1242 ui_get_vals[i_cmd - IA_API_CMD_GET_TABLE_INFO_SIZE]));
1243 } else {
1244 *pui_value = (WORD32)(ui_get_vals[i_cmd - IA_API_CMD_GET_TABLE_INFO_SIZE]);
1245 }
1246
1247 return IA_NO_ERROR;
1248 }
1249
ixheaacd_dec_init(ia_exhaacplus_dec_api_struct * p_obj_exhaacplus_dec)1250 IA_ERRORCODE ixheaacd_dec_init(
1251 ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec) {
1252 FLAG frame_status = 1;
1253 WORD32 frame_size_1;
1254 WORD32 sample_rate_1;
1255 WORD16 num_channels_1;
1256 WORD32 ps_detected = 0;
1257 UWORD8 *in_buffer;
1258 WORD16 *time_data;
1259 WORD ch_idx;
1260 WORD sbr_present_flag = 0;
1261 ia_aac_dec_state_struct *p_state_enhaacplus_dec;
1262
1263 WORD32 error_code = IA_NO_ERROR;
1264 WORD32 persistent_used = 0;
1265 IA_ERRORCODE err_code = IA_NO_ERROR;
1266 struct ia_aac_persistent_struct *aac_persistent_mem;
1267 struct ia_sbr_pers_struct *sbr_persistent_mem;
1268 WORD32 ret_val;
1269
1270 p_obj_exhaacplus_dec->p_state_aac =
1271 p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_PERSIST_IDX];
1272
1273 if (p_obj_exhaacplus_dec->p_state_aac != NULL) {
1274 ret_val = setjmp(p_obj_exhaacplus_dec->p_state_aac->xaac_jmp_buf);
1275 if (ret_val != 0) {
1276 p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed =
1277 p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes;
1278 p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = 0;
1279 return IA_NO_ERROR;
1280 }
1281 }
1282
1283 time_data = (WORD16 *)(p_obj_exhaacplus_dec
1284 ->pp_mem_aac[IA_ENHAACPLUS_DEC_OUTPUT_IDX]);
1285
1286 if (p_obj_exhaacplus_dec->aac_config.ui_flush_cmd == 0) {
1287 in_buffer = p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_INPUT_IDX];
1288 } else {
1289 in_buffer = p_obj_exhaacplus_dec->p_state_aac->header_ptr;
1290 }
1291
1292 p_state_enhaacplus_dec = p_obj_exhaacplus_dec->p_state_aac;
1293
1294 p_state_enhaacplus_dec->aac_scratch_mem_v =
1295 p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_SCRATCH_IDX];
1296 p_obj_exhaacplus_dec->p_state_aac->huffman_code_book_scl =
1297 p_obj_exhaacplus_dec->aac_tables.pstr_huffmann_tables
1298 ->huffman_code_book_scl;
1299 p_obj_exhaacplus_dec->p_state_aac->huffman_code_book_scl_index =
1300 p_obj_exhaacplus_dec->aac_tables.pstr_huffmann_tables
1301 ->huffman_code_book_scl_index;
1302
1303 p_state_enhaacplus_dec->pstr_aac_tables = &p_obj_exhaacplus_dec->aac_tables;
1304 if (p_obj_exhaacplus_dec->aac_config.header_dec_done == 0) {
1305 WORD32 channels;
1306
1307 p_obj_exhaacplus_dec->p_state_aac->p_config =
1308 &p_obj_exhaacplus_dec->aac_config;
1309
1310 p_obj_exhaacplus_dec->p_state_aac->pstr_stream_sbr =
1311 (pVOID)((SIZE_T)((pWORD8)p_obj_exhaacplus_dec->p_state_aac +
1312 sizeof(ia_aac_dec_state_struct) + sizeof(SIZE_T) - 1) &
1313 (SIZE_T)(~(sizeof(SIZE_T) - 1)));
1314 if (p_obj_exhaacplus_dec->aac_config.ui_max_channels > 2) {
1315 p_state_enhaacplus_dec->aac_persistent_mem_v =
1316 (pVOID)((pWORD8)p_obj_exhaacplus_dec->p_state_aac->pstr_stream_sbr +
1317 (MAX_BS_ELEMENT)*2 *
1318 ALIGN_SIZE64(sizeof(ia_aac_dec_sbr_bitstream_struct)));
1319
1320 memset(p_obj_exhaacplus_dec->p_state_aac->pstr_stream_sbr, 0,
1321 (MAX_BS_ELEMENT)*2 *
1322 ALIGN_SIZE64(sizeof(ia_aac_dec_sbr_bitstream_struct)));
1323 } else {
1324 p_state_enhaacplus_dec->aac_persistent_mem_v = (pVOID)(
1325 (pWORD8)p_obj_exhaacplus_dec->p_state_aac->pstr_stream_sbr +
1326 (2) * 2 * ALIGN_SIZE64(sizeof(ia_aac_dec_sbr_bitstream_struct)));
1327
1328 memset(p_obj_exhaacplus_dec->p_state_aac->pstr_stream_sbr, 0,
1329 (2) * 2 * ALIGN_SIZE64(sizeof(ia_aac_dec_sbr_bitstream_struct)));
1330 }
1331 if (1 == p_obj_exhaacplus_dec->aac_config.ui_max_channels)
1332 channels = 1;
1333 else
1334 channels = 2;
1335
1336 persistent_used = ixheaacd_set_aac_persistent_buffers(
1337 p_state_enhaacplus_dec->aac_persistent_mem_v, channels);
1338
1339 p_state_enhaacplus_dec->sbr_persistent_mem_v =
1340 (pVOID)((SIZE_T)((pWORD8)p_state_enhaacplus_dec->aac_persistent_mem_v +
1341 persistent_used + sizeof(SIZE_T) - 1) &
1342 (SIZE_T)(~(sizeof(SIZE_T) - 1)));
1343
1344 persistent_used = ixheaacd_getsize_sbr_persistent();
1345 ixheaacd_set_sbr_persistent_buffers(
1346 p_state_enhaacplus_dec->sbr_persistent_mem_v, &persistent_used,
1347 channels, 1);
1348
1349 aac_persistent_mem = (struct ia_aac_persistent_struct *)
1350 p_state_enhaacplus_dec->aac_persistent_mem_v;
1351 if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD ||
1352 p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD)
1353 p_state_enhaacplus_dec->frame_len_flag =
1354 p_obj_exhaacplus_dec->aac_config.framesize_480;
1355
1356 p_state_enhaacplus_dec->ptr_overlap_buf =
1357 aac_persistent_mem->overlap_buffer;
1358
1359 p_state_enhaacplus_dec->bit_count = 0;
1360 p_state_enhaacplus_dec->sync_status = 0;
1361 p_state_enhaacplus_dec->bs_format = ADTS_BSFORMAT;
1362 p_state_enhaacplus_dec->latm_initialized = 0;
1363 p_state_enhaacplus_dec->frame_size = 0;
1364 memset(&p_state_enhaacplus_dec->latm_struct_element, 0,
1365 sizeof(ixheaacd_latm_struct));
1366 memset(&p_state_enhaacplus_dec->b_n_raw_data_blk, 0,
1367 sizeof(WORD32) * (9 + MAX_BS_ELEMENT));
1368
1369 p_state_enhaacplus_dec->sbr_present_flag = 0;
1370
1371 for (ch_idx = 0; ch_idx < MAX_BS_ELEMENT; ch_idx++) {
1372 p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = 0;
1373 }
1374
1375 memset(&p_state_enhaacplus_dec->ind_cc_info, 0,
1376 sizeof(ia_enhaacplus_dec_ind_cc));
1377
1378 p_state_enhaacplus_dec->last_frame_ok = 1;
1379 p_obj_exhaacplus_dec->aac_config.header_dec_done = 1;
1380
1381 aac_persistent_mem->str_aac_decoder.pstr_aac_tables =
1382 &p_obj_exhaacplus_dec->aac_tables;
1383 aac_persistent_mem->str_aac_decoder.pstr_common_tables =
1384 p_obj_exhaacplus_dec->common_tables;
1385
1386 p_obj_exhaacplus_dec->p_state_aac->sbr_persistent_mem_u =
1387 p_obj_exhaacplus_dec->p_state_aac->sbr_persistent_mem_v;
1388
1389 p_obj_exhaacplus_dec->p_state_aac->sbr_scratch_mem_u =
1390 p_obj_exhaacplus_dec->p_state_aac->aac_scratch_mem_v;
1391
1392 ixheaacd_set_sbr_persistent_table_pointer(
1393 p_obj_exhaacplus_dec->p_state_aac->sbr_persistent_mem_v,
1394 &p_obj_exhaacplus_dec->str_sbr_tables,
1395 p_obj_exhaacplus_dec->common_tables);
1396 }
1397
1398 if (p_obj_exhaacplus_dec->p_state_aac->ui_input_over == 1) {
1399 return IA_ENHAACPLUS_DEC_INIT_FATAL_EO_INPUT_REACHED;
1400 }
1401
1402 if (p_obj_exhaacplus_dec->p_state_aac->header_dec_done == 0) {
1403 if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD ||
1404 p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD)
1405 p_state_enhaacplus_dec->frame_len_flag =
1406 p_obj_exhaacplus_dec->aac_config.framesize_480;
1407
1408 aac_persistent_mem = (struct ia_aac_persistent_struct *)
1409 p_state_enhaacplus_dec->aac_persistent_mem_v;
1410 sbr_persistent_mem = (struct ia_sbr_pers_struct *)
1411 p_state_enhaacplus_dec->sbr_persistent_mem_v;
1412
1413 if (p_obj_exhaacplus_dec->aac_config.ui_samp_freq == 0) {
1414 WORD32 header_bytes_consumed, return_val;
1415
1416 if (p_state_enhaacplus_dec->ui_in_bytes == 0) {
1417 p_state_enhaacplus_dec->i_bytes_consumed = 0;
1418 return IA_NO_ERROR;
1419 }
1420
1421 memset(&(p_state_enhaacplus_dec->eld_specific_config), 0,
1422 sizeof(ia_eld_specific_config_struct));
1423 return_val = ixheaacd_aac_headerdecode(
1424 p_obj_exhaacplus_dec, (UWORD8 *)in_buffer, &header_bytes_consumed,
1425 aac_persistent_mem->str_aac_decoder.pstr_aac_tables
1426 ->pstr_huffmann_tables);
1427 if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD ||
1428 p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) {
1429 *sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_header[0] =
1430 p_obj_exhaacplus_dec->p_state_aac->str_sbr_config;
1431 *sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_header[1] =
1432 p_obj_exhaacplus_dec->p_state_aac->str_sbr_config;
1433 } else {
1434 memset(&(p_state_enhaacplus_dec->eld_specific_config), 0,
1435 sizeof(ia_eld_specific_config_struct));
1436 }
1437
1438 if (return_val < 0) {
1439 if (return_val ==
1440 (WORD32)IA_ENHAACPLUS_DEC_INIT_FATAL_STREAM_CHAN_GT_MAX) {
1441 p_state_enhaacplus_dec->i_bytes_consumed = header_bytes_consumed;
1442 return return_val;
1443 }
1444 p_state_enhaacplus_dec->i_bytes_consumed = 1;
1445
1446 return return_val;
1447 }
1448
1449 if (return_val ==
1450 IA_ENHAACPLUS_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES) {
1451 p_state_enhaacplus_dec->i_bytes_consumed = header_bytes_consumed;
1452 return return_val;
1453 }
1454
1455 p_state_enhaacplus_dec->i_bytes_consumed = header_bytes_consumed;
1456
1457 if ((return_val == 0) &&
1458 (p_obj_exhaacplus_dec->p_state_aac->audio_object_type == AOT_USAC)) {
1459 {
1460 WORD32 pcm_size = p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz;
1461 WORD8 *inbuffer =
1462 p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_INPUT_IDX];
1463 WORD8 *outbuffer =
1464 p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_OUTPUT_IDX];
1465 WORD32 out_bytes = 0;
1466 WORD32 frames_done = p_obj_exhaacplus_dec->p_state_aac->frame_counter;
1467
1468 if (p_obj_exhaacplus_dec->p_state_aac->ui_input_over == 0) {
1469 error_code = ixheaacd_dec_main(
1470 p_obj_exhaacplus_dec, inbuffer, outbuffer, &out_bytes,
1471 frames_done, pcm_size,
1472 &p_obj_exhaacplus_dec->p_state_aac->num_of_output_ch);
1473 if (error_code) return error_code;
1474 p_obj_exhaacplus_dec->p_state_aac->frame_counter++;
1475 } else {
1476 out_bytes = 0;
1477 }
1478
1479 p_obj_exhaacplus_dec->aac_config.ui_n_channels =
1480 p_obj_exhaacplus_dec->p_state_aac->num_of_output_ch;
1481 }
1482 if (return_val == 0)
1483 p_obj_exhaacplus_dec->p_state_aac->ui_init_done = 1;
1484 return return_val;
1485 }
1486
1487 if (return_val == 0) {
1488 p_obj_exhaacplus_dec->p_state_aac->header_dec_done = 1;
1489 if (p_obj_exhaacplus_dec->aac_config.ui_flush_cmd == 0) {
1490 memcpy(p_state_enhaacplus_dec->header_ptr, in_buffer,
1491 header_bytes_consumed * sizeof(UWORD8));
1492 p_state_enhaacplus_dec->header_length = header_bytes_consumed;
1493 }
1494 }
1495
1496 if (p_obj_exhaacplus_dec->p_state_aac->header_dec_done != 1)
1497 return IA_ENHAACPLUS_DEC_INIT_NONFATAL_HEADER_NOT_AT_START;
1498
1499 if (p_state_enhaacplus_dec->dwnsmp_signal == 1 &&
1500 p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD)
1501 p_obj_exhaacplus_dec->aac_config.down_sample_flag = 1;
1502
1503 if (p_state_enhaacplus_dec->sampling_rate ==
1504 p_state_enhaacplus_dec->extension_samp_rate) {
1505 p_obj_exhaacplus_dec->aac_config.down_sample_flag = 1;
1506 }
1507
1508 } else {
1509 p_obj_exhaacplus_dec->p_state_aac->header_dec_done = 1;
1510 p_state_enhaacplus_dec->i_bytes_consumed = 0;
1511
1512 p_state_enhaacplus_dec->sampling_rate =
1513 p_obj_exhaacplus_dec->aac_config.ui_samp_freq;
1514 }
1515
1516 p_state_enhaacplus_dec->pstr_bit_buf = ixheaacd_create_bit_buf(
1517 &p_state_enhaacplus_dec->str_bit_buf, (UWORD8 *)in_buffer,
1518 p_obj_exhaacplus_dec->p_mem_info_aac[IA_ENHAACPLUS_DEC_INPUT_IDX]
1519 .ui_size);
1520 p_state_enhaacplus_dec->pstr_bit_buf->xaac_jmp_buf =
1521 &(p_state_enhaacplus_dec->xaac_jmp_buf);
1522
1523 p_state_enhaacplus_dec->ptr_bit_stream =
1524 p_state_enhaacplus_dec->pstr_bit_buf;
1525
1526 if (p_state_enhaacplus_dec->s_adts_hdr_present) { // rajat
1527 if (p_obj_exhaacplus_dec->aac_config.ld_decoder == 1)
1528 p_state_enhaacplus_dec->audio_object_type = 23;
1529 }
1530
1531 if ((p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) ||
1532 (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD))
1533 if (p_state_enhaacplus_dec->s_adts_hdr_present) {
1534 if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) {
1535 p_state_enhaacplus_dec->eld_specific_config.ld_sbr_samp_rate = 1;
1536 p_state_enhaacplus_dec->eld_specific_config.ld_sbr_crc_flag = 0;
1537 p_state_enhaacplus_dec->eld_specific_config.ld_sbr_flag_present = 0;
1538
1539 if (p_obj_exhaacplus_dec->aac_config.eld_sbr_present == 1) {
1540 p_state_enhaacplus_dec->eld_specific_config.ld_sbr_flag_present = 1;
1541 }
1542 }
1543 if (p_obj_exhaacplus_dec->aac_config.framesize_480)
1544 p_state_enhaacplus_dec->frame_length = 480;
1545 else
1546 p_state_enhaacplus_dec->frame_length = 512;
1547 }
1548
1549 {
1550 for (ch_idx = 0; ch_idx < MAX_BS_ELEMENT; ch_idx++) {
1551 WORD32 channels;
1552 channels = 2;
1553
1554 p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx] =
1555 ixheaacd_aac_decoder_init(
1556 p_state_enhaacplus_dec,
1557
1558 p_state_enhaacplus_dec->pstr_stream_sbr[0], channels,
1559 p_state_enhaacplus_dec->aac_persistent_mem_v,
1560 p_state_enhaacplus_dec->frame_length);
1561
1562 if (!p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]) {
1563 p_state_enhaacplus_dec->i_bytes_consumed = 1;
1564 return IA_ENHAACPLUS_DEC_INIT_FATAL_DEC_INIT_FAIL;
1565 }
1566 }
1567
1568 {
1569 p_state_enhaacplus_dec->pstr_drc_dec =
1570 &p_state_enhaacplus_dec->str_drc_dec_info;
1571 ixheaacd_drc_dec_create(p_state_enhaacplus_dec->pstr_drc_dec, 127, 127);
1572 }
1573 p_state_enhaacplus_dec->pstr_drc_dec->cut_factor =
1574 p_obj_exhaacplus_dec->aac_config.ui_drc_cut;
1575 p_state_enhaacplus_dec->pstr_drc_dec->boost_factor =
1576 p_obj_exhaacplus_dec->aac_config.ui_drc_boost;
1577 p_state_enhaacplus_dec->pstr_drc_dec->target_ref_level =
1578 p_obj_exhaacplus_dec->aac_config.ui_drc_target_level;
1579 p_state_enhaacplus_dec->pstr_drc_dec->prog_ref_level =
1580 p_obj_exhaacplus_dec->aac_config.ui_drc_target_level;
1581
1582 if (1 == p_obj_exhaacplus_dec->aac_config.ui_drc_set) {
1583 if (p_obj_exhaacplus_dec->aac_config.ui_drc_heavy_comp == 1) {
1584 p_state_enhaacplus_dec->pstr_drc_dec->drc_on = 1;
1585 p_state_enhaacplus_dec->pstr_drc_dec->heavy_mode = 1;
1586 } else {
1587 p_state_enhaacplus_dec->pstr_drc_dec->heavy_mode = 0;
1588 if (p_state_enhaacplus_dec->pstr_drc_dec->target_ref_level > 127)
1589 p_state_enhaacplus_dec->pstr_drc_dec->target_ref_level = 127;
1590 if (p_state_enhaacplus_dec->pstr_drc_dec->target_ref_level < 0) {
1591 if (p_state_enhaacplus_dec->pstr_drc_dec->cut_factor > 0 ||
1592 p_state_enhaacplus_dec->pstr_drc_dec->boost_factor > 0)
1593 p_state_enhaacplus_dec->pstr_drc_dec->drc_on = 1;
1594 else
1595 p_state_enhaacplus_dec->pstr_drc_dec->drc_on = 0;
1596 p_state_enhaacplus_dec->pstr_drc_dec->drc_dig_norm = 0;
1597 p_state_enhaacplus_dec->pstr_drc_dec->target_ref_level = 108;
1598 } else {
1599 p_state_enhaacplus_dec->pstr_drc_dec->drc_on = 1;
1600 p_state_enhaacplus_dec->pstr_drc_dec->drc_dig_norm = 1;
1601 }
1602 }
1603 }
1604 }
1605 } else {
1606 struct ia_bit_buf_struct temp_bit_buff = {0};
1607 ia_adts_header_struct adts;
1608 struct ia_bit_buf_struct *it_bit_buff;
1609
1610 WORD16 frame_size_2 = 0;
1611 WORD32 sample_rate_2 = 0;
1612 WORD32 sample_rate = 0;
1613 WORD type, i;
1614 WORD elements_number;
1615
1616 memset(&adts, 0, sizeof(ia_adts_header_struct));
1617
1618 for (i = 0; i < MAX_BS_ELEMENT + 1; i++) {
1619 p_obj_exhaacplus_dec->aac_config.element_type[i] = -1;
1620 }
1621
1622 it_bit_buff = p_state_enhaacplus_dec->pstr_bit_buf;
1623
1624 p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 0;
1625 p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = 0;
1626
1627 if (p_state_enhaacplus_dec->ui_in_bytes == 0) {
1628 p_state_enhaacplus_dec->i_bytes_consumed = 0;
1629 return IA_NO_ERROR;
1630 }
1631
1632 if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD ||
1633 p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) {
1634 if (p_obj_exhaacplus_dec->aac_config.ui_mp4_flag)
1635 p_state_enhaacplus_dec->frame_size =
1636 p_state_enhaacplus_dec->ui_in_bytes;
1637 }
1638
1639 ixheaacd_create_init_bit_buf(it_bit_buff, in_buffer,
1640 p_state_enhaacplus_dec->ui_in_bytes);
1641 p_state_enhaacplus_dec->pstr_bit_buf->xaac_jmp_buf =
1642 &(p_state_enhaacplus_dec->xaac_jmp_buf);
1643
1644 it_bit_buff->adts_header_present =
1645 p_state_enhaacplus_dec->s_adts_hdr_present;
1646 it_bit_buff->no_raw_data_blocks =
1647 (WORD8)p_state_enhaacplus_dec->b_n_raw_data_blk;
1648 it_bit_buff->protection_absent = p_state_enhaacplus_dec->protection_absent;
1649
1650 memcpy(&temp_bit_buff, it_bit_buff, sizeof(struct ia_bit_buf_struct));
1651
1652 if (p_obj_exhaacplus_dec->aac_config.ui_max_channels > 2)
1653 elements_number = MAX_BS_ELEMENT;
1654 else
1655 elements_number = 2;
1656
1657 for (i = 0; i < elements_number; i++)
1658 p_state_enhaacplus_dec->pstr_stream_sbr[i][0].no_elements = 0;
1659
1660 { it_bit_buff->initial_cnt_bits = it_bit_buff->cnt_bits; }
1661
1662 ixheaacd_byte_align(
1663 p_state_enhaacplus_dec->ptr_bit_stream,
1664 &p_state_enhaacplus_dec->pstr_aac_dec_info[0]->byte_align_bits);
1665
1666 if (p_state_enhaacplus_dec->s_adts_hdr_present) {
1667 WORD32 error;
1668
1669 if (p_state_enhaacplus_dec->b_n_raw_data_blk == 0) {
1670 error = ixheaacd_readifadts(p_state_enhaacplus_dec, it_bit_buff, &adts);
1671
1672 if (error) return error;
1673
1674 p_state_enhaacplus_dec->protection_absent = adts.protection_absent;
1675
1676 if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD ||
1677 p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) {
1678 p_state_enhaacplus_dec->frame_size = adts.aac_frame_length;
1679 if (p_obj_exhaacplus_dec->aac_config.framesize_480)
1680 p_state_enhaacplus_dec->frame_length = 480;
1681 else
1682 p_state_enhaacplus_dec->frame_length = 512;
1683 }
1684 }
1685 }
1686
1687 if (p_state_enhaacplus_dec->bs_format == LOAS_BSFORMAT) {
1688 WORD32 result;
1689 WORD32 sync;
1690 WORD32 cnt_bits;
1691
1692 sync = ixheaacd_read_bits_buf(it_bit_buff, 11);
1693 cnt_bits = it_bit_buff->cnt_bits;
1694 if (it_bit_buff->cnt_bits <= 24) {
1695 return IA_ENHAACPLUS_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES;
1696 }
1697
1698 while (sync != 0x2b7) {
1699 sync = ((sync & 0x3ff) << 1) | ixheaacd_read_bits_buf(it_bit_buff, 1);
1700 if (it_bit_buff->cnt_bits < 11) {
1701 ixheaacd_read_bidirection(it_bit_buff, -11);
1702 p_state_enhaacplus_dec->i_bytes_consumed =
1703 (cnt_bits - it_bit_buff->cnt_bits) / 8;
1704 return (IA_ENHAACPLUS_DEC_INIT_NONFATAL_HEADER_NOT_AT_START);
1705 }
1706 }
1707
1708 it_bit_buff->audio_mux_align = it_bit_buff->cnt_bits - 13;
1709
1710 if (sync == 0x2b7) {
1711 result = ixheaacd_latm_audio_mux_element(
1712 it_bit_buff, &p_state_enhaacplus_dec->latm_struct_element,
1713 p_state_enhaacplus_dec,
1714 (ia_sampling_rate_info_struct *)&p_obj_exhaacplus_dec->aac_tables
1715 .pstr_huffmann_tables->str_sample_rate_info[0]);
1716 if (result < 0) {
1717 return result;
1718 }
1719 }
1720 }
1721
1722 p_state_enhaacplus_dec->pstr_aac_dec_info[0]->byte_align_bits =
1723 it_bit_buff->cnt_bits;
1724
1725 type = -1;
1726 ch_idx = 0;
1727
1728 while ((type != 7)) {
1729 ia_aac_dec_scratch_struct aac_scratch_struct;
1730
1731 if (ch_idx >= elements_number) {
1732 p_state_enhaacplus_dec->i_bytes_consumed = 1;
1733
1734 return IA_ENHAACPLUS_DEC_INIT_FATAL_STREAM_CHAN_GT_MAX;
1735 }
1736
1737 ixheaacd_allocate_aac_scr(
1738 &aac_scratch_struct, p_state_enhaacplus_dec->aac_scratch_mem_v,
1739 time_data, 1, p_obj_exhaacplus_dec->aac_config.ui_max_channels,
1740 p_state_enhaacplus_dec->audio_object_type);
1741
1742 p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->p_ind_channel_info =
1743 &p_state_enhaacplus_dec->ind_cc_info;
1744
1745 error_code = ixheaacd_aacdec_decodeframe(
1746 p_obj_exhaacplus_dec, &aac_scratch_struct, time_data, frame_status,
1747 &type, &ch_idx, 1, 2,
1748 p_obj_exhaacplus_dec->aac_config.element_instance_order, 0, 1, 0,
1749 p_obj_exhaacplus_dec->aac_config.ui_max_channels, 2,
1750 p_obj_exhaacplus_dec->p_state_aac->frame_length,
1751 p_obj_exhaacplus_dec->p_state_aac->frame_size,
1752 p_state_enhaacplus_dec->pstr_drc_dec,
1753 p_state_enhaacplus_dec->audio_object_type,
1754 p_state_enhaacplus_dec->ch_config,
1755 p_state_enhaacplus_dec->eld_specific_config,
1756 p_state_enhaacplus_dec->s_adts_hdr_present,
1757 &p_state_enhaacplus_dec->drc_dummy);
1758
1759 memset(&(p_obj_exhaacplus_dec->p_state_aac->pstr_aac_dec_info[ch_idx]
1760 ->pstr_aac_dec_ch_info[0]
1761 ->str_ics_info.ltp),
1762 0, sizeof(ltp_info));
1763 memset(&(p_obj_exhaacplus_dec->p_state_aac->pstr_aac_dec_info[ch_idx]
1764 ->pstr_aac_dec_ch_info[0]
1765 ->str_ics_info.ltp2),
1766 0, sizeof(ltp_info));
1767 memset(&(p_obj_exhaacplus_dec->p_state_aac->pstr_aac_dec_info[ch_idx]
1768 ->pstr_aac_dec_ch_info[1]
1769 ->str_ics_info.ltp),
1770 0, sizeof(ltp_info));
1771 memset(&(p_obj_exhaacplus_dec->p_state_aac->pstr_aac_dec_info[ch_idx]
1772 ->pstr_aac_dec_ch_info[1]
1773 ->str_ics_info.ltp2),
1774 0, sizeof(ltp_info));
1775
1776 {
1777 if ((p_state_enhaacplus_dec->audio_object_type != AOT_ER_AAC_LD) &&
1778 (p_state_enhaacplus_dec->audio_object_type != AOT_ER_AAC_ELD))
1779 frame_size_1 = 1024;
1780 else
1781 frame_size_1 = p_state_enhaacplus_dec->frame_length;
1782 sample_rate_1 =
1783 p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->sampling_rate;
1784 num_channels_1 =
1785 p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->channels;
1786 }
1787
1788 if ((p_obj_exhaacplus_dec->aac_config.ui_max_channels <= 2) &&
1789 (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 2)) {
1790 p_state_enhaacplus_dec->i_bytes_consumed = 1;
1791 return IA_ENHAACPLUS_DEC_EXE_FATAL_UNIMPLEMENTED_CCE;
1792 }
1793
1794 if (p_state_enhaacplus_dec->pstr_stream_sbr[0][0].no_elements) {
1795 sbr_present_flag = 1;
1796 p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 1;
1797 }
1798
1799 if (error_code) {
1800 if (p_state_enhaacplus_dec->ui_input_over) {
1801 return IA_ENHAACPLUS_DEC_INIT_FATAL_EO_INPUT_REACHED;
1802 }
1803
1804 ixheaacd_updatebytesconsumed(p_state_enhaacplus_dec, it_bit_buff);
1805 return error_code;
1806 }
1807
1808 if (p_state_enhaacplus_dec->s_adts_hdr_present) {
1809 if (adts.no_raw_data_blocks != 0) {
1810 if (adts.protection_absent == 0) {
1811 adts.crc_check = ixheaacd_read_bits_buf(it_bit_buff, 16);
1812 }
1813 }
1814 p_state_enhaacplus_dec->b_n_raw_data_blk--;
1815 }
1816
1817 sample_rate_2 = sample_rate_1;
1818 frame_size_2 = frame_size_1;
1819
1820 if (!p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] &&
1821 p_state_enhaacplus_dec->pstr_stream_sbr[0][0].no_elements) {
1822 if ((p_obj_exhaacplus_dec->aac_config.flag_16khz_out == 1) &&
1823 (sample_rate_1 == 8000)) {
1824 p_obj_exhaacplus_dec->aac_config.flag_16khz_out = 0;
1825 }
1826
1827 p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = ixheaacd_init_sbr(
1828 sample_rate_1, frame_size_1,
1829 (FLAG *)&p_obj_exhaacplus_dec->aac_config.down_sample_flag,
1830 p_state_enhaacplus_dec->sbr_persistent_mem_v,
1831 p_state_enhaacplus_dec->ptr_overlap_buf, MAXNRSBRCHANNELS, (WORD)1,
1832 1, frame_size_1 * 2, NULL, NULL,
1833 p_state_enhaacplus_dec->str_sbr_config,
1834 p_state_enhaacplus_dec->audio_object_type);
1835 if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) {
1836 p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->xaac_jmp_buf =
1837 &(p_state_enhaacplus_dec->xaac_jmp_buf);
1838 }
1839 } else {
1840 }
1841
1842 if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] &&
1843 p_state_enhaacplus_dec->pstr_stream_sbr[0][0].no_elements) {
1844 ia_sbr_scr_struct sbr_scratch_struct;
1845 WORD16 num_channels_1_t = num_channels_1;
1846 ixheaacd_allocate_sbr_scr(
1847 &sbr_scratch_struct, p_state_enhaacplus_dec->aac_scratch_mem_v,
1848 time_data, 1, 1, p_state_enhaacplus_dec->audio_object_type);
1849
1850 if (ixheaacd_applysbr(
1851 p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx],
1852 &p_state_enhaacplus_dec->pstr_stream_sbr[0][0], time_data,
1853 &num_channels_1, frame_status,
1854 p_obj_exhaacplus_dec->aac_config.down_sample_flag, 0,
1855 &sbr_scratch_struct, 1, 1, 0, NULL, NULL,
1856 p_state_enhaacplus_dec->eld_specific_config.ld_sbr_flag_present,
1857 p_state_enhaacplus_dec->audio_object_type) != SBRDEC_OK) {
1858 p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = 0;
1859 return -1;
1860 } else {
1861 if (!p_obj_exhaacplus_dec->aac_config.down_sample_flag) {
1862 sample_rate_1 *= 2;
1863 }
1864 }
1865
1866 if (p_obj_exhaacplus_dec->aac_config.flag_downmix) {
1867 num_channels_1 = 1;
1868 }
1869 if (num_channels_1_t == 1 && num_channels_1 == 2) ps_detected = 1;
1870 }
1871
1872 p_state_enhaacplus_dec->i_bytes_consumed = 0;
1873 p_state_enhaacplus_dec->pstr_bit_buf = it_bit_buff;
1874
1875 {
1876 p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx] =
1877 ixheaacd_aac_decoder_init(
1878 p_state_enhaacplus_dec,
1879 p_state_enhaacplus_dec->pstr_stream_sbr[0], 2,
1880 p_state_enhaacplus_dec->aac_persistent_mem_v,
1881 p_state_enhaacplus_dec->frame_length);
1882
1883 if (!p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]) {
1884 p_state_enhaacplus_dec->i_bytes_consumed = 1;
1885 return IA_ENHAACPLUS_DEC_INIT_FATAL_DEC_INIT_FAIL;
1886 }
1887
1888 if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) {
1889 p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = ixheaacd_init_sbr(
1890 sample_rate_2, frame_size_2,
1891 (FLAG *)&p_obj_exhaacplus_dec->aac_config.down_sample_flag,
1892 p_state_enhaacplus_dec->sbr_persistent_mem_v,
1893 p_state_enhaacplus_dec->ptr_overlap_buf, MAXNRSBRCHANNELS, 1, 1,
1894 frame_size_2 * 2, NULL, NULL,
1895 p_state_enhaacplus_dec->str_sbr_config,
1896 p_state_enhaacplus_dec->audio_object_type);
1897 }
1898 if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) {
1899 p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->xaac_jmp_buf =
1900 &(p_state_enhaacplus_dec->xaac_jmp_buf);
1901 }
1902 }
1903
1904 if (sample_rate < sample_rate_1) sample_rate = sample_rate_1;
1905
1906 ch_idx++;
1907
1908 if (p_state_enhaacplus_dec->audio_object_type >= ER_OBJECT_START &&
1909 (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD ||
1910 p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD))
1911 break;
1912 }
1913
1914 {
1915 ia_adts_crc_info_struct *ptr_adts_crc_info =
1916 p_state_enhaacplus_dec->ptr_bit_stream->pstr_adts_crc_info;
1917 if (ptr_adts_crc_info->crc_active == 1) {
1918 if ((error_code = ixheaacd_adts_crc_check_crc(ptr_adts_crc_info))) {
1919 return error_code;
1920 }
1921 }
1922 }
1923
1924 {
1925 VOID *temp;
1926 WORD prev_persistent_used_t;
1927 WORD prev_sbrpersistent_used_t;
1928 WORD ps_enable;
1929 WORD ch_idx_err = 0;
1930 WORD persistent_used_t = 0;
1931 WORD channel_check = 0;
1932 WORD max_ch_num = p_obj_exhaacplus_dec->aac_config.ui_max_channels;
1933 i = 0;
1934
1935 p_obj_exhaacplus_dec->aac_config.ui_n_channels = ch_idx;
1936 while (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx_err] <= 3 &&
1937 p_obj_exhaacplus_dec->aac_config.element_type[ch_idx_err] >= 0) {
1938 ch_idx_err++;
1939 }
1940
1941 if (ch_idx_err == 0) {
1942 p_obj_exhaacplus_dec->p_state_aac->header_dec_done = 0;
1943 p_state_enhaacplus_dec->i_bytes_consumed =
1944 it_bit_buff->ptr_read_next - it_bit_buff->ptr_bit_buf_base;
1945 return IA_ENHAACPLUS_DEC_EXE_NONFATAL_DECODE_FRAME_ERROR;
1946 }
1947
1948 if (ch_idx == 1)
1949 ps_enable = 1;
1950 else
1951 ps_enable = 0;
1952
1953 while (p_obj_exhaacplus_dec->aac_config.element_type[i] >= 0 &&
1954 p_obj_exhaacplus_dec->aac_config.element_type[i] <= 3) {
1955 WORD32 channel = 0;
1956 if (p_obj_exhaacplus_dec->aac_config.element_type[i] == 0 ||
1957 p_obj_exhaacplus_dec->aac_config.element_type[i] == 3) {
1958 channel = 1;
1959 }
1960
1961 if (p_obj_exhaacplus_dec->aac_config.element_type[i] == 1) {
1962 channel = 2;
1963 }
1964
1965 if (p_obj_exhaacplus_dec->aac_config.element_type[i] == 2) {
1966 if (max_ch_num > 2) {
1967 if (p_obj_exhaacplus_dec->aac_config.element_instance_order[i] !=
1968 p_obj_exhaacplus_dec->aac_config.ui_coupling_channel) {
1969 i++;
1970 continue;
1971 }
1972 channel = 1;
1973 } else
1974
1975 {
1976 i++;
1977 continue;
1978 }
1979 }
1980 if (ps_enable == 1) {
1981 channel = 2;
1982 }
1983
1984 if (p_obj_exhaacplus_dec->aac_config.element_type[i] != 2) {
1985 channel_check += channel;
1986 }
1987
1988 if (channel_check > max_ch_num) {
1989 p_state_enhaacplus_dec->i_bytes_consumed = 1;
1990 return IA_ENHAACPLUS_DEC_INIT_FATAL_STREAM_CHAN_GT_MAX;
1991 }
1992
1993 temp = p_state_enhaacplus_dec->aac_persistent_mem_v;
1994
1995 prev_persistent_used_t = persistent_used_t;
1996
1997 ixheaacd_allocate_mem_persistent(
1998 p_obj_exhaacplus_dec, p_state_enhaacplus_dec, channel,
1999 &persistent_used_t, &prev_sbrpersistent_used_t, ps_enable);
2000
2001 p_state_enhaacplus_dec->aac_persistent_mem_v = temp;
2002 p_state_enhaacplus_dec->last_frame_ok = 1;
2003
2004 p_state_enhaacplus_dec->num_channel_last = 0;
2005 p_state_enhaacplus_dec->ui_init_done = 0;
2006 p_state_enhaacplus_dec->ui_input_over = 0;
2007 p_state_enhaacplus_dec->ptr_bit_stream =
2008 p_state_enhaacplus_dec->pstr_bit_buf;
2009
2010 p_state_enhaacplus_dec->pstr_aac_dec_info[i] = 0;
2011
2012 p_state_enhaacplus_dec->pstr_aac_dec_info[i] =
2013 ixheaacd_aac_decoder_init(
2014 p_state_enhaacplus_dec,
2015 p_state_enhaacplus_dec->pstr_stream_sbr[i], channel,
2016 (WORD8 *)p_state_enhaacplus_dec->aac_persistent_mem_v +
2017 prev_persistent_used_t,
2018 p_state_enhaacplus_dec->frame_length);
2019
2020 if (!p_state_enhaacplus_dec->pstr_aac_dec_info[i]) {
2021 p_state_enhaacplus_dec->i_bytes_consumed = 1;
2022 return IA_ENHAACPLUS_DEC_INIT_FATAL_DEC_INIT_FAIL;
2023 }
2024
2025 p_state_enhaacplus_dec->str_sbr_dec_info[i] = ixheaacd_init_sbr(
2026 sample_rate_2, frame_size_2,
2027 (FLAG *)&p_obj_exhaacplus_dec->aac_config.down_sample_flag,
2028 p_state_enhaacplus_dec->sbr_persistent_mem_v,
2029 p_state_enhaacplus_dec->ptr_overlap_buf, channel, ps_enable, 1,
2030 frame_size_2 * 2, NULL, NULL,
2031 p_state_enhaacplus_dec->str_sbr_config,
2032 p_state_enhaacplus_dec->audio_object_type);
2033 if (p_state_enhaacplus_dec->str_sbr_dec_info[i]) {
2034 p_state_enhaacplus_dec->str_sbr_dec_info[i]->xaac_jmp_buf =
2035 &(p_state_enhaacplus_dec->xaac_jmp_buf);
2036 }
2037
2038 i++;
2039 }
2040
2041 p_obj_exhaacplus_dec->aac_config.i_channel_mask =
2042 ixheaacd_get_channel_mask(p_obj_exhaacplus_dec);
2043
2044 {
2045 num_channels_1 = 0;
2046 ch_idx = 0;
2047 while (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] >= 0 &&
2048 p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] <= 3) {
2049 if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 0 ||
2050 p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 3)
2051 num_channels_1 += 1;
2052 if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 1)
2053 num_channels_1 += 2;
2054 ch_idx++;
2055 }
2056
2057 if (ch_idx == 2 && num_channels_1 == 2) {
2058 p_obj_exhaacplus_dec->aac_config.ui_channel_mode = 2;
2059 }
2060 if (ch_idx == 1) {
2061 if (num_channels_1 == 1)
2062 p_obj_exhaacplus_dec->aac_config.ui_channel_mode = 0;
2063 if (num_channels_1 == 2)
2064 p_obj_exhaacplus_dec->aac_config.ui_channel_mode = 1;
2065 }
2066
2067 if (ps_detected == 1 && num_channels_1 == 1) num_channels_1 = 2;
2068 }
2069 }
2070 if (1 == p_obj_exhaacplus_dec->aac_config.downmix) num_channels_1 = 2;
2071
2072 if (p_obj_exhaacplus_dec->aac_config.flag_downmix == 1) {
2073 num_channels_1 = 1;
2074 }
2075
2076 if ((p_obj_exhaacplus_dec->aac_config.flag_to_stereo == 1) &&
2077 (ch_idx == 1 || num_channels_1 <= 2)) {
2078 num_channels_1 = 2;
2079 }
2080
2081 p_obj_exhaacplus_dec->aac_config.ui_n_channels = num_channels_1;
2082 p_obj_exhaacplus_dec->aac_config.ui_samp_freq = sample_rate;
2083 p_state_enhaacplus_dec->ui_init_done = 1;
2084
2085 memcpy(it_bit_buff, &temp_bit_buff, sizeof(struct ia_bit_buf_struct));
2086
2087 p_state_enhaacplus_dec->b_n_raw_data_blk = 0;
2088
2089 if (p_obj_exhaacplus_dec->p_state_aac->header_dec_done == 1) {
2090 p_obj_exhaacplus_dec->p_state_aac->header_dec_done = 0;
2091 }
2092 }
2093 return err_code;
2094 }
2095
ixheaacd_fill_slot_order(ia_aac_dec_state_struct * p_state_enhaacplus_dec,WORD32 ch,WORD8 * ptr_is_cpe,WORD8 * ptr_tag_select,WORD32 * ptr_idx_no)2096 VOID ixheaacd_fill_slot_order(ia_aac_dec_state_struct *p_state_enhaacplus_dec,
2097 WORD32 ch, WORD8 *ptr_is_cpe,
2098 WORD8 *ptr_tag_select, WORD32 *ptr_idx_no) {
2099 WORD32 i;
2100 WORD32 idx_no = *ptr_idx_no;
2101 WORD *p_slot_element = p_state_enhaacplus_dec->p_config->slot_element;
2102 WORD *p_element_type = p_state_enhaacplus_dec->p_config->element_type;
2103 WORD *p_element_instance_order =
2104 p_state_enhaacplus_dec->p_config->element_instance_order;
2105
2106 for (i = 0; i < ch; i++) {
2107 if (ptr_is_cpe[i] == 0) {
2108 *p_slot_element++ = idx_no++;
2109 *p_element_type++ = 0;
2110 *p_element_instance_order++ = ptr_tag_select[i];
2111 }
2112 }
2113 *ptr_idx_no = idx_no;
2114 }
2115
ixheaacd_fill_prog_config_slots(ia_aac_dec_state_struct * p_state_enhaacplus_dec)2116 VOID ixheaacd_fill_prog_config_slots(
2117 ia_aac_dec_state_struct *p_state_enhaacplus_dec) {
2118 WORD32 idx_no = 0;
2119
2120 ixheaacd_fill_slot_order(
2121 p_state_enhaacplus_dec, p_state_enhaacplus_dec->p_config->str_prog_config
2122 .num_front_channel_elements,
2123 p_state_enhaacplus_dec->p_config->str_prog_config.front_element_is_cpe,
2124 p_state_enhaacplus_dec->p_config->str_prog_config
2125 .front_element_tag_select,
2126 &idx_no);
2127
2128 ixheaacd_fill_slot_order(
2129 p_state_enhaacplus_dec, p_state_enhaacplus_dec->p_config->str_prog_config
2130 .num_side_channel_elements,
2131 p_state_enhaacplus_dec->p_config->str_prog_config.side_element_is_cpe,
2132 p_state_enhaacplus_dec->p_config->str_prog_config.side_element_tag_select,
2133 &idx_no);
2134
2135 ixheaacd_fill_slot_order(
2136 p_state_enhaacplus_dec, p_state_enhaacplus_dec->p_config->str_prog_config
2137 .num_back_channel_elements,
2138 p_state_enhaacplus_dec->p_config->str_prog_config.back_element_is_cpe,
2139 p_state_enhaacplus_dec->p_config->str_prog_config.back_element_tag_select,
2140 &idx_no);
2141 }
2142
ixheaacd_dec_execute(ia_exhaacplus_dec_api_struct * p_obj_exhaacplus_dec)2143 IA_ERRORCODE ixheaacd_dec_execute(
2144 ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec) {
2145 ia_adts_header_struct adts = {0};
2146 ia_aac_dec_state_struct *p_state_enhaacplus_dec;
2147
2148 UWORD8 *in_buffer;
2149 WORD16 *time_data;
2150 WORD16 num_of_out_samples = 0;
2151 WORD16 frame_size = 0;
2152 WORD32 sample_rate_dec = 0;
2153 WORD32 sample_rate = 0;
2154 WORD16 num_ch = 0;
2155 struct ia_bit_buf_struct *it_bit_buff;
2156 WORD32 error_code = IA_NO_ERROR;
2157 WORD ch_idx1;
2158 WORD type;
2159 WORD total_channels = 0;
2160 WORD total_elements = 0;
2161 WORD16 *actual_out_buffer;
2162 WORD ps_enable;
2163 WORD esbr_mono_downmix = 0;
2164 WORD8 element_used[MAX_BS_ELEMENT];
2165 WORD32 channel_coupling_flag = 0;
2166
2167 SIZE_T bytes_for_sync;
2168 WORD32 audio_mux_length_bytes_last = 0;
2169 WORD32 ret_val;
2170
2171 p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 0;
2172
2173 if (p_obj_exhaacplus_dec->p_state_aac != NULL) {
2174 ret_val = setjmp(p_obj_exhaacplus_dec->p_state_aac->xaac_jmp_buf);
2175 if (ret_val != 0) {
2176 p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed =
2177 p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes;
2178 p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = 0;
2179 return IA_NO_ERROR;
2180 }
2181 }
2182
2183 time_data = (WORD16 *)(p_obj_exhaacplus_dec
2184 ->pp_mem_aac[IA_ENHAACPLUS_DEC_OUTPUT_IDX]);
2185 in_buffer = p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_INPUT_IDX];
2186 p_state_enhaacplus_dec = p_obj_exhaacplus_dec->p_state_aac;
2187 p_state_enhaacplus_dec->aac_scratch_mem_v =
2188 p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_SCRATCH_IDX];
2189
2190 it_bit_buff = p_state_enhaacplus_dec->pstr_bit_buf;
2191
2192 ch_idx1 = 0;
2193 p_state_enhaacplus_dec->i_bytes_consumed = 0;
2194
2195 if (p_state_enhaacplus_dec->audio_object_type == AOT_USAC) {
2196 WORD32 pcm_size = p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz;
2197 WORD8 *inbuffer = (WORD8 *)(p_obj_exhaacplus_dec
2198 ->pp_mem_aac[IA_ENHAACPLUS_DEC_INPUT_IDX]);
2199 WORD8 *outbuffer =
2200 (WORD8 *)(p_obj_exhaacplus_dec
2201 ->pp_mem_aac[IA_ENHAACPLUS_DEC_OUTPUT_IDX]);
2202 WORD32 out_bytes = 0;
2203
2204 WORD32 frames_done = p_obj_exhaacplus_dec->p_state_aac->frame_counter;
2205
2206 if (p_obj_exhaacplus_dec->p_state_aac->ui_input_over == 0) {
2207 error_code = ixheaacd_dec_main(
2208 p_obj_exhaacplus_dec, inbuffer, outbuffer, &out_bytes, frames_done,
2209 pcm_size, &p_obj_exhaacplus_dec->p_state_aac->num_of_output_ch);
2210 if (error_code == -1) return error_code;
2211 p_obj_exhaacplus_dec->p_state_aac->frame_counter++;
2212 } else {
2213 out_bytes = 0;
2214 }
2215
2216 p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed =
2217 p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes;
2218 p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = out_bytes;
2219 p_obj_exhaacplus_dec->aac_config.ui_n_channels =
2220 p_obj_exhaacplus_dec->p_state_aac->num_of_output_ch;
2221
2222 return 0;
2223 }
2224
2225 while (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx1] <= 3 &&
2226 p_obj_exhaacplus_dec->aac_config.element_type[ch_idx1] >= 0) {
2227 if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx1] == 0 ||
2228 p_obj_exhaacplus_dec->aac_config.element_type[ch_idx1] == 3) {
2229 total_channels += 1;
2230 total_elements += 1;
2231 }
2232 if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx1] == 1) {
2233 total_elements += 1;
2234 total_channels += 2;
2235 }
2236 if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx1] == 2) {
2237 total_elements += 1;
2238 }
2239
2240 ch_idx1++;
2241 }
2242
2243 if (ch_idx1 != 1) {
2244 ps_enable = 0;
2245 if (p_obj_exhaacplus_dec->aac_config.ui_max_channels > 2) {
2246 WORD32 scratch_pointer;
2247
2248 scratch_pointer = 12 * 1024;
2249
2250 p_state_enhaacplus_dec->coup_ch_output =
2251 (WORD16 *)((WORD8 *)
2252 p_obj_exhaacplus_dec->p_state_aac->aac_scratch_mem_v +
2253 scratch_pointer);
2254 }
2255
2256 }
2257
2258 else {
2259 if (total_channels < (WORD)p_obj_exhaacplus_dec->aac_config.ui_n_channels)
2260 total_channels = p_obj_exhaacplus_dec->aac_config.ui_n_channels;
2261 ps_enable = 1;
2262 }
2263
2264 p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = 0;
2265
2266 if (p_state_enhaacplus_dec->ui_in_bytes == 0) {
2267 p_state_enhaacplus_dec->i_bytes_consumed = 0;
2268 return IA_NO_ERROR;
2269 }
2270
2271 if (ch_idx1 == 0) {
2272 p_state_enhaacplus_dec->i_bytes_consumed = 1;
2273 return IA_ENHAACPLUS_DEC_EXE_NONFATAL_DECODE_FRAME_ERROR;
2274 }
2275 if (total_channels > (WORD)p_obj_exhaacplus_dec->aac_config.ui_max_channels) {
2276 p_state_enhaacplus_dec->i_bytes_consumed = 1;
2277 return IA_ENHAACPLUS_DEC_CONFIG_NONFATAL_INVALID_MAX_CHANNEL;
2278 }
2279
2280 if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD ||
2281 p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) {
2282 if (p_obj_exhaacplus_dec->aac_config.ui_mp4_flag)
2283 p_state_enhaacplus_dec->frame_size = p_state_enhaacplus_dec->ui_in_bytes;
2284 }
2285
2286 {
2287 ixheaacd_create_init_bit_buf(it_bit_buff, in_buffer,
2288 p_state_enhaacplus_dec->ui_in_bytes);
2289 it_bit_buff->xaac_jmp_buf = &(p_state_enhaacplus_dec->xaac_jmp_buf);
2290
2291 it_bit_buff->adts_header_present =
2292 p_state_enhaacplus_dec->s_adts_hdr_present;
2293 it_bit_buff->no_raw_data_blocks =
2294 (WORD8)p_state_enhaacplus_dec->b_n_raw_data_blk;
2295 it_bit_buff->protection_absent = p_state_enhaacplus_dec->protection_absent;
2296
2297 if (p_state_enhaacplus_dec->s_adts_hdr_present) {
2298 if (p_state_enhaacplus_dec->b_n_raw_data_blk == 0) {
2299 WORD32 error;
2300
2301 error = ixheaacd_readifadts(p_state_enhaacplus_dec, it_bit_buff, &adts);
2302
2303 if (error) return error;
2304
2305 if ((WORD32)p_state_enhaacplus_dec->sampling_rate !=
2306 (WORD32)((p_obj_exhaacplus_dec->aac_tables.pstr_huffmann_tables
2307 ->str_sample_rate_info[adts.samp_freq_index]
2308 .sampling_frequency))) {
2309 p_state_enhaacplus_dec->i_bytes_consumed = 0;
2310 return IA_ENHAACPLUS_DEC_EXE_NONFATAL_CHANGED_ADTS_SF;
2311 }
2312 }
2313 }
2314
2315 bytes_for_sync = (SIZE_T)it_bit_buff->ptr_read_next;
2316
2317 if (p_state_enhaacplus_dec->bs_format == LOAS_BSFORMAT) {
2318 WORD32 result, audio_mux_len_bytes_last;
2319 WORD32 cnt_bits = it_bit_buff->cnt_bits;
2320 WORD32 sync = ixheaacd_read_bits_buf(it_bit_buff, 11);
2321 UWORD32 curr_samp_rate = 0;
2322
2323 if (p_state_enhaacplus_dec->latm_initialized)
2324 curr_samp_rate =
2325 p_state_enhaacplus_dec->latm_struct_element.layer_info[0][0]
2326 .asc.sampling_freq;
2327
2328 while (sync != 0x2b7) {
2329 sync = ((sync & 0x3ff) << 1) | ixheaacd_read_bits_buf(it_bit_buff, 1);
2330 if (it_bit_buff->cnt_bits < 13) {
2331 ixheaacd_read_bidirection(it_bit_buff, -11);
2332 p_state_enhaacplus_dec->i_bytes_consumed =
2333 (cnt_bits - it_bit_buff->cnt_bits) / 8;
2334
2335 if (p_state_enhaacplus_dec->i_bytes_consumed == 0)
2336 p_state_enhaacplus_dec->i_bytes_consumed = 1;
2337
2338 return (IA_ENHAACPLUS_DEC_INIT_NONFATAL_HEADER_NOT_AT_START);
2339 }
2340 }
2341
2342 it_bit_buff->audio_mux_align = it_bit_buff->cnt_bits - 13;
2343
2344 audio_mux_len_bytes_last = ixheaacd_read_bits_buf(it_bit_buff, 13);
2345
2346 audio_mux_length_bytes_last = audio_mux_len_bytes_last;
2347
2348 bytes_for_sync = (SIZE_T)it_bit_buff->ptr_read_next - bytes_for_sync;
2349
2350 if (it_bit_buff->cnt_bits < (audio_mux_len_bytes_last << 3)) {
2351 ixheaacd_read_bidirection(it_bit_buff, -(13 + 11));
2352 p_state_enhaacplus_dec->i_bytes_consumed =
2353 (cnt_bits - it_bit_buff->cnt_bits) / 8;
2354 return IA_ENHAACPLUS_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES;
2355 } else {
2356 ixheaacd_read_bidirection(it_bit_buff, -(13));
2357 }
2358
2359 if (sync == 0x2b7) {
2360 result = ixheaacd_latm_audio_mux_element(
2361 it_bit_buff, &p_state_enhaacplus_dec->latm_struct_element,
2362 p_state_enhaacplus_dec,
2363 (ia_sampling_rate_info_struct *)&p_obj_exhaacplus_dec->aac_tables
2364 .pstr_huffmann_tables->str_sample_rate_info[0]);
2365 if (result < 0) return result;
2366 if (!p_state_enhaacplus_dec->latm_initialized) {
2367 p_state_enhaacplus_dec->sampling_rate =
2368 p_state_enhaacplus_dec->latm_struct_element.layer_info[0][0]
2369 .asc.sampling_freq;
2370 p_state_enhaacplus_dec->latm_initialized = 1;
2371 } else {
2372 if (p_state_enhaacplus_dec->sampling_rate != curr_samp_rate) {
2373 p_state_enhaacplus_dec->i_bytes_consumed = 0;
2374 return IA_ENHAACPLUS_DEC_EXE_NONFATAL_CHANGED_ADTS_SF;
2375 }
2376 }
2377 }
2378 }
2379 }
2380
2381 if (total_elements == 2 && total_channels == 2 &&
2382 (p_state_enhaacplus_dec->p_config->ui_pce_found_in_hdr == 1 ||
2383 p_state_enhaacplus_dec->p_config->ui_pce_found_in_hdr == 3)) {
2384 ixheaacd_fill_prog_config_slots(p_state_enhaacplus_dec);
2385 }
2386
2387 memset(element_used, 0, sizeof(WORD8) * MAX_BS_ELEMENT);
2388
2389 if (it_bit_buff->cnt_bits <= 0) {
2390 it_bit_buff->cnt_bits = -1;
2391 ixheaacd_updatebytesconsumed(p_state_enhaacplus_dec, it_bit_buff);
2392 return (WORD16)(
2393 (WORD32)IA_ENHAACPLUS_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES);
2394 }
2395
2396 { it_bit_buff->initial_cnt_bits = it_bit_buff->cnt_bits; }
2397
2398 if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD) {
2399 if (p_state_enhaacplus_dec->s_adts_hdr_present)
2400 p_state_enhaacplus_dec->frame_size = adts.aac_frame_length;
2401 }
2402
2403 if (p_state_enhaacplus_dec->pstr_drc_dec) {
2404 p_state_enhaacplus_dec->pstr_drc_dec->num_drc_elements = 0;
2405
2406 p_state_enhaacplus_dec->pstr_drc_dec->state = 1;
2407 }
2408
2409 for (ch_idx1 = 0; ch_idx1 < total_elements; ch_idx1++) {
2410 WORD32 skip_full_decode = 0;
2411 WORD32 ch_idx = ch_idx1;
2412 WORD32 channel;
2413 WORD ch_fac, slot_ele;
2414
2415 if (p_state_enhaacplus_dec->audio_object_type < ER_OBJECT_START ||
2416 (p_state_enhaacplus_dec->audio_object_type != AOT_ER_AAC_LD &&
2417 p_state_enhaacplus_dec->audio_object_type != AOT_ER_AAC_ELD)) {
2418 error_code = ixheaacd_get_element_index_tag(
2419 p_obj_exhaacplus_dec, ch_idx1, &ch_idx, &channel,
2420 p_obj_exhaacplus_dec->aac_config.element_instance_order,
2421 total_elements, element_used, total_channels,
2422 p_state_enhaacplus_dec->pstr_drc_dec,
2423 &p_state_enhaacplus_dec->drc_dummy);
2424
2425 if (error_code) {
2426 ixheaacd_updatebytesconsumed(p_state_enhaacplus_dec, it_bit_buff);
2427 p_state_enhaacplus_dec->i_bytes_consumed = 1;
2428 p_state_enhaacplus_dec->b_n_raw_data_blk = 0;
2429 return error_code;
2430 }
2431 } else {
2432 if (p_obj_exhaacplus_dec->aac_config.element_type[0] == ID_SCE)
2433 channel = 1;
2434 else
2435 channel = 2;
2436 }
2437
2438 ch_fac = total_channels;
2439 slot_ele = p_obj_exhaacplus_dec->aac_config.slot_element[ch_idx];
2440 actual_out_buffer = time_data;
2441 if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 2) {
2442 p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->p_ind_channel_info =
2443 &p_state_enhaacplus_dec->ind_cc_info;
2444 if (p_obj_exhaacplus_dec->aac_config.element_instance_order[ch_idx] !=
2445 p_obj_exhaacplus_dec->aac_config.ui_coupling_channel) {
2446 WORD32 pers_used = 0;
2447 skip_full_decode = 1;
2448 pers_used = ixheaacd_set_aac_persistent_buffers(
2449 (WORD8 *)p_state_enhaacplus_dec->aac_scratch_mem_v + (8 * 1024),
2450 channel);
2451
2452 {
2453 struct ia_aac_persistent_struct *aac_persistent_mem =
2454 (struct ia_aac_persistent_struct
2455 *)((WORD8 *)p_state_enhaacplus_dec->aac_scratch_mem_v +
2456 (8 * 1024));
2457 aac_persistent_mem->str_aac_decoder.pstr_aac_tables =
2458 &p_obj_exhaacplus_dec->aac_tables;
2459 aac_persistent_mem->str_aac_decoder.pstr_common_tables =
2460 p_obj_exhaacplus_dec->common_tables;
2461 }
2462
2463 p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx] = 0;
2464
2465 p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = 0;
2466
2467 p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx] =
2468 ixheaacd_aac_decoder_init(
2469 p_state_enhaacplus_dec,
2470
2471 p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx],
2472
2473 channel,
2474 (WORD8 *)p_state_enhaacplus_dec->aac_scratch_mem_v + (8 * 1024),
2475 p_state_enhaacplus_dec->frame_length
2476
2477 );
2478 if (!p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]) {
2479 p_state_enhaacplus_dec->i_bytes_consumed = 1;
2480 return IA_ENHAACPLUS_DEC_INIT_FATAL_DEC_INIT_FAIL;
2481 }
2482 p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->p_ind_channel_info =
2483 (WORD8 *)p_state_enhaacplus_dec->aac_scratch_mem_v + (8 * 1024) +
2484 pers_used;
2485 }
2486 if (p_obj_exhaacplus_dec->aac_config.element_type[1] < 3 &&
2487 p_obj_exhaacplus_dec->aac_config.element_type[1] > 0 &&
2488 p_obj_exhaacplus_dec->aac_config.ui_max_channels > 2) {
2489 actual_out_buffer = p_state_enhaacplus_dec->coup_ch_output;
2490 }
2491 ch_fac = 1;
2492 slot_ele = 0;
2493 }
2494
2495 type = -1;
2496 p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx][0].no_elements = 0;
2497
2498 {
2499 WORD element_index_order1[MAX_BS_ELEMENT];
2500 ia_aac_dec_scratch_struct aac_scratch_struct;
2501 ixheaacd_allocate_aac_scr(
2502 &aac_scratch_struct, p_state_enhaacplus_dec->aac_scratch_mem_v,
2503 time_data, channel, p_obj_exhaacplus_dec->aac_config.ui_max_channels,
2504 p_state_enhaacplus_dec->audio_object_type);
2505
2506 if(p_state_enhaacplus_dec->ch_config == 2 && channel == 1)
2507 return IA_ENHAACPLUS_DEC_EXE_NONFATAL_DECODE_FRAME_ERROR;
2508
2509 error_code = ixheaacd_aacdec_decodeframe(
2510 p_obj_exhaacplus_dec, &aac_scratch_struct, actual_out_buffer,
2511 p_obj_exhaacplus_dec->aac_config.frame_status, &type, &ch_idx, 0,
2512 channel, element_index_order1, skip_full_decode, ch_fac, slot_ele,
2513 p_obj_exhaacplus_dec->aac_config.ui_max_channels, total_channels,
2514 p_obj_exhaacplus_dec->p_state_aac->frame_length,
2515 p_obj_exhaacplus_dec->p_state_aac->frame_size,
2516 p_state_enhaacplus_dec->pstr_drc_dec,
2517 p_state_enhaacplus_dec->audio_object_type,
2518 p_state_enhaacplus_dec->ch_config,
2519 p_state_enhaacplus_dec->eld_specific_config,
2520 p_state_enhaacplus_dec->s_adts_hdr_present,
2521 &p_state_enhaacplus_dec->drc_dummy);
2522
2523 if (p_state_enhaacplus_dec->audio_object_type < ER_OBJECT_START ||
2524 (p_state_enhaacplus_dec->audio_object_type != AOT_ER_AAC_LD &&
2525 p_state_enhaacplus_dec->audio_object_type != AOT_ER_AAC_ELD)) {
2526 if ((error_code == 0) && ((ch_idx1 + 1) == total_elements) &&
2527 (type != ID_END)) {
2528 {
2529 p_state_enhaacplus_dec->i_bytes_consumed =
2530 it_bit_buff->ptr_read_next - it_bit_buff->ptr_bit_buf_base;
2531 p_state_enhaacplus_dec->b_n_raw_data_blk = 0;
2532 return IA_ENHAACPLUS_DEC_EXE_NONFATAL_ELE_INSTANCE_TAG_NOT_FOUND;
2533 }
2534 }
2535 }
2536
2537 num_ch = p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->channels;
2538 if (skip_full_decode == 0) {
2539 if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD ||
2540 p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD)
2541 frame_size = p_state_enhaacplus_dec->frame_length;
2542 else
2543 frame_size = 1024;
2544
2545 sample_rate_dec =
2546 p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->sampling_rate;
2547 }
2548 }
2549
2550 if (skip_full_decode == 1) {
2551 p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx][0].no_elements = 0;
2552 }
2553
2554 if (p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx][0].no_elements != 0) {
2555 p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 1;
2556 }
2557
2558 if (error_code) {
2559 if (p_state_enhaacplus_dec->ui_input_over) {
2560 return IA_ENHAACPLUS_DEC_INIT_FATAL_EO_INPUT_REACHED;
2561 }
2562 ixheaacd_updatebytesconsumed(p_state_enhaacplus_dec, it_bit_buff);
2563 p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes +=
2564 p_state_enhaacplus_dec->num_of_out_samples * num_ch * sizeof(WORD16);
2565 return error_code;
2566 }
2567
2568 error_code = IA_NO_ERROR;
2569
2570 if (p_obj_exhaacplus_dec->aac_config.ui_auto_sbr_upsample == 0) {
2571 if (p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx][0].no_elements == 0 &&
2572 p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) {
2573 p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = 0;
2574 error_code = IA_ENHAACPLUS_DEC_EXE_NONFATAL_SBR_TURNED_OFF;
2575 }
2576 }
2577 if ((!p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) &&
2578 p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx][0].no_elements) {
2579 error_code = IA_ENHAACPLUS_DEC_EXE_NONFATAL_SBR_TURNED_ON;
2580
2581 p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = ixheaacd_init_sbr(
2582 sample_rate_dec, frame_size,
2583 (FLAG *)&p_obj_exhaacplus_dec->aac_config.down_sample_flag,
2584 p_state_enhaacplus_dec->sbr_persistent_mem_v,
2585 p_state_enhaacplus_dec->ptr_overlap_buf, ps_enable ? 2 : channel,
2586 ps_enable, 1, frame_size * 2, NULL, NULL,
2587 p_state_enhaacplus_dec->str_sbr_config,
2588 p_state_enhaacplus_dec->audio_object_type);
2589 if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) {
2590 p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->xaac_jmp_buf =
2591 &(p_state_enhaacplus_dec->xaac_jmp_buf);
2592 }
2593 }
2594
2595 {
2596 if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] &&
2597 p_state_enhaacplus_dec->pstr_stream_sbr[0][0].no_elements) {
2598 ia_sbr_scr_struct sbr_scratch_struct;
2599 ixheaacd_allocate_sbr_scr(&sbr_scratch_struct,
2600 p_state_enhaacplus_dec->aac_scratch_mem_v,
2601 time_data, total_elements, ch_fac,
2602 p_state_enhaacplus_dec->audio_object_type);
2603
2604 if (ixheaacd_applysbr(
2605 p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx],
2606 &p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx][0],
2607 actual_out_buffer, &num_ch,
2608 p_obj_exhaacplus_dec->aac_config.frame_status,
2609 p_obj_exhaacplus_dec->aac_config.down_sample_flag,
2610 esbr_mono_downmix, &sbr_scratch_struct, ps_enable, ch_fac,
2611 slot_ele, NULL, &p_state_enhaacplus_dec->str_drc_dec_info,
2612 p_state_enhaacplus_dec->eld_specific_config.ld_sbr_flag_present,
2613 p_state_enhaacplus_dec->audio_object_type) != SBRDEC_OK) {
2614 p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = 0;
2615 return -1;
2616 } else {
2617 if (!p_obj_exhaacplus_dec->aac_config.down_sample_flag) {
2618 frame_size = (WORD16)(frame_size * 2);
2619 sample_rate_dec *= 2;
2620 }
2621 }
2622 }
2623 }
2624 if (sample_rate < sample_rate_dec) {
2625 sample_rate = sample_rate_dec;
2626 }
2627
2628 p_obj_exhaacplus_dec->aac_config.ui_samp_freq = sample_rate;
2629 num_of_out_samples = frame_size;
2630
2631 p_state_enhaacplus_dec->num_channel_last = num_ch;
2632 p_state_enhaacplus_dec->num_of_out_samples = num_of_out_samples;
2633
2634 if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] != 2)
2635
2636 {
2637 if (p_obj_exhaacplus_dec->aac_config.flag_to_stereo == 1 &&
2638 channel == 1 && total_elements == 1 && num_ch == 1) {
2639 WORD i;
2640 num_ch = 2;
2641
2642 for (i = 0; i < frame_size; i++) {
2643 actual_out_buffer[2 * i + 1] = actual_out_buffer[2 * i + 0];
2644 }
2645 }
2646
2647 p_obj_exhaacplus_dec->aac_config.ui_n_channels = num_ch;
2648
2649 p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes +=
2650 p_state_enhaacplus_dec->num_of_out_samples * num_ch * sizeof(WORD16);
2651
2652 }
2653
2654 else {
2655 channel_coupling_flag = 1;
2656 }
2657 }
2658
2659 {
2660 ia_adts_crc_info_struct *ptr_adts_crc_info =
2661 p_state_enhaacplus_dec->ptr_bit_stream->pstr_adts_crc_info;
2662 if (ptr_adts_crc_info->crc_active == 1) {
2663 if ((error_code = ixheaacd_adts_crc_check_crc(ptr_adts_crc_info))) {
2664 return error_code;
2665 }
2666 }
2667 }
2668
2669 p_obj_exhaacplus_dec->aac_config.ui_n_channels = total_channels;
2670
2671 p_state_enhaacplus_dec->frame_counter++;
2672
2673 if (channel_coupling_flag) {
2674 ixheaacd_dec_ind_coupling(p_obj_exhaacplus_dec,
2675 p_state_enhaacplus_dec->coup_ch_output,
2676 num_of_out_samples, total_channels, time_data);
2677 }
2678
2679 if ((total_channels > 2) && (1 == p_obj_exhaacplus_dec->aac_config.downmix)) {
2680 ixheaacd_dec_downmix_to_stereo(p_obj_exhaacplus_dec, num_of_out_samples,
2681 total_elements, time_data, total_channels);
2682
2683 total_channels = 2;
2684 p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes =
2685 p_state_enhaacplus_dec->num_of_out_samples * 2 * sizeof(WORD16);
2686 }
2687
2688 if (p_obj_exhaacplus_dec->aac_config.flag_downmix && total_channels == 2) {
2689 WORD32 out_ch = 1;
2690 WORD i;
2691 if (p_obj_exhaacplus_dec->aac_config.flag_to_stereo == 1) {
2692 out_ch = 2;
2693 }
2694
2695 p_obj_exhaacplus_dec->aac_config.ui_n_channels = out_ch;
2696 p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes =
2697 p_state_enhaacplus_dec->num_of_out_samples * out_ch * sizeof(WORD16);
2698
2699 for (i = 0; i < num_of_out_samples; i++) {
2700 WORD16 temp;
2701
2702 temp = (time_data[2 * i + 0] >> 1) + (time_data[2 * i + 1] >> 1);
2703
2704 if (out_ch == 2) {
2705 time_data[2 * i + 0] = temp;
2706 time_data[2 * i + 1] = time_data[2 * i + 0];
2707 } else {
2708 time_data[i] = temp;
2709 }
2710 }
2711 }
2712
2713 if (p_state_enhaacplus_dec->s_adts_hdr_present) {
2714 if (adts.no_raw_data_blocks != 0) {
2715 if (adts.protection_absent == 0) {
2716 adts.crc_check = ixheaacd_read_bits_buf(it_bit_buff, 16);
2717 }
2718 }
2719 p_state_enhaacplus_dec->b_n_raw_data_blk--;
2720 }
2721
2722 ixheaacd_updatebytesconsumed(p_state_enhaacplus_dec, it_bit_buff);
2723
2724 if (p_state_enhaacplus_dec->bs_format == LOAS_BSFORMAT)
2725 p_state_enhaacplus_dec->i_bytes_consumed =
2726 (audio_mux_length_bytes_last + (SIZE_T)bytes_for_sync);
2727
2728 return error_code;
2729 }
2730