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