xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_api.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
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 "ixheaac_type_def.h"
25 #include "ixheaacd_memory_standards.h"
26 #include "ixheaacd_mps_struct_def.h"
27 #include "ixheaacd_mps_res_rom.h"
28 #include "ixheaacd_mps_aac_struct.h"
29 #include "ixheaac_constants.h"
30 #include "ixheaac_basic_ops32.h"
31 #include "ixheaac_basic_ops16.h"
32 #include "ixheaac_basic_ops40.h"
33 #include "ixheaac_basic_ops.h"
34 
35 #include "ixheaac_error_standards.h"
36 #include "ixheaacd_apicmd_standards.h"
37 #include "ixheaacd_aac_config.h"
38 #include "ixheaacd_api_defs.h"
39 
40 #include "ixheaacd_definitions.h"
41 #include "ixheaacd_error_codes.h"
42 #include "ixheaacd_bitbuffer.h"
43 
44 #include "ixheaacd_audioobjtypes.h"
45 #include "ixheaacd_sbrdecsettings.h"
46 #include "ixheaacd_memory_standards.h"
47 
48 #include "ixheaacd_bitbuffer.h"
49 #include "ixheaacd_adts.h"
50 #include "ixheaacd_defines.h"
51 #include "ixheaacd_cnst.h"
52 #include "ixheaacd_aac_rom.h"
53 #include "ixheaacd_ec_defines.h"
54 #include "ixheaacd_ec_struct_def.h"
55 
56 #include "ixheaacd_sbr_scale.h"
57 #include "ixheaacd_lpp_tran.h"
58 #include "ixheaacd_env_extr_part.h"
59 #include "ixheaacd_sbr_rom.h"
60 
61 #include "ixheaacd_hybrid.h"
62 #include "ixheaacd_ps_dec.h"
63 #include "ixheaacd_ps_bitdec.h"
64 
65 #include "ixheaacd_pulsedata.h"
66 
67 #include "ixheaacd_pns.h"
68 #include "ixheaacd_drc_data_struct.h"
69 
70 #include "ixheaacd_lt_predict.h"
71 
72 #include "ixheaacd_channelinfo.h"
73 #include "ixheaacd_drc_dec.h"
74 #include "ixheaac_sbr_const.h"
75 #include "ixheaacd_sbrdecoder.h"
76 #include "ixheaacd_env_extr.h"
77 #include "ixheaacd_common_rom.h"
78 #include "ixheaacd_freq_sca.h"
79 #include "ixheaacd_qmf_dec.h"
80 #include "ixheaacd_env_calc.h"
81 
82 #include "ixheaacd_pvc_dec.h"
83 #include "ixheaacd_sbr_dec.h"
84 #include "ixheaacd_block.h"
85 #include "ixheaacd_channel.h"
86 
87 #include "ixheaacd_audioobjtypes.h"
88 #include "ixheaacd_latmdemux.h"
89 
90 #include "ixheaacd_aacdec.h"
91 #include "ixheaacd_mps_polyphase.h"
92 #include "ixheaacd_config.h"
93 #include "ixheaacd_mps_dec.h"
94 #include "ixheaacd_struct_def.h"
95 #include "ixheaacd_headerdecode.h"
96 #include "ixheaacd_adts_crc_check.h"
97 
98 #include "ixheaacd_multichannel.h"
99 #include "ixheaacd_ver_number.h"
100 
101 #include "ixheaacd_interface.h"
102 #include "ixheaacd_info.h"
103 
104 #include "ixheaacd_config.h"
105 
106 #include "ixheaacd_struct.h"
107 #include "ixheaacd_mps_polyphase.h"
108 #include "ixheaacd_tns_usac.h"
109 #include "ixheaacd_acelp_info.h"
110 
111 #include "ixheaacd_main.h"
112 #include "ixheaacd_arith_dec.h"
113 #include "ixheaacd_create.h"
114 #include "ixheaacd_function_selector.h"
115 #include "ixheaacd_ld_mps_dec.h"
116 #include "ixheaacd_mps_tables.h"
117 #define MAX_TRACKS_PER_LAYER 50
118 
119 #define ALIGN_SIZE64(x) ((((x) + 7) >> 3) << 3)
120 
121 #define IA_ENHAACPDEC_NUM_MEMTABS (4)
122 
123 #define NUM_AAC_TABLES 8
124 
125 #define LD_OBJ -2
126 
127 #define SCR_BASE_SCR_8K_SIZE \
128   (IXHEAAC_GET_SIZE_ALIGNED((2 * CHANNELS * MAX_BINS_LONG * sizeof(WORD32)), BYTE_ALIGN_8))
129 #define SCR_EXTRA_SCR_4K_0_SIZE                                                           \
130   (2 * IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_channel_info_struct), sizeof(WORD32)) + \
131    2 * IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_sfb_code_book_struct), sizeof(WORD32)) +    \
132    IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_pns_stereo_data_struct), sizeof(WORD32)))
133 #define SCR_EXTRA_SCR_4K_2_SIZE \
134   (IXHEAAC_GET_SIZE_ALIGNED((IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME * sizeof(WORD32)), BYTE_ALIGN_8))
135 #define SCR_EXTRA_SCR_4K_3_SIZE \
136   (IXHEAAC_GET_SIZE_ALIGNED((IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME * sizeof(WORD32)), BYTE_ALIGN_8))
137 #define SCR_OUT_DATA_SIZE \
138   (IXHEAAC_GET_SIZE_ALIGNED((IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME * sizeof(WORD32)), BYTE_ALIGN_8))
139 #define SCR_IN_DATA_SIZE                                                                \
140   (2 * IXHEAAC_GET_SIZE_ALIGNED((IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME * sizeof(WORD32)), \
141                                 BYTE_ALIGN_8))
142 #define SCR_INTER_SCR_SIZE                                                          \
143   (MAX_CHANNEL_COUNT *                                                              \
144    IXHEAAC_GET_SIZE_ALIGNED((IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME * sizeof(WORD16)), \
145                             BYTE_ALIGN_8))
146 #define SCR_COUP_CH_OUT_SIZE                                                        \
147   (MAX_CHANNEL_COUNT *                                                              \
148    IXHEAAC_GET_SIZE_ALIGNED((IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME * sizeof(WORD16)), \
149                             BYTE_ALIGN_8))
150 
151 #define P_IND_CH_INFO_OFFSET \
152   (SCR_BASE_SCR_8K_SIZE + SCR_EXTRA_SCR_4K_0_SIZE + SCR_EXTRA_SCR_4K_2_SIZE)
153 
154 #define HEAACV2_MAX_SIZE                                                          \
155   (max(SCR_BASE_SCR_8K_SIZE + SCR_EXTRA_SCR_4K_0_SIZE + SCR_EXTRA_SCR_4K_2_SIZE + \
156            SCR_INTER_SCR_SIZE + SCR_COUP_CH_OUT_SIZE,                             \
157        MPS_SCRATCH_MEM_SIZE))
158 #define ELDV2_MAX_SIZE                                                            \
159   (max(SCR_BASE_SCR_8K_SIZE + SCR_EXTRA_SCR_4K_0_SIZE + SCR_EXTRA_SCR_4K_2_SIZE + \
160            SCR_EXTRA_SCR_4K_3_SIZE + SCR_INTER_SCR_SIZE + SCR_COUP_CH_OUT_SIZE,   \
161        MPS_SCRATCH_MEM_SIZE))
162 #define LD_MAX_SIZE                                                                          \
163   (max(SCR_BASE_SCR_8K_SIZE + SCR_EXTRA_SCR_4K_0_SIZE + SCR_EXTRA_SCR_4K_2_SIZE +            \
164            SCR_OUT_DATA_SIZE + SCR_IN_DATA_SIZE + SCR_INTER_SCR_SIZE + SCR_COUP_CH_OUT_SIZE, \
165        MPS_SCRATCH_MEM_SIZE))
166 
167 #define MAX_SCR_SIZE (max(max(HEAACV2_MAX_SIZE, ELDV2_MAX_SIZE), LD_MAX_SIZE))
168 
ixheaacd_dec_mem_api(ia_exhaacplus_dec_api_struct * p_obj_exhaacplus_dec,WORD32 i_cmd,WORD32 i_idx,VOID * pv_value)169 IA_ERRORCODE ixheaacd_dec_mem_api(ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec,
170                                   WORD32 i_cmd, WORD32 i_idx, VOID *pv_value) {
171   pUWORD32 pui_value = pv_value;
172 
173   if (i_idx < 0 || i_idx >= IA_ENHAACPDEC_NUM_MEMTABS) {
174     return IA_XHEAAC_DEC_API_FATAL_INVALID_MEMTAB_INDEX;
175   }
176 
177   if (i_cmd == IA_API_CMD_SET_MEM_PTR) {
178     if (pv_value == 0) {
179       return (IA_XHEAAC_DEC_API_FATAL_MEM_ALLOC);
180     }
181     if (((SIZE_T)pv_value %
182          p_obj_exhaacplus_dec->p_mem_info_aac[i_idx].ui_alignment) != 0) {
183       return (IA_XHEAAC_DEC_API_FATAL_MEM_ALIGN);
184     }
185     p_obj_exhaacplus_dec->pp_mem_aac[i_idx] = pv_value;
186     memset(p_obj_exhaacplus_dec->pp_mem_aac[i_idx], 0,
187            p_obj_exhaacplus_dec->p_mem_info_aac[i_idx].ui_size);
188 
189     if (i_idx == IA_ENHAACPLUS_DEC_PERSIST_IDX) {
190       pUWORD8 p_temp = pv_value;
191       UWORD32 *meminfo =
192           (UWORD32 *)p_obj_exhaacplus_dec->p_mem_info_aac + i_idx;
193       UWORD32 pers_size = meminfo[0];
194       p_temp = p_temp + pers_size -
195                (IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_dec_data_struct), BYTE_ALIGN_8) +
196                 IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_audio_specific_config_struct), BYTE_ALIGN_8) +
197                 IXHEAAC_GET_SIZE_ALIGNED(MAX_HEADER_BUF_SIZE, BYTE_ALIGN_8));
198       p_obj_exhaacplus_dec->p_state_aac = pv_value;
199       memset(p_obj_exhaacplus_dec->p_state_aac, 0,
200              IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_state_struct), BYTE_ALIGN_8));
201       p_obj_exhaacplus_dec->p_state_aac->pstr_dec_data = p_temp;
202       p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config =
203           p_temp + IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_dec_data_struct), BYTE_ALIGN_8);
204       p_obj_exhaacplus_dec->p_state_aac->header_ptr =
205           p_temp + IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_dec_data_struct), BYTE_ALIGN_8) +
206           IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_audio_specific_config_struct), BYTE_ALIGN_8);
207     }
208 
209   } else {
210     UWORD32 *meminfo =
211         (UWORD32 *)(p_obj_exhaacplus_dec->p_mem_info_aac + i_idx);
212     *pui_value = *(meminfo + (i_cmd - IA_API_CMD_GET_MEM_INFO_SIZE));
213   }
214 
215   return IA_NO_ERROR;
216 }
217 
218 static PLATFORM_INLINE VOID
ixheaacd_init_sbr_tables(ia_sbr_tables_struct * ptr_sbr_tables)219 ixheaacd_init_sbr_tables(ia_sbr_tables_struct *ptr_sbr_tables) {
220   ptr_sbr_tables->env_calc_tables_ptr =
221       (ia_env_calc_tables_struct *)&ixheaacd_aac_dec_env_calc_tables;
222   ptr_sbr_tables->qmf_dec_tables_ptr =
223       (ia_qmf_dec_tables_struct *)&ixheaacd_aac_qmf_dec_tables;
224   ptr_sbr_tables->env_extr_tables_ptr =
225       (ia_env_extr_tables_struct *)&ixheaacd_aac_dec_env_extr_tables;
226   ptr_sbr_tables->ps_tables_ptr =
227       (ia_ps_tables_struct *)&ixheaacd_aac_dec_ps_tables;
228 }
229 
ixheaacd_updatebytesconsumed(ia_aac_dec_state_struct * p_state_enhaacplus_dec,struct ia_bit_buf_struct * it_bit_buff)230 VOID ixheaacd_updatebytesconsumed(
231     ia_aac_dec_state_struct *p_state_enhaacplus_dec,
232     struct ia_bit_buf_struct *it_bit_buff) {
233   p_state_enhaacplus_dec->i_bytes_consumed =
234       (WORD32)(it_bit_buff->ptr_read_next - it_bit_buff->ptr_bit_buf_base);
235   if ((p_state_enhaacplus_dec->i_bytes_consumed == 0) &&
236       (it_bit_buff->cnt_bits == 0)) {
237     p_state_enhaacplus_dec->i_bytes_consumed =
238         p_state_enhaacplus_dec->ui_in_bytes;
239   }
240   if (it_bit_buff->cnt_bits < 0) {
241     p_state_enhaacplus_dec->i_bytes_consumed = 0;
242     p_state_enhaacplus_dec->ui_out_bytes = 0;
243     p_state_enhaacplus_dec->ui_mps_out_bytes = 0;
244     p_state_enhaacplus_dec->b_n_raw_data_blk = 0;
245   }
246 }
247 
copy_qmf_to_ldmps(ia_mps_dec_state_struct * mps_dec_handle,VOID * sbr_persistent_mem_v)248 static VOID copy_qmf_to_ldmps(ia_mps_dec_state_struct *mps_dec_handle,
249                               VOID *sbr_persistent_mem_v) {
250   ia_sbr_pers_struct *sbr_persistent_mem =
251       (ia_sbr_pers_struct *)sbr_persistent_mem_v;
252   memcpy(&mps_dec_handle->str_mps_qmf_bank,
253          &sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_channel[0]
254               ->str_sbr_dec.str_codec_qmf_bank,
255          sizeof(ia_sbr_qmf_filter_bank_struct));
256 
257   mps_dec_handle->sbr_tables_ptr =
258       sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_tables;
259   mps_dec_handle->qmf_dec_tables_ptr =
260       sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_tables->qmf_dec_tables_ptr;
261   mps_dec_handle->str_sbr_scale_fact =
262       &sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_channel[0]
263            ->str_sbr_dec.str_sbr_scale_fact;
264 }
265 
ixheaacd_readifadts(ia_aac_dec_state_struct * p_state_enhaacplus_dec,struct ia_bit_buf_struct * it_bit_buff,ia_adts_header_struct * adts)266 WORD32 ixheaacd_readifadts(ia_aac_dec_state_struct *p_state_enhaacplus_dec,
267                            struct ia_bit_buf_struct *it_bit_buff,
268                            ia_adts_header_struct *adts) {
269   WORD error;
270 
271   if ((error = ixheaacd_find_syncword(adts, it_bit_buff)) != 0) {
272     ixheaacd_updatebytesconsumed(p_state_enhaacplus_dec, it_bit_buff);
273     return IA_XHEAAC_DEC_EXE_NONFATAL_ADTS_SYNC_LOST;
274   }
275   if ((error = ixheaacd_check_if_adts(
276            adts, it_bit_buff,
277            p_state_enhaacplus_dec->p_config->ui_max_channels)) != 0) {
278     p_state_enhaacplus_dec->i_bytes_consumed = 1;
279 
280     if (it_bit_buff->cnt_bits < 0) {
281       p_state_enhaacplus_dec->i_bytes_consumed = 0;
282       p_state_enhaacplus_dec->ui_out_bytes = 0;
283       p_state_enhaacplus_dec->ui_mps_out_bytes = 0;
284       error = IA_XHEAAC_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES;
285       return error;
286     }
287     return IA_XHEAAC_DEC_EXE_NONFATAL_ADTS_SYNC_LOST;
288   }
289   p_state_enhaacplus_dec->b_n_raw_data_blk =
290       (WORD8)(adts->no_raw_data_blocks + 1);
291   return 0;
292 }
293 
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)294 static VOID ixheaacd_allocate_aac_scr(
295     ia_aac_dec_scratch_struct *aac_scratch_struct, VOID *base_scratch_ptr,
296     VOID *output_ptr, WORD channel, WORD max_channel,
297     WORD32 audio_object_type) {
298   WORD32 scratch_used = 0;
299   aac_scratch_struct->base_scr_8k = base_scratch_ptr;
300   aac_scratch_struct->extra_scr_4k[1] = (WORD8 *)base_scratch_ptr;
301   scratch_used += SCR_BASE_SCR_8K_SIZE;
302   if (channel == 1) {
303     aac_scratch_struct->extra_scr_4k[0] = (WORD8 *)base_scratch_ptr + scratch_used;
304     scratch_used += SCR_EXTRA_SCR_4K_0_SIZE;
305     aac_scratch_struct->extra_scr_4k[2] = (WORD8 *)base_scratch_ptr + scratch_used;
306     scratch_used += SCR_EXTRA_SCR_4K_2_SIZE;
307   } else {
308     aac_scratch_struct->extra_scr_4k[0] = output_ptr;
309 
310     if (max_channel > 2) {
311       aac_scratch_struct->extra_scr_4k[0] = (WORD8 *)base_scratch_ptr + scratch_used;
312       scratch_used += SCR_EXTRA_SCR_4K_0_SIZE;
313     }
314     aac_scratch_struct->extra_scr_4k[2] = (WORD8 *)base_scratch_ptr + scratch_used;
315     scratch_used += SCR_EXTRA_SCR_4K_2_SIZE;
316   }
317 
318   if (audio_object_type == AOT_ER_AAC_ELD || audio_object_type == AOT_ER_AAC_LD) {
319     aac_scratch_struct->extra_scr_4k[0] = (WORD8 *)base_scratch_ptr + scratch_used;
320     scratch_used += SCR_EXTRA_SCR_4K_0_SIZE;
321 
322     aac_scratch_struct->extra_scr_4k[2] = (WORD8 *)base_scratch_ptr + scratch_used;
323     scratch_used += SCR_EXTRA_SCR_4K_2_SIZE;
324 
325     aac_scratch_struct->extra_scr_4k[3] = (WORD8 *)base_scratch_ptr + scratch_used;
326     scratch_used += SCR_EXTRA_SCR_4K_3_SIZE;
327   }
328   if ((audio_object_type == AOT_ER_AAC_LD) || (audio_object_type == AOT_AAC_LTP)) {
329     aac_scratch_struct->out_data = (WORD32 *)((WORD8 *)base_scratch_ptr + scratch_used);
330     scratch_used += SCR_OUT_DATA_SIZE;
331 
332     aac_scratch_struct->in_data = (WORD32 *)((WORD8 *)base_scratch_ptr + scratch_used);
333     scratch_used += SCR_IN_DATA_SIZE;
334   }
335 }
336 
ixheaacd_allocate_sbr_scr(ia_sbr_scr_struct * sbr_scratch_struct,VOID * base_scratch_ptr,VOID * output_ptr,WORD32 total_channels,WORD8 * p_qshift_arr,UWORD8 slot_pos,UWORD8 num_ch)337 VOID ixheaacd_allocate_sbr_scr(ia_sbr_scr_struct *sbr_scratch_struct, VOID *base_scratch_ptr,
338                                VOID *output_ptr, WORD32 total_channels, WORD8 *p_qshift_arr,
339                                UWORD8 slot_pos, UWORD8 num_ch) {
340   WORD32 j, i;
341   sbr_scratch_struct->ptr_work_buf_core = base_scratch_ptr;
342 
343   if (p_qshift_arr != NULL && *p_qshift_arr != LD_OBJ) {
344     WORD32 *tmp_buf = (WORD32 *)output_ptr;
345 
346     for (j = 1; j < num_ch; j++) {
347       if ((*p_qshift_arr + j) == 0)
348         *(p_qshift_arr + j) = *(p_qshift_arr + j - 1);
349     }
350 
351     if (total_channels > 2) {
352       for (j = 0; j < num_ch; j++) {
353         for (i = 0; i < 1024; i++) {
354           *((WORD16 *)tmp_buf + slot_pos + total_channels * i + j) =
355               ixheaac_round16(ixheaac_shl32_sat(
356                   *(tmp_buf + slot_pos + total_channels * i + j),
357                   *(p_qshift_arr + j)));
358         }
359       }
360     } else {
361       for (j = 0; j < num_ch; j++) {
362         for (i = 0; i < 1024; i++) {
363           *((WORD16 *)tmp_buf + total_channels * i + j) =
364               ixheaac_round16(ixheaac_shl32_sat(
365                   *(tmp_buf + total_channels * i + j), *(p_qshift_arr + j)));
366         }
367       }
368     }
369   }
370 }
371 
ixheaacd_get_lib_id_strings(pVOID pv_output)372 VOID ixheaacd_get_lib_id_strings(pVOID pv_output) {
373   ia_lib_info_struct *pstr_lib_info = (ia_lib_info_struct *)pv_output;
374 
375   pstr_lib_info->p_lib_name = (WORD8 *)LIBNAME;
376   pstr_lib_info->p_version_num = (WORD8 *)xHE_AAC_DEC_ITTIAM_VER;
377 
378   return;
379 }
380 
ixheaacd_dec_api(pVOID p_ia_xheaac_dec_obj,WORD32 i_cmd,WORD32 i_idx,pVOID pv_value)381 IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_xheaac_dec_obj, WORD32 i_cmd,
382                               WORD32 i_idx, pVOID pv_value) {
383   ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec = p_ia_xheaac_dec_obj;
384   pUWORD32 pui_value = pv_value;
385   pWORD32 pui_value_signed = pv_value;
386   pWORD8 pb_value = pv_value;
387   pVOID *pp_value = (pVOID *)pv_value;
388   float *pf_value = pv_value;
389 
390   if ((i_cmd != IA_API_CMD_GET_API_SIZE) &&
391       (i_cmd != IA_API_CMD_GET_LIB_ID_STRINGS)) {
392     if (p_ia_xheaac_dec_obj == 0) {
393       return (IA_XHEAAC_DEC_API_FATAL_MEM_ALLOC);
394     }
395     if (((SIZE_T)p_ia_xheaac_dec_obj & 3) != 0) {
396       return (IA_XHEAAC_DEC_API_FATAL_MEM_ALIGN);
397     }
398   }
399 
400   switch (i_cmd) {
401     case IA_API_CMD_GET_MEM_INFO_SIZE:
402     case IA_API_CMD_GET_MEM_INFO_ALIGNMENT:
403     case IA_API_CMD_GET_MEM_INFO_TYPE:
404     case IA_API_CMD_SET_MEM_PTR: {
405       return ixheaacd_dec_mem_api(p_ia_xheaac_dec_obj, i_cmd, i_idx,
406                                   pv_value);
407     }
408 
409     case IA_API_CMD_GET_TABLE_INFO_SIZE:
410     case IA_API_CMD_GET_TABLE_INFO_ALIGNMENT:
411     case IA_API_CMD_SET_TABLE_PTR:
412     case IA_API_CMD_GET_TABLE_PTR: {
413       return ixheaacd_dec_table_api(p_ia_xheaac_dec_obj, i_cmd, i_idx,
414                                     pv_value);
415     }
416   };
417 
418   switch (i_cmd) {
419     case IA_API_CMD_GET_LIB_ID_STRINGS: {
420       WORD8 *i1_ver;
421       WORD8 ver_char;
422 
423       if (i_idx == IA_CMD_TYPE_LIB_NAME)
424         i1_ver = (WORD8 *)LIBNAME;
425       else if (i_idx == IA_CMD_TYPE_LIB_VERSION)
426         i1_ver = (WORD8 *)xHE_AAC_DEC_ITTIAM_VER;
427       else
428         return IA_XHEAAC_DEC_API_FATAL_INVALID_LIB_ID_STRINGS_IDX;
429 
430       ver_char = *i1_ver++;
431 
432       for (; ver_char != '\0';) {
433         if (ver_char != '$') {
434           *pb_value++ = ver_char;
435         }
436         ver_char = *i1_ver++;
437       }
438       *pb_value = ver_char;
439 
440       break;
441     }
442     case IA_API_CMD_GET_API_SIZE: {
443       *pui_value = sizeof(ia_exhaacplus_dec_api_struct);
444       break;
445     }
446     case IA_API_CMD_INIT: {
447       switch (i_idx) {
448         case IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS: {
449           memset(p_obj_exhaacplus_dec, 0, sizeof(*p_obj_exhaacplus_dec));
450           p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz = 16;
451           p_obj_exhaacplus_dec->aac_config.flag_downmix = 0;
452           p_obj_exhaacplus_dec->aac_config.flag_08khz_out = 0;
453           p_obj_exhaacplus_dec->aac_config.flag_16khz_out = 0;
454           p_obj_exhaacplus_dec->aac_config.flag_to_stereo = 0;
455           p_obj_exhaacplus_dec->aac_config.down_sample_flag = 0;
456           p_obj_exhaacplus_dec->aac_config.header_dec_done = 0;
457           p_obj_exhaacplus_dec->aac_config.frame_status = 1;
458           p_obj_exhaacplus_dec->aac_config.ui_mp4_flag = 0;
459           p_obj_exhaacplus_dec->aac_config.ui_disable_sync = 0;
460           p_obj_exhaacplus_dec->aac_config.ui_auto_sbr_upsample = 1;
461           p_obj_exhaacplus_dec->aac_config.ui_samp_freq = 0;
462           p_obj_exhaacplus_dec->aac_config.ui_frame_size = 0;
463 
464           p_obj_exhaacplus_dec->aac_config.ui_n_channels = 2;
465           p_obj_exhaacplus_dec->aac_config.i_channel_mask = 3;
466           p_obj_exhaacplus_dec->aac_config.ui_channel_mode = 3;
467           p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 0;
468           p_obj_exhaacplus_dec->aac_config.ui_effect_type = 0;
469           p_obj_exhaacplus_dec->aac_config.ui_target_loudness = -24;
470           p_obj_exhaacplus_dec->aac_config.ui_loud_norm_flag = 0;
471           p_obj_exhaacplus_dec->aac_config.ui_hq_esbr = 0;
472           p_obj_exhaacplus_dec->aac_config.ui_enh_sbr = 1;
473           p_obj_exhaacplus_dec->aac_config.ui_enh_sbr_ps = 0;
474           p_obj_exhaacplus_dec->aac_config.ui_pce_found_in_hdr = 0;
475           p_obj_exhaacplus_dec->aac_config.loas_present = 0;
476           p_obj_exhaacplus_dec->aac_config.ld_decoder = 0;
477           p_obj_exhaacplus_dec->aac_config.ui_drc_boost = 0;
478           p_obj_exhaacplus_dec->aac_config.ui_drc_cut = 0;
479           p_obj_exhaacplus_dec->aac_config.ui_drc_target_level = 108;
480           p_obj_exhaacplus_dec->aac_config.ui_drc_set = 0;
481           p_obj_exhaacplus_dec->aac_config.ui_flush_cmd = 0;
482           p_obj_exhaacplus_dec->aac_config.output_level = -1;
483 
484           p_obj_exhaacplus_dec->aac_config.ui_max_channels = 6;
485 
486           p_obj_exhaacplus_dec->aac_config.ui_coupling_channel = 0;
487           p_obj_exhaacplus_dec->aac_config.downmix = 0;
488 
489           p_obj_exhaacplus_dec->aac_config.ui_err_conceal = 0;
490 
491           {
492             ia_aac_dec_tables_struct *pstr_aac_tables =
493                 &p_obj_exhaacplus_dec->aac_tables;
494             pstr_aac_tables->pstr_huffmann_tables =
495                 (ia_aac_dec_huffman_tables_struct
496                      *)&ixheaacd_aac_huffmann_tables;
497             pstr_aac_tables->pstr_block_tables =
498                 (ia_aac_dec_block_tables_struct *)&ixheaacd_aac_block_tables;
499             pstr_aac_tables->pstr_imdct_tables =
500                 (ia_aac_dec_imdct_tables_struct *)&ixheaacd_imdct_tables;
501 
502             ixheaacd_huff_tables_create(pstr_aac_tables);
503           }
504           ixheaacd_init_sbr_tables(&p_obj_exhaacplus_dec->str_sbr_tables);
505           p_obj_exhaacplus_dec->common_tables =
506               (ixheaacd_misc_tables *)&ixheaacd_str_fft_n_transcendent_tables;
507           p_obj_exhaacplus_dec->aac_config.ui_qmf_bands = 64;
508 
509           break;
510         }
511         case IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS: {
512           ixheaacd_fill_aac_mem_tables(p_obj_exhaacplus_dec);
513           break;
514         }
515         case IA_CMD_TYPE_INIT_PROCESS: {
516           WORD32 err_code = 0;
517           if (p_obj_exhaacplus_dec->p_state_aac->fatal_err_present) {
518             err_code = IA_FATAL_ERROR;
519           } else {
520             err_code = ixheaacd_dec_init(p_obj_exhaacplus_dec);
521             if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal && err_code) {
522               if (err_code & IA_FATAL_ERROR) {
523                 err_code = IA_XHEAAC_DEC_INIT_FATAL_EC_INIT_FAIL;
524               } else {
525                 err_code = IA_XHEAAC_DEC_INIT_NONFATAL_EC_INIT_FAIL;
526               }
527             }
528           }
529           if (err_code != 0) {
530             if (err_code < 0)
531               p_obj_exhaacplus_dec->p_state_aac->fatal_err_present = 1;
532             p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed =
533                 p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes;
534           }
535           return err_code;
536           break;
537         }
538         case IA_CMD_TYPE_INIT_DONE_QUERY: {
539           if (p_obj_exhaacplus_dec->p_state_aac->ui_init_done == 1) {
540             *pui_value = 1;
541           } else {
542             *pui_value = 0;
543           }
544           break;
545         }
546 
547         case IA_CMD_TYPE_GA_HDR: {
548           return ixheaacd_decoder_2_ga_hdr(p_obj_exhaacplus_dec);
549           break;
550         }
551 
552         case IA_CMD_TYPE_FLUSH_MEM: {
553           return ixheaacd_decoder_flush_api(p_obj_exhaacplus_dec);
554           break;
555         }
556 
557         default: {
558           return IA_XHEAAC_DEC_API_NONFATAL_CMD_TYPE_NOT_SUPPORTED;
559         }
560       };
561       break;
562     }
563     case IA_API_CMD_SET_CONFIG_PARAM: {
564       switch (i_idx) {
565         case IA_XHEAAC_DEC_CONFIG_PARAM_SAMP_FREQ: {
566           if ((*pui_value < 8000) || (*pui_value > 96000)) {
567             return (IA_XHEAAC_DEC_CONFIG_FATAL_INVALID_SAMPLE_RATE);
568           }
569           p_obj_exhaacplus_dec->aac_config.ui_samp_freq = *pui_value;
570           break;
571         }
572         case IA_XHEAAC_DEC_CONFIG_PARAM_FRAMELENGTH_FLAG: {
573           if ((*pui_value != 1) && (*pui_value != 0)) {
574             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_FRAMELENGTHFLAG);
575           }
576           p_obj_exhaacplus_dec->aac_config.ui_frame_size = *pui_value;
577           break;
578         }
579         case IA_XHEAAC_DEC_CONFIG_PARAM_PCM_WDSZ: {
580           if ((*pui_value != 16) && (*pui_value != 24)) {
581             p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz = 16;
582             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_PCM_WDSZ);
583           }
584           p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz = *pui_value;
585           break;
586         }
587         case IA_XHEAAC_DEC_CONFIG_PARAM_DOWNMIX: {
588           if ((*pui_value != 1) && (*pui_value != 0)) {
589             p_obj_exhaacplus_dec->aac_config.flag_downmix = 0;
590             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_DOWNMIX);
591           }
592           p_obj_exhaacplus_dec->aac_config.flag_downmix = *pui_value;
593           p_obj_exhaacplus_dec->aac_config.downmix = *pui_value;
594           break;
595         }
596 
597         case IA_XHEAAC_DEC_CONFIG_PARAM_TOSTEREO: {
598           if ((*pui_value != 1) && (*pui_value != 0)) {
599             p_obj_exhaacplus_dec->aac_config.flag_to_stereo = 1;
600             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_TOSTEREO);
601           }
602           p_obj_exhaacplus_dec->aac_config.flag_to_stereo = *pui_value;
603           break;
604         }
605         case IA_XHEAAC_DEC_CONFIG_PARAM_DSAMPLE: {
606           if ((*pui_value != 1) && (*pui_value != 0)) {
607             p_obj_exhaacplus_dec->aac_config.down_sample_flag = 0;
608             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_DSAMPLE);
609           }
610           p_obj_exhaacplus_dec->aac_config.down_sample_flag = *pui_value;
611           break;
612         }
613 
614         case IA_XHEAAC_DEC_CONFIG_PARAM_MP4FLAG: {
615           if ((*pui_value != 1) && (*pui_value != 0)) {
616             p_obj_exhaacplus_dec->aac_config.ui_mp4_flag = 0;
617             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_MP4FLAG);
618           }
619           p_obj_exhaacplus_dec->aac_config.ui_mp4_flag = *pui_value;
620           break;
621         }
622         case IA_XHEAAC_DEC_CONFIG_PARAM_DRC_CUT: {
623           p_obj_exhaacplus_dec->aac_config.ui_drc_set = 1;
624           if (*pf_value > 1) {
625             p_obj_exhaacplus_dec->aac_config.ui_drc_cut = 0;
626             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_DRC_CUT);
627           }
628           p_obj_exhaacplus_dec->aac_config.ui_drc_cut =
629               (WORD32)((*pf_value) * 100);
630           break;
631         }
632 
633         case IA_XHEAAC_DEC_CONFIG_PARAM_DRC_BOOST: {
634           p_obj_exhaacplus_dec->aac_config.ui_drc_set = 1;
635           if (*pf_value > 1) {
636             p_obj_exhaacplus_dec->aac_config.ui_drc_boost = 0;
637             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_DRC_BOOST);
638           }
639           p_obj_exhaacplus_dec->aac_config.ui_drc_boost =
640               (WORD32)((*pf_value) * 100);
641           break;
642         }
643 
644         case IA_XHEAAC_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL: {
645           p_obj_exhaacplus_dec->aac_config.ui_drc_set = 1;
646           p_obj_exhaacplus_dec->aac_config.i_loud_ref_level = *pui_value_signed;
647           if (*pui_value > 127) {
648             p_obj_exhaacplus_dec->aac_config.ui_drc_target_level = 108;
649             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_DRC_TARGET);
650           }
651           p_obj_exhaacplus_dec->aac_config.ui_drc_target_level = *pui_value;
652           break;
653         }
654         case IA_XHEAAC_DEC_CONFIG_PARAM_DRC_HEAVY_COMP: {
655           p_obj_exhaacplus_dec->aac_config.ui_drc_set = 1;
656           if ((*pui_value != 1) && (*pui_value != 0)) {
657             p_obj_exhaacplus_dec->aac_config.ui_drc_heavy_comp = 0;
658             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_DRCFLAG);
659           }
660           p_obj_exhaacplus_dec->aac_config.ui_drc_heavy_comp = *pui_value;
661           break;
662         }
663         case IA_XHEAAC_DEC_CONFIG_DISABLE_SYNC: {
664           if ((*pui_value != 1) && (*pui_value != 0)) {
665             p_obj_exhaacplus_dec->aac_config.ui_disable_sync = 0;
666             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_SYNCFLAG);
667           }
668           p_obj_exhaacplus_dec->aac_config.ui_disable_sync = *pui_value;
669           break;
670         }
671         case IA_XHEAAC_DEC_CONFIG_PARAM_AUTO_SBR_UPSAMPLE: {
672           if ((*pui_value != 1) && (*pui_value != 0)) {
673             p_obj_exhaacplus_dec->aac_config.ui_auto_sbr_upsample = 0;
674             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_SBRUPFLAG);
675           }
676           p_obj_exhaacplus_dec->aac_config.ui_auto_sbr_upsample = *pui_value;
677           break;
678         }
679         case IA_XHEAAC_DEC_CONFIG_PARAM_MAX_CHANNEL: {
680           if (*pui_value > 8) {
681             p_obj_exhaacplus_dec->aac_config.ui_max_channels = 8;
682             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_MAX_CHANNEL);
683           }
684           if (*pui_value < 2) {
685             p_obj_exhaacplus_dec->aac_config.ui_max_channels = 2;
686             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_MAX_CHANNEL);
687           }
688           p_obj_exhaacplus_dec->aac_config.ui_max_channels = *pui_value;
689           break;
690         }
691         case IA_XHEAAC_DEC_CONFIG_PARAM_FRAMESIZE: {
692           if (*pui_value == 1) {
693             p_obj_exhaacplus_dec->aac_config.framesize_480 = 1;
694           } else if (*pui_value == 0) {
695             p_obj_exhaacplus_dec->aac_config.framesize_480 = 0;
696           } else {
697             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_FRAMSZ);
698           }
699           break;
700         }
701 
702         case IA_XHEAAC_DEC_CONFIG_PARAM_LD_TESTING: {
703           if (*pui_value == 1) {
704             p_obj_exhaacplus_dec->aac_config.ld_decoder = 1;
705           } else if (*pui_value == 0) {
706             p_obj_exhaacplus_dec->aac_config.ld_decoder = 0;
707           } else {
708             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_LD_CONFIG);
709           }
710           break;
711         }
712 
713         case IA_XHEAAC_DEC_CONFIG_PARAM_COUP_CHANNEL: {
714           if (*pui_value > 16) {
715             p_obj_exhaacplus_dec->aac_config.ui_coupling_channel = 1;
716             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_COUP_CHANNEL);
717           }
718           p_obj_exhaacplus_dec->aac_config.ui_coupling_channel = *pui_value;
719           break;
720         }
721 
722         case IA_XHEAAC_DEC_CONFIG_PARAM_DOWNMIX_STEREO: {
723           if ((*pui_value != 1) && (*pui_value != 0)) {
724             p_obj_exhaacplus_dec->aac_config.downmix = 0;
725             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_DOWNMIX_STEREO);
726           }
727           p_obj_exhaacplus_dec->aac_config.downmix = *pui_value;
728           break;
729         }
730 
731         case IA_XHEAAC_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE: {
732           if (((*pui_value_signed) > 8) || ((*pui_value_signed) < -1)) {
733             p_obj_exhaacplus_dec->aac_config.ui_effect_type = -1;
734             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_EFFECT_TYPE);
735           }
736           p_obj_exhaacplus_dec->aac_config.ui_effect_type = *pui_value_signed;
737           break;
738         }
739         case IA_XHEAAC_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS: {
740           if (*pui_value_signed >= 0) {
741             p_obj_exhaacplus_dec->aac_config.ui_loud_norm_flag = 1;
742           }
743           *pui_value_signed = -(*pui_value_signed >> 2);
744           if (((*pui_value_signed) > 0) || ((*pui_value_signed) < -63)) {
745             p_obj_exhaacplus_dec->aac_config.ui_target_loudness = 0;
746             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_TARGET_LOUDNESS);
747           }
748           p_obj_exhaacplus_dec->aac_config.ui_target_loudness =
749               *pui_value_signed;
750           break;
751         }
752         case IA_XHEAAC_DEC_CONFIG_PARAM_HQ_ESBR: {
753           if (((*pui_value_signed) != 0) && ((*pui_value_signed) != 1)) {
754             p_obj_exhaacplus_dec->aac_config.ui_hq_esbr = 0;
755             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_ESBR_HQ_FLAG);
756           }
757           p_obj_exhaacplus_dec->aac_config.ui_hq_esbr = *pui_value_signed;
758           break;
759         }
760         case IA_XHEAAC_DEC_CONFIG_PARAM_PS_ENABLE: {
761           if (((*pui_value_signed) != 0) && ((*pui_value_signed) != 1)) {
762             p_obj_exhaacplus_dec->aac_config.ui_enh_sbr_ps = 0;
763             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_ESBR_PS_FLAG);
764           }
765           p_obj_exhaacplus_dec->aac_config.ui_enh_sbr_ps = *pui_value_signed;
766           break;
767         }
768         case IA_XHEAAC_DEC_CONFIG_PARAM_PEAK_LIMITER: {
769           if (((*pui_value_signed) != 0) && ((*pui_value_signed) != 1)) {
770             p_obj_exhaacplus_dec->aac_config.peak_limiter_off = 0;
771             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_PEAK_LIM_FLAG_TYPE);
772           }
773           p_obj_exhaacplus_dec->aac_config.peak_limiter_off = *pui_value_signed;
774           break;
775         }
776         case IA_XHEAAC_DEC_CONFIG_ERROR_CONCEALMENT: {
777           if (((*pui_value_signed) != 0) && ((*pui_value_signed) != 1)) {
778             p_obj_exhaacplus_dec->aac_config.ui_err_conceal = 0;
779             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_ERR_CONCEAL_FLAG_TYPE);
780           }
781           p_obj_exhaacplus_dec->aac_config.ui_err_conceal = *pui_value_signed;
782           break;
783         }
784         case IA_XHEAAC_DEC_CONFIG_PARAM_ESBR: {
785           if (((*pui_value_signed) != 0) && ((*pui_value_signed) != 1)) {
786             p_obj_exhaacplus_dec->aac_config.ui_enh_sbr = 1;
787             return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_ESBR_FLAG);
788           }
789           p_obj_exhaacplus_dec->aac_config.ui_enh_sbr = *pui_value_signed;
790           break;
791         }
792         default: { return IA_XHEAAC_DEC_API_FATAL_INVALID_CONFIG_PARAM; }
793       }
794       break;
795     }
796 
797     case IA_API_CMD_GET_CONFIG_PARAM: {
798       UWORD32 i;
799       WORD32 *pvalue =
800           (WORD32 *)(&p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz);
801       if (IA_XHEAAC_DEC_CONFIG_PARAM_NUM_CHANNELS == i_idx) {
802         if (p_obj_exhaacplus_dec->p_state_aac != NULL &&
803             p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle
804                     .heaac_mps_present == 1) {
805           *pui_value = p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle
806                            .num_output_channels_at;
807         } else {
808           *pui_value = pvalue[i_idx];
809         }
810       } else if (IA_XHEAAC_DEC_CONFIG_PARAM_CHANNEL_MASK == i_idx) {
811         if (p_obj_exhaacplus_dec->p_state_aac != NULL &&
812             p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle
813                     .heaac_mps_present == 1) {
814           *pui_value = p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle
815                            .bs_config.ui_channel_mask;
816         } else {
817           *pui_value = pvalue[i_idx];
818         }
819       } else
820       if (i_idx >= 0 && i_idx <= 8) {
821         *pui_value = pvalue[i_idx];
822       } else if (IA_ENHAACPLUS_DEC_CONFIG_GET_NUM_PRE_ROLL_FRAMES == i_idx) {
823         WORD32 *ptri_value = (WORD32 *)pv_value;
824         ia_audio_specific_config_struct *ptr_audio_specific_config =
825             ((ia_audio_specific_config_struct *)
826                  p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config);
827 
828         for (i = 0; i < MAX_AUDIO_PREROLLS + 1; i++) {
829           if (ptr_audio_specific_config->str_usac_config.str_usac_dec_config
830                   .preroll_bytes[i] == 0) {
831             break;
832           }
833         }
834 
835         *ptri_value = i;
836       } else if (IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR == i_idx) {
837         ia_audio_specific_config_struct *ptr_audio_specific_config =
838             ((ia_audio_specific_config_struct *)
839                 p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config);
840 
841         for (i = 0; i < ptr_audio_specific_config->str_usac_config
842                             .str_usac_dec_config.num_config_extensions;
843              i++) {
844           pp_value[i] = ptr_audio_specific_config->str_usac_config
845                             .str_usac_dec_config.usac_cfg_ext_info_buf[i];
846         }
847 
848         for (i = 0; i < ptr_audio_specific_config->str_usac_config
849                             .str_usac_dec_config.num_elements;
850              i++) {
851           if (ptr_audio_specific_config->str_usac_config.str_usac_dec_config
852                   .usac_ext_ele_payload_present[i]) {
853             pp_value[i + 16] =
854                 ptr_audio_specific_config->str_usac_config.str_usac_dec_config
855                     .usac_ext_ele_payload_buf[i];
856           }
857         }
858       } else if (IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES == i_idx) {
859         WORD32 *ptri_value = (WORD32 *)pv_value;
860         ia_audio_specific_config_struct *ptr_audio_specific_config =
861             ((ia_audio_specific_config_struct *)
862                  p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config);
863         for (i = 0; i < ptr_audio_specific_config->str_usac_config
864                             .str_usac_dec_config.num_config_extensions;
865              i++) {
866           ptri_value[i] = ptr_audio_specific_config->str_usac_config
867                               .str_usac_dec_config.usac_cfg_ext_info_len[i];
868         }
869         for (i = 0; i < ptr_audio_specific_config->str_usac_config
870                             .str_usac_dec_config.num_elements;
871              i++) {
872           ptri_value[i + 16] =
873               ptr_audio_specific_config->str_usac_config.str_usac_dec_config
874                   .usac_ext_ele_payload_len[i];
875         }
876 
877       } else if (IA_ENHAACPLUS_DEC_DRC_IS_CONFIG_CHANGED == i_idx) {
878         *pui_value = p_obj_exhaacplus_dec->p_state_aac->drc_config_changed;
879       } else if (IA_ENHAACPLUS_DEC_DRC_APPLY_CROSSFADE == i_idx) {
880         *pui_value = p_obj_exhaacplus_dec->p_state_aac->apply_crossfade;
881       } else if (IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE == i_idx) {
882         UWORD32 *ptri_value = (UWORD32 *)pv_value;
883         ia_audio_specific_config_struct *ptr_audio_specific_config =
884             ((ia_audio_specific_config_struct *)
885                  p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config);
886         *ptri_value = ptr_audio_specific_config->str_usac_config
887                           .str_usac_dec_config.num_elements;
888 
889       } else if (IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT == i_idx) {
890         UWORD32 *ptri_value = (UWORD32 *)pv_value;
891         ia_audio_specific_config_struct *ptr_audio_specific_config =
892             ((ia_audio_specific_config_struct *)
893                  p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config);
894         *ptri_value = ptr_audio_specific_config->str_usac_config
895                           .str_usac_dec_config.num_config_extensions;
896       } else if (IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN == i_idx) {
897         UWORD32 *ptri_value = (UWORD32 *)pv_value;
898         ia_audio_specific_config_struct *ptr_audio_specific_config =
899             ((ia_audio_specific_config_struct *)
900                  p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config);
901         WORD32 preroll_counter = ptr_audio_specific_config->str_usac_config
902                                      .str_usac_dec_config.preroll_counter;
903         *ptri_value =
904             ptr_audio_specific_config->str_usac_config.str_usac_dec_config
905                 .usac_ext_gain_payload_len[preroll_counter];
906       } else if (IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF == i_idx) {
907         WORD32 payload_buffer_offeset = 0;
908         ia_audio_specific_config_struct *ptr_audio_specific_config =
909             ((ia_audio_specific_config_struct *)
910                  p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config);
911         WORD32 preroll_counter = ptr_audio_specific_config->str_usac_config
912                                      .str_usac_dec_config.preroll_counter;
913         for (i = 0; i < (UWORD32)preroll_counter; i++)
914           payload_buffer_offeset +=
915               ptr_audio_specific_config->str_usac_config.str_usac_dec_config
916                   .usac_ext_gain_payload_len[i] *
917               sizeof(WORD8);
918         *pp_value = ptr_audio_specific_config->str_usac_config
919                         .str_usac_dec_config.usac_ext_gain_payload_buf +
920                     payload_buffer_offeset;
921       } else if (IA_XHEAAC_DEC_CONFIG_PARAM_AOT == i_idx) {
922         if (p_obj_exhaacplus_dec->p_state_aac != NULL) {
923           if (p_obj_exhaacplus_dec->aac_config.ui_mp4_flag == 1) {
924             ia_audio_specific_config_struct *ptr_audio_specific_config =
925                 ((ia_audio_specific_config_struct *)
926                     p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config);
927             *pui_value = ptr_audio_specific_config->audio_object_type;
928           } else {
929             *pui_value = p_obj_exhaacplus_dec->p_state_aac->audio_object_type;
930           }
931         } else {
932           *pui_value = AOT_AAC_LC;
933         }
934       } else {
935         return IA_XHEAAC_DEC_API_FATAL_INVALID_CONFIG_PARAM;
936       }
937       break;
938     }
939 
940     case IA_API_CMD_GET_MEMTABS_SIZE: {
941       *pui_value = (sizeof(ia_mem_info_struct) + sizeof(pVOID *)) *
942                    (IA_ENHAACPDEC_NUM_MEMTABS);
943       break;
944     }
945     case IA_API_CMD_GET_LOUDNESS_VAL: {
946       *pui_value = p_obj_exhaacplus_dec->aac_config.output_level;
947       break;
948     }
949     case IA_API_CMD_SET_MEMTABS_PTR: {
950       if (pv_value == NULL) return IA_XHEAAC_DEC_API_FATAL_MEM_ALLOC;
951       memset(pv_value, 0, (sizeof(ia_mem_info_struct) + sizeof(pVOID *)) *
952                               (IA_ENHAACPDEC_NUM_MEMTABS));
953 
954       p_obj_exhaacplus_dec->p_mem_info_aac = pv_value;
955       p_obj_exhaacplus_dec->pp_mem_aac =
956           (pVOID *)((WORD8 *)pv_value +
957                     sizeof(ia_mem_info_struct) * IA_ENHAACPDEC_NUM_MEMTABS);
958 
959       break;
960     }
961     case IA_API_CMD_GET_N_MEMTABS: {
962       *pui_value = IA_ENHAACPDEC_NUM_MEMTABS;
963       break;
964     }
965 
966     case IA_API_CMD_GET_N_TABLES: {
967       *pui_value = NUM_AAC_TABLES + NUM_MPS_TABLES;
968       break;
969     }
970     case IA_API_CMD_EXECUTE: {
971       switch (i_idx) {
972         case IA_CMD_TYPE_DO_EXECUTE: {
973           WORD32 err_code = 0;
974           if (!p_obj_exhaacplus_dec->p_state_aac->ui_init_done ||
975               p_obj_exhaacplus_dec->p_state_aac->fatal_err_present) {
976             err_code = IA_FATAL_ERROR;
977           } else {
978             memset(p_obj_exhaacplus_dec->p_state_aac->qshift_adj, 0,
979                    sizeof(p_obj_exhaacplus_dec->p_state_aac->qshift_adj));
980             p_obj_exhaacplus_dec->p_state_aac->qshift_cnt = 0;
981             err_code = ixheaacd_dec_execute(p_obj_exhaacplus_dec);
982           }
983           if (err_code != IA_NO_ERROR) {
984             if (err_code < 0) {
985               p_obj_exhaacplus_dec->p_state_aac->fatal_err_present = 1;
986             }
987             p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed =
988                 p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes;
989           }
990           return err_code;
991           break;
992         }
993         case IA_CMD_TYPE_DONE_QUERY: {
994           if (p_obj_exhaacplus_dec->p_state_aac->ui_input_over == 1) {
995             *pui_value = 1;
996           } else {
997             *pui_value = 0;
998           }
999 
1000           break;
1001         }
1002         default: { return IA_XHEAAC_DEC_API_FATAL_INVALID_EXECUTE_TYPE; }
1003       };
1004       break;
1005     }
1006     case IA_API_CMD_GET_CURIDX_INPUT_BUF: {
1007       *pui_value = p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed;
1008       break;
1009     }
1010     case IA_API_CMD_SET_INPUT_BYTES: {
1011       p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes = *pui_value;
1012       break;
1013     }
1014     case IA_API_CMD_GET_OUTPUT_BYTES: {
1015       if (1 == i_idx) {
1016         *pui_value = p_obj_exhaacplus_dec->p_state_aac->ui_mps_out_bytes;
1017       } else {
1018         *pui_value = p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes;
1019       }
1020       if (p_obj_exhaacplus_dec->p_state_aac->audio_object_type == AOT_USAC) {
1021         ia_audio_specific_config_struct *ptr_audio_specific_config =
1022             ((ia_audio_specific_config_struct *)
1023                  p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config);
1024 
1025         WORD32 preroll_counter = ptr_audio_specific_config->str_usac_config
1026                                      .str_usac_dec_config.preroll_counter;
1027 
1028         *pui_value = ptr_audio_specific_config->str_usac_config
1029                          .str_usac_dec_config.preroll_bytes[preroll_counter];
1030 
1031         preroll_counter++;
1032         if (preroll_counter > (MAX_AUDIO_PREROLLS + 1)) return IA_FATAL_ERROR;
1033         ptr_audio_specific_config->str_usac_config.str_usac_dec_config
1034             .preroll_counter = preroll_counter;
1035       }
1036       break;
1037     }
1038     case IA_API_CMD_INPUT_OVER: {
1039       p_obj_exhaacplus_dec->p_state_aac->ui_input_over = 1;
1040       break;
1041     }
1042     default: { return IA_XHEAAC_DEC_API_FATAL_INVALID_CMD; }
1043   };
1044   return IA_NO_ERROR;
1045 }
1046 
ixheaacd_decoder_2_ga_hdr(ia_exhaacplus_dec_api_struct * p_obj_exhaacplus_dec)1047 IA_ERRORCODE ixheaacd_decoder_2_ga_hdr(ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec) {
1048   IA_ERRORCODE err_code = IA_NO_ERROR;
1049   if (p_obj_exhaacplus_dec->aac_config.ui_flush_cmd == 0) {
1050     p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz = 16;
1051     p_obj_exhaacplus_dec->aac_config.flag_downmix = 0;
1052     p_obj_exhaacplus_dec->aac_config.flag_08khz_out = 0;
1053     p_obj_exhaacplus_dec->aac_config.flag_16khz_out = 0;
1054     p_obj_exhaacplus_dec->aac_config.flag_to_stereo = 0;
1055     p_obj_exhaacplus_dec->aac_config.down_sample_flag = 0;
1056     p_obj_exhaacplus_dec->aac_config.header_dec_done = 0;
1057     p_obj_exhaacplus_dec->aac_config.frame_status = 1;
1058     p_obj_exhaacplus_dec->aac_config.ui_mp4_flag = 1;
1059     p_obj_exhaacplus_dec->aac_config.ui_disable_sync = 0;
1060     p_obj_exhaacplus_dec->aac_config.ui_auto_sbr_upsample = 1;
1061     p_obj_exhaacplus_dec->aac_config.ui_samp_freq = 0;
1062     p_obj_exhaacplus_dec->aac_config.ui_channel_mode = 3;
1063     p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 2;
1064     p_obj_exhaacplus_dec->aac_config.ui_pce_found_in_hdr = 0;
1065     p_obj_exhaacplus_dec->aac_config.loas_present = 0;
1066     p_obj_exhaacplus_dec->aac_config.ui_drc_boost = 0;
1067     p_obj_exhaacplus_dec->aac_config.ui_drc_cut = 0;
1068     p_obj_exhaacplus_dec->aac_config.ui_drc_target_level = 108;
1069     p_obj_exhaacplus_dec->aac_config.ui_drc_set = 0;
1070     p_obj_exhaacplus_dec->aac_config.ui_flush_cmd = 1;
1071 
1072     p_obj_exhaacplus_dec->aac_config.ui_max_channels = 6;
1073 
1074     p_obj_exhaacplus_dec->aac_config.ui_coupling_channel = 0;
1075     p_obj_exhaacplus_dec->aac_config.downmix = 0;
1076 
1077     {
1078       ia_aac_dec_tables_struct *pstr_aac_tables =
1079           &p_obj_exhaacplus_dec->aac_tables;
1080       pstr_aac_tables->pstr_huffmann_tables =
1081           (ia_aac_dec_huffman_tables_struct *)&ixheaacd_aac_huffmann_tables;
1082       pstr_aac_tables->pstr_block_tables =
1083           (ia_aac_dec_block_tables_struct *)&ixheaacd_aac_block_tables;
1084       pstr_aac_tables->pstr_imdct_tables =
1085           (ia_aac_dec_imdct_tables_struct *)&ixheaacd_imdct_tables;
1086 
1087       ixheaacd_huff_tables_create(pstr_aac_tables);
1088     }
1089     ixheaacd_init_sbr_tables(&p_obj_exhaacplus_dec->str_sbr_tables);
1090     p_obj_exhaacplus_dec->common_tables =
1091         (ixheaacd_misc_tables *)&ixheaacd_str_fft_n_transcendent_tables;
1092     p_obj_exhaacplus_dec->aac_config.ui_qmf_bands = 64;
1093     p_obj_exhaacplus_dec->p_state_aac->ui_init_done = 0;
1094 
1095     err_code = ixheaacd_dec_init(p_obj_exhaacplus_dec);
1096   } else {
1097     p_obj_exhaacplus_dec->aac_config.ui_flush_cmd = 0;
1098     err_code = ixheaacd_dec_init(p_obj_exhaacplus_dec);
1099   }
1100   if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal && err_code) {
1101     if (err_code & IA_FATAL_ERROR) {
1102       return IA_XHEAAC_DEC_INIT_FATAL_EC_INIT_FAIL;
1103     } else {
1104       return IA_XHEAAC_DEC_INIT_NONFATAL_EC_INIT_FAIL;
1105     }
1106   } else {
1107     return err_code;
1108   }
1109 }
1110 
ixheaacd_decoder_flush_api(ia_exhaacplus_dec_api_struct * p_obj_exhaacplus_dec)1111 IA_ERRORCODE ixheaacd_decoder_flush_api(ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec) {
1112   IA_ERRORCODE err_code = IA_NO_ERROR;
1113   UWORD8 *header_temp_ptr;
1114   WORD32 header_length;
1115   if (p_obj_exhaacplus_dec->aac_config.ui_flush_cmd == 0) {
1116     header_temp_ptr = p_obj_exhaacplus_dec->p_state_aac->header_ptr;
1117     header_length = p_obj_exhaacplus_dec->p_state_aac->header_length;
1118     memset(p_obj_exhaacplus_dec->p_state_aac, 0,
1119            IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_state_struct), BYTE_ALIGN_8));
1120     {
1121       pUWORD8 p_temp = (pUWORD8)p_obj_exhaacplus_dec->p_state_aac;
1122       UWORD32 *meminfo = (UWORD32 *)p_obj_exhaacplus_dec->p_mem_info_aac;
1123       UWORD32 pers_size = meminfo[0];
1124       p_temp = p_temp + pers_size -
1125                (IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_dec_data_struct), BYTE_ALIGN_8) +
1126                 IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_audio_specific_config_struct), BYTE_ALIGN_8) +
1127                 IXHEAAC_GET_SIZE_ALIGNED(MAX_HEADER_BUF_SIZE, BYTE_ALIGN_8));
1128 
1129       p_obj_exhaacplus_dec->p_state_aac->pstr_dec_data = p_temp;
1130       p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config =
1131           p_temp + IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_dec_data_struct), BYTE_ALIGN_8);
1132       p_obj_exhaacplus_dec->p_state_aac->header_ptr =
1133           p_temp + IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_dec_data_struct), BYTE_ALIGN_8) +
1134           IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_audio_specific_config_struct), BYTE_ALIGN_8);
1135     }
1136     memset(&(p_obj_exhaacplus_dec->aac_config), 0,
1137            sizeof(ia_aac_dec_config_struct));
1138 
1139     p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz = 16;
1140     p_obj_exhaacplus_dec->aac_config.flag_downmix = 0;
1141     p_obj_exhaacplus_dec->aac_config.flag_08khz_out = 0;
1142     p_obj_exhaacplus_dec->aac_config.flag_16khz_out = 0;
1143     p_obj_exhaacplus_dec->aac_config.flag_to_stereo = 0;
1144     p_obj_exhaacplus_dec->aac_config.down_sample_flag = 0;
1145     p_obj_exhaacplus_dec->aac_config.header_dec_done = 0;
1146     p_obj_exhaacplus_dec->aac_config.frame_status = 1;
1147     p_obj_exhaacplus_dec->aac_config.ui_mp4_flag = 1;
1148     p_obj_exhaacplus_dec->aac_config.ui_disable_sync = 0;
1149     p_obj_exhaacplus_dec->aac_config.ui_auto_sbr_upsample = 1;
1150     p_obj_exhaacplus_dec->aac_config.ui_samp_freq = 0;
1151     p_obj_exhaacplus_dec->aac_config.ui_channel_mode = 3;
1152     p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 2;
1153     p_obj_exhaacplus_dec->aac_config.ui_pce_found_in_hdr = 0;
1154     p_obj_exhaacplus_dec->aac_config.loas_present = 0;
1155     p_obj_exhaacplus_dec->aac_config.ui_drc_boost = 0;
1156     p_obj_exhaacplus_dec->aac_config.ui_drc_cut = 0;
1157     p_obj_exhaacplus_dec->aac_config.ui_drc_target_level = 108;
1158     p_obj_exhaacplus_dec->aac_config.ui_drc_set = 0;
1159     p_obj_exhaacplus_dec->aac_config.ui_flush_cmd = 1;
1160 
1161     p_obj_exhaacplus_dec->aac_config.ui_max_channels = 6;
1162 
1163     p_obj_exhaacplus_dec->aac_config.ui_coupling_channel = 0;
1164     p_obj_exhaacplus_dec->aac_config.downmix = 0;
1165     p_obj_exhaacplus_dec->p_state_aac->peak_lim_init = 0;
1166 
1167     {
1168       ia_aac_dec_tables_struct *pstr_aac_tables =
1169           &p_obj_exhaacplus_dec->aac_tables;
1170       pstr_aac_tables->pstr_huffmann_tables =
1171           (ia_aac_dec_huffman_tables_struct *)&ixheaacd_aac_huffmann_tables;
1172       pstr_aac_tables->pstr_block_tables =
1173           (ia_aac_dec_block_tables_struct *)&ixheaacd_aac_block_tables;
1174       pstr_aac_tables->pstr_imdct_tables =
1175           (ia_aac_dec_imdct_tables_struct *)&ixheaacd_imdct_tables;
1176 
1177       ixheaacd_huff_tables_create(pstr_aac_tables);
1178     }
1179     ixheaacd_init_sbr_tables(&p_obj_exhaacplus_dec->str_sbr_tables);
1180     p_obj_exhaacplus_dec->common_tables =
1181         (ixheaacd_misc_tables *)&ixheaacd_str_fft_n_transcendent_tables;
1182     p_obj_exhaacplus_dec->aac_config.ui_qmf_bands = 64;
1183     p_obj_exhaacplus_dec->p_state_aac->header_ptr = header_temp_ptr;
1184     p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes = header_length;
1185     p_obj_exhaacplus_dec->p_state_aac->header_length = header_length;
1186 
1187     err_code = ixheaacd_dec_init(p_obj_exhaacplus_dec);
1188   } else {
1189     p_obj_exhaacplus_dec->aac_config.ui_flush_cmd = 0;
1190     err_code = ixheaacd_dec_init(p_obj_exhaacplus_dec);
1191   }
1192   if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal && err_code) {
1193     if (err_code & IA_FATAL_ERROR) {
1194       return IA_XHEAAC_DEC_INIT_FATAL_EC_INIT_FAIL;
1195     } else {
1196       return IA_XHEAAC_DEC_INIT_NONFATAL_EC_INIT_FAIL;
1197     }
1198   } else {
1199     return err_code;
1200   }
1201 }
1202 
1203 static PLATFORM_INLINE WORD32
ixheaacd_persistent_buffer_sizes(WORD32 num_channel)1204 ixheaacd_persistent_buffer_sizes(WORD32 num_channel) {
1205   WORD32 size_buffers = 0;
1206 
1207   WORD32 temp;
1208   WORD32 max_channels;
1209 
1210   size_buffers += IXHEAAC_GET_SIZE_ALIGNED(4 * 512 * num_channel * sizeof(WORD32), BYTE_ALIGN_8);
1211 
1212   size_buffers +=
1213       num_channel * IXHEAAC_GET_SIZE_ALIGNED(ltp_buffer_size * sizeof(WORD16), BYTE_ALIGN_8);
1214 
1215   size_buffers +=
1216       num_channel * IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_channel_info), BYTE_ALIGN_8);
1217 
1218   if (num_channel > 2) {
1219     max_channels = MAX_BS_ELEMENT;
1220   } else {
1221     max_channels = 2;
1222   }
1223   size_buffers += (max_channels)*2 *
1224                   IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_sbr_bitstream_struct), BYTE_ALIGN_8);
1225 
1226   size_buffers +=
1227       num_channel * IXHEAAC_GET_SIZE_ALIGNED(MAXSBRBYTES * sizeof(WORD8), BYTE_ALIGN_8);
1228 
1229   size_buffers +=
1230       num_channel * IXHEAAC_GET_SIZE_ALIGNED(MAXSBRBYTES * sizeof(WORD8), BYTE_ALIGN_8);
1231 
1232   size_buffers +=
1233       2 * num_channel *
1234       IXHEAAC_GET_SIZE_ALIGNED(
1235           (QMF_FILTER_STATE_ANA_SIZE + 2 * NO_ANALYSIS_CHANNELS) * sizeof(WORD16), BYTE_ALIGN_8);
1236 
1237   size_buffers +=
1238       2 * num_channel *
1239       IXHEAAC_GET_SIZE_ALIGNED(
1240           (QMF_FILTER_STATE_ANA_SIZE + 2 * NO_ANALYSIS_CHANNELS) * sizeof(WORD32), BYTE_ALIGN_8);
1241 
1242   size_buffers +=
1243       2 * num_channel *
1244       IXHEAAC_GET_SIZE_ALIGNED(
1245           (QMF_FILTER_STATE_SYN_SIZE + 2 * NO_SYNTHESIS_CHANNELS) * sizeof(WORD16), BYTE_ALIGN_8);
1246 
1247   size_buffers +=
1248       2 * num_channel *
1249       IXHEAAC_GET_SIZE_ALIGNED(
1250           (QMF_FILTER_STATE_SYN_SIZE + 2 * NO_SYNTHESIS_CHANNELS) * sizeof(WORD32), BYTE_ALIGN_8);
1251 
1252   size_buffers += num_channel * 2 *
1253                   IXHEAAC_GET_SIZE_ALIGNED(MAX_OV_COLS * NO_SYNTHESIS_CHANNELS * sizeof(WORD32),
1254                                            BYTE_ALIGN_8);
1255 
1256   size_buffers += 2 * LPC_ORDER * num_channel *
1257                   IXHEAAC_GET_SIZE_ALIGNED(NO_ANALYSIS_CHANNELS * sizeof(WORD32), BYTE_ALIGN_8);
1258 
1259   size_buffers += 2 * IXHEAAC_GET_SIZE_ALIGNED(LPC_ORDER * sizeof(WORD32 *), BYTE_ALIGN_8);
1260 
1261   size_buffers += 2 * LPC_ORDER * num_channel *
1262                   IXHEAAC_GET_SIZE_ALIGNED(NO_ANALYSIS_CHANNELS * sizeof(WORD32), BYTE_ALIGN_8);
1263 
1264   size_buffers += 2 * num_channel * 3 *
1265                   IXHEAAC_GET_SIZE_ALIGNED(MAX_FREQ_COEFFS * sizeof(WORD16), BYTE_ALIGN_8);
1266 
1267   temp = IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_freq_band_data_struct), BYTE_ALIGN_8) +
1268          IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_sbr_prev_frame_data_struct), BYTE_ALIGN_8) +
1269          IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_sbr_channel_struct), BYTE_ALIGN_8) +
1270          IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_sbr_header_data_struct), BYTE_ALIGN_8);
1271   size_buffers += 2 * num_channel * temp;
1272 
1273   size_buffers += MAX_BS_ELEMENT *
1274                   IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaac_drc_bs_data_struct *), BYTE_ALIGN_8);
1275 
1276   size_buffers += num_channel * IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_ps_dec_struct), BYTE_ALIGN_8);
1277 
1278   {
1279     WORD32 temp_size = 0;
1280     size_buffers += (num_channel * 2 *
1281                      IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_sbr_frame_info_data_struct) +
1282                                                   MAX_FREQ_COEFFS * sizeof(WORD32) * 2 + 8,
1283                                               BYTE_ALIGN_8));
1284     temp_size += IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_pvc_data_struct), BYTE_ALIGN_8);
1285     temp_size += 2 * IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_esbr_hbe_txposer_struct), BYTE_ALIGN_8);
1286     temp_size += 2 * IXHEAAC_GET_SIZE_ALIGNED(MAX_HBE_PERSISTENT_SIZE, BYTE_ALIGN_8);
1287     temp_size +=
1288         2 * 2 * IXHEAAC_GET_SIZE_ALIGNED(MAX_QMF_BUF_LEN * sizeof(FLOAT32 *), BYTE_ALIGN_8);
1289     temp_size += 2 * 2 * MAX_QMF_BUF_LEN *
1290                  IXHEAAC_GET_SIZE_ALIGNED(MAX_QMF_BUF_LEN * sizeof(FLOAT32), BYTE_ALIGN_8);
1291     temp_size += 2 * 2 * MAX_ENV_COLS *
1292                  IXHEAAC_GET_SIZE_ALIGNED(MAX_QMF_BUF_LEN * sizeof(WORD32), BYTE_ALIGN_8);
1293     size_buffers += num_channel * temp_size;
1294   }
1295 
1296   return (size_buffers);
1297 }
1298 
ixheaacd_fill_aac_mem_tables(ia_exhaacplus_dec_api_struct * p_obj_exhaacplus_dec)1299 VOID ixheaacd_fill_aac_mem_tables(
1300     ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec) {
1301   ia_mem_info_struct *p_mem_info_aac;
1302 
1303   WORD32 num_channels;
1304   WORD32 channels;
1305   WORD32 buffer_size;
1306 
1307   if (p_obj_exhaacplus_dec->aac_config.ui_max_channels > 2) {
1308     num_channels = (p_obj_exhaacplus_dec->aac_config.ui_max_channels + 1);
1309   } else
1310 
1311   {
1312     num_channels = p_obj_exhaacplus_dec->aac_config.ui_max_channels;
1313   }
1314 
1315   channels = num_channels;
1316   buffer_size = ixheaacd_persistent_buffer_sizes(num_channels);
1317 
1318   {
1319     p_mem_info_aac =
1320         &p_obj_exhaacplus_dec->p_mem_info_aac[IA_ENHAACPLUS_DEC_PERSIST_IDX];
1321     p_mem_info_aac->ui_size =
1322         IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_state_struct), BYTE_ALIGN_8) +
1323         channels *
1324             IXHEAAC_GET_SIZE_ALIGNED(sizeof(struct ia_aac_persistent_struct), BYTE_ALIGN_8) +
1325         buffer_size + channels * ixheaacd_getsize_sbr_persistent() + channels * 16 +
1326         ixheaacd_mps_persistent_buffer_sizes();
1327     p_mem_info_aac->ui_size += IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_dec_data_struct), BYTE_ALIGN_8);
1328     p_mem_info_aac->ui_size +=
1329         IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_audio_specific_config_struct), BYTE_ALIGN_8);
1330     p_mem_info_aac->ui_size += IXHEAAC_GET_SIZE_ALIGNED(MAX_HEADER_BUF_SIZE, BYTE_ALIGN_8);
1331     p_mem_info_aac->ui_alignment = 16;
1332     p_mem_info_aac->ui_type = IA_MEMTYPE_PERSIST;
1333   }
1334 
1335   {
1336     p_mem_info_aac =
1337         &p_obj_exhaacplus_dec->p_mem_info_aac[IA_ENHAACPLUS_DEC_SCRATCH_IDX];
1338 
1339     p_mem_info_aac->ui_size = MAX_SCR_SIZE;
1340 
1341     p_mem_info_aac->ui_alignment = 8;
1342     p_mem_info_aac->ui_type = IA_MEMTYPE_SCRATCH;
1343   }
1344   {
1345     p_mem_info_aac =
1346         &p_obj_exhaacplus_dec->p_mem_info_aac[IA_ENHAACPLUS_DEC_INPUT_IDX];
1347 
1348     p_mem_info_aac->ui_size = IA_MAX_INP_BUFFER_SIZE;
1349 
1350     p_mem_info_aac->ui_alignment = 8;
1351     p_mem_info_aac->ui_type = IA_MEMTYPE_INPUT;
1352   }
1353   {
1354     p_mem_info_aac =
1355         &p_obj_exhaacplus_dec->p_mem_info_aac[IA_ENHAACPLUS_DEC_OUTPUT_IDX];
1356     p_mem_info_aac->ui_size = IA_ENHAACPLUS_DEC_OUT_BUF_SIZE;
1357     p_mem_info_aac->ui_alignment = 8;
1358     p_mem_info_aac->ui_type = IA_MEMTYPE_OUTPUT;
1359   }
1360   return;
1361 }
1362 
ixheaacd_dec_table_api(ia_exhaacplus_dec_api_struct * p_obj_exhaacplus_dec,WORD32 i_cmd,WORD32 i_idx,pVOID pv_value)1363 IA_ERRORCODE ixheaacd_dec_table_api(
1364     ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec, WORD32 i_cmd,
1365     WORD32 i_idx, pVOID pv_value) {
1366   ia_heaac_mps_state_struct *pstr_mps_state =
1367       &p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle;
1368   pUWORD32 pui_value = pv_value;
1369   pUWORD32 *p_pui_value = pv_value;
1370   SIZE_T ui_get_vals[5];
1371 
1372   pVOID *table_ptrs[8 + NUM_MPS_TABLES];
1373   UWORD32 table_sizes[8 + NUM_MPS_TABLES] = {
1374       sizeof(ixheaacd_aac_huffmann_tables),
1375       sizeof(ixheaacd_aac_block_tables),
1376       sizeof(ixheaacd_imdct_tables),
1377       sizeof(ixheaacd_str_fft_n_transcendent_tables),
1378       sizeof(ixheaacd_aac_dec_env_calc_tables),
1379       sizeof(ixheaacd_aac_qmf_dec_tables),
1380       sizeof(ixheaacd_aac_dec_env_extr_tables),
1381       sizeof(ixheaacd_aac_dec_ps_tables),
1382       sizeof(ixheaacd_mps_dec_qmf_tables),
1383       sizeof(ixheaacd_mps_dec_common_tables),
1384       sizeof(ixheaacd_mps_dec_hybrid_tables),
1385       sizeof(ixheaacd_mps_dec_m1_m2_tables),
1386       sizeof(ixheaacd_mps_dec_decorr_tables),
1387       sizeof(ixheaacd_mps_dec_tp_process_tables),
1388       sizeof(ixheaacd_mps_dec_mdct2qmf_table),
1389       sizeof(ixheaacd_mps_dec_tonality_tables),
1390       sizeof(ixheaacd_mps_dec_bitdec_tables),
1391       sizeof(ixheaacd_mps_dec_blind_tables),
1392       sizeof(ixheaacd_mps_dec_mdct2qmf_tables),
1393       sizeof(ia_mps_dec_mdct2qmf_cos_table_struct),
1394       sizeof(ia_mps_dec_residual_aac_tables_struct)};
1395   table_ptrs[0] =
1396       (pVOID *)&(p_obj_exhaacplus_dec->aac_tables.pstr_huffmann_tables);
1397   table_ptrs[1] =
1398       (pVOID *)&(p_obj_exhaacplus_dec->aac_tables.pstr_block_tables);
1399   table_ptrs[2] =
1400       (pVOID *)&(p_obj_exhaacplus_dec->aac_tables.pstr_imdct_tables);
1401   table_ptrs[3] = (pVOID *)&(p_obj_exhaacplus_dec->common_tables);
1402   table_ptrs[4] =
1403       (pVOID *)&p_obj_exhaacplus_dec->str_sbr_tables.env_calc_tables_ptr;
1404   table_ptrs[5] =
1405       (pVOID *)&p_obj_exhaacplus_dec->str_sbr_tables.qmf_dec_tables_ptr;
1406   table_ptrs[6] =
1407       (pVOID *)&p_obj_exhaacplus_dec->str_sbr_tables.env_extr_tables_ptr;
1408   table_ptrs[7] = (pVOID *)&p_obj_exhaacplus_dec->str_sbr_tables.ps_tables_ptr;
1409   table_ptrs[8] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.qmf_table_ptr);
1410   table_ptrs[9] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.common_table_ptr);
1411   table_ptrs[10] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.hybrid_table_ptr);
1412   table_ptrs[11] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.m1_m2_table_ptr);
1413   table_ptrs[12] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.decor_table_ptr);
1414   table_ptrs[13] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.tp_process_table_ptr);
1415   table_ptrs[14] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.mdct2qmf_table_ptr);
1416   table_ptrs[15] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.tonality_table_ptr);
1417   table_ptrs[16] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.bitdec_table_ptr);
1418   table_ptrs[17] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.blind_table_ptr);
1419   table_ptrs[18] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.mdct2qmfcos_table_ptr);
1420   table_ptrs[19] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.mdct2qmfcos_tab_ptr);
1421   table_ptrs[20] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.aac_tab);
1422 
1423   if (i_idx < 0 || i_idx >= (NUM_AAC_TABLES + NUM_MPS_TABLES)) {
1424     return IA_XHEAAC_DEC_API_FATAL_INVALID_MEMTAB_INDEX;
1425   }
1426 
1427   ui_get_vals[0] = table_sizes[i_idx];
1428   ui_get_vals[1] = 4;
1429   ui_get_vals[4] = (SIZE_T)(*table_ptrs[i_idx]);
1430 
1431   if (i_cmd == IA_API_CMD_SET_TABLE_PTR) {
1432     if (pv_value == 0) {
1433       return (IA_XHEAAC_DEC_API_FATAL_MEM_ALLOC);
1434     }
1435     if (((SIZE_T)pv_value) & 3) {
1436       return IA_XHEAAC_DEC_API_FATAL_MEM_ALIGN;
1437     }
1438 
1439     *table_ptrs[i_idx] = pv_value;
1440 
1441     if (i_idx == 0) {
1442       ixheaacd_huff_tables_create(&p_obj_exhaacplus_dec->aac_tables);
1443     }
1444 
1445   }
1446 
1447   else if (i_cmd == IA_API_CMD_GET_TABLE_PTR) {
1448     *p_pui_value = (UWORD32 *)((SIZE_T)(
1449         ui_get_vals[i_cmd - IA_API_CMD_GET_TABLE_INFO_SIZE]));
1450   } else {
1451     *pui_value = (WORD32)(ui_get_vals[i_cmd - IA_API_CMD_GET_TABLE_INFO_SIZE]);
1452   }
1453 
1454   return IA_NO_ERROR;
1455 }
1456 
ixheaacd_mps_payload(ia_handle_sbr_dec_inst_struct self,ia_exhaacplus_dec_api_struct * p_obj_exhaacplus_dec)1457 VOID ixheaacd_mps_payload(ia_handle_sbr_dec_inst_struct self,
1458                           ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec) {
1459   struct ia_bit_buf_struct local_bit_buff;
1460   struct ia_bit_buf_struct *it_bit_buff;
1461   if (self->ptr_mps_data != NULL) {
1462     ixheaacd_create_init_bit_buf(&local_bit_buff, (UWORD8 *)self->ptr_mps_data,
1463                                  (self->left_mps_bits >> 3) + 1);
1464   }
1465 
1466   local_bit_buff.xaac_jmp_buf =
1467       &p_obj_exhaacplus_dec->p_state_aac->xaac_jmp_buf;
1468 
1469   it_bit_buff = &local_bit_buff;
1470 
1471   it_bit_buff->bit_pos = self->mps_bits_pos;
1472   it_bit_buff->cnt_bits = self->left_mps_bits;
1473 
1474   while (self->left_mps_bits >= 8) {
1475     ixheaacd_extension_payload(
1476         it_bit_buff, &self->left_mps_bits,
1477         &p_obj_exhaacplus_dec->p_state_aac->mps_dec_handle);
1478   }
1479 }
1480 
ixheaacd_dec_init(ia_exhaacplus_dec_api_struct * p_obj_exhaacplus_dec)1481 IA_ERRORCODE ixheaacd_dec_init(
1482     ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec) {
1483   FLAG frame_status = 1;
1484   WORD32 frame_size_1;
1485   WORD32 sample_rate_1;
1486   WORD16 num_channels_1;
1487   WORD32 ps_detected = 0;
1488   UWORD8 *in_buffer;
1489   WORD16 *time_data;
1490   WORD ch_idx;
1491   WORD sbr_present_flag = 0;
1492   UWORD8 *mps_buffer;
1493   ia_aac_dec_state_struct *p_state_enhaacplus_dec;
1494 
1495   WORD32 error_code = IA_NO_ERROR;
1496   WORD32 persistent_used = 0;
1497   IA_ERRORCODE err_code = IA_NO_ERROR;
1498   struct ia_aac_persistent_struct *aac_persistent_mem;
1499   struct ia_sbr_pers_struct *sbr_persistent_mem;
1500   WORD32 ret_val;
1501 
1502   p_obj_exhaacplus_dec->p_state_aac =
1503       p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_PERSIST_IDX];
1504 
1505   if (p_obj_exhaacplus_dec->p_state_aac->ui_init_done)
1506   {
1507     return IA_NO_ERROR;
1508   }
1509 
1510   p_obj_exhaacplus_dec->p_state_aac->preroll_config_present = 0;
1511 
1512   if (p_obj_exhaacplus_dec->p_state_aac != NULL) {
1513     ret_val = setjmp(p_obj_exhaacplus_dec->p_state_aac->xaac_jmp_buf);
1514     if (ret_val != 0) {
1515       p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed =
1516           p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes;
1517       p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = 0;
1518       return IA_NO_ERROR;
1519     }
1520   }
1521 
1522   time_data = (WORD16 *)(p_obj_exhaacplus_dec
1523                              ->pp_mem_aac[IA_ENHAACPLUS_DEC_OUTPUT_IDX]);
1524 
1525   if (p_obj_exhaacplus_dec->aac_config.ui_flush_cmd == 0) {
1526     in_buffer = p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_INPUT_IDX];
1527   } else {
1528     in_buffer = p_obj_exhaacplus_dec->p_state_aac->header_ptr;
1529   }
1530 
1531   p_state_enhaacplus_dec = p_obj_exhaacplus_dec->p_state_aac;
1532 
1533   p_state_enhaacplus_dec->aac_scratch_mem_v =
1534       p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_SCRATCH_IDX];
1535   p_obj_exhaacplus_dec->p_state_aac->huffman_code_book_scl =
1536       p_obj_exhaacplus_dec->aac_tables.pstr_huffmann_tables
1537           ->huffman_code_book_scl;
1538   mps_buffer = p_obj_exhaacplus_dec->p_state_aac->mps_buffer;
1539   p_state_enhaacplus_dec->mps_header = -1;
1540   p_obj_exhaacplus_dec->p_state_aac->huffman_code_book_scl_index =
1541       p_obj_exhaacplus_dec->aac_tables.pstr_huffmann_tables
1542           ->huffman_code_book_scl_index;
1543 
1544   p_state_enhaacplus_dec->pstr_aac_tables = &p_obj_exhaacplus_dec->aac_tables;
1545   if (p_obj_exhaacplus_dec->p_state_aac->header_dec_done == 0)
1546   {
1547     p_obj_exhaacplus_dec->aac_config.header_dec_done = 0;
1548     p_state_enhaacplus_dec->mps_dec_handle.ldmps_config.ldmps_present_flag = 0;
1549   }
1550   if (p_obj_exhaacplus_dec->aac_config.header_dec_done == 0) {
1551     WORD32 channels;
1552     UWORD32 total_persistent_used = 0;
1553 
1554     p_obj_exhaacplus_dec->p_state_aac->p_config =
1555         &p_obj_exhaacplus_dec->aac_config;
1556 
1557     p_obj_exhaacplus_dec->p_state_aac->pstr_stream_sbr =
1558         (pVOID)((pWORD8)p_obj_exhaacplus_dec->p_state_aac +
1559                 IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_state_struct), BYTE_ALIGN_8));
1560     if (p_obj_exhaacplus_dec->aac_config.ui_max_channels > 2) {
1561       p_state_enhaacplus_dec->aac_persistent_mem_v =
1562           (pVOID)((pWORD8)p_obj_exhaacplus_dec->p_state_aac->pstr_stream_sbr +
1563                   (MAX_BS_ELEMENT)*2 *
1564                       IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_sbr_bitstream_struct),
1565                                                BYTE_ALIGN_8));
1566 
1567       memset(p_obj_exhaacplus_dec->p_state_aac->pstr_stream_sbr, 0,
1568              (MAX_BS_ELEMENT)*2 *
1569                  IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_sbr_bitstream_struct), BYTE_ALIGN_8));
1570     } else {
1571       p_state_enhaacplus_dec->aac_persistent_mem_v =
1572           (pVOID)((pWORD8)p_obj_exhaacplus_dec->p_state_aac->pstr_stream_sbr +
1573                   (2) * 2 *
1574                       IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_sbr_bitstream_struct),
1575                                                BYTE_ALIGN_8));
1576 
1577       memset(p_obj_exhaacplus_dec->p_state_aac->pstr_stream_sbr, 0,
1578              (2) * 2 *
1579                  IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_sbr_bitstream_struct), BYTE_ALIGN_8));
1580     }
1581     if (1 == p_obj_exhaacplus_dec->aac_config.ui_max_channels)
1582       channels = 1;
1583     else
1584       channels = 2;
1585 
1586     persistent_used = ixheaacd_set_aac_persistent_buffers(
1587         p_state_enhaacplus_dec->aac_persistent_mem_v, channels);
1588 
1589     p_state_enhaacplus_dec->sbr_persistent_mem_v =
1590         (pVOID)((pWORD8)p_state_enhaacplus_dec->aac_persistent_mem_v +
1591                 IXHEAAC_GET_SIZE_ALIGNED(persistent_used, BYTE_ALIGN_8));
1592     total_persistent_used += IXHEAAC_GET_SIZE_ALIGNED(persistent_used, BYTE_ALIGN_8);
1593 
1594     persistent_used = ixheaacd_getsize_sbr_persistent();
1595     ixheaacd_set_sbr_persistent_buffers(
1596         p_state_enhaacplus_dec->sbr_persistent_mem_v, &persistent_used,
1597         channels, 1);
1598 
1599     p_state_enhaacplus_dec->heaac_mps_handle.mps_persistent_mem_v =
1600         (pVOID)((pWORD8)p_state_enhaacplus_dec->sbr_persistent_mem_v +
1601                 IXHEAAC_GET_SIZE_ALIGNED(persistent_used, BYTE_ALIGN_8));
1602     total_persistent_used += IXHEAAC_GET_SIZE_ALIGNED(persistent_used, BYTE_ALIGN_8);
1603 
1604     persistent_used = ixheaacd_getsize_mps_persistent();
1605 
1606     ixheaacd_set_mps_persistent_buffers(
1607         &p_state_enhaacplus_dec->heaac_mps_handle, &persistent_used, channels,
1608         p_state_enhaacplus_dec->heaac_mps_handle.mps_persistent_mem_v);
1609     total_persistent_used += IXHEAAC_GET_SIZE_ALIGNED(persistent_used, BYTE_ALIGN_8);
1610 
1611     if (total_persistent_used >
1612         p_obj_exhaacplus_dec->p_mem_info_aac[IA_ENHAACPLUS_DEC_PERSIST_IDX].ui_size) {
1613       return IA_XHEAAC_DEC_INIT_FATAL_DEC_INIT_FAIL;
1614     }
1615 
1616     aac_persistent_mem = (struct ia_aac_persistent_struct *)
1617                              p_state_enhaacplus_dec->aac_persistent_mem_v;
1618     if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD ||
1619         p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD)
1620       p_state_enhaacplus_dec->frame_len_flag =
1621           p_obj_exhaacplus_dec->aac_config.framesize_480;
1622 
1623     p_state_enhaacplus_dec->ptr_overlap_buf =
1624         aac_persistent_mem->overlap_buffer;
1625 
1626     p_state_enhaacplus_dec->bit_count = 0;
1627     p_state_enhaacplus_dec->ec_enable = p_obj_exhaacplus_dec->aac_config.ui_err_conceal;
1628     p_state_enhaacplus_dec->sync_status = 0;
1629     p_state_enhaacplus_dec->bs_format = ADTS_BSFORMAT;
1630     p_state_enhaacplus_dec->latm_initialized = 0;
1631     p_state_enhaacplus_dec->frame_size = 0;
1632     memset(&p_state_enhaacplus_dec->latm_struct_element, 0,
1633            sizeof(ixheaacd_latm_struct));
1634     memset(&p_state_enhaacplus_dec->b_n_raw_data_blk, 0,
1635            sizeof(WORD32) * (9 + MAX_BS_ELEMENT));
1636 
1637     p_state_enhaacplus_dec->sbr_present_flag = 0;
1638 
1639     for (ch_idx = 0; ch_idx < MAX_BS_ELEMENT; ch_idx++) {
1640       p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = 0;
1641     }
1642 
1643     memset(&p_state_enhaacplus_dec->ind_cc_info, 0,
1644            sizeof(ia_enhaacplus_dec_ind_cc));
1645 
1646     p_state_enhaacplus_dec->last_frame_ok = 1;
1647     p_obj_exhaacplus_dec->aac_config.header_dec_done = 1;
1648 
1649     aac_persistent_mem->str_aac_decoder.pstr_aac_tables =
1650         &p_obj_exhaacplus_dec->aac_tables;
1651     aac_persistent_mem->str_aac_decoder.pstr_common_tables =
1652         p_obj_exhaacplus_dec->common_tables;
1653 
1654     p_obj_exhaacplus_dec->p_state_aac->sbr_persistent_mem_u =
1655         p_obj_exhaacplus_dec->p_state_aac->sbr_persistent_mem_v;
1656 
1657     p_obj_exhaacplus_dec->p_state_aac->sbr_scratch_mem_u =
1658         p_obj_exhaacplus_dec->p_state_aac->aac_scratch_mem_v;
1659 
1660     ixheaacd_set_sbr_persistent_table_pointer(
1661         p_obj_exhaacplus_dec->p_state_aac->sbr_persistent_mem_v,
1662         &p_obj_exhaacplus_dec->str_sbr_tables,
1663         p_obj_exhaacplus_dec->common_tables);
1664     ixheaacd_set_scratch_buffers(
1665         &p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle,
1666         p_state_enhaacplus_dec->aac_scratch_mem_v);
1667   }
1668 
1669   if (p_obj_exhaacplus_dec->p_state_aac->ui_input_over == 1) {
1670     return IA_XHEAAC_DEC_INIT_FATAL_EO_INPUT_REACHED;
1671   }
1672 
1673   if (p_obj_exhaacplus_dec->p_state_aac->header_dec_done == 0) {
1674     if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD ||
1675         p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD)
1676       p_state_enhaacplus_dec->frame_len_flag =
1677           p_obj_exhaacplus_dec->aac_config.framesize_480;
1678 
1679     aac_persistent_mem = (struct ia_aac_persistent_struct *)
1680                              p_state_enhaacplus_dec->aac_persistent_mem_v;
1681     sbr_persistent_mem = (struct ia_sbr_pers_struct *)
1682                              p_state_enhaacplus_dec->sbr_persistent_mem_v;
1683     if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
1684       p_obj_exhaacplus_dec->p_state_aac->first_frame = 1;
1685     }
1686 
1687     if (p_obj_exhaacplus_dec->aac_config.ui_samp_freq == 0) {
1688       WORD32 header_bytes_consumed, return_val;
1689 
1690       if (p_state_enhaacplus_dec->ui_in_bytes == 0) {
1691         p_state_enhaacplus_dec->i_bytes_consumed = 0;
1692         return IA_NO_ERROR;
1693       }
1694 
1695       if (1 == p_obj_exhaacplus_dec->aac_config.ui_frame_size) {
1696         p_state_enhaacplus_dec->frame_len_flag = 1;
1697         p_state_enhaacplus_dec->frame_length = 960;
1698       } else {
1699         p_state_enhaacplus_dec->frame_len_flag = 0;
1700         p_state_enhaacplus_dec->frame_length = 1024;
1701       }
1702 
1703       p_state_enhaacplus_dec->ui_init_done = 0;
1704       memset(&(p_state_enhaacplus_dec->eld_specific_config), 0,
1705              sizeof(ia_eld_specific_config_struct));
1706       return_val = ixheaacd_aac_headerdecode(
1707           p_obj_exhaacplus_dec, (UWORD8 *)in_buffer, &header_bytes_consumed,
1708           aac_persistent_mem->str_aac_decoder.pstr_aac_tables
1709               ->pstr_huffmann_tables);
1710       if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD ||
1711           p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD ||
1712           p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LC) {
1713         *sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_header[0] =
1714             p_obj_exhaacplus_dec->p_state_aac->str_sbr_config;
1715         *sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_header[1] =
1716             p_obj_exhaacplus_dec->p_state_aac->str_sbr_config;
1717       } else {
1718         memset(&(p_state_enhaacplus_dec->eld_specific_config), 0,
1719                sizeof(ia_eld_specific_config_struct));
1720       }
1721 
1722       if (return_val < 0) {
1723         if (return_val ==
1724             (WORD32)IA_XHEAAC_DEC_INIT_FATAL_STREAM_CHAN_GT_MAX) {
1725           p_state_enhaacplus_dec->i_bytes_consumed = header_bytes_consumed;
1726           return return_val;
1727         }
1728         p_state_enhaacplus_dec->i_bytes_consumed = 1;
1729 
1730         return return_val;
1731       }
1732 
1733       if (return_val ==
1734           IA_XHEAAC_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES) {
1735         p_state_enhaacplus_dec->i_bytes_consumed = header_bytes_consumed;
1736         return return_val;
1737       }
1738 
1739       p_state_enhaacplus_dec->i_bytes_consumed = header_bytes_consumed;
1740 
1741       if ((return_val == 0) &&
1742           (p_obj_exhaacplus_dec->p_state_aac->audio_object_type == AOT_USAC)) {
1743         {
1744           WORD32 pcm_size = p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz;
1745           WORD8 *inbuffer =
1746               p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_INPUT_IDX];
1747           WORD8 *outbuffer =
1748               p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_OUTPUT_IDX];
1749           WORD32 out_bytes = 0;
1750           WORD32 frames_done = p_obj_exhaacplus_dec->p_state_aac->frame_counter;
1751           p_obj_exhaacplus_dec->p_state_aac->decode_create_done = 0;
1752 
1753           if (p_obj_exhaacplus_dec->p_state_aac->ui_input_over == 0) {
1754             error_code = ixheaacd_dec_main(
1755                 p_obj_exhaacplus_dec, inbuffer, outbuffer, &out_bytes,
1756                 frames_done, pcm_size,
1757                 &p_obj_exhaacplus_dec->p_state_aac->num_of_output_ch);
1758             if (error_code) return error_code;
1759             p_obj_exhaacplus_dec->p_state_aac->frame_counter++;
1760           } else {
1761             out_bytes = 0;
1762           }
1763 
1764           p_obj_exhaacplus_dec->aac_config.ui_n_channels =
1765               p_obj_exhaacplus_dec->p_state_aac->num_of_output_ch;
1766         }
1767         if (return_val == 0)
1768           p_obj_exhaacplus_dec->p_state_aac->ui_init_done = 1;
1769         return return_val;
1770       }
1771 
1772       if (return_val == 0) {
1773         p_obj_exhaacplus_dec->p_state_aac->header_dec_done = 1;
1774         if (p_obj_exhaacplus_dec->aac_config.ui_flush_cmd == 0) {
1775           memcpy(p_state_enhaacplus_dec->header_ptr, in_buffer,
1776                  header_bytes_consumed * sizeof(UWORD8));
1777           p_state_enhaacplus_dec->header_length = header_bytes_consumed;
1778         }
1779       }
1780 
1781       if (p_obj_exhaacplus_dec->p_state_aac->header_dec_done != 1)
1782         return IA_XHEAAC_DEC_INIT_NONFATAL_HEADER_NOT_AT_START;
1783 
1784       if (p_state_enhaacplus_dec->dwnsmp_signal == 1 &&
1785           p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD)
1786         p_obj_exhaacplus_dec->aac_config.down_sample_flag = 1;
1787 
1788       if (p_state_enhaacplus_dec->sampling_rate ==
1789           p_state_enhaacplus_dec->extension_samp_rate) {
1790         p_obj_exhaacplus_dec->aac_config.down_sample_flag = 1;
1791       }
1792 
1793     } else {
1794       p_obj_exhaacplus_dec->p_state_aac->header_dec_done = 1;
1795       p_state_enhaacplus_dec->i_bytes_consumed = 0;
1796 
1797       p_state_enhaacplus_dec->sampling_rate =
1798           p_obj_exhaacplus_dec->aac_config.ui_samp_freq;
1799 
1800       if (1 == p_obj_exhaacplus_dec->aac_config.ui_frame_size) {
1801         p_state_enhaacplus_dec->frame_len_flag = 1;
1802         p_state_enhaacplus_dec->frame_length = 960;
1803       } else {
1804         p_state_enhaacplus_dec->frame_len_flag = 0;
1805         p_state_enhaacplus_dec->frame_length = 1024;
1806       }
1807     }
1808 
1809     p_state_enhaacplus_dec->pstr_bit_buf = ixheaacd_create_bit_buf(
1810         &p_state_enhaacplus_dec->str_bit_buf, (UWORD8 *)in_buffer,
1811         p_obj_exhaacplus_dec->p_mem_info_aac[IA_ENHAACPLUS_DEC_INPUT_IDX]
1812             .ui_size);
1813     p_state_enhaacplus_dec->pstr_bit_buf->xaac_jmp_buf =
1814         &(p_state_enhaacplus_dec->xaac_jmp_buf);
1815 
1816     p_state_enhaacplus_dec->ptr_bit_stream =
1817         p_state_enhaacplus_dec->pstr_bit_buf;
1818 
1819     if (p_state_enhaacplus_dec->s_adts_hdr_present) {
1820       if (p_obj_exhaacplus_dec->aac_config.ld_decoder == 1)
1821         p_state_enhaacplus_dec->audio_object_type = 23;
1822     }
1823 
1824     if ((p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) ||
1825         (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD))
1826       if (p_state_enhaacplus_dec->s_adts_hdr_present) {
1827         if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) {
1828           p_state_enhaacplus_dec->eld_specific_config.ld_sbr_samp_rate = 1;
1829           p_state_enhaacplus_dec->eld_specific_config.ld_sbr_crc_flag = 0;
1830           p_state_enhaacplus_dec->eld_specific_config.ld_sbr_flag_present = 0;
1831 
1832           if (p_obj_exhaacplus_dec->aac_config.eld_sbr_present == 1) {
1833             p_state_enhaacplus_dec->eld_specific_config.ld_sbr_flag_present = 1;
1834           }
1835         }
1836         if (p_obj_exhaacplus_dec->aac_config.framesize_480)
1837           p_state_enhaacplus_dec->frame_length = 480;
1838         else
1839           p_state_enhaacplus_dec->frame_length = 512;
1840       }
1841 
1842     {
1843       for (ch_idx = 0; ch_idx < MAX_BS_ELEMENT; ch_idx++) {
1844         WORD32 channels;
1845         channels = 2;
1846 
1847         p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx] =
1848             ixheaacd_aac_decoder_init(
1849                 p_state_enhaacplus_dec,
1850 
1851                 p_state_enhaacplus_dec->pstr_stream_sbr[0], channels,
1852                 p_state_enhaacplus_dec->aac_persistent_mem_v,
1853                 p_state_enhaacplus_dec->frame_length);
1854 
1855         if (!p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]) {
1856           p_state_enhaacplus_dec->i_bytes_consumed = 1;
1857           return IA_XHEAAC_DEC_INIT_FATAL_DEC_INIT_FAIL;
1858         }
1859       }
1860 
1861       {
1862         p_state_enhaacplus_dec->pstr_drc_dec =
1863             &p_state_enhaacplus_dec->str_drc_dec_info;
1864         ixheaacd_drc_dec_create(p_state_enhaacplus_dec->pstr_drc_dec, 127, 127);
1865       }
1866       p_state_enhaacplus_dec->pstr_drc_dec->cut_factor =
1867           p_obj_exhaacplus_dec->aac_config.ui_drc_cut;
1868       p_state_enhaacplus_dec->pstr_drc_dec->boost_factor =
1869           p_obj_exhaacplus_dec->aac_config.ui_drc_boost;
1870       p_state_enhaacplus_dec->pstr_drc_dec->target_ref_level =
1871           p_obj_exhaacplus_dec->aac_config.ui_drc_target_level;
1872       p_state_enhaacplus_dec->pstr_drc_dec->prog_ref_level =
1873           p_obj_exhaacplus_dec->aac_config.ui_drc_target_level;
1874 
1875       if (1 == p_obj_exhaacplus_dec->aac_config.ui_drc_set) {
1876         if (p_obj_exhaacplus_dec->aac_config.ui_drc_heavy_comp == 1) {
1877           p_state_enhaacplus_dec->pstr_drc_dec->drc_on = 1;
1878           p_state_enhaacplus_dec->pstr_drc_dec->heavy_mode = 1;
1879         } else {
1880           p_state_enhaacplus_dec->pstr_drc_dec->heavy_mode = 0;
1881           if (p_state_enhaacplus_dec->pstr_drc_dec->target_ref_level > 127)
1882             p_state_enhaacplus_dec->pstr_drc_dec->target_ref_level = 127;
1883           if (p_state_enhaacplus_dec->pstr_drc_dec->target_ref_level < 0) {
1884             if (p_state_enhaacplus_dec->pstr_drc_dec->cut_factor > 0 ||
1885                 p_state_enhaacplus_dec->pstr_drc_dec->boost_factor > 0)
1886               p_state_enhaacplus_dec->pstr_drc_dec->drc_on = 1;
1887             else
1888               p_state_enhaacplus_dec->pstr_drc_dec->drc_on = 0;
1889             p_state_enhaacplus_dec->pstr_drc_dec->drc_dig_norm = 0;
1890             p_state_enhaacplus_dec->pstr_drc_dec->target_ref_level = 108;
1891           } else {
1892             p_state_enhaacplus_dec->pstr_drc_dec->drc_on = 1;
1893             p_state_enhaacplus_dec->pstr_drc_dec->drc_dig_norm = 1;
1894           }
1895         }
1896       }
1897     }
1898   } else {
1899     struct ia_bit_buf_struct temp_bit_buff = {0};
1900     ia_adts_header_struct adts;
1901     struct ia_bit_buf_struct *it_bit_buff;
1902 
1903     WORD16 frame_size_2 = 0;
1904     WORD32 sample_rate_2 = 0;
1905     WORD32 sample_rate = 0;
1906     WORD type, i;
1907     WORD elements_number;
1908 
1909     if (p_state_enhaacplus_dec->audio_object_type == AOT_USAC)
1910       return IA_FATAL_ERROR;
1911 
1912     memset(&adts, 0, sizeof(ia_adts_header_struct));
1913 
1914     for (i = 0; i < MAX_BS_ELEMENT + 1; i++) {
1915       p_obj_exhaacplus_dec->aac_config.element_type[i] = -1;
1916     }
1917 
1918     it_bit_buff = p_state_enhaacplus_dec->pstr_bit_buf;
1919 
1920     p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 0;
1921     p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = 0;
1922     p_state_enhaacplus_dec->ui_mps_out_bytes = 0;
1923     if (p_state_enhaacplus_dec->ui_in_bytes == 0) {
1924       p_state_enhaacplus_dec->i_bytes_consumed = 0;
1925       return IA_NO_ERROR;
1926     }
1927 
1928     if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD ||
1929         p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) {
1930       if (p_obj_exhaacplus_dec->aac_config.ui_mp4_flag)
1931         p_state_enhaacplus_dec->frame_size =
1932             p_state_enhaacplus_dec->ui_in_bytes;
1933     }
1934 
1935     ixheaacd_create_init_bit_buf(it_bit_buff, in_buffer,
1936                                  p_state_enhaacplus_dec->ui_in_bytes);
1937     p_state_enhaacplus_dec->pstr_bit_buf->xaac_jmp_buf =
1938         &(p_state_enhaacplus_dec->xaac_jmp_buf);
1939 
1940     it_bit_buff->adts_header_present =
1941         p_state_enhaacplus_dec->s_adts_hdr_present;
1942     it_bit_buff->no_raw_data_blocks =
1943         (WORD8)p_state_enhaacplus_dec->b_n_raw_data_blk;
1944     it_bit_buff->protection_absent = p_state_enhaacplus_dec->protection_absent;
1945 
1946     memcpy(&temp_bit_buff, it_bit_buff, sizeof(struct ia_bit_buf_struct));
1947 
1948     if (p_obj_exhaacplus_dec->aac_config.ui_max_channels > 2)
1949       elements_number = MAX_BS_ELEMENT;
1950     else
1951       elements_number = 2;
1952 
1953     for (i = 0; i < elements_number; i++)
1954       p_state_enhaacplus_dec->pstr_stream_sbr[i][0].no_elements = 0;
1955 
1956     { it_bit_buff->initial_cnt_bits = it_bit_buff->cnt_bits; }
1957 
1958     ixheaacd_byte_align(
1959         p_state_enhaacplus_dec->ptr_bit_stream,
1960         &p_state_enhaacplus_dec->pstr_aac_dec_info[0]->byte_align_bits);
1961 
1962     if (p_state_enhaacplus_dec->s_adts_hdr_present) {
1963       WORD32 error;
1964 
1965       if (p_state_enhaacplus_dec->b_n_raw_data_blk == 0) {
1966         error = ixheaacd_readifadts(p_state_enhaacplus_dec, it_bit_buff, &adts);
1967 
1968         if (error) return error;
1969 
1970         p_state_enhaacplus_dec->protection_absent = adts.protection_absent;
1971 
1972         if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD ||
1973             p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) {
1974           p_state_enhaacplus_dec->frame_size = adts.aac_frame_length;
1975           if (p_obj_exhaacplus_dec->aac_config.framesize_480)
1976             p_state_enhaacplus_dec->frame_length = 480;
1977           else
1978             p_state_enhaacplus_dec->frame_length = 512;
1979         }
1980       }
1981     }
1982 
1983     if (p_state_enhaacplus_dec->bs_format == LOAS_BSFORMAT) {
1984       WORD32 result;
1985       WORD32 sync;
1986       WORD32 cnt_bits;
1987 
1988       sync = ixheaacd_read_bits_buf(it_bit_buff, 11);
1989       cnt_bits = it_bit_buff->cnt_bits;
1990       if (it_bit_buff->cnt_bits <= 24) {
1991         return IA_XHEAAC_DEC_INIT_NONFATAL_INSUFFICIENT_INPUT_BYTES;
1992       }
1993 
1994       while (sync != 0x2b7) {
1995         sync = ((sync & 0x3ff) << 1) | ixheaacd_read_bits_buf(it_bit_buff, 1);
1996         if (it_bit_buff->cnt_bits < 11) {
1997           ixheaacd_read_bidirection(it_bit_buff, -11);
1998           p_state_enhaacplus_dec->i_bytes_consumed =
1999               (cnt_bits - it_bit_buff->cnt_bits) / 8;
2000           return (IA_XHEAAC_DEC_INIT_NONFATAL_HEADER_NOT_AT_START);
2001         }
2002       }
2003 
2004       it_bit_buff->audio_mux_align = it_bit_buff->cnt_bits - 13;
2005 
2006       if (sync == 0x2b7) {
2007         result = ixheaacd_latm_audio_mux_element(
2008             it_bit_buff, &p_state_enhaacplus_dec->latm_struct_element,
2009             p_state_enhaacplus_dec,
2010             (ia_sampling_rate_info_struct *)&p_obj_exhaacplus_dec->aac_tables
2011                 .pstr_huffmann_tables->str_sample_rate_info[0]);
2012         if (result < 0) {
2013           return result;
2014         }
2015       }
2016     }
2017 
2018     p_state_enhaacplus_dec->pstr_aac_dec_info[0]->byte_align_bits =
2019         it_bit_buff->cnt_bits;
2020 
2021     type = -1;
2022     ch_idx = 0;
2023 
2024     while ((type != 7)) {
2025       ia_aac_dec_scratch_struct aac_scratch_struct;
2026       memset(&aac_scratch_struct, 0, sizeof(aac_scratch_struct));
2027 
2028       if (ch_idx >= elements_number) {
2029         p_state_enhaacplus_dec->i_bytes_consumed = 1;
2030 
2031         return IA_XHEAAC_DEC_INIT_FATAL_STREAM_CHAN_GT_MAX;
2032       }
2033 
2034       ixheaacd_allocate_aac_scr(
2035           &aac_scratch_struct, p_state_enhaacplus_dec->aac_scratch_mem_v,
2036           time_data, 1, p_obj_exhaacplus_dec->aac_config.ui_max_channels,
2037           p_state_enhaacplus_dec->audio_object_type);
2038 
2039       p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->p_ind_channel_info =
2040           &p_state_enhaacplus_dec->ind_cc_info;
2041       if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
2042         p_obj_exhaacplus_dec->aac_config.first_frame = 1;
2043       }
2044 
2045       error_code = ixheaacd_aacdec_decodeframe(
2046           p_obj_exhaacplus_dec, &aac_scratch_struct, time_data, frame_status, &type, &ch_idx, 1,
2047           2, p_obj_exhaacplus_dec->aac_config.element_instance_order, 0, 1, 0,
2048           p_obj_exhaacplus_dec->aac_config.ui_max_channels, 2,
2049           p_obj_exhaacplus_dec->p_state_aac->frame_length,
2050           p_obj_exhaacplus_dec->p_state_aac->frame_size, p_state_enhaacplus_dec->pstr_drc_dec,
2051           p_state_enhaacplus_dec->audio_object_type, p_state_enhaacplus_dec->ch_config,
2052           p_state_enhaacplus_dec->eld_specific_config, p_state_enhaacplus_dec->s_adts_hdr_present,
2053           &p_state_enhaacplus_dec->drc_dummy, p_state_enhaacplus_dec->ldmps_present,
2054           &p_state_enhaacplus_dec->slot_pos, mps_buffer, &p_state_enhaacplus_dec->mps_header,
2055           &p_state_enhaacplus_dec->ui_mps_out_bytes, 1,
2056           p_obj_exhaacplus_dec->aac_config.first_frame);
2057 
2058       if (p_state_enhaacplus_dec->pstr_drc_dec->drc_element_found == 1) {
2059         if (p_obj_exhaacplus_dec->aac_config.i_loud_ref_level < 0) {
2060           p_obj_exhaacplus_dec->aac_config.output_level =
2061               p_state_enhaacplus_dec->pstr_drc_dec->prog_ref_level;
2062         } else {
2063           p_obj_exhaacplus_dec->aac_config.output_level =
2064               p_obj_exhaacplus_dec->aac_config.i_loud_ref_level;
2065         }
2066       }
2067 
2068       memset(&(p_obj_exhaacplus_dec->p_state_aac->pstr_aac_dec_info[ch_idx]
2069                    ->pstr_aac_dec_ch_info[0]
2070                    ->str_ics_info.ltp),
2071              0, sizeof(ltp_info));
2072       memset(&(p_obj_exhaacplus_dec->p_state_aac->pstr_aac_dec_info[ch_idx]
2073                    ->pstr_aac_dec_ch_info[0]
2074                    ->str_ics_info.ltp2),
2075              0, sizeof(ltp_info));
2076       memset(&(p_obj_exhaacplus_dec->p_state_aac->pstr_aac_dec_info[ch_idx]
2077                    ->pstr_aac_dec_ch_info[1]
2078                    ->str_ics_info.ltp),
2079              0, sizeof(ltp_info));
2080       memset(&(p_obj_exhaacplus_dec->p_state_aac->pstr_aac_dec_info[ch_idx]
2081                    ->pstr_aac_dec_ch_info[1]
2082                    ->str_ics_info.ltp2),
2083              0, sizeof(ltp_info));
2084 
2085       {
2086 
2087         frame_size_1 = p_state_enhaacplus_dec->frame_length;
2088         sample_rate_1 =
2089             p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->sampling_rate;
2090         num_channels_1 =
2091             p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->channels;
2092       }
2093 
2094       if ((p_obj_exhaacplus_dec->aac_config.ui_max_channels <= 2) &&
2095           (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 2)) {
2096         p_state_enhaacplus_dec->i_bytes_consumed = 1;
2097         return IA_XHEAAC_DEC_INIT_FATAL_UNIMPLEMENTED_CCE;
2098       }
2099 
2100       if (p_state_enhaacplus_dec->pstr_stream_sbr[0][0].no_elements) {
2101         sbr_present_flag = 1;
2102         p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 1;
2103       }
2104 
2105       if (error_code) {
2106         if (p_state_enhaacplus_dec->ui_input_over) {
2107           return IA_XHEAAC_DEC_INIT_FATAL_EO_INPUT_REACHED;
2108         }
2109 
2110         ixheaacd_updatebytesconsumed(p_state_enhaacplus_dec, it_bit_buff);
2111         return error_code;
2112       }
2113 
2114       if (p_state_enhaacplus_dec->s_adts_hdr_present) {
2115         if (adts.no_raw_data_blocks != 0) {
2116           if (adts.protection_absent == 0 && it_bit_buff->cnt_bits >= 16) {
2117             adts.crc_check = ixheaacd_read_bits_buf(it_bit_buff, 16);
2118           }
2119         }
2120         p_state_enhaacplus_dec->b_n_raw_data_blk--;
2121       }
2122 
2123       sample_rate_2 = sample_rate_1;
2124       frame_size_2 = frame_size_1;
2125 
2126       if (!p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] &&
2127           p_state_enhaacplus_dec->pstr_stream_sbr[0][0].no_elements) {
2128         WORD32 harmonic_sbr_flag = 0;
2129         if ((p_obj_exhaacplus_dec->aac_config.flag_16khz_out == 1) &&
2130             (sample_rate_1 == 8000)) {
2131           p_obj_exhaacplus_dec->aac_config.flag_16khz_out = 0;
2132         }
2133 
2134         p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = ixheaacd_init_sbr(
2135             sample_rate_1, frame_size_1,
2136             (FLAG *)&p_obj_exhaacplus_dec->aac_config.down_sample_flag,
2137             p_state_enhaacplus_dec->sbr_persistent_mem_v,
2138             p_state_enhaacplus_dec->ptr_overlap_buf, MAXNRSBRCHANNELS, (WORD)1,
2139             1, frame_size_1 * 2, &harmonic_sbr_flag, NULL,
2140             p_state_enhaacplus_dec->str_sbr_config,
2141             p_state_enhaacplus_dec->audio_object_type,
2142             p_state_enhaacplus_dec->mps_dec_handle.ldmps_config
2143                 .ldmps_present_flag,
2144             p_state_enhaacplus_dec->mps_dec_handle.ldmps_config
2145                 .no_ldsbr_present);
2146         if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) {
2147           p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->xaac_jmp_buf =
2148               &(p_state_enhaacplus_dec->xaac_jmp_buf);
2149         }
2150       } else {
2151       }
2152 
2153       if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] &&
2154           p_state_enhaacplus_dec->pstr_stream_sbr[0][0].no_elements) {
2155         ia_sbr_scr_struct sbr_scratch_struct;
2156         WORD16 num_channels_1_t = num_channels_1;
2157         ixheaacd_allocate_sbr_scr(&sbr_scratch_struct, p_state_enhaacplus_dec->aac_scratch_mem_v,
2158                                   time_data, 0, NULL, 0, 0);
2159         {
2160           WORD32 audio_object_type = p_state_enhaacplus_dec->audio_object_type;
2161 
2162           if (audio_object_type != AOT_ER_AAC_ELD && audio_object_type != AOT_ER_AAC_LD) {
2163             WORD32 i = 0;
2164             ia_dec_data_struct *pstr_dec_data =
2165                 (ia_dec_data_struct *)p_state_enhaacplus_dec->pstr_dec_data;
2166             if (num_channels_1 == 1) {
2167               for (; i < 1024; i++) {
2168                 pstr_dec_data->str_usac_data.time_sample_vector[0][i] =
2169                     ((FLOAT32)time_data[i]);
2170               }
2171               p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[0] =
2172                   &pstr_dec_data->str_usac_data.time_sample_vector[0][0];
2173 
2174               p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[1] =
2175                   &pstr_dec_data->str_usac_data.time_sample_vector[1][0];
2176             } else if (num_channels_1 == 2) {
2177               for (; i < 1024; i++) {
2178                 pstr_dec_data->str_usac_data.time_sample_vector[0][i] =
2179                     ((FLOAT32)time_data[2 * i + 0]);
2180                 pstr_dec_data->str_usac_data.time_sample_vector[1][i] =
2181                     ((FLOAT32)time_data[2 * i + 1]);
2182               }
2183               p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[0] =
2184                   &pstr_dec_data->str_usac_data.time_sample_vector[0][0];
2185 
2186               p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[1] =
2187                   &pstr_dec_data->str_usac_data.time_sample_vector[1][0];
2188             }
2189           }
2190         }
2191         p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->ec_flag =
2192             p_obj_exhaacplus_dec->aac_config.ui_err_conceal;
2193         p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->esbr_hq =
2194             p_obj_exhaacplus_dec->aac_config.ui_hq_esbr;
2195         p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->enh_sbr =
2196             p_obj_exhaacplus_dec->aac_config.ui_enh_sbr;
2197         p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->enh_sbr_ps =
2198             p_obj_exhaacplus_dec->aac_config.ui_enh_sbr_ps;
2199 
2200         if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) {
2201           p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->xaac_jmp_buf =
2202               &(p_state_enhaacplus_dec->xaac_jmp_buf);
2203         }
2204 
2205         if (ixheaacd_applysbr(p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx],
2206                               &p_state_enhaacplus_dec->pstr_stream_sbr[0][0], time_data,
2207                               &num_channels_1, frame_status,
2208                               p_obj_exhaacplus_dec->aac_config.down_sample_flag, 0,
2209                               &sbr_scratch_struct, 1, 1, 0, NULL, NULL,
2210                               p_state_enhaacplus_dec->eld_specific_config.ld_sbr_flag_present,
2211                               p_state_enhaacplus_dec->audio_object_type, 1,
2212                               p_state_enhaacplus_dec->ldmps_present, frame_size_1,
2213                               p_state_enhaacplus_dec->heaac_mps_handle.heaac_mps_present,
2214                               p_obj_exhaacplus_dec->aac_config.ui_err_conceal,
2215                               p_obj_exhaacplus_dec->aac_config.first_frame) != SBRDEC_OK) {
2216           p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = 0;
2217           return -1;
2218         } else {
2219           if (!p_obj_exhaacplus_dec->aac_config.down_sample_flag) {
2220             sample_rate_1 *= 2;
2221           }
2222           if (p_state_enhaacplus_dec->eld_specific_config.ld_sbr_flag_present == 1) {
2223             p_obj_exhaacplus_dec->p_state_aac->mps_dec_handle.pre_mix_req = 1;
2224             ixheaacd_mps_payload(
2225               p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx],
2226               p_obj_exhaacplus_dec);
2227           }
2228         }
2229         {
2230           WORD32 audio_object_type = p_state_enhaacplus_dec->audio_object_type;
2231 
2232           if (audio_object_type != AOT_ER_AAC_ELD && audio_object_type != AOT_ER_AAC_LD) {
2233             WORD32 out_bytes = 0;
2234             ia_dec_data_struct *pstr_dec_data =
2235                 (ia_dec_data_struct *)p_state_enhaacplus_dec->pstr_dec_data;
2236             ixheaacd_samples_sat((WORD8 *)time_data, 2048, 16,
2237                                  pstr_dec_data->str_usac_data.time_sample_vector, &out_bytes, 1);
2238           }
2239         }
2240         if (p_obj_exhaacplus_dec->aac_config.flag_downmix) {
2241           num_channels_1 = 1;
2242         }
2243         if (num_channels_1_t == 1 && num_channels_1 == 2) ps_detected = 1;
2244       } else {
2245         p_state_enhaacplus_dec->mps_dec_handle.ldmps_config.no_ldsbr_present = 1;
2246       }
2247 
2248       p_state_enhaacplus_dec->i_bytes_consumed = 0;
2249       p_state_enhaacplus_dec->pstr_bit_buf = it_bit_buff;
2250 
2251       {
2252         p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx] =
2253             ixheaacd_aac_decoder_init(
2254                 p_state_enhaacplus_dec,
2255                 p_state_enhaacplus_dec->pstr_stream_sbr[0], 2,
2256                 p_state_enhaacplus_dec->aac_persistent_mem_v,
2257                 p_state_enhaacplus_dec->frame_length);
2258 
2259         if (!p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]) {
2260           p_state_enhaacplus_dec->i_bytes_consumed = 1;
2261           return IA_XHEAAC_DEC_INIT_FATAL_DEC_INIT_FAIL;
2262         }
2263 
2264         if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) {
2265           WORD32 harmonic_sbr_flag = 0;
2266           p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = ixheaacd_init_sbr(
2267               sample_rate_2, frame_size_2,
2268               (FLAG *)&p_obj_exhaacplus_dec->aac_config.down_sample_flag,
2269               p_state_enhaacplus_dec->sbr_persistent_mem_v,
2270               p_state_enhaacplus_dec->ptr_overlap_buf, MAXNRSBRCHANNELS, 1, 1,
2271               frame_size_2 * 2, &harmonic_sbr_flag, NULL,
2272               p_state_enhaacplus_dec->str_sbr_config,
2273               p_state_enhaacplus_dec->audio_object_type,
2274               p_state_enhaacplus_dec->mps_dec_handle.ldmps_config
2275                 .ldmps_present_flag,
2276               p_state_enhaacplus_dec->mps_dec_handle.ldmps_config
2277                 .no_ldsbr_present);
2278         }
2279         if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) {
2280           p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->xaac_jmp_buf =
2281               &(p_state_enhaacplus_dec->xaac_jmp_buf);
2282         }
2283       }
2284 
2285       if (sample_rate < sample_rate_1) sample_rate = sample_rate_1;
2286 
2287       ch_idx++;
2288 
2289       if (p_state_enhaacplus_dec->audio_object_type >= ER_OBJECT_START &&
2290           (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD ||
2291           p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD ||
2292           p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LC))
2293         break;
2294     }
2295 
2296     {
2297       ia_adts_crc_info_struct *ptr_adts_crc_info =
2298           p_state_enhaacplus_dec->ptr_bit_stream->pstr_adts_crc_info;
2299       if (ptr_adts_crc_info->crc_active == 1) {
2300         if ((error_code = ixheaacd_adts_crc_check_crc(ptr_adts_crc_info))) {
2301           return error_code;
2302         }
2303       }
2304     }
2305 
2306     {
2307       VOID *temp;
2308       WORD prev_persistent_used_t;
2309       WORD prev_sbrpersistent_used_t;
2310       WORD ps_enable;
2311       WORD ch_idx_err = 0;
2312       WORD persistent_used_t = 0;
2313       WORD channel_check = 0;
2314       WORD cc_channel_check = 0;
2315       WORD max_ch_num = p_obj_exhaacplus_dec->aac_config.ui_max_channels;
2316       WORD32 harmonic_sbr_flag = 0;
2317       i = 0;
2318 
2319       p_obj_exhaacplus_dec->aac_config.ui_n_channels = ch_idx;
2320       while (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx_err] <= 3 &&
2321              p_obj_exhaacplus_dec->aac_config.element_type[ch_idx_err] >= 0) {
2322         ch_idx_err++;
2323       }
2324 
2325       if (ch_idx_err == 0) {
2326         p_obj_exhaacplus_dec->p_state_aac->header_dec_done = 0;
2327         p_state_enhaacplus_dec->i_bytes_consumed = (WORD32)(
2328             it_bit_buff->ptr_read_next - it_bit_buff->ptr_bit_buf_base);
2329         return IA_XHEAAC_DEC_INIT_NONFATAL_DECODE_FRAME_ERROR;
2330       }
2331 
2332       if (ch_idx_err == 1)
2333         ps_enable = 1;
2334       else
2335         ps_enable = 0;
2336 
2337       while (p_obj_exhaacplus_dec->aac_config.element_type[i] >= 0 &&
2338              p_obj_exhaacplus_dec->aac_config.element_type[i] <= 3) {
2339         WORD32 channel = 0;
2340         switch (p_obj_exhaacplus_dec->aac_config.element_type[i]) {
2341           case 0:
2342           case 3:
2343             channel = 1;
2344             break;
2345           case 1:
2346             channel = 2;
2347             break;
2348           case 2:
2349             if (max_ch_num > 2) {
2350               if (p_obj_exhaacplus_dec->aac_config.element_instance_order[i] !=
2351                   p_obj_exhaacplus_dec->aac_config.ui_coupling_channel) {
2352                 i++;
2353                 continue;
2354               }
2355               channel = 1;
2356             } else {
2357               i++;
2358               continue;
2359             }
2360             cc_channel_check++;
2361             break;
2362           default:
2363             return -1;
2364         }
2365 
2366         if (cc_channel_check > MAX_CC_CHANNEL_NUM)
2367           return IA_XHEAAC_DEC_EXE_FATAL_UNIMPLEMENTED_CCE;
2368         if (ps_enable == 1) {
2369           channel = 2;
2370         }
2371 
2372         if (p_obj_exhaacplus_dec->aac_config.element_type[i] != 2) {
2373           channel_check += channel;
2374         }
2375 
2376         if (channel_check > max_ch_num) {
2377           p_state_enhaacplus_dec->i_bytes_consumed = 1;
2378           return IA_XHEAAC_DEC_INIT_FATAL_STREAM_CHAN_GT_MAX;
2379         }
2380 
2381         temp = p_state_enhaacplus_dec->aac_persistent_mem_v;
2382 
2383         prev_persistent_used_t = persistent_used_t;
2384 
2385         ixheaacd_allocate_mem_persistent(
2386             p_obj_exhaacplus_dec, p_state_enhaacplus_dec, channel,
2387             &persistent_used_t, &prev_sbrpersistent_used_t, ps_enable);
2388 
2389         p_state_enhaacplus_dec->aac_persistent_mem_v = temp;
2390         p_state_enhaacplus_dec->last_frame_ok = 1;
2391 
2392         p_state_enhaacplus_dec->num_channel_last = 0;
2393         p_state_enhaacplus_dec->ui_init_done = 0;
2394         p_state_enhaacplus_dec->ui_input_over = 0;
2395         p_state_enhaacplus_dec->ptr_bit_stream =
2396             p_state_enhaacplus_dec->pstr_bit_buf;
2397 
2398         p_state_enhaacplus_dec->pstr_aac_dec_info[i] = 0;
2399 
2400         p_state_enhaacplus_dec->pstr_aac_dec_info[i] =
2401             ixheaacd_aac_decoder_init(
2402                 p_state_enhaacplus_dec,
2403                 p_state_enhaacplus_dec->pstr_stream_sbr[i], channel,
2404                 (WORD8 *)p_state_enhaacplus_dec->aac_persistent_mem_v +
2405                     prev_persistent_used_t,
2406                 p_state_enhaacplus_dec->frame_length);
2407 
2408         if (!p_state_enhaacplus_dec->pstr_aac_dec_info[i]) {
2409           p_state_enhaacplus_dec->i_bytes_consumed = 1;
2410           return IA_XHEAAC_DEC_INIT_FATAL_DEC_INIT_FAIL;
2411         }
2412 
2413         p_state_enhaacplus_dec->str_sbr_dec_info[i] = ixheaacd_init_sbr(
2414             sample_rate_2, frame_size_2,
2415             (FLAG *)&p_obj_exhaacplus_dec->aac_config.down_sample_flag,
2416             p_state_enhaacplus_dec->sbr_persistent_mem_v,
2417             p_state_enhaacplus_dec->ptr_overlap_buf, channel, ps_enable, 1,
2418             frame_size_2 * 2, &harmonic_sbr_flag, NULL,
2419             p_state_enhaacplus_dec->str_sbr_config,
2420             p_state_enhaacplus_dec->audio_object_type,
2421             p_state_enhaacplus_dec->mps_dec_handle.ldmps_config
2422                 .ldmps_present_flag,
2423             p_state_enhaacplus_dec->mps_dec_handle.ldmps_config
2424                 .no_ldsbr_present);
2425         if (p_state_enhaacplus_dec->str_sbr_dec_info[i]) {
2426           p_state_enhaacplus_dec->str_sbr_dec_info[i]->xaac_jmp_buf =
2427               &(p_state_enhaacplus_dec->xaac_jmp_buf);
2428         }
2429         if ((sbr_present_flag &&
2430             ((p_obj_exhaacplus_dec->p_state_aac->audio_object_type ==
2431               AOT_AAC_LC) ||
2432              (p_obj_exhaacplus_dec->p_state_aac->audio_object_type ==
2433               AOT_SBR) ||
2434              (p_obj_exhaacplus_dec->p_state_aac->audio_object_type ==
2435                AOT_PS))) ||
2436             ((p_state_enhaacplus_dec->mps_dec_handle.ldmps_config
2437                   .ldmps_present_flag == 1) &&
2438              (p_obj_exhaacplus_dec->p_state_aac->audio_object_type ==
2439               AOT_ER_AAC_ELD)))
2440           p_obj_exhaacplus_dec->aac_config.flag_to_stereo = 1;
2441         copy_qmf_to_ldmps(&p_obj_exhaacplus_dec->p_state_aac->mps_dec_handle,
2442                           p_state_enhaacplus_dec->sbr_persistent_mem_v);
2443         if (p_state_enhaacplus_dec->audio_object_type == AOT_AAC_LC &&
2444             p_state_enhaacplus_dec->ui_mps_out_bytes != 0) {
2445           p_state_enhaacplus_dec->heaac_mps_handle.heaac_mps_present = 1;
2446           if (p_state_enhaacplus_dec->pstr_stream_sbr[0][0].no_elements) {
2447             p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle.mps_with_sbr = 1;
2448           }
2449           error_code =
2450               ixheaacd_aac_mps_init(p_obj_exhaacplus_dec, mps_buffer,
2451                                     p_state_enhaacplus_dec->ui_mps_out_bytes, sample_rate_1);
2452           if (error_code) return error_code;
2453           p_obj_exhaacplus_dec->aac_config.ui_n_channels =
2454               p_state_enhaacplus_dec->heaac_mps_handle.num_output_channels_at;
2455           if (p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle.mps_with_sbr == 1) {
2456             p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 1;
2457           }
2458           if (p_obj_exhaacplus_dec->aac_config.element_type[i + 1] >= 0 &&
2459               p_obj_exhaacplus_dec->aac_config.element_type[i + 1] <= 3) {
2460             return IA_FATAL_ERROR;
2461           }
2462           break;
2463         }
2464         i++;
2465       }
2466       p_state_enhaacplus_dec->pers_mem_ptr =
2467           (WORD8 *)p_state_enhaacplus_dec->aac_persistent_mem_v +
2468           persistent_used_t;
2469 
2470       p_obj_exhaacplus_dec->aac_config.i_channel_mask =
2471           ixheaacd_get_channel_mask(p_obj_exhaacplus_dec);
2472 
2473       {
2474         num_channels_1 = 0;
2475         ch_idx = 0;
2476         while (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] >= 0 &&
2477                p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] <= 3) {
2478           if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 0 ||
2479               p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 3)
2480             num_channels_1 += 1;
2481           if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 1)
2482             num_channels_1 += 2;
2483           ch_idx++;
2484         }
2485 
2486         if (ch_idx == 2 && num_channels_1 == 2) {
2487           p_obj_exhaacplus_dec->aac_config.ui_channel_mode = 2;
2488         }
2489         if (ch_idx == 1) {
2490           if (num_channels_1 == 1)
2491             p_obj_exhaacplus_dec->aac_config.ui_channel_mode = 0;
2492           if (num_channels_1 == 2)
2493             p_obj_exhaacplus_dec->aac_config.ui_channel_mode = 1;
2494         }
2495 
2496         if (ps_detected == 1 && num_channels_1 == 1) num_channels_1 = 2;
2497       }
2498     }
2499     if (1 == p_obj_exhaacplus_dec->aac_config.downmix) num_channels_1 = 2;
2500 
2501     if (p_obj_exhaacplus_dec->aac_config.flag_downmix == 1) {
2502       num_channels_1 = 1;
2503     }
2504 
2505     if ((p_obj_exhaacplus_dec->aac_config.flag_to_stereo == 1) &&
2506         (ch_idx == 1 || num_channels_1 <= 2)) {
2507       num_channels_1 = 2;
2508     }
2509 
2510     p_obj_exhaacplus_dec->aac_config.ui_n_channels = num_channels_1;
2511     p_obj_exhaacplus_dec->aac_config.ui_samp_freq = sample_rate;
2512     p_state_enhaacplus_dec->ui_init_done = 1;
2513 
2514     memcpy(it_bit_buff, &temp_bit_buff, sizeof(struct ia_bit_buf_struct));
2515 
2516     p_state_enhaacplus_dec->b_n_raw_data_blk = 0;
2517 
2518     if (p_obj_exhaacplus_dec->p_state_aac->header_dec_done == 1) {
2519       p_obj_exhaacplus_dec->p_state_aac->header_dec_done = 0;
2520     }
2521   }
2522   return err_code;
2523 }
2524 
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)2525 VOID ixheaacd_fill_slot_order(ia_aac_dec_state_struct *p_state_enhaacplus_dec,
2526                               WORD32 ch, WORD8 *ptr_is_cpe,
2527                               WORD8 *ptr_tag_select, WORD32 *ptr_idx_no) {
2528   WORD32 i;
2529   WORD32 idx_no = *ptr_idx_no;
2530   WORD *p_slot_element = p_state_enhaacplus_dec->p_config->slot_element;
2531   WORD *p_element_type = p_state_enhaacplus_dec->p_config->element_type;
2532   WORD *p_element_instance_order =
2533       p_state_enhaacplus_dec->p_config->element_instance_order;
2534 
2535   for (i = 0; i < ch; i++) {
2536     if (ptr_is_cpe[i] == 0) {
2537       *p_slot_element++ = idx_no++;
2538       *p_element_type++ = 0;
2539       *p_element_instance_order++ = ptr_tag_select[i];
2540     }
2541   }
2542   *ptr_idx_no = idx_no;
2543 }
2544 
ixheaacd_fill_prog_config_slots(ia_aac_dec_state_struct * p_state_enhaacplus_dec)2545 VOID ixheaacd_fill_prog_config_slots(
2546     ia_aac_dec_state_struct *p_state_enhaacplus_dec) {
2547   WORD32 idx_no = 0;
2548 
2549   ixheaacd_fill_slot_order(
2550       p_state_enhaacplus_dec, p_state_enhaacplus_dec->p_config->str_prog_config
2551                                   .num_front_channel_elements,
2552       p_state_enhaacplus_dec->p_config->str_prog_config.front_element_is_cpe,
2553       p_state_enhaacplus_dec->p_config->str_prog_config
2554           .front_element_tag_select,
2555       &idx_no);
2556 
2557   ixheaacd_fill_slot_order(
2558       p_state_enhaacplus_dec, p_state_enhaacplus_dec->p_config->str_prog_config
2559                                   .num_side_channel_elements,
2560       p_state_enhaacplus_dec->p_config->str_prog_config.side_element_is_cpe,
2561       p_state_enhaacplus_dec->p_config->str_prog_config.side_element_tag_select,
2562       &idx_no);
2563 
2564   ixheaacd_fill_slot_order(
2565       p_state_enhaacplus_dec, p_state_enhaacplus_dec->p_config->str_prog_config
2566                                   .num_back_channel_elements,
2567       p_state_enhaacplus_dec->p_config->str_prog_config.back_element_is_cpe,
2568       p_state_enhaacplus_dec->p_config->str_prog_config.back_element_tag_select,
2569       &idx_no);
2570 }
2571 
ixheaacd_dec_execute(ia_exhaacplus_dec_api_struct * p_obj_exhaacplus_dec)2572 IA_ERRORCODE ixheaacd_dec_execute(
2573     ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec) {
2574   ia_adts_header_struct adts = {0};
2575   ia_aac_dec_state_struct *p_state_enhaacplus_dec;
2576 
2577   UWORD8 *in_buffer;
2578   WORD16 *time_data;
2579   WORD16 num_of_out_samples = 0;
2580   WORD16 frame_size = 0;
2581   WORD32 sample_rate_dec = 0;
2582   WORD32 sample_rate = 0;
2583   WORD16 num_ch = 0;
2584   struct ia_bit_buf_struct *it_bit_buff;
2585   UWORD8 *mps_buffer;
2586   WORD32 error_code = IA_NO_ERROR;
2587   WORD ch_idx1;
2588   WORD type;
2589   WORD total_channels = 0;
2590   WORD total_elements = 0;
2591   WORD16 *actual_out_buffer = NULL;
2592   WORD ps_enable;
2593   WORD esbr_mono_downmix = 0;
2594   WORD8 element_used[MAX_BS_ELEMENT];
2595   WORD32 channel_coupling_flag = 0;
2596 
2597   SIZE_T bytes_for_sync;
2598   WORD32 audio_mux_length_bytes_last = 0;
2599   WORD32 ret_val;
2600   WORD32 mps_out_samples;
2601 
2602   p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 0;
2603   p_obj_exhaacplus_dec->aac_config.frame_status = 1;
2604 
2605   if (p_obj_exhaacplus_dec->p_state_aac != NULL) {
2606     ret_val = setjmp(p_obj_exhaacplus_dec->p_state_aac->xaac_jmp_buf);
2607     if (ret_val != 0) {
2608       p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed =
2609           p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes;
2610       p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = 0;
2611       p_obj_exhaacplus_dec->aac_config.frame_status = 0;
2612       return IA_NO_ERROR;
2613     }
2614   }
2615 
2616   time_data = (WORD16 *)(p_obj_exhaacplus_dec
2617                              ->pp_mem_aac[IA_ENHAACPLUS_DEC_OUTPUT_IDX]);
2618   in_buffer = p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_INPUT_IDX];
2619   p_state_enhaacplus_dec = p_obj_exhaacplus_dec->p_state_aac;
2620   p_state_enhaacplus_dec->aac_scratch_mem_v =
2621       p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_SCRATCH_IDX];
2622   p_state_enhaacplus_dec->mps_header = -1;
2623   mps_buffer = p_state_enhaacplus_dec->mps_buffer;
2624   it_bit_buff = p_state_enhaacplus_dec->pstr_bit_buf;
2625 
2626   ch_idx1 = 0;
2627   p_state_enhaacplus_dec->i_bytes_consumed = 0;
2628 
2629   if (p_state_enhaacplus_dec->audio_object_type == AOT_USAC) {
2630     WORD32 pcm_size = p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz;
2631     WORD8 *inbuffer = (WORD8 *)(p_obj_exhaacplus_dec
2632                                     ->pp_mem_aac[IA_ENHAACPLUS_DEC_INPUT_IDX]);
2633     WORD8 *outbuffer =
2634         (WORD8 *)(p_obj_exhaacplus_dec
2635                       ->pp_mem_aac[IA_ENHAACPLUS_DEC_OUTPUT_IDX]);
2636     WORD32 out_bytes = 0;
2637 
2638     WORD32 frames_done = p_obj_exhaacplus_dec->p_state_aac->frame_counter;
2639 
2640     ia_dec_data_struct *pstr_dec_data =
2641         (ia_dec_data_struct *)(p_obj_exhaacplus_dec->p_state_aac
2642                                    ->pstr_dec_data);
2643 
2644     if (pstr_dec_data->str_usac_data.down_samp_sbr != 0) return IA_FATAL_ERROR;
2645 
2646     if (p_obj_exhaacplus_dec->p_state_aac->ui_input_over == 0) {
2647       ia_audio_specific_config_struct *ptr_audio_specific_config =
2648           ((ia_audio_specific_config_struct *)
2649                p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config);
2650 
2651       ptr_audio_specific_config->str_usac_config.str_usac_dec_config
2652           .preroll_counter = 0;
2653       {
2654         WORD32 iii = 0;
2655         for (iii = 0; iii < (MAX_AUDIO_PREROLLS + 1); iii++) {
2656           ((ia_dec_data_struct *)(p_obj_exhaacplus_dec->p_state_aac
2657                                       ->pstr_dec_data))
2658               ->str_frame_data.str_audio_specific_config.str_usac_config
2659               .str_usac_dec_config.usac_ext_gain_payload_len[iii] = 0;
2660           ptr_audio_specific_config->str_usac_config.str_usac_dec_config
2661               .usac_ext_gain_payload_len[iii] =
2662               0;  // reinitilize the payload len buff
2663           ptr_audio_specific_config->str_usac_config.str_usac_dec_config
2664               .preroll_bytes[iii] = 0;
2665         }
2666       }
2667 
2668       ((ia_dec_data_struct *)(p_obj_exhaacplus_dec->p_state_aac->pstr_dec_data))
2669           ->str_frame_data.str_audio_specific_config.str_usac_config
2670           .str_usac_dec_config.preroll_counter = 0;
2671       error_code = ixheaacd_dec_main(
2672           p_obj_exhaacplus_dec, inbuffer, outbuffer, &out_bytes, frames_done,
2673           pcm_size, &p_obj_exhaacplus_dec->p_state_aac->num_of_output_ch);
2674       if (error_code) {
2675         if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
2676           p_obj_exhaacplus_dec->aac_config.frame_status = 0;
2677         } else {
2678           return error_code;
2679         }
2680       }
2681       p_obj_exhaacplus_dec->p_state_aac->frame_counter++;
2682     } else {
2683       out_bytes = 0;
2684     }
2685 
2686     if (pstr_dec_data->str_usac_data.ec_flag == 0) {
2687       if (p_state_enhaacplus_dec->bs_format != LOAS_BSFORMAT) {
2688         p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed =
2689             p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes;
2690       }
2691     } else {
2692       if (p_state_enhaacplus_dec->bs_format != LOAS_BSFORMAT) {
2693         if (pstr_dec_data->str_usac_data.frame_ok == 0) {
2694           p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed =
2695               p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes;
2696           pstr_dec_data->dec_bit_buf.cnt_bits = 0;
2697         } else {
2698           ia_dec_data_struct *pstr_dec_data =
2699               (ia_dec_data_struct *)p_obj_exhaacplus_dec->p_state_aac->pstr_dec_data;
2700 
2701           if (pstr_dec_data->dec_bit_buf.cnt_bits & 7) {
2702             pstr_dec_data->dec_bit_buf.cnt_bits -= (pstr_dec_data->dec_bit_buf.cnt_bits & 7);
2703           }
2704           if (pstr_dec_data->dec_bit_buf.cnt_bits == 0) {
2705             p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed =
2706                 p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes;
2707           } else {
2708             p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed =
2709                 p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes -
2710                 (pstr_dec_data->dec_bit_buf.cnt_bits >> 3);
2711           }
2712         }
2713       }
2714     }
2715 
2716     p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = out_bytes;
2717     p_obj_exhaacplus_dec->aac_config.ui_n_channels =
2718         p_obj_exhaacplus_dec->p_state_aac->num_of_output_ch;
2719     pstr_dec_data->str_usac_data.sbr_parse_err_flag = 0;
2720 
2721     return 0;
2722   }
2723 
2724   while (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx1] <= 3 &&
2725          p_obj_exhaacplus_dec->aac_config.element_type[ch_idx1] >= 0) {
2726     if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx1] == 0 ||
2727         p_obj_exhaacplus_dec->aac_config.element_type[ch_idx1] == 3) {
2728       total_channels += 1;
2729       total_elements += 1;
2730     }
2731     if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx1] == 1) {
2732       total_elements += 1;
2733       total_channels += 2;
2734     }
2735     if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx1] == 2) {
2736       total_elements += 1;
2737     }
2738 
2739     ch_idx1++;
2740     if (ch_idx1 > MAX_BS_ELEMENT) {
2741       if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal)
2742         break;
2743       else
2744         return IA_FATAL_ERROR;
2745     }
2746   }
2747 
2748   if (ch_idx1 != 1) {
2749     ps_enable = 0;
2750     if (p_obj_exhaacplus_dec->aac_config.ui_max_channels > 2) {
2751       WORD32 scratch_pointer;
2752 
2753       scratch_pointer = (MAX_SCR_SIZE - SCR_INTER_SCR_SIZE);
2754 
2755       p_state_enhaacplus_dec->coup_ch_output =
2756           (WORD32 *)((WORD8 *)
2757                          p_obj_exhaacplus_dec->p_state_aac->aac_scratch_mem_v +
2758                      scratch_pointer);
2759     }
2760 
2761   }
2762 
2763   else {
2764     if (total_channels < (WORD)p_obj_exhaacplus_dec->aac_config.ui_n_channels)
2765       total_channels = p_obj_exhaacplus_dec->aac_config.ui_n_channels;
2766     ps_enable = 1;
2767   }
2768 
2769   p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = 0;
2770   p_obj_exhaacplus_dec->p_state_aac->ui_mps_out_bytes = 0;
2771   if (p_state_enhaacplus_dec->ui_in_bytes == 0) {
2772     UWORD32 i;
2773     WORD32 j;
2774     if (p_state_enhaacplus_dec->peak_lim_init == 1) {
2775       p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes =
2776           (p_state_enhaacplus_dec->peak_limiter.attack_time_samples) *
2777           total_channels * sizeof(WORD16);
2778 
2779       for (j = 0; j < total_channels; j++) {
2780         for (i = 0;
2781              i < (p_state_enhaacplus_dec->peak_limiter.attack_time_samples -
2782                   p_state_enhaacplus_dec->peak_limiter.delayed_input_index);
2783              i++) {
2784           *(time_data + total_channels * i + j) = ixheaac_round16(
2785               (WORD32)*(p_state_enhaacplus_dec->peak_limiter.delayed_input +
2786                 (p_state_enhaacplus_dec->peak_limiter.delayed_input_index) *
2787                     total_channels +
2788                 total_channels * i + j));
2789         }
2790       }
2791 
2792       for (j = 0; j < total_channels; j++) {
2793         for (i = 0;
2794              i < p_state_enhaacplus_dec->peak_limiter.delayed_input_index;
2795              i++) {
2796           *(time_data +
2797             (p_state_enhaacplus_dec->peak_limiter.attack_time_samples -
2798              p_state_enhaacplus_dec->peak_limiter.delayed_input_index) *
2799                 total_channels +
2800             total_channels * i + j) =
2801               ixheaac_round16(
2802                   (WORD32)*(p_state_enhaacplus_dec->peak_limiter.delayed_input +
2803                    total_channels * i + j));
2804         }
2805       }
2806 
2807       if (p_obj_exhaacplus_dec->aac_config.dup_stereo_flag) {
2808         for (i = 0;
2809              i < (p_state_enhaacplus_dec->peak_limiter.attack_time_samples);
2810              i++) {
2811           time_data[2 * i + 1] = time_data[2 * i + 0];
2812         }
2813       }
2814     } else {
2815       p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = 0;
2816     }
2817 
2818     p_state_enhaacplus_dec->i_bytes_consumed = 0;
2819     return IA_NO_ERROR;
2820   }
2821 
2822   if (ch_idx1 == 0) {
2823     p_state_enhaacplus_dec->i_bytes_consumed = 1;
2824     if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
2825       p_obj_exhaacplus_dec->aac_config.frame_status = 0;
2826     } else {
2827       return IA_XHEAAC_DEC_EXE_NONFATAL_DECODE_FRAME_ERROR;
2828     }
2829   }
2830   if (total_channels > (WORD)p_obj_exhaacplus_dec->aac_config.ui_max_channels) {
2831     p_state_enhaacplus_dec->i_bytes_consumed = 1;
2832     if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
2833       p_obj_exhaacplus_dec->aac_config.frame_status = 0;
2834     } else {
2835       return IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_MAX_CHANNEL;
2836     }
2837   }
2838 
2839   if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD ||
2840       p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) {
2841     if (p_obj_exhaacplus_dec->aac_config.ui_mp4_flag)
2842       p_state_enhaacplus_dec->frame_size = p_state_enhaacplus_dec->ui_in_bytes;
2843   }
2844 
2845   if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LC) {
2846     if (p_obj_exhaacplus_dec->aac_config.ui_mp4_flag)
2847       p_state_enhaacplus_dec->frame_size = 1024;
2848   }
2849 
2850   {
2851     ixheaacd_create_init_bit_buf(it_bit_buff, in_buffer,
2852                                  p_state_enhaacplus_dec->ui_in_bytes);
2853     it_bit_buff->xaac_jmp_buf = &(p_state_enhaacplus_dec->xaac_jmp_buf);
2854 
2855     it_bit_buff->adts_header_present =
2856         p_state_enhaacplus_dec->s_adts_hdr_present;
2857     it_bit_buff->no_raw_data_blocks =
2858         (WORD8)p_state_enhaacplus_dec->b_n_raw_data_blk;
2859     it_bit_buff->protection_absent = p_state_enhaacplus_dec->protection_absent;
2860 
2861     if (p_state_enhaacplus_dec->s_adts_hdr_present) {
2862       if (p_state_enhaacplus_dec->b_n_raw_data_blk == 0) {
2863         WORD32 error;
2864 
2865         error = ixheaacd_readifadts(p_state_enhaacplus_dec, it_bit_buff, &adts);
2866         if (error) {
2867           if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
2868             p_obj_exhaacplus_dec->aac_config.frame_status = 0;
2869             if (adts.samp_freq_index > 11) {
2870               adts.samp_freq_index = 11;
2871             }
2872           } else {
2873             return error;
2874           }
2875         }
2876 
2877         if ((WORD32)p_state_enhaacplus_dec->sampling_rate !=
2878             (WORD32)((p_obj_exhaacplus_dec->aac_tables.pstr_huffmann_tables
2879                           ->str_sample_rate_info[adts.samp_freq_index]
2880                           .sampling_frequency))) {
2881           p_state_enhaacplus_dec->i_bytes_consumed = 0;
2882           if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
2883             p_obj_exhaacplus_dec->aac_config.frame_status = 0;
2884           } else {
2885             return IA_XHEAAC_DEC_EXE_NONFATAL_CHANGED_ADTS_SF;
2886           }
2887         }
2888       }
2889     }
2890 
2891     bytes_for_sync = (SIZE_T)it_bit_buff->ptr_read_next;
2892 
2893     if (p_state_enhaacplus_dec->bs_format == LOAS_BSFORMAT) {
2894       WORD32 result, audio_mux_len_bytes_last;
2895       WORD32 cnt_bits = it_bit_buff->cnt_bits;
2896       WORD32 sync = ixheaacd_read_bits_buf(it_bit_buff, 11);
2897       UWORD32 curr_samp_rate = 0;
2898 
2899       if (p_state_enhaacplus_dec->latm_initialized)
2900         curr_samp_rate =
2901             p_state_enhaacplus_dec->latm_struct_element.layer_info[0][0]
2902                 .asc.sampling_freq;
2903 
2904       while (sync != 0x2b7) {
2905         sync = ((sync & 0x3ff) << 1) | ixheaacd_read_bits_buf(it_bit_buff, 1);
2906         if (it_bit_buff->cnt_bits < 13) {
2907           ixheaacd_read_bidirection(it_bit_buff, -11);
2908           p_state_enhaacplus_dec->i_bytes_consumed =
2909               (cnt_bits - it_bit_buff->cnt_bits) / 8;
2910 
2911           if (p_state_enhaacplus_dec->i_bytes_consumed == 0)
2912             p_state_enhaacplus_dec->i_bytes_consumed = 1;
2913           if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
2914             p_obj_exhaacplus_dec->aac_config.frame_status = 0;
2915           } else {
2916             return (IA_XHEAAC_DEC_INIT_NONFATAL_HEADER_NOT_AT_START);
2917           }
2918         }
2919       }
2920 
2921       it_bit_buff->audio_mux_align = it_bit_buff->cnt_bits - 13;
2922 
2923       audio_mux_len_bytes_last = ixheaacd_read_bits_buf(it_bit_buff, 13);
2924 
2925       audio_mux_length_bytes_last = audio_mux_len_bytes_last;
2926 
2927       bytes_for_sync = (SIZE_T)it_bit_buff->ptr_read_next - bytes_for_sync;
2928 
2929       if (it_bit_buff->cnt_bits < (audio_mux_len_bytes_last << 3)) {
2930         ixheaacd_read_bidirection(it_bit_buff, -(13 + 11));
2931         p_state_enhaacplus_dec->i_bytes_consumed = (cnt_bits - it_bit_buff->cnt_bits) / 8;
2932         if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
2933           p_obj_exhaacplus_dec->aac_config.frame_status = 0;
2934         } else {
2935           return IA_XHEAAC_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES;
2936         }
2937       } else {
2938         ixheaacd_read_bidirection(it_bit_buff, -(13));
2939       }
2940 
2941       if (sync == 0x2b7) {
2942         result = ixheaacd_latm_audio_mux_element(
2943             it_bit_buff, &p_state_enhaacplus_dec->latm_struct_element,
2944             p_state_enhaacplus_dec,
2945             (ia_sampling_rate_info_struct *)&p_obj_exhaacplus_dec->aac_tables
2946                 .pstr_huffmann_tables->str_sample_rate_info[0]);
2947         if (result < 0) {
2948           if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
2949             p_obj_exhaacplus_dec->aac_config.frame_status = 0;
2950           } else {
2951             return result;
2952           }
2953         }
2954         if (!p_state_enhaacplus_dec->latm_initialized) {
2955           p_state_enhaacplus_dec->sampling_rate =
2956               p_state_enhaacplus_dec->latm_struct_element.layer_info[0][0].asc.sampling_freq;
2957           p_state_enhaacplus_dec->latm_initialized = 1;
2958         } else {
2959           if (p_state_enhaacplus_dec->sampling_rate != curr_samp_rate) {
2960             p_state_enhaacplus_dec->i_bytes_consumed = 0;
2961             if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
2962               p_obj_exhaacplus_dec->aac_config.frame_status = 0;
2963             } else {
2964               return IA_XHEAAC_DEC_EXE_NONFATAL_CHANGED_ADTS_SF;
2965             }
2966           }
2967         }
2968       }
2969     }
2970   }
2971 
2972   if (total_elements == 2 && total_channels == 2 &&
2973       (p_state_enhaacplus_dec->p_config->ui_pce_found_in_hdr == 1 ||
2974        p_state_enhaacplus_dec->p_config->ui_pce_found_in_hdr == 3)) {
2975     ixheaacd_fill_prog_config_slots(p_state_enhaacplus_dec);
2976   }
2977 
2978   memset(element_used, 0, sizeof(WORD8) * MAX_BS_ELEMENT);
2979 
2980   if (it_bit_buff->cnt_bits <= 0) {
2981     it_bit_buff->cnt_bits = -1;
2982     ixheaacd_updatebytesconsumed(p_state_enhaacplus_dec, it_bit_buff);
2983     if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
2984       p_obj_exhaacplus_dec->aac_config.frame_status = 0;
2985     } else {
2986       return (WORD16)((WORD32)IA_XHEAAC_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES);
2987     }
2988   }
2989 
2990   { it_bit_buff->initial_cnt_bits = it_bit_buff->cnt_bits; }
2991 
2992   if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD) {
2993     if (p_state_enhaacplus_dec->s_adts_hdr_present)
2994       p_state_enhaacplus_dec->frame_size = adts.aac_frame_length;
2995   }
2996 
2997   if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LC) {
2998     if (p_state_enhaacplus_dec->s_adts_hdr_present)
2999       p_state_enhaacplus_dec->frame_size = 1024;
3000   }
3001 
3002   if (p_state_enhaacplus_dec->pstr_drc_dec) {
3003     p_state_enhaacplus_dec->pstr_drc_dec->num_drc_elements = 0;
3004 
3005     p_state_enhaacplus_dec->pstr_drc_dec->state = 1;
3006   }
3007   if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
3008     if (total_elements > MAX_BS_ELEMENT) {
3009       total_elements = MAX_BS_ELEMENT;
3010     }
3011   }
3012 
3013   WORD16 *intermediate_scr = (WORD16 *)(WORD8 *)p_state_enhaacplus_dec->aac_scratch_mem_v +
3014                              (MAX_SCR_SIZE - SCR_INTER_SCR_SIZE - SCR_COUP_CH_OUT_SIZE);
3015 
3016   for (ch_idx1 = 0; ch_idx1 < total_elements; ch_idx1++) {
3017     WORD32 skip_full_decode = 0;
3018     WORD32 ch_idx = ch_idx1;
3019     WORD32 channel = 0;
3020     WORD ch_fac, slot_ele;
3021 
3022     if (p_state_enhaacplus_dec->audio_object_type < ER_OBJECT_START ||
3023         (p_state_enhaacplus_dec->audio_object_type != AOT_ER_AAC_LD &&
3024          p_state_enhaacplus_dec->audio_object_type != AOT_ER_AAC_ELD &&
3025          p_state_enhaacplus_dec->audio_object_type != AOT_ER_AAC_LC)) {
3026       jmp_buf local;
3027 
3028       if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal == 1) {
3029         ret_val = setjmp(local);
3030       }
3031       if (ret_val == 0) {
3032         if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal == 1) {
3033           p_obj_exhaacplus_dec->p_state_aac->ptr_bit_stream->xaac_jmp_buf = &local;
3034         }
3035         error_code = ixheaacd_get_element_index_tag(
3036             p_obj_exhaacplus_dec, ch_idx1, &ch_idx, &channel,
3037             p_obj_exhaacplus_dec->aac_config.element_instance_order, total_elements, element_used,
3038             total_channels, p_state_enhaacplus_dec->pstr_drc_dec,
3039             &p_state_enhaacplus_dec->drc_dummy, mps_buffer, &p_state_enhaacplus_dec->mps_header,
3040             &p_state_enhaacplus_dec->ui_mps_out_bytes);
3041       }
3042 
3043       if (error_code || ret_val) {
3044         ixheaacd_updatebytesconsumed(p_state_enhaacplus_dec, it_bit_buff);
3045         if (it_bit_buff->cnt_bits < 0) {
3046           p_state_enhaacplus_dec->ui_out_bytes = 0;
3047           p_state_enhaacplus_dec->ui_mps_out_bytes = 0;
3048           p_state_enhaacplus_dec->b_n_raw_data_blk = 0;
3049         }
3050         p_state_enhaacplus_dec->i_bytes_consumed = 1;
3051         p_state_enhaacplus_dec->b_n_raw_data_blk = 0;
3052         if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
3053           p_obj_exhaacplus_dec->aac_config.frame_status = 0;
3054         } else {
3055           return error_code;
3056         }
3057       }
3058       if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == ID_CPE)
3059       {
3060         if (channel != 2)
3061         {
3062           if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal)
3063           {
3064             p_obj_exhaacplus_dec->aac_config.frame_status = 0;
3065             channel = 2;
3066           }
3067           else
3068           {
3069             return IA_FATAL_ERROR;
3070           }
3071         }
3072       }
3073       else
3074       {
3075         if (channel != 1)
3076         {
3077           if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal)
3078           {
3079             p_obj_exhaacplus_dec->aac_config.frame_status = 0;
3080             channel = 1;
3081           }
3082           else
3083           {
3084             return IA_FATAL_ERROR;
3085           }
3086         }
3087       }
3088     } else {
3089       if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == ID_SCE)
3090         channel = 1;
3091       else
3092         channel = 2;
3093     }
3094 
3095     if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal && (error_code || ret_val)) {
3096       if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 0 ||
3097           p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 3) {
3098         if (channel > 1) {
3099           channel = 1;
3100         }
3101       }
3102       if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 1) {
3103         if (channel > 2) {
3104           channel = 2;
3105         }
3106       }
3107       if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 2) {
3108         if (p_obj_exhaacplus_dec->aac_config.ui_max_channels > 2) {
3109           if (!(p_obj_exhaacplus_dec->aac_config.element_instance_order[ch_idx] !=
3110                 p_obj_exhaacplus_dec->aac_config.ui_coupling_channel)) {
3111             if (channel > 1) {
3112               channel = 1;
3113             }
3114           }
3115         }
3116       }
3117       if (ps_enable == 1) {
3118         if (channel > 2) {
3119           channel = 2;
3120         }
3121       }
3122     }
3123 
3124     ch_fac = total_channels;
3125     slot_ele = p_obj_exhaacplus_dec->aac_config.slot_element[ch_idx];
3126     actual_out_buffer = time_data;
3127     if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 2) {
3128       p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->p_ind_channel_info =
3129           &p_state_enhaacplus_dec->ind_cc_info;
3130       if (p_obj_exhaacplus_dec->aac_config.element_instance_order[ch_idx] !=
3131           p_obj_exhaacplus_dec->aac_config.ui_coupling_channel) {
3132         skip_full_decode = 1;
3133         ixheaacd_set_aac_persistent_buffers(
3134             p_state_enhaacplus_dec->pers_mem_ptr, channel);
3135 
3136         {
3137           struct ia_aac_persistent_struct *aac_persistent_mem =
3138               (struct ia_aac_persistent_struct *)
3139                   p_state_enhaacplus_dec->pers_mem_ptr;
3140           aac_persistent_mem->str_aac_decoder.pstr_aac_tables =
3141               &p_obj_exhaacplus_dec->aac_tables;
3142           aac_persistent_mem->str_aac_decoder.pstr_common_tables =
3143               p_obj_exhaacplus_dec->common_tables;
3144         }
3145 
3146         p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx] = 0;
3147 
3148         p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = 0;
3149 
3150         p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx] =
3151             ixheaacd_aac_decoder_init(
3152                 p_state_enhaacplus_dec,
3153 
3154                 p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx],
3155 
3156                 channel, p_state_enhaacplus_dec->pers_mem_ptr,
3157                 p_state_enhaacplus_dec->frame_length
3158 
3159                 );
3160         if (!p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]) {
3161           p_state_enhaacplus_dec->i_bytes_consumed = 1;
3162           if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
3163             p_obj_exhaacplus_dec->aac_config.frame_status = 0;
3164           } else {
3165             return IA_XHEAAC_DEC_INIT_FATAL_DEC_INIT_FAIL;
3166           }
3167         }
3168         p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->p_ind_channel_info =
3169             (WORD8 *)p_state_enhaacplus_dec->aac_scratch_mem_v + (P_IND_CH_INFO_OFFSET);
3170       }
3171       if (p_obj_exhaacplus_dec->aac_config.element_type[1] < 3 &&
3172           p_obj_exhaacplus_dec->aac_config.element_type[1] > 0 &&
3173           p_obj_exhaacplus_dec->aac_config.ui_max_channels > 2) {
3174         actual_out_buffer =
3175             (WORD16 *)(VOID *)p_state_enhaacplus_dec->coup_ch_output;
3176       }
3177       ch_fac = 1;
3178       slot_ele = 0;
3179     }
3180 
3181     type = -1;
3182     p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx][0].no_elements = 0;
3183 
3184     {
3185       WORD element_index_order1[MAX_BS_ELEMENT];
3186       ia_aac_dec_scratch_struct aac_scratch_struct;
3187       memset(&aac_scratch_struct, 0, sizeof(aac_scratch_struct));
3188 
3189       ixheaacd_allocate_aac_scr(
3190           &aac_scratch_struct, p_state_enhaacplus_dec->aac_scratch_mem_v,
3191           time_data, channel, p_obj_exhaacplus_dec->aac_config.ui_max_channels,
3192           p_state_enhaacplus_dec->audio_object_type);
3193 
3194       if (p_state_enhaacplus_dec->ch_config == 2 && channel == 1) {
3195         if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
3196           p_obj_exhaacplus_dec->aac_config.frame_status = 0;
3197         } else {
3198           return IA_XHEAAC_DEC_EXE_NONFATAL_DECODE_FRAME_ERROR;
3199         }
3200       }
3201 
3202       error_code = ixheaacd_aacdec_decodeframe(
3203           p_obj_exhaacplus_dec, &aac_scratch_struct, actual_out_buffer,
3204           p_obj_exhaacplus_dec->aac_config.frame_status, &type, &ch_idx, 0, channel,
3205           element_index_order1, skip_full_decode, ch_fac, slot_ele,
3206           p_obj_exhaacplus_dec->aac_config.ui_max_channels, total_channels,
3207           p_obj_exhaacplus_dec->p_state_aac->frame_length,
3208           p_obj_exhaacplus_dec->p_state_aac->frame_size, p_state_enhaacplus_dec->pstr_drc_dec,
3209           p_state_enhaacplus_dec->audio_object_type, p_state_enhaacplus_dec->ch_config,
3210           p_state_enhaacplus_dec->eld_specific_config, p_state_enhaacplus_dec->s_adts_hdr_present,
3211           &p_state_enhaacplus_dec->drc_dummy, p_state_enhaacplus_dec->ldmps_present,
3212           &p_state_enhaacplus_dec->slot_pos, mps_buffer, &p_state_enhaacplus_dec->mps_header,
3213           &p_state_enhaacplus_dec->ui_mps_out_bytes, 0,
3214           p_obj_exhaacplus_dec->aac_config.first_frame);
3215 
3216       p_state_enhaacplus_dec->slot_pos -= (channel - 1);
3217       p_state_enhaacplus_dec->sbr_present = 0;
3218 
3219       if (p_obj_exhaacplus_dec->p_state_aac->qshift_adj[0] != LD_OBJ &&
3220           p_state_enhaacplus_dec->frame_counter == 0) {
3221         ixheaacd_peak_limiter_init(
3222             &p_state_enhaacplus_dec->peak_limiter, total_channels,
3223             p_obj_exhaacplus_dec->p_state_aac->p_config->ui_samp_freq,
3224             &p_state_enhaacplus_dec->peak_limiter.buffer[0],
3225             &p_obj_exhaacplus_dec->p_state_aac->delay_in_samples);
3226         p_obj_exhaacplus_dec->p_state_aac->peak_lim_init = 1;
3227       }
3228 
3229       if (p_state_enhaacplus_dec->audio_object_type < ER_OBJECT_START ||
3230           (p_state_enhaacplus_dec->audio_object_type != AOT_ER_AAC_LD &&
3231            p_state_enhaacplus_dec->audio_object_type != AOT_ER_AAC_ELD &&
3232            p_state_enhaacplus_dec->audio_object_type != AOT_ER_AAC_LC)) {
3233         if ((error_code == 0) && ((ch_idx1 + 1) == total_elements) &&
3234             (type != ID_END)) {
3235           {
3236             p_state_enhaacplus_dec->i_bytes_consumed = (WORD32)(
3237                 it_bit_buff->ptr_read_next - it_bit_buff->ptr_bit_buf_base);
3238             p_state_enhaacplus_dec->b_n_raw_data_blk = 0;
3239             if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
3240               p_obj_exhaacplus_dec->aac_config.frame_status = 0;
3241             } else {
3242             return IA_XHEAAC_DEC_EXE_NONFATAL_ELE_INSTANCE_TAG_NOT_FOUND;
3243           }
3244           }
3245         }
3246       }
3247 
3248       num_ch = p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->channels;
3249       if (skip_full_decode == 0) {
3250         if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD ||
3251             p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD)
3252           frame_size = p_state_enhaacplus_dec->frame_length;
3253         else {
3254           frame_size = p_state_enhaacplus_dec->frame_length;
3255         }
3256 
3257         sample_rate_dec =
3258             p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->sampling_rate;
3259       }
3260     }
3261 
3262     if (skip_full_decode == 1) {
3263       p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx][0].no_elements = 0;
3264     }
3265 
3266     if (p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx][0].no_elements != 0) {
3267       p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 1;
3268     }
3269 
3270     if (error_code) {
3271       if (p_state_enhaacplus_dec->ui_input_over) {
3272         if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
3273           p_obj_exhaacplus_dec->aac_config.frame_status = 0;
3274         } else {
3275           return IA_XHEAAC_DEC_INIT_FATAL_EO_INPUT_REACHED;
3276         }
3277       }
3278       ixheaacd_updatebytesconsumed(p_state_enhaacplus_dec, it_bit_buff);
3279       p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes +=
3280           p_state_enhaacplus_dec->num_of_out_samples * num_ch * sizeof(WORD16);
3281       if (error_code) {
3282         if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
3283           p_obj_exhaacplus_dec->aac_config.frame_status = 0;
3284         } else {
3285           return error_code;
3286         }
3287       }
3288     }
3289 
3290     error_code = IA_NO_ERROR;
3291 
3292     if (p_obj_exhaacplus_dec->aac_config.ui_auto_sbr_upsample == 0) {
3293       if (p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx][0].no_elements == 0 &&
3294           p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) {
3295         p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = 0;
3296         error_code = IA_XHEAAC_DEC_EXE_NONFATAL_SBR_TURNED_OFF;
3297       }
3298     }
3299     if ((!p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) &&
3300         p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx][0].no_elements) {
3301       WORD32 harmonic_sbr_flag = 0;
3302       error_code = IA_XHEAAC_DEC_EXE_NONFATAL_SBR_TURNED_ON;
3303       p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = ixheaacd_init_sbr(
3304           sample_rate_dec, frame_size,
3305           (FLAG *)&p_obj_exhaacplus_dec->aac_config.down_sample_flag,
3306           p_state_enhaacplus_dec->sbr_persistent_mem_v,
3307           p_state_enhaacplus_dec->ptr_overlap_buf, ps_enable ? 2 : channel,
3308           ps_enable, 1, frame_size * 2, &harmonic_sbr_flag, NULL,
3309           p_state_enhaacplus_dec->str_sbr_config,
3310           p_state_enhaacplus_dec->audio_object_type,
3311           p_state_enhaacplus_dec->mps_dec_handle.ldmps_config
3312               .ldmps_present_flag,
3313           p_state_enhaacplus_dec->mps_dec_handle.ldmps_config.no_ldsbr_present);
3314       if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) {
3315         p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->xaac_jmp_buf =
3316             &(p_state_enhaacplus_dec->xaac_jmp_buf);
3317       }
3318     }
3319 
3320     {
3321       if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] &&
3322           p_state_enhaacplus_dec->pstr_stream_sbr[0][0].no_elements) {
3323         ia_sbr_scr_struct sbr_scratch_struct;
3324         ixheaacd_allocate_sbr_scr(&sbr_scratch_struct, p_state_enhaacplus_dec->aac_scratch_mem_v,
3325                                   time_data, total_channels,
3326                                   p_obj_exhaacplus_dec->p_state_aac->qshift_adj,
3327                                   p_state_enhaacplus_dec->slot_pos, channel);
3328 
3329         p_state_enhaacplus_dec->sbr_present = 1;
3330         p_state_enhaacplus_dec->peak_lim_init = 0;
3331 
3332         if (p_obj_exhaacplus_dec->aac_config.ui_enh_sbr)
3333         {
3334           WORD32 audio_object_type = p_state_enhaacplus_dec->audio_object_type;
3335 
3336           if (audio_object_type != AOT_ER_AAC_ELD && audio_object_type != AOT_ER_AAC_LD) {
3337             WORD32 i = 0;
3338             ia_dec_data_struct* pstr_dec_data =
3339                 (ia_dec_data_struct*)p_state_enhaacplus_dec->pstr_dec_data;
3340             if (ch_fac == 1) {
3341               for (; i < 1024; i++) {
3342                 pstr_dec_data->str_usac_data.time_sample_vector[0][i] =
3343                     (FLOAT32)time_data[i];
3344               }
3345               p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[0] =
3346                   &pstr_dec_data->str_usac_data.time_sample_vector[0][0];
3347 
3348               p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[1] =
3349                   &pstr_dec_data->str_usac_data.time_sample_vector[1][0];
3350             } else if (ch_fac == 2) {
3351               for (; i < 1024; i++) {
3352                 pstr_dec_data->str_usac_data.time_sample_vector[0][i] =
3353                     (FLOAT32)time_data[2 * i + 0];
3354                 pstr_dec_data->str_usac_data.time_sample_vector[1][i] =
3355                     (FLOAT32)time_data[2 * i + 1];
3356               }
3357               p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[0] =
3358                   &pstr_dec_data->str_usac_data.time_sample_vector[0][0];
3359 
3360               p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[1] =
3361                   &pstr_dec_data->str_usac_data.time_sample_vector[1][0];
3362             } else if (ch_fac > 2) {
3363               if (channel == 1) {
3364                 for (; i < 1024; i++) {
3365                   pstr_dec_data->str_usac_data.time_sample_vector[0][i] =
3366                       (FLOAT32)(time_data + slot_ele)[i* ch_fac];
3367                 }
3368                 p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[0] =
3369                     &pstr_dec_data->str_usac_data.time_sample_vector[0][0];
3370               } else if (channel == 2) {
3371                 for (; i < 1024; i++) {
3372                   pstr_dec_data->str_usac_data.time_sample_vector[0][i] =
3373                       (FLOAT32)(time_data + slot_ele)[ch_fac * i + 0];
3374                   pstr_dec_data->str_usac_data.time_sample_vector[1][i] =
3375                       (FLOAT32)(time_data + slot_ele)[ch_fac * i + 1];
3376                 }
3377                 p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[0] =
3378                     &pstr_dec_data->str_usac_data.time_sample_vector[0][0];
3379 
3380                 p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[1] =
3381                     &pstr_dec_data->str_usac_data.time_sample_vector[1][0];
3382               }
3383             }
3384           }
3385         }
3386         p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->esbr_hq =
3387             p_obj_exhaacplus_dec->aac_config.ui_hq_esbr;
3388         p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->enh_sbr =
3389             p_obj_exhaacplus_dec->aac_config.ui_enh_sbr;
3390         p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->enh_sbr_ps =
3391             p_obj_exhaacplus_dec->aac_config.ui_enh_sbr_ps;
3392 
3393         if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) {
3394           p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->xaac_jmp_buf =
3395               &(p_state_enhaacplus_dec->xaac_jmp_buf);
3396         }
3397 
3398         if (ixheaacd_applysbr(p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx],
3399                               &p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx][0],
3400                               actual_out_buffer, &num_ch,
3401                               p_obj_exhaacplus_dec->aac_config.frame_status,
3402                               p_obj_exhaacplus_dec->aac_config.down_sample_flag,
3403                               esbr_mono_downmix, &sbr_scratch_struct, ps_enable, ch_fac, slot_ele,
3404                               NULL, &p_state_enhaacplus_dec->str_drc_dec_info,
3405                               p_state_enhaacplus_dec->eld_specific_config.ld_sbr_flag_present,
3406                               p_state_enhaacplus_dec->audio_object_type, 0,
3407                               p_state_enhaacplus_dec->ldmps_present, frame_size,
3408                               p_state_enhaacplus_dec->heaac_mps_handle.heaac_mps_present,
3409                               p_obj_exhaacplus_dec->aac_config.ui_err_conceal,
3410                               p_obj_exhaacplus_dec->aac_config.first_frame) != SBRDEC_OK) {
3411           p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = 0;
3412           if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
3413             p_obj_exhaacplus_dec->aac_config.frame_status = 0;
3414           } else {
3415             return -1;
3416           }
3417         } else {
3418           if (!p_obj_exhaacplus_dec->aac_config.down_sample_flag) {
3419             frame_size = (WORD16)(frame_size * 2);
3420             sample_rate_dec *= 2;
3421           }
3422           if (p_state_enhaacplus_dec->mps_dec_handle.ldmps_config
3423                   .ldmps_present_flag == 1) {
3424             ixheaacd_mps_payload(
3425                 p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx],
3426                 p_obj_exhaacplus_dec);
3427           }
3428         }
3429 
3430         if (p_obj_exhaacplus_dec->aac_config.ui_enh_sbr)
3431         {
3432           WORD32 audio_object_type = p_state_enhaacplus_dec->audio_object_type;
3433 
3434           if (audio_object_type != AOT_ER_AAC_ELD && audio_object_type != AOT_ER_AAC_LD) {
3435             WORD32 out_bytes = 0;
3436             ia_dec_data_struct *pstr_dec_data =
3437                 (ia_dec_data_struct *)p_state_enhaacplus_dec->pstr_dec_data;
3438             if (ch_fac <= 2) {
3439               ixheaacd_samples_sat((WORD8*)time_data, 2048, 16,
3440                                    pstr_dec_data->str_usac_data.time_sample_vector,
3441                                    &out_bytes, ch_fac);
3442             } else {
3443               ixheaacd_samples_sat_mc((WORD8*)(time_data + slot_ele), 2048,
3444                                       pstr_dec_data->str_usac_data.time_sample_vector,
3445                                       &out_bytes, channel, ch_fac);
3446             }
3447           }
3448         }
3449         p_state_enhaacplus_dec->mps_dec_handle.ldmps_config.no_ldsbr_present =
3450             0;
3451         if (p_state_enhaacplus_dec->ui_mps_out_bytes > 0) {
3452           p_state_enhaacplus_dec->heaac_mps_handle.heaac_mps_present = 1;
3453         }
3454       } else {
3455         p_state_enhaacplus_dec->mps_dec_handle.ldmps_config.no_ldsbr_present = 1;
3456       }
3457     }
3458 
3459     if (p_state_enhaacplus_dec->mps_dec_handle.ldmps_config
3460                 .ldmps_present_flag == 1 &&
3461          p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] &&
3462          p_state_enhaacplus_dec->mps_dec_handle.mps_init_done == 1) {
3463       if (p_state_enhaacplus_dec->ec_enable) {
3464         if (!p_obj_exhaacplus_dec->aac_config.first_frame) {
3465           error_code = ixheaacd_ld_mps_apply(p_obj_exhaacplus_dec, actual_out_buffer);
3466           if (error_code) p_obj_exhaacplus_dec->aac_config.frame_status = 0;
3467         }
3468       } else {
3469         error_code = ixheaacd_ld_mps_apply(p_obj_exhaacplus_dec, actual_out_buffer);
3470 
3471         if (error_code)
3472           return error_code;
3473       }
3474     }
3475     if (sample_rate < sample_rate_dec) {
3476       sample_rate = sample_rate_dec;
3477     }
3478 
3479     if (p_state_enhaacplus_dec->sbr_present ||
3480         p_obj_exhaacplus_dec->p_state_aac->qshift_adj[0] == LD_OBJ) {
3481       num_of_out_samples = frame_size;
3482 
3483     } else {
3484       num_of_out_samples =
3485           frame_size -
3486           MIN((WORD16)p_obj_exhaacplus_dec->p_state_aac->delay_in_samples, frame_size);
3487     }
3488 
3489     if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal &&
3490         p_obj_exhaacplus_dec->aac_config.first_frame &&
3491         (p_obj_exhaacplus_dec->p_state_aac->audio_object_type == AOT_ER_AAC_ELD ||
3492          p_obj_exhaacplus_dec->p_state_aac->audio_object_type == AOT_ER_AAC_LD)) {
3493       num_of_out_samples = frame_size;
3494     }
3495 
3496     p_obj_exhaacplus_dec->aac_config.ui_samp_freq = sample_rate;
3497 
3498     p_state_enhaacplus_dec->num_channel_last = num_ch;
3499     p_state_enhaacplus_dec->num_of_out_samples = num_of_out_samples;
3500 
3501     if (p_state_enhaacplus_dec->mps_dec_handle.ldmps_config
3502             .ldmps_present_flag == 1 &&
3503         p_state_enhaacplus_dec->mps_dec_handle.mps_init_done == 1 &&
3504         p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) {
3505       if (p_obj_exhaacplus_dec->p_state_aac->mps_dec_handle.output_buffer) {
3506         ixheaacd_samples_sat((WORD8 *)actual_out_buffer, num_of_out_samples,
3507                              p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz,
3508                              p_obj_exhaacplus_dec->p_state_aac->mps_dec_handle.output_buffer,
3509                              &mps_out_samples, 2);
3510         p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = mps_out_samples;
3511       }
3512       num_ch = p_obj_exhaacplus_dec->p_state_aac->mps_dec_handle.out_ch_count;
3513       if (p_state_enhaacplus_dec->ec_enable) {
3514         if (p_obj_exhaacplus_dec->aac_config.first_frame) {
3515           p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes =
3516               p_state_enhaacplus_dec->num_of_out_samples * num_ch * sizeof(WORD16);
3517         }
3518       }
3519     } else {
3520       if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] != 2) {
3521         if (p_obj_exhaacplus_dec->aac_config.flag_to_stereo == 1 &&
3522           channel == 1 && total_elements == 1 && num_ch == 1) {
3523         num_ch = 2;
3524         p_obj_exhaacplus_dec->aac_config.dup_stereo_flag = 1;
3525 
3526       } else {
3527         p_obj_exhaacplus_dec->aac_config.dup_stereo_flag = 0;
3528       }
3529 
3530       p_obj_exhaacplus_dec->aac_config.ui_n_channels = 2;
3531 
3532       p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes +=
3533           p_state_enhaacplus_dec->num_of_out_samples * num_ch * sizeof(WORD16);
3534 
3535     } else {
3536       channel_coupling_flag = 1;
3537     }
3538   }
3539 
3540     if (p_state_enhaacplus_dec->sbr_present && total_channels > 2) {
3541       for (WORD32 j = 0; j < channel; j++) {
3542         for (WORD32 i = 0; i < frame_size; i++) {
3543           intermediate_scr[total_channels * i + j +
3544                            p_state_enhaacplus_dec->slot_pos] =
3545               actual_out_buffer[total_channels * i + j +
3546                                 p_state_enhaacplus_dec->slot_pos];
3547         }
3548       }
3549     }
3550   }
3551 
3552   if (p_state_enhaacplus_dec->sbr_present && total_channels > 2) {
3553     memcpy(time_data, intermediate_scr,
3554            sizeof(WORD16) * frame_size * total_channels);
3555   }
3556 
3557   {
3558     ia_adts_crc_info_struct *ptr_adts_crc_info =
3559         p_state_enhaacplus_dec->ptr_bit_stream->pstr_adts_crc_info;
3560     if (ptr_adts_crc_info->crc_active == 1) {
3561       if ((error_code = ixheaacd_adts_crc_check_crc(ptr_adts_crc_info))) {
3562         if (error_code) {
3563           if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
3564             p_obj_exhaacplus_dec->aac_config.frame_status = 0;
3565           } else {
3566             return error_code;
3567           }
3568         }
3569       }
3570     }
3571   }
3572 
3573   p_obj_exhaacplus_dec->aac_config.ui_n_channels = total_channels;
3574 
3575   p_state_enhaacplus_dec->frame_counter++;
3576 
3577   WORD32 i, j;
3578 
3579   if (channel_coupling_flag) {
3580     error_code = ixheaacd_dec_ind_coupling(p_obj_exhaacplus_dec,
3581                                            p_state_enhaacplus_dec->coup_ch_output,
3582                                            num_of_out_samples, total_channels, time_data);
3583     if (error_code)
3584       return error_code;
3585   }
3586 
3587   for (i = 0; i < total_channels; i++) {
3588     if (p_obj_exhaacplus_dec->p_state_aac->qshift_adj[i + 1] == 0)
3589       p_obj_exhaacplus_dec->p_state_aac->qshift_adj[i + 1] =
3590           p_obj_exhaacplus_dec->p_state_aac->qshift_adj[0];
3591   }
3592 
3593   if (p_obj_exhaacplus_dec->aac_config.flag_to_stereo == 1 &&
3594       total_elements == 1 && num_ch == 2 &&
3595       p_obj_exhaacplus_dec->aac_config.dup_stereo_flag == 1) {
3596     WORD i;
3597 
3598     if (!p_state_enhaacplus_dec->sbr_present &&
3599         p_obj_exhaacplus_dec->p_state_aac->qshift_adj[0] != LD_OBJ) {
3600       for (i = 0; i < frame_size; i++) {
3601         *((WORD32 *)actual_out_buffer + 2 * i + 1) =
3602             *((WORD32 *)actual_out_buffer + 2 * i);
3603       }
3604     } else {
3605       for (i = 0; i < frame_size; i++) {
3606         *(actual_out_buffer + 2 * i + 1) = *(actual_out_buffer + 2 * i);
3607       }
3608     }
3609   }
3610 
3611   if (!p_state_enhaacplus_dec->sbr_present &&
3612       p_obj_exhaacplus_dec->p_state_aac->peak_lim_init == 1 &&
3613       p_obj_exhaacplus_dec->p_state_aac->qshift_adj[0] != LD_OBJ) {
3614     if (!p_obj_exhaacplus_dec->aac_config.peak_limiter_off) {
3615       ixheaacd_peak_limiter_process(
3616           &p_state_enhaacplus_dec->peak_limiter, time_data, frame_size,
3617           p_obj_exhaacplus_dec->p_state_aac->qshift_adj);
3618     } else {
3619       ixheaacd_scale_adjust(time_data, frame_size,
3620                             p_obj_exhaacplus_dec->p_state_aac->qshift_adj,
3621                             total_channels);
3622     }
3623 
3624     for (i = 0; i < frame_size * 2; i++) {
3625       for (j = 0; j < total_channels; j++) {
3626         *((WORD16 *)time_data + total_channels * i + j) =
3627             ixheaac_round16(*((WORD32 *)time_data + total_channels * i + j));
3628       }
3629     }
3630 
3631     memmove(
3632         time_data,
3633         (time_data +
3634          total_channels * p_obj_exhaacplus_dec->p_state_aac->delay_in_samples),
3635         sizeof(WORD16) * num_of_out_samples * total_channels);
3636 
3637     p_obj_exhaacplus_dec->p_state_aac->delay_in_samples =
3638         p_obj_exhaacplus_dec->p_state_aac->delay_in_samples -
3639         MIN(p_obj_exhaacplus_dec->p_state_aac->delay_in_samples, (UWORD16)frame_size);
3640   }
3641   if (p_state_enhaacplus_dec->heaac_mps_handle.heaac_mps_present == 1) {
3642     ia_heaac_mps_state_struct *pstr_mps_state =
3643         &p_state_enhaacplus_dec->heaac_mps_handle;
3644     if (p_state_enhaacplus_dec->sbr_present == 0) {
3645       p_state_enhaacplus_dec->heaac_mps_handle.mps_decode = 1;
3646     } else {
3647       p_state_enhaacplus_dec->heaac_mps_handle.mps_with_sbr = 1;
3648     }
3649     if (!p_obj_exhaacplus_dec->aac_config.ui_enh_sbr)
3650     {
3651       p_state_enhaacplus_dec->heaac_mps_handle.mps_decode = 1;
3652     }
3653     if (p_state_enhaacplus_dec->heaac_mps_handle.mps_init_done == 1) {
3654       p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle.frame_ok =
3655           p_obj_exhaacplus_dec->aac_config.frame_status;
3656       p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle.ec_flag =
3657           p_obj_exhaacplus_dec->aac_config.ui_err_conceal;
3658 
3659       ixheaacd_heaac_mps_apply(p_obj_exhaacplus_dec, actual_out_buffer,
3660                                mps_buffer,
3661                                p_state_enhaacplus_dec->ui_mps_out_bytes);
3662 
3663       p_state_enhaacplus_dec->heaac_mps_handle.mps_decode = 1;
3664       p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes =
3665           (pstr_mps_state->num_output_channels_at *
3666            pstr_mps_state->frame_length *
3667            (p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz >> 3));
3668       p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle.first_frame = 0;
3669     }
3670   }
3671   if ((total_channels > 2) && (1 == p_obj_exhaacplus_dec->aac_config.downmix)) {
3672     ixheaacd_dec_downmix_to_stereo(p_obj_exhaacplus_dec, num_of_out_samples,
3673                                    total_elements, time_data, total_channels);
3674 
3675     total_channels = 2;
3676     p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes =
3677         p_state_enhaacplus_dec->num_of_out_samples * 2 * sizeof(WORD16);
3678   }
3679 
3680   if (p_obj_exhaacplus_dec->aac_config.flag_downmix && total_channels == 2) {
3681     WORD32 out_ch = 1;
3682     WORD i;
3683     if (p_obj_exhaacplus_dec->aac_config.flag_to_stereo == 1) {
3684       out_ch = 2;
3685     }
3686 
3687     p_obj_exhaacplus_dec->aac_config.ui_n_channels = out_ch;
3688     p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes =
3689         p_state_enhaacplus_dec->num_of_out_samples * out_ch * sizeof(WORD16);
3690 
3691     for (i = 0; i < num_of_out_samples; i++) {
3692       WORD16 temp;
3693 
3694       temp = (time_data[2 * i + 0] >> 1) + (time_data[2 * i + 1] >> 1);
3695 
3696       if (out_ch == 2) {
3697         time_data[2 * i + 0] = temp;
3698         time_data[2 * i + 1] = time_data[2 * i + 0];
3699       } else {
3700         time_data[i] = temp;
3701       }
3702     }
3703   }
3704 
3705   if (p_state_enhaacplus_dec->s_adts_hdr_present) {
3706     if (adts.no_raw_data_blocks != 0) {
3707       if (adts.protection_absent == 0 && it_bit_buff->cnt_bits >= 16) {
3708         adts.crc_check = ixheaacd_read_bits_buf(it_bit_buff, 16);
3709       }
3710     }
3711     p_state_enhaacplus_dec->b_n_raw_data_blk--;
3712   }
3713 
3714   ixheaacd_updatebytesconsumed(p_state_enhaacplus_dec, it_bit_buff);
3715 
3716   if (p_state_enhaacplus_dec->bs_format == LOAS_BSFORMAT)
3717     p_state_enhaacplus_dec->i_bytes_consumed =
3718         (WORD32)(audio_mux_length_bytes_last + bytes_for_sync);
3719 
3720   if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal &&
3721       p_obj_exhaacplus_dec->aac_config.first_frame) {
3722     p_obj_exhaacplus_dec->aac_config.first_frame = 0;
3723   }
3724 
3725   if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) {
3726     if (p_obj_exhaacplus_dec->aac_config.frame_status != 1) {
3727       p_state_enhaacplus_dec->i_bytes_consumed = p_state_enhaacplus_dec->ui_in_bytes;
3728     }
3729     return IA_NO_ERROR;
3730   } else {
3731     return error_code;
3732   }
3733 }
3734