/****************************************************************************** * * * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ #include #include #include #include "ixheaacd_sbr_common.h" #include "ixheaac_type_def.h" #include "ixheaacd_memory_standards.h" #include "ixheaacd_mps_struct_def.h" #include "ixheaacd_mps_res_rom.h" #include "ixheaacd_mps_aac_struct.h" #include "ixheaac_constants.h" #include "ixheaac_basic_ops32.h" #include "ixheaac_basic_ops16.h" #include "ixheaac_basic_ops40.h" #include "ixheaac_basic_ops.h" #include "ixheaac_error_standards.h" #include "ixheaacd_apicmd_standards.h" #include "ixheaacd_aac_config.h" #include "ixheaacd_api_defs.h" #include "ixheaacd_definitions.h" #include "ixheaacd_error_codes.h" #include "ixheaacd_bitbuffer.h" #include "ixheaacd_audioobjtypes.h" #include "ixheaacd_sbrdecsettings.h" #include "ixheaacd_memory_standards.h" #include "ixheaacd_bitbuffer.h" #include "ixheaacd_adts.h" #include "ixheaacd_defines.h" #include "ixheaacd_cnst.h" #include "ixheaacd_aac_rom.h" #include "ixheaacd_ec_defines.h" #include "ixheaacd_ec_struct_def.h" #include "ixheaacd_sbr_scale.h" #include "ixheaacd_lpp_tran.h" #include "ixheaacd_env_extr_part.h" #include "ixheaacd_sbr_rom.h" #include "ixheaacd_hybrid.h" #include "ixheaacd_ps_dec.h" #include "ixheaacd_ps_bitdec.h" #include "ixheaacd_pulsedata.h" #include "ixheaacd_pns.h" #include "ixheaacd_drc_data_struct.h" #include "ixheaacd_lt_predict.h" #include "ixheaacd_channelinfo.h" #include "ixheaacd_drc_dec.h" #include "ixheaac_sbr_const.h" #include "ixheaacd_sbrdecoder.h" #include "ixheaacd_env_extr.h" #include "ixheaacd_common_rom.h" #include "ixheaacd_freq_sca.h" #include "ixheaacd_qmf_dec.h" #include "ixheaacd_env_calc.h" #include "ixheaacd_pvc_dec.h" #include "ixheaacd_sbr_dec.h" #include "ixheaacd_block.h" #include "ixheaacd_channel.h" #include "ixheaacd_audioobjtypes.h" #include "ixheaacd_latmdemux.h" #include "ixheaacd_aacdec.h" #include "ixheaacd_mps_polyphase.h" #include "ixheaacd_config.h" #include "ixheaacd_mps_dec.h" #include "ixheaacd_struct_def.h" #include "ixheaacd_headerdecode.h" #include "ixheaacd_adts_crc_check.h" #include "ixheaacd_multichannel.h" #include "ixheaacd_ver_number.h" #include "ixheaacd_interface.h" #include "ixheaacd_info.h" #include "ixheaacd_config.h" #include "ixheaacd_struct.h" #include "ixheaacd_mps_polyphase.h" #include "ixheaacd_tns_usac.h" #include "ixheaacd_acelp_info.h" #include "ixheaacd_main.h" #include "ixheaacd_arith_dec.h" #include "ixheaacd_create.h" #include "ixheaacd_function_selector.h" #include "ixheaacd_ld_mps_dec.h" #include "ixheaacd_mps_tables.h" #define MAX_TRACKS_PER_LAYER 50 #define ALIGN_SIZE64(x) ((((x) + 7) >> 3) << 3) #define IA_ENHAACPDEC_NUM_MEMTABS (4) #define NUM_AAC_TABLES 8 #define LD_OBJ -2 #define SCR_BASE_SCR_8K_SIZE \ (IXHEAAC_GET_SIZE_ALIGNED((2 * CHANNELS * MAX_BINS_LONG * sizeof(WORD32)), BYTE_ALIGN_8)) #define SCR_EXTRA_SCR_4K_0_SIZE \ (2 * IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_channel_info_struct), sizeof(WORD32)) + \ 2 * IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_sfb_code_book_struct), sizeof(WORD32)) + \ IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_pns_stereo_data_struct), sizeof(WORD32))) #define SCR_EXTRA_SCR_4K_2_SIZE \ (IXHEAAC_GET_SIZE_ALIGNED((IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME * sizeof(WORD32)), BYTE_ALIGN_8)) #define SCR_EXTRA_SCR_4K_3_SIZE \ (IXHEAAC_GET_SIZE_ALIGNED((IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME * sizeof(WORD32)), BYTE_ALIGN_8)) #define SCR_OUT_DATA_SIZE \ (IXHEAAC_GET_SIZE_ALIGNED((IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME * sizeof(WORD32)), BYTE_ALIGN_8)) #define SCR_IN_DATA_SIZE \ (2 * IXHEAAC_GET_SIZE_ALIGNED((IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME * sizeof(WORD32)), \ BYTE_ALIGN_8)) #define SCR_INTER_SCR_SIZE \ (MAX_CHANNEL_COUNT * \ IXHEAAC_GET_SIZE_ALIGNED((IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME * sizeof(WORD16)), \ BYTE_ALIGN_8)) #define SCR_COUP_CH_OUT_SIZE \ (MAX_CHANNEL_COUNT * \ IXHEAAC_GET_SIZE_ALIGNED((IA_ENHAACPLUS_DEC_SAMPLES_PER_FRAME * sizeof(WORD16)), \ BYTE_ALIGN_8)) #define P_IND_CH_INFO_OFFSET \ (SCR_BASE_SCR_8K_SIZE + SCR_EXTRA_SCR_4K_0_SIZE + SCR_EXTRA_SCR_4K_2_SIZE) #define HEAACV2_MAX_SIZE \ (max(SCR_BASE_SCR_8K_SIZE + SCR_EXTRA_SCR_4K_0_SIZE + SCR_EXTRA_SCR_4K_2_SIZE + \ SCR_INTER_SCR_SIZE + SCR_COUP_CH_OUT_SIZE, \ MPS_SCRATCH_MEM_SIZE)) #define ELDV2_MAX_SIZE \ (max(SCR_BASE_SCR_8K_SIZE + SCR_EXTRA_SCR_4K_0_SIZE + SCR_EXTRA_SCR_4K_2_SIZE + \ SCR_EXTRA_SCR_4K_3_SIZE + SCR_INTER_SCR_SIZE + SCR_COUP_CH_OUT_SIZE, \ MPS_SCRATCH_MEM_SIZE)) #define LD_MAX_SIZE \ (max(SCR_BASE_SCR_8K_SIZE + SCR_EXTRA_SCR_4K_0_SIZE + SCR_EXTRA_SCR_4K_2_SIZE + \ SCR_OUT_DATA_SIZE + SCR_IN_DATA_SIZE + SCR_INTER_SCR_SIZE + SCR_COUP_CH_OUT_SIZE, \ MPS_SCRATCH_MEM_SIZE)) #define MAX_SCR_SIZE (max(max(HEAACV2_MAX_SIZE, ELDV2_MAX_SIZE), LD_MAX_SIZE)) IA_ERRORCODE ixheaacd_dec_mem_api(ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec, WORD32 i_cmd, WORD32 i_idx, VOID *pv_value) { pUWORD32 pui_value = pv_value; if (i_idx < 0 || i_idx >= IA_ENHAACPDEC_NUM_MEMTABS) { return IA_XHEAAC_DEC_API_FATAL_INVALID_MEMTAB_INDEX; } if (i_cmd == IA_API_CMD_SET_MEM_PTR) { if (pv_value == 0) { return (IA_XHEAAC_DEC_API_FATAL_MEM_ALLOC); } if (((SIZE_T)pv_value % p_obj_exhaacplus_dec->p_mem_info_aac[i_idx].ui_alignment) != 0) { return (IA_XHEAAC_DEC_API_FATAL_MEM_ALIGN); } p_obj_exhaacplus_dec->pp_mem_aac[i_idx] = pv_value; memset(p_obj_exhaacplus_dec->pp_mem_aac[i_idx], 0, p_obj_exhaacplus_dec->p_mem_info_aac[i_idx].ui_size); if (i_idx == IA_ENHAACPLUS_DEC_PERSIST_IDX) { pUWORD8 p_temp = pv_value; UWORD32 *meminfo = (UWORD32 *)p_obj_exhaacplus_dec->p_mem_info_aac + i_idx; UWORD32 pers_size = meminfo[0]; p_temp = p_temp + pers_size - (IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_dec_data_struct), BYTE_ALIGN_8) + IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_audio_specific_config_struct), BYTE_ALIGN_8) + IXHEAAC_GET_SIZE_ALIGNED(MAX_HEADER_BUF_SIZE, BYTE_ALIGN_8)); p_obj_exhaacplus_dec->p_state_aac = pv_value; memset(p_obj_exhaacplus_dec->p_state_aac, 0, IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_state_struct), BYTE_ALIGN_8)); p_obj_exhaacplus_dec->p_state_aac->pstr_dec_data = p_temp; p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config = p_temp + IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_dec_data_struct), BYTE_ALIGN_8); p_obj_exhaacplus_dec->p_state_aac->header_ptr = p_temp + IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_dec_data_struct), BYTE_ALIGN_8) + IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_audio_specific_config_struct), BYTE_ALIGN_8); } } else { UWORD32 *meminfo = (UWORD32 *)(p_obj_exhaacplus_dec->p_mem_info_aac + i_idx); *pui_value = *(meminfo + (i_cmd - IA_API_CMD_GET_MEM_INFO_SIZE)); } return IA_NO_ERROR; } static PLATFORM_INLINE VOID ixheaacd_init_sbr_tables(ia_sbr_tables_struct *ptr_sbr_tables) { ptr_sbr_tables->env_calc_tables_ptr = (ia_env_calc_tables_struct *)&ixheaacd_aac_dec_env_calc_tables; ptr_sbr_tables->qmf_dec_tables_ptr = (ia_qmf_dec_tables_struct *)&ixheaacd_aac_qmf_dec_tables; ptr_sbr_tables->env_extr_tables_ptr = (ia_env_extr_tables_struct *)&ixheaacd_aac_dec_env_extr_tables; ptr_sbr_tables->ps_tables_ptr = (ia_ps_tables_struct *)&ixheaacd_aac_dec_ps_tables; } VOID ixheaacd_updatebytesconsumed( ia_aac_dec_state_struct *p_state_enhaacplus_dec, struct ia_bit_buf_struct *it_bit_buff) { p_state_enhaacplus_dec->i_bytes_consumed = (WORD32)(it_bit_buff->ptr_read_next - it_bit_buff->ptr_bit_buf_base); if ((p_state_enhaacplus_dec->i_bytes_consumed == 0) && (it_bit_buff->cnt_bits == 0)) { p_state_enhaacplus_dec->i_bytes_consumed = p_state_enhaacplus_dec->ui_in_bytes; } if (it_bit_buff->cnt_bits < 0) { p_state_enhaacplus_dec->i_bytes_consumed = 0; p_state_enhaacplus_dec->ui_out_bytes = 0; p_state_enhaacplus_dec->ui_mps_out_bytes = 0; p_state_enhaacplus_dec->b_n_raw_data_blk = 0; } } static VOID copy_qmf_to_ldmps(ia_mps_dec_state_struct *mps_dec_handle, VOID *sbr_persistent_mem_v) { ia_sbr_pers_struct *sbr_persistent_mem = (ia_sbr_pers_struct *)sbr_persistent_mem_v; memcpy(&mps_dec_handle->str_mps_qmf_bank, &sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_channel[0] ->str_sbr_dec.str_codec_qmf_bank, sizeof(ia_sbr_qmf_filter_bank_struct)); mps_dec_handle->sbr_tables_ptr = sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_tables; mps_dec_handle->qmf_dec_tables_ptr = sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_tables->qmf_dec_tables_ptr; mps_dec_handle->str_sbr_scale_fact = &sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_channel[0] ->str_sbr_dec.str_sbr_scale_fact; } WORD32 ixheaacd_readifadts(ia_aac_dec_state_struct *p_state_enhaacplus_dec, struct ia_bit_buf_struct *it_bit_buff, ia_adts_header_struct *adts) { WORD error; if ((error = ixheaacd_find_syncword(adts, it_bit_buff)) != 0) { ixheaacd_updatebytesconsumed(p_state_enhaacplus_dec, it_bit_buff); return IA_XHEAAC_DEC_EXE_NONFATAL_ADTS_SYNC_LOST; } if ((error = ixheaacd_check_if_adts( adts, it_bit_buff, p_state_enhaacplus_dec->p_config->ui_max_channels)) != 0) { p_state_enhaacplus_dec->i_bytes_consumed = 1; if (it_bit_buff->cnt_bits < 0) { p_state_enhaacplus_dec->i_bytes_consumed = 0; p_state_enhaacplus_dec->ui_out_bytes = 0; p_state_enhaacplus_dec->ui_mps_out_bytes = 0; error = IA_XHEAAC_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES; return error; } return IA_XHEAAC_DEC_EXE_NONFATAL_ADTS_SYNC_LOST; } p_state_enhaacplus_dec->b_n_raw_data_blk = (WORD8)(adts->no_raw_data_blocks + 1); return 0; } static VOID ixheaacd_allocate_aac_scr( ia_aac_dec_scratch_struct *aac_scratch_struct, VOID *base_scratch_ptr, VOID *output_ptr, WORD channel, WORD max_channel, WORD32 audio_object_type) { WORD32 scratch_used = 0; aac_scratch_struct->base_scr_8k = base_scratch_ptr; aac_scratch_struct->extra_scr_4k[1] = (WORD8 *)base_scratch_ptr; scratch_used += SCR_BASE_SCR_8K_SIZE; if (channel == 1) { aac_scratch_struct->extra_scr_4k[0] = (WORD8 *)base_scratch_ptr + scratch_used; scratch_used += SCR_EXTRA_SCR_4K_0_SIZE; aac_scratch_struct->extra_scr_4k[2] = (WORD8 *)base_scratch_ptr + scratch_used; scratch_used += SCR_EXTRA_SCR_4K_2_SIZE; } else { aac_scratch_struct->extra_scr_4k[0] = output_ptr; if (max_channel > 2) { aac_scratch_struct->extra_scr_4k[0] = (WORD8 *)base_scratch_ptr + scratch_used; scratch_used += SCR_EXTRA_SCR_4K_0_SIZE; } aac_scratch_struct->extra_scr_4k[2] = (WORD8 *)base_scratch_ptr + scratch_used; scratch_used += SCR_EXTRA_SCR_4K_2_SIZE; } if (audio_object_type == AOT_ER_AAC_ELD || audio_object_type == AOT_ER_AAC_LD) { aac_scratch_struct->extra_scr_4k[0] = (WORD8 *)base_scratch_ptr + scratch_used; scratch_used += SCR_EXTRA_SCR_4K_0_SIZE; aac_scratch_struct->extra_scr_4k[2] = (WORD8 *)base_scratch_ptr + scratch_used; scratch_used += SCR_EXTRA_SCR_4K_2_SIZE; aac_scratch_struct->extra_scr_4k[3] = (WORD8 *)base_scratch_ptr + scratch_used; scratch_used += SCR_EXTRA_SCR_4K_3_SIZE; } if ((audio_object_type == AOT_ER_AAC_LD) || (audio_object_type == AOT_AAC_LTP)) { aac_scratch_struct->out_data = (WORD32 *)((WORD8 *)base_scratch_ptr + scratch_used); scratch_used += SCR_OUT_DATA_SIZE; aac_scratch_struct->in_data = (WORD32 *)((WORD8 *)base_scratch_ptr + scratch_used); scratch_used += SCR_IN_DATA_SIZE; } } VOID ixheaacd_allocate_sbr_scr(ia_sbr_scr_struct *sbr_scratch_struct, VOID *base_scratch_ptr, VOID *output_ptr, WORD32 total_channels, WORD8 *p_qshift_arr, UWORD8 slot_pos, UWORD8 num_ch) { WORD32 j, i; sbr_scratch_struct->ptr_work_buf_core = base_scratch_ptr; if (p_qshift_arr != NULL && *p_qshift_arr != LD_OBJ) { WORD32 *tmp_buf = (WORD32 *)output_ptr; for (j = 1; j < num_ch; j++) { if ((*p_qshift_arr + j) == 0) *(p_qshift_arr + j) = *(p_qshift_arr + j - 1); } if (total_channels > 2) { for (j = 0; j < num_ch; j++) { for (i = 0; i < 1024; i++) { *((WORD16 *)tmp_buf + slot_pos + total_channels * i + j) = ixheaac_round16(ixheaac_shl32_sat( *(tmp_buf + slot_pos + total_channels * i + j), *(p_qshift_arr + j))); } } } else { for (j = 0; j < num_ch; j++) { for (i = 0; i < 1024; i++) { *((WORD16 *)tmp_buf + total_channels * i + j) = ixheaac_round16(ixheaac_shl32_sat( *(tmp_buf + total_channels * i + j), *(p_qshift_arr + j))); } } } } } VOID ixheaacd_get_lib_id_strings(pVOID pv_output) { ia_lib_info_struct *pstr_lib_info = (ia_lib_info_struct *)pv_output; pstr_lib_info->p_lib_name = (WORD8 *)LIBNAME; pstr_lib_info->p_version_num = (WORD8 *)xHE_AAC_DEC_ITTIAM_VER; return; } IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_xheaac_dec_obj, WORD32 i_cmd, WORD32 i_idx, pVOID pv_value) { ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec = p_ia_xheaac_dec_obj; pUWORD32 pui_value = pv_value; pWORD32 pui_value_signed = pv_value; pWORD8 pb_value = pv_value; pVOID *pp_value = (pVOID *)pv_value; float *pf_value = pv_value; if ((i_cmd != IA_API_CMD_GET_API_SIZE) && (i_cmd != IA_API_CMD_GET_LIB_ID_STRINGS)) { if (p_ia_xheaac_dec_obj == 0) { return (IA_XHEAAC_DEC_API_FATAL_MEM_ALLOC); } if (((SIZE_T)p_ia_xheaac_dec_obj & 3) != 0) { return (IA_XHEAAC_DEC_API_FATAL_MEM_ALIGN); } } switch (i_cmd) { case IA_API_CMD_GET_MEM_INFO_SIZE: case IA_API_CMD_GET_MEM_INFO_ALIGNMENT: case IA_API_CMD_GET_MEM_INFO_TYPE: case IA_API_CMD_SET_MEM_PTR: { return ixheaacd_dec_mem_api(p_ia_xheaac_dec_obj, i_cmd, i_idx, pv_value); } case IA_API_CMD_GET_TABLE_INFO_SIZE: case IA_API_CMD_GET_TABLE_INFO_ALIGNMENT: case IA_API_CMD_SET_TABLE_PTR: case IA_API_CMD_GET_TABLE_PTR: { return ixheaacd_dec_table_api(p_ia_xheaac_dec_obj, i_cmd, i_idx, pv_value); } }; switch (i_cmd) { case IA_API_CMD_GET_LIB_ID_STRINGS: { WORD8 *i1_ver; WORD8 ver_char; if (i_idx == IA_CMD_TYPE_LIB_NAME) i1_ver = (WORD8 *)LIBNAME; else if (i_idx == IA_CMD_TYPE_LIB_VERSION) i1_ver = (WORD8 *)xHE_AAC_DEC_ITTIAM_VER; else return IA_XHEAAC_DEC_API_FATAL_INVALID_LIB_ID_STRINGS_IDX; ver_char = *i1_ver++; for (; ver_char != '\0';) { if (ver_char != '$') { *pb_value++ = ver_char; } ver_char = *i1_ver++; } *pb_value = ver_char; break; } case IA_API_CMD_GET_API_SIZE: { *pui_value = sizeof(ia_exhaacplus_dec_api_struct); break; } case IA_API_CMD_INIT: { switch (i_idx) { case IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS: { memset(p_obj_exhaacplus_dec, 0, sizeof(*p_obj_exhaacplus_dec)); p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz = 16; p_obj_exhaacplus_dec->aac_config.flag_downmix = 0; p_obj_exhaacplus_dec->aac_config.flag_08khz_out = 0; p_obj_exhaacplus_dec->aac_config.flag_16khz_out = 0; p_obj_exhaacplus_dec->aac_config.flag_to_stereo = 0; p_obj_exhaacplus_dec->aac_config.down_sample_flag = 0; p_obj_exhaacplus_dec->aac_config.header_dec_done = 0; p_obj_exhaacplus_dec->aac_config.frame_status = 1; p_obj_exhaacplus_dec->aac_config.ui_mp4_flag = 0; p_obj_exhaacplus_dec->aac_config.ui_disable_sync = 0; p_obj_exhaacplus_dec->aac_config.ui_auto_sbr_upsample = 1; p_obj_exhaacplus_dec->aac_config.ui_samp_freq = 0; p_obj_exhaacplus_dec->aac_config.ui_frame_size = 0; p_obj_exhaacplus_dec->aac_config.ui_n_channels = 2; p_obj_exhaacplus_dec->aac_config.i_channel_mask = 3; p_obj_exhaacplus_dec->aac_config.ui_channel_mode = 3; p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 0; p_obj_exhaacplus_dec->aac_config.ui_effect_type = 0; p_obj_exhaacplus_dec->aac_config.ui_target_loudness = -24; p_obj_exhaacplus_dec->aac_config.ui_loud_norm_flag = 0; p_obj_exhaacplus_dec->aac_config.ui_hq_esbr = 0; p_obj_exhaacplus_dec->aac_config.ui_enh_sbr = 1; p_obj_exhaacplus_dec->aac_config.ui_enh_sbr_ps = 0; p_obj_exhaacplus_dec->aac_config.ui_pce_found_in_hdr = 0; p_obj_exhaacplus_dec->aac_config.loas_present = 0; p_obj_exhaacplus_dec->aac_config.ld_decoder = 0; p_obj_exhaacplus_dec->aac_config.ui_drc_boost = 0; p_obj_exhaacplus_dec->aac_config.ui_drc_cut = 0; p_obj_exhaacplus_dec->aac_config.ui_drc_target_level = 108; p_obj_exhaacplus_dec->aac_config.ui_drc_set = 0; p_obj_exhaacplus_dec->aac_config.ui_flush_cmd = 0; p_obj_exhaacplus_dec->aac_config.output_level = -1; p_obj_exhaacplus_dec->aac_config.ui_max_channels = 6; p_obj_exhaacplus_dec->aac_config.ui_coupling_channel = 0; p_obj_exhaacplus_dec->aac_config.downmix = 0; p_obj_exhaacplus_dec->aac_config.ui_err_conceal = 0; { ia_aac_dec_tables_struct *pstr_aac_tables = &p_obj_exhaacplus_dec->aac_tables; pstr_aac_tables->pstr_huffmann_tables = (ia_aac_dec_huffman_tables_struct *)&ixheaacd_aac_huffmann_tables; pstr_aac_tables->pstr_block_tables = (ia_aac_dec_block_tables_struct *)&ixheaacd_aac_block_tables; pstr_aac_tables->pstr_imdct_tables = (ia_aac_dec_imdct_tables_struct *)&ixheaacd_imdct_tables; ixheaacd_huff_tables_create(pstr_aac_tables); } ixheaacd_init_sbr_tables(&p_obj_exhaacplus_dec->str_sbr_tables); p_obj_exhaacplus_dec->common_tables = (ixheaacd_misc_tables *)&ixheaacd_str_fft_n_transcendent_tables; p_obj_exhaacplus_dec->aac_config.ui_qmf_bands = 64; break; } case IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS: { ixheaacd_fill_aac_mem_tables(p_obj_exhaacplus_dec); break; } case IA_CMD_TYPE_INIT_PROCESS: { WORD32 err_code = 0; if (p_obj_exhaacplus_dec->p_state_aac->fatal_err_present) { err_code = IA_FATAL_ERROR; } else { err_code = ixheaacd_dec_init(p_obj_exhaacplus_dec); if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal && err_code) { if (err_code & IA_FATAL_ERROR) { err_code = IA_XHEAAC_DEC_INIT_FATAL_EC_INIT_FAIL; } else { err_code = IA_XHEAAC_DEC_INIT_NONFATAL_EC_INIT_FAIL; } } } if (err_code != 0) { if (err_code < 0) p_obj_exhaacplus_dec->p_state_aac->fatal_err_present = 1; p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed = p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes; } return err_code; break; } case IA_CMD_TYPE_INIT_DONE_QUERY: { if (p_obj_exhaacplus_dec->p_state_aac->ui_init_done == 1) { *pui_value = 1; } else { *pui_value = 0; } break; } case IA_CMD_TYPE_GA_HDR: { return ixheaacd_decoder_2_ga_hdr(p_obj_exhaacplus_dec); break; } case IA_CMD_TYPE_FLUSH_MEM: { return ixheaacd_decoder_flush_api(p_obj_exhaacplus_dec); break; } default: { return IA_XHEAAC_DEC_API_NONFATAL_CMD_TYPE_NOT_SUPPORTED; } }; break; } case IA_API_CMD_SET_CONFIG_PARAM: { switch (i_idx) { case IA_XHEAAC_DEC_CONFIG_PARAM_SAMP_FREQ: { if ((*pui_value < 8000) || (*pui_value > 96000)) { return (IA_XHEAAC_DEC_CONFIG_FATAL_INVALID_SAMPLE_RATE); } p_obj_exhaacplus_dec->aac_config.ui_samp_freq = *pui_value; break; } case IA_XHEAAC_DEC_CONFIG_PARAM_FRAMELENGTH_FLAG: { if ((*pui_value != 1) && (*pui_value != 0)) { return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_FRAMELENGTHFLAG); } p_obj_exhaacplus_dec->aac_config.ui_frame_size = *pui_value; break; } case IA_XHEAAC_DEC_CONFIG_PARAM_PCM_WDSZ: { if ((*pui_value != 16) && (*pui_value != 24)) { p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz = 16; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_PCM_WDSZ); } p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz = *pui_value; break; } case IA_XHEAAC_DEC_CONFIG_PARAM_DOWNMIX: { if ((*pui_value != 1) && (*pui_value != 0)) { p_obj_exhaacplus_dec->aac_config.flag_downmix = 0; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_DOWNMIX); } p_obj_exhaacplus_dec->aac_config.flag_downmix = *pui_value; p_obj_exhaacplus_dec->aac_config.downmix = *pui_value; break; } case IA_XHEAAC_DEC_CONFIG_PARAM_TOSTEREO: { if ((*pui_value != 1) && (*pui_value != 0)) { p_obj_exhaacplus_dec->aac_config.flag_to_stereo = 1; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_TOSTEREO); } p_obj_exhaacplus_dec->aac_config.flag_to_stereo = *pui_value; break; } case IA_XHEAAC_DEC_CONFIG_PARAM_DSAMPLE: { if ((*pui_value != 1) && (*pui_value != 0)) { p_obj_exhaacplus_dec->aac_config.down_sample_flag = 0; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_DSAMPLE); } p_obj_exhaacplus_dec->aac_config.down_sample_flag = *pui_value; break; } case IA_XHEAAC_DEC_CONFIG_PARAM_MP4FLAG: { if ((*pui_value != 1) && (*pui_value != 0)) { p_obj_exhaacplus_dec->aac_config.ui_mp4_flag = 0; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_MP4FLAG); } p_obj_exhaacplus_dec->aac_config.ui_mp4_flag = *pui_value; break; } case IA_XHEAAC_DEC_CONFIG_PARAM_DRC_CUT: { p_obj_exhaacplus_dec->aac_config.ui_drc_set = 1; if (*pf_value > 1) { p_obj_exhaacplus_dec->aac_config.ui_drc_cut = 0; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_DRC_CUT); } p_obj_exhaacplus_dec->aac_config.ui_drc_cut = (WORD32)((*pf_value) * 100); break; } case IA_XHEAAC_DEC_CONFIG_PARAM_DRC_BOOST: { p_obj_exhaacplus_dec->aac_config.ui_drc_set = 1; if (*pf_value > 1) { p_obj_exhaacplus_dec->aac_config.ui_drc_boost = 0; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_DRC_BOOST); } p_obj_exhaacplus_dec->aac_config.ui_drc_boost = (WORD32)((*pf_value) * 100); break; } case IA_XHEAAC_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL: { p_obj_exhaacplus_dec->aac_config.ui_drc_set = 1; p_obj_exhaacplus_dec->aac_config.i_loud_ref_level = *pui_value_signed; if (*pui_value > 127) { p_obj_exhaacplus_dec->aac_config.ui_drc_target_level = 108; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_DRC_TARGET); } p_obj_exhaacplus_dec->aac_config.ui_drc_target_level = *pui_value; break; } case IA_XHEAAC_DEC_CONFIG_PARAM_DRC_HEAVY_COMP: { p_obj_exhaacplus_dec->aac_config.ui_drc_set = 1; if ((*pui_value != 1) && (*pui_value != 0)) { p_obj_exhaacplus_dec->aac_config.ui_drc_heavy_comp = 0; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_DRCFLAG); } p_obj_exhaacplus_dec->aac_config.ui_drc_heavy_comp = *pui_value; break; } case IA_XHEAAC_DEC_CONFIG_DISABLE_SYNC: { if ((*pui_value != 1) && (*pui_value != 0)) { p_obj_exhaacplus_dec->aac_config.ui_disable_sync = 0; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_SYNCFLAG); } p_obj_exhaacplus_dec->aac_config.ui_disable_sync = *pui_value; break; } case IA_XHEAAC_DEC_CONFIG_PARAM_AUTO_SBR_UPSAMPLE: { if ((*pui_value != 1) && (*pui_value != 0)) { p_obj_exhaacplus_dec->aac_config.ui_auto_sbr_upsample = 0; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_SBRUPFLAG); } p_obj_exhaacplus_dec->aac_config.ui_auto_sbr_upsample = *pui_value; break; } case IA_XHEAAC_DEC_CONFIG_PARAM_MAX_CHANNEL: { if (*pui_value > 8) { p_obj_exhaacplus_dec->aac_config.ui_max_channels = 8; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_MAX_CHANNEL); } if (*pui_value < 2) { p_obj_exhaacplus_dec->aac_config.ui_max_channels = 2; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_MAX_CHANNEL); } p_obj_exhaacplus_dec->aac_config.ui_max_channels = *pui_value; break; } case IA_XHEAAC_DEC_CONFIG_PARAM_FRAMESIZE: { if (*pui_value == 1) { p_obj_exhaacplus_dec->aac_config.framesize_480 = 1; } else if (*pui_value == 0) { p_obj_exhaacplus_dec->aac_config.framesize_480 = 0; } else { return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_FRAMSZ); } break; } case IA_XHEAAC_DEC_CONFIG_PARAM_LD_TESTING: { if (*pui_value == 1) { p_obj_exhaacplus_dec->aac_config.ld_decoder = 1; } else if (*pui_value == 0) { p_obj_exhaacplus_dec->aac_config.ld_decoder = 0; } else { return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_LD_CONFIG); } break; } case IA_XHEAAC_DEC_CONFIG_PARAM_COUP_CHANNEL: { if (*pui_value > 16) { p_obj_exhaacplus_dec->aac_config.ui_coupling_channel = 1; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_COUP_CHANNEL); } p_obj_exhaacplus_dec->aac_config.ui_coupling_channel = *pui_value; break; } case IA_XHEAAC_DEC_CONFIG_PARAM_DOWNMIX_STEREO: { if ((*pui_value != 1) && (*pui_value != 0)) { p_obj_exhaacplus_dec->aac_config.downmix = 0; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_DOWNMIX_STEREO); } p_obj_exhaacplus_dec->aac_config.downmix = *pui_value; break; } case IA_XHEAAC_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE: { if (((*pui_value_signed) > 8) || ((*pui_value_signed) < -1)) { p_obj_exhaacplus_dec->aac_config.ui_effect_type = -1; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_EFFECT_TYPE); } p_obj_exhaacplus_dec->aac_config.ui_effect_type = *pui_value_signed; break; } case IA_XHEAAC_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS: { if (*pui_value_signed >= 0) { p_obj_exhaacplus_dec->aac_config.ui_loud_norm_flag = 1; } *pui_value_signed = -(*pui_value_signed >> 2); if (((*pui_value_signed) > 0) || ((*pui_value_signed) < -63)) { p_obj_exhaacplus_dec->aac_config.ui_target_loudness = 0; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_TARGET_LOUDNESS); } p_obj_exhaacplus_dec->aac_config.ui_target_loudness = *pui_value_signed; break; } case IA_XHEAAC_DEC_CONFIG_PARAM_HQ_ESBR: { if (((*pui_value_signed) != 0) && ((*pui_value_signed) != 1)) { p_obj_exhaacplus_dec->aac_config.ui_hq_esbr = 0; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_ESBR_HQ_FLAG); } p_obj_exhaacplus_dec->aac_config.ui_hq_esbr = *pui_value_signed; break; } case IA_XHEAAC_DEC_CONFIG_PARAM_PS_ENABLE: { if (((*pui_value_signed) != 0) && ((*pui_value_signed) != 1)) { p_obj_exhaacplus_dec->aac_config.ui_enh_sbr_ps = 0; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_ESBR_PS_FLAG); } p_obj_exhaacplus_dec->aac_config.ui_enh_sbr_ps = *pui_value_signed; break; } case IA_XHEAAC_DEC_CONFIG_PARAM_PEAK_LIMITER: { if (((*pui_value_signed) != 0) && ((*pui_value_signed) != 1)) { p_obj_exhaacplus_dec->aac_config.peak_limiter_off = 0; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_PEAK_LIM_FLAG_TYPE); } p_obj_exhaacplus_dec->aac_config.peak_limiter_off = *pui_value_signed; break; } case IA_XHEAAC_DEC_CONFIG_ERROR_CONCEALMENT: { if (((*pui_value_signed) != 0) && ((*pui_value_signed) != 1)) { p_obj_exhaacplus_dec->aac_config.ui_err_conceal = 0; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_ERR_CONCEAL_FLAG_TYPE); } p_obj_exhaacplus_dec->aac_config.ui_err_conceal = *pui_value_signed; break; } case IA_XHEAAC_DEC_CONFIG_PARAM_ESBR: { if (((*pui_value_signed) != 0) && ((*pui_value_signed) != 1)) { p_obj_exhaacplus_dec->aac_config.ui_enh_sbr = 1; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_ESBR_FLAG); } p_obj_exhaacplus_dec->aac_config.ui_enh_sbr = *pui_value_signed; break; } default: { return IA_XHEAAC_DEC_API_FATAL_INVALID_CONFIG_PARAM; } } break; } case IA_API_CMD_GET_CONFIG_PARAM: { UWORD32 i; WORD32 *pvalue = (WORD32 *)(&p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz); if (IA_XHEAAC_DEC_CONFIG_PARAM_NUM_CHANNELS == i_idx) { if (p_obj_exhaacplus_dec->p_state_aac != NULL && p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle .heaac_mps_present == 1) { *pui_value = p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle .num_output_channels_at; } else { *pui_value = pvalue[i_idx]; } } else if (IA_XHEAAC_DEC_CONFIG_PARAM_CHANNEL_MASK == i_idx) { if (p_obj_exhaacplus_dec->p_state_aac != NULL && p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle .heaac_mps_present == 1) { *pui_value = p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle .bs_config.ui_channel_mask; } else { *pui_value = pvalue[i_idx]; } } else if (i_idx >= 0 && i_idx <= 8) { *pui_value = pvalue[i_idx]; } else if (IA_ENHAACPLUS_DEC_CONFIG_GET_NUM_PRE_ROLL_FRAMES == i_idx) { WORD32 *ptri_value = (WORD32 *)pv_value; ia_audio_specific_config_struct *ptr_audio_specific_config = ((ia_audio_specific_config_struct *) p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config); for (i = 0; i < MAX_AUDIO_PREROLLS + 1; i++) { if (ptr_audio_specific_config->str_usac_config.str_usac_dec_config .preroll_bytes[i] == 0) { break; } } *ptri_value = i; } else if (IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR == i_idx) { ia_audio_specific_config_struct *ptr_audio_specific_config = ((ia_audio_specific_config_struct *) p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config); for (i = 0; i < ptr_audio_specific_config->str_usac_config .str_usac_dec_config.num_config_extensions; i++) { pp_value[i] = ptr_audio_specific_config->str_usac_config .str_usac_dec_config.usac_cfg_ext_info_buf[i]; } for (i = 0; i < ptr_audio_specific_config->str_usac_config .str_usac_dec_config.num_elements; i++) { if (ptr_audio_specific_config->str_usac_config.str_usac_dec_config .usac_ext_ele_payload_present[i]) { pp_value[i + 16] = ptr_audio_specific_config->str_usac_config.str_usac_dec_config .usac_ext_ele_payload_buf[i]; } } } else if (IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES == i_idx) { WORD32 *ptri_value = (WORD32 *)pv_value; ia_audio_specific_config_struct *ptr_audio_specific_config = ((ia_audio_specific_config_struct *) p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config); for (i = 0; i < ptr_audio_specific_config->str_usac_config .str_usac_dec_config.num_config_extensions; i++) { ptri_value[i] = ptr_audio_specific_config->str_usac_config .str_usac_dec_config.usac_cfg_ext_info_len[i]; } for (i = 0; i < ptr_audio_specific_config->str_usac_config .str_usac_dec_config.num_elements; i++) { ptri_value[i + 16] = ptr_audio_specific_config->str_usac_config.str_usac_dec_config .usac_ext_ele_payload_len[i]; } } else if (IA_ENHAACPLUS_DEC_DRC_IS_CONFIG_CHANGED == i_idx) { *pui_value = p_obj_exhaacplus_dec->p_state_aac->drc_config_changed; } else if (IA_ENHAACPLUS_DEC_DRC_APPLY_CROSSFADE == i_idx) { *pui_value = p_obj_exhaacplus_dec->p_state_aac->apply_crossfade; } else if (IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE == i_idx) { UWORD32 *ptri_value = (UWORD32 *)pv_value; ia_audio_specific_config_struct *ptr_audio_specific_config = ((ia_audio_specific_config_struct *) p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config); *ptri_value = ptr_audio_specific_config->str_usac_config .str_usac_dec_config.num_elements; } else if (IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT == i_idx) { UWORD32 *ptri_value = (UWORD32 *)pv_value; ia_audio_specific_config_struct *ptr_audio_specific_config = ((ia_audio_specific_config_struct *) p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config); *ptri_value = ptr_audio_specific_config->str_usac_config .str_usac_dec_config.num_config_extensions; } else if (IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN == i_idx) { UWORD32 *ptri_value = (UWORD32 *)pv_value; ia_audio_specific_config_struct *ptr_audio_specific_config = ((ia_audio_specific_config_struct *) p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config); WORD32 preroll_counter = ptr_audio_specific_config->str_usac_config .str_usac_dec_config.preroll_counter; *ptri_value = ptr_audio_specific_config->str_usac_config.str_usac_dec_config .usac_ext_gain_payload_len[preroll_counter]; } else if (IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF == i_idx) { WORD32 payload_buffer_offeset = 0; ia_audio_specific_config_struct *ptr_audio_specific_config = ((ia_audio_specific_config_struct *) p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config); WORD32 preroll_counter = ptr_audio_specific_config->str_usac_config .str_usac_dec_config.preroll_counter; for (i = 0; i < (UWORD32)preroll_counter; i++) payload_buffer_offeset += ptr_audio_specific_config->str_usac_config.str_usac_dec_config .usac_ext_gain_payload_len[i] * sizeof(WORD8); *pp_value = ptr_audio_specific_config->str_usac_config .str_usac_dec_config.usac_ext_gain_payload_buf + payload_buffer_offeset; } else if (IA_XHEAAC_DEC_CONFIG_PARAM_AOT == i_idx) { if (p_obj_exhaacplus_dec->p_state_aac != NULL) { if (p_obj_exhaacplus_dec->aac_config.ui_mp4_flag == 1) { ia_audio_specific_config_struct *ptr_audio_specific_config = ((ia_audio_specific_config_struct *) p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config); *pui_value = ptr_audio_specific_config->audio_object_type; } else { *pui_value = p_obj_exhaacplus_dec->p_state_aac->audio_object_type; } } else { *pui_value = AOT_AAC_LC; } } else { return IA_XHEAAC_DEC_API_FATAL_INVALID_CONFIG_PARAM; } break; } case IA_API_CMD_GET_MEMTABS_SIZE: { *pui_value = (sizeof(ia_mem_info_struct) + sizeof(pVOID *)) * (IA_ENHAACPDEC_NUM_MEMTABS); break; } case IA_API_CMD_GET_LOUDNESS_VAL: { *pui_value = p_obj_exhaacplus_dec->aac_config.output_level; break; } case IA_API_CMD_SET_MEMTABS_PTR: { if (pv_value == NULL) return IA_XHEAAC_DEC_API_FATAL_MEM_ALLOC; memset(pv_value, 0, (sizeof(ia_mem_info_struct) + sizeof(pVOID *)) * (IA_ENHAACPDEC_NUM_MEMTABS)); p_obj_exhaacplus_dec->p_mem_info_aac = pv_value; p_obj_exhaacplus_dec->pp_mem_aac = (pVOID *)((WORD8 *)pv_value + sizeof(ia_mem_info_struct) * IA_ENHAACPDEC_NUM_MEMTABS); break; } case IA_API_CMD_GET_N_MEMTABS: { *pui_value = IA_ENHAACPDEC_NUM_MEMTABS; break; } case IA_API_CMD_GET_N_TABLES: { *pui_value = NUM_AAC_TABLES + NUM_MPS_TABLES; break; } case IA_API_CMD_EXECUTE: { switch (i_idx) { case IA_CMD_TYPE_DO_EXECUTE: { WORD32 err_code = 0; if (!p_obj_exhaacplus_dec->p_state_aac->ui_init_done || p_obj_exhaacplus_dec->p_state_aac->fatal_err_present) { err_code = IA_FATAL_ERROR; } else { memset(p_obj_exhaacplus_dec->p_state_aac->qshift_adj, 0, sizeof(p_obj_exhaacplus_dec->p_state_aac->qshift_adj)); p_obj_exhaacplus_dec->p_state_aac->qshift_cnt = 0; err_code = ixheaacd_dec_execute(p_obj_exhaacplus_dec); } if (err_code != IA_NO_ERROR) { if (err_code < 0) { p_obj_exhaacplus_dec->p_state_aac->fatal_err_present = 1; } p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed = p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes; } return err_code; break; } case IA_CMD_TYPE_DONE_QUERY: { if (p_obj_exhaacplus_dec->p_state_aac->ui_input_over == 1) { *pui_value = 1; } else { *pui_value = 0; } break; } default: { return IA_XHEAAC_DEC_API_FATAL_INVALID_EXECUTE_TYPE; } }; break; } case IA_API_CMD_GET_CURIDX_INPUT_BUF: { *pui_value = p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed; break; } case IA_API_CMD_SET_INPUT_BYTES: { p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes = *pui_value; break; } case IA_API_CMD_GET_OUTPUT_BYTES: { if (1 == i_idx) { *pui_value = p_obj_exhaacplus_dec->p_state_aac->ui_mps_out_bytes; } else { *pui_value = p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes; } if (p_obj_exhaacplus_dec->p_state_aac->audio_object_type == AOT_USAC) { ia_audio_specific_config_struct *ptr_audio_specific_config = ((ia_audio_specific_config_struct *) p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config); WORD32 preroll_counter = ptr_audio_specific_config->str_usac_config .str_usac_dec_config.preroll_counter; *pui_value = ptr_audio_specific_config->str_usac_config .str_usac_dec_config.preroll_bytes[preroll_counter]; preroll_counter++; if (preroll_counter > (MAX_AUDIO_PREROLLS + 1)) return IA_FATAL_ERROR; ptr_audio_specific_config->str_usac_config.str_usac_dec_config .preroll_counter = preroll_counter; } break; } case IA_API_CMD_INPUT_OVER: { p_obj_exhaacplus_dec->p_state_aac->ui_input_over = 1; break; } default: { return IA_XHEAAC_DEC_API_FATAL_INVALID_CMD; } }; return IA_NO_ERROR; } IA_ERRORCODE ixheaacd_decoder_2_ga_hdr(ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec) { IA_ERRORCODE err_code = IA_NO_ERROR; if (p_obj_exhaacplus_dec->aac_config.ui_flush_cmd == 0) { p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz = 16; p_obj_exhaacplus_dec->aac_config.flag_downmix = 0; p_obj_exhaacplus_dec->aac_config.flag_08khz_out = 0; p_obj_exhaacplus_dec->aac_config.flag_16khz_out = 0; p_obj_exhaacplus_dec->aac_config.flag_to_stereo = 0; p_obj_exhaacplus_dec->aac_config.down_sample_flag = 0; p_obj_exhaacplus_dec->aac_config.header_dec_done = 0; p_obj_exhaacplus_dec->aac_config.frame_status = 1; p_obj_exhaacplus_dec->aac_config.ui_mp4_flag = 1; p_obj_exhaacplus_dec->aac_config.ui_disable_sync = 0; p_obj_exhaacplus_dec->aac_config.ui_auto_sbr_upsample = 1; p_obj_exhaacplus_dec->aac_config.ui_samp_freq = 0; p_obj_exhaacplus_dec->aac_config.ui_channel_mode = 3; p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 2; p_obj_exhaacplus_dec->aac_config.ui_pce_found_in_hdr = 0; p_obj_exhaacplus_dec->aac_config.loas_present = 0; p_obj_exhaacplus_dec->aac_config.ui_drc_boost = 0; p_obj_exhaacplus_dec->aac_config.ui_drc_cut = 0; p_obj_exhaacplus_dec->aac_config.ui_drc_target_level = 108; p_obj_exhaacplus_dec->aac_config.ui_drc_set = 0; p_obj_exhaacplus_dec->aac_config.ui_flush_cmd = 1; p_obj_exhaacplus_dec->aac_config.ui_max_channels = 6; p_obj_exhaacplus_dec->aac_config.ui_coupling_channel = 0; p_obj_exhaacplus_dec->aac_config.downmix = 0; { ia_aac_dec_tables_struct *pstr_aac_tables = &p_obj_exhaacplus_dec->aac_tables; pstr_aac_tables->pstr_huffmann_tables = (ia_aac_dec_huffman_tables_struct *)&ixheaacd_aac_huffmann_tables; pstr_aac_tables->pstr_block_tables = (ia_aac_dec_block_tables_struct *)&ixheaacd_aac_block_tables; pstr_aac_tables->pstr_imdct_tables = (ia_aac_dec_imdct_tables_struct *)&ixheaacd_imdct_tables; ixheaacd_huff_tables_create(pstr_aac_tables); } ixheaacd_init_sbr_tables(&p_obj_exhaacplus_dec->str_sbr_tables); p_obj_exhaacplus_dec->common_tables = (ixheaacd_misc_tables *)&ixheaacd_str_fft_n_transcendent_tables; p_obj_exhaacplus_dec->aac_config.ui_qmf_bands = 64; p_obj_exhaacplus_dec->p_state_aac->ui_init_done = 0; err_code = ixheaacd_dec_init(p_obj_exhaacplus_dec); } else { p_obj_exhaacplus_dec->aac_config.ui_flush_cmd = 0; err_code = ixheaacd_dec_init(p_obj_exhaacplus_dec); } if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal && err_code) { if (err_code & IA_FATAL_ERROR) { return IA_XHEAAC_DEC_INIT_FATAL_EC_INIT_FAIL; } else { return IA_XHEAAC_DEC_INIT_NONFATAL_EC_INIT_FAIL; } } else { return err_code; } } IA_ERRORCODE ixheaacd_decoder_flush_api(ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec) { IA_ERRORCODE err_code = IA_NO_ERROR; UWORD8 *header_temp_ptr; WORD32 header_length; if (p_obj_exhaacplus_dec->aac_config.ui_flush_cmd == 0) { header_temp_ptr = p_obj_exhaacplus_dec->p_state_aac->header_ptr; header_length = p_obj_exhaacplus_dec->p_state_aac->header_length; memset(p_obj_exhaacplus_dec->p_state_aac, 0, IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_state_struct), BYTE_ALIGN_8)); { pUWORD8 p_temp = (pUWORD8)p_obj_exhaacplus_dec->p_state_aac; UWORD32 *meminfo = (UWORD32 *)p_obj_exhaacplus_dec->p_mem_info_aac; UWORD32 pers_size = meminfo[0]; p_temp = p_temp + pers_size - (IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_dec_data_struct), BYTE_ALIGN_8) + IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_audio_specific_config_struct), BYTE_ALIGN_8) + IXHEAAC_GET_SIZE_ALIGNED(MAX_HEADER_BUF_SIZE, BYTE_ALIGN_8)); p_obj_exhaacplus_dec->p_state_aac->pstr_dec_data = p_temp; p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config = p_temp + IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_dec_data_struct), BYTE_ALIGN_8); p_obj_exhaacplus_dec->p_state_aac->header_ptr = p_temp + IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_dec_data_struct), BYTE_ALIGN_8) + IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_audio_specific_config_struct), BYTE_ALIGN_8); } memset(&(p_obj_exhaacplus_dec->aac_config), 0, sizeof(ia_aac_dec_config_struct)); p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz = 16; p_obj_exhaacplus_dec->aac_config.flag_downmix = 0; p_obj_exhaacplus_dec->aac_config.flag_08khz_out = 0; p_obj_exhaacplus_dec->aac_config.flag_16khz_out = 0; p_obj_exhaacplus_dec->aac_config.flag_to_stereo = 0; p_obj_exhaacplus_dec->aac_config.down_sample_flag = 0; p_obj_exhaacplus_dec->aac_config.header_dec_done = 0; p_obj_exhaacplus_dec->aac_config.frame_status = 1; p_obj_exhaacplus_dec->aac_config.ui_mp4_flag = 1; p_obj_exhaacplus_dec->aac_config.ui_disable_sync = 0; p_obj_exhaacplus_dec->aac_config.ui_auto_sbr_upsample = 1; p_obj_exhaacplus_dec->aac_config.ui_samp_freq = 0; p_obj_exhaacplus_dec->aac_config.ui_channel_mode = 3; p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 2; p_obj_exhaacplus_dec->aac_config.ui_pce_found_in_hdr = 0; p_obj_exhaacplus_dec->aac_config.loas_present = 0; p_obj_exhaacplus_dec->aac_config.ui_drc_boost = 0; p_obj_exhaacplus_dec->aac_config.ui_drc_cut = 0; p_obj_exhaacplus_dec->aac_config.ui_drc_target_level = 108; p_obj_exhaacplus_dec->aac_config.ui_drc_set = 0; p_obj_exhaacplus_dec->aac_config.ui_flush_cmd = 1; p_obj_exhaacplus_dec->aac_config.ui_max_channels = 6; p_obj_exhaacplus_dec->aac_config.ui_coupling_channel = 0; p_obj_exhaacplus_dec->aac_config.downmix = 0; p_obj_exhaacplus_dec->p_state_aac->peak_lim_init = 0; { ia_aac_dec_tables_struct *pstr_aac_tables = &p_obj_exhaacplus_dec->aac_tables; pstr_aac_tables->pstr_huffmann_tables = (ia_aac_dec_huffman_tables_struct *)&ixheaacd_aac_huffmann_tables; pstr_aac_tables->pstr_block_tables = (ia_aac_dec_block_tables_struct *)&ixheaacd_aac_block_tables; pstr_aac_tables->pstr_imdct_tables = (ia_aac_dec_imdct_tables_struct *)&ixheaacd_imdct_tables; ixheaacd_huff_tables_create(pstr_aac_tables); } ixheaacd_init_sbr_tables(&p_obj_exhaacplus_dec->str_sbr_tables); p_obj_exhaacplus_dec->common_tables = (ixheaacd_misc_tables *)&ixheaacd_str_fft_n_transcendent_tables; p_obj_exhaacplus_dec->aac_config.ui_qmf_bands = 64; p_obj_exhaacplus_dec->p_state_aac->header_ptr = header_temp_ptr; p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes = header_length; p_obj_exhaacplus_dec->p_state_aac->header_length = header_length; err_code = ixheaacd_dec_init(p_obj_exhaacplus_dec); } else { p_obj_exhaacplus_dec->aac_config.ui_flush_cmd = 0; err_code = ixheaacd_dec_init(p_obj_exhaacplus_dec); } if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal && err_code) { if (err_code & IA_FATAL_ERROR) { return IA_XHEAAC_DEC_INIT_FATAL_EC_INIT_FAIL; } else { return IA_XHEAAC_DEC_INIT_NONFATAL_EC_INIT_FAIL; } } else { return err_code; } } static PLATFORM_INLINE WORD32 ixheaacd_persistent_buffer_sizes(WORD32 num_channel) { WORD32 size_buffers = 0; WORD32 temp; WORD32 max_channels; size_buffers += IXHEAAC_GET_SIZE_ALIGNED(4 * 512 * num_channel * sizeof(WORD32), BYTE_ALIGN_8); size_buffers += num_channel * IXHEAAC_GET_SIZE_ALIGNED(ltp_buffer_size * sizeof(WORD16), BYTE_ALIGN_8); size_buffers += num_channel * IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_channel_info), BYTE_ALIGN_8); if (num_channel > 2) { max_channels = MAX_BS_ELEMENT; } else { max_channels = 2; } size_buffers += (max_channels)*2 * IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_sbr_bitstream_struct), BYTE_ALIGN_8); size_buffers += num_channel * IXHEAAC_GET_SIZE_ALIGNED(MAXSBRBYTES * sizeof(WORD8), BYTE_ALIGN_8); size_buffers += num_channel * IXHEAAC_GET_SIZE_ALIGNED(MAXSBRBYTES * sizeof(WORD8), BYTE_ALIGN_8); size_buffers += 2 * num_channel * IXHEAAC_GET_SIZE_ALIGNED( (QMF_FILTER_STATE_ANA_SIZE + 2 * NO_ANALYSIS_CHANNELS) * sizeof(WORD16), BYTE_ALIGN_8); size_buffers += 2 * num_channel * IXHEAAC_GET_SIZE_ALIGNED( (QMF_FILTER_STATE_ANA_SIZE + 2 * NO_ANALYSIS_CHANNELS) * sizeof(WORD32), BYTE_ALIGN_8); size_buffers += 2 * num_channel * IXHEAAC_GET_SIZE_ALIGNED( (QMF_FILTER_STATE_SYN_SIZE + 2 * NO_SYNTHESIS_CHANNELS) * sizeof(WORD16), BYTE_ALIGN_8); size_buffers += 2 * num_channel * IXHEAAC_GET_SIZE_ALIGNED( (QMF_FILTER_STATE_SYN_SIZE + 2 * NO_SYNTHESIS_CHANNELS) * sizeof(WORD32), BYTE_ALIGN_8); size_buffers += num_channel * 2 * IXHEAAC_GET_SIZE_ALIGNED(MAX_OV_COLS * NO_SYNTHESIS_CHANNELS * sizeof(WORD32), BYTE_ALIGN_8); size_buffers += 2 * LPC_ORDER * num_channel * IXHEAAC_GET_SIZE_ALIGNED(NO_ANALYSIS_CHANNELS * sizeof(WORD32), BYTE_ALIGN_8); size_buffers += 2 * IXHEAAC_GET_SIZE_ALIGNED(LPC_ORDER * sizeof(WORD32 *), BYTE_ALIGN_8); size_buffers += 2 * LPC_ORDER * num_channel * IXHEAAC_GET_SIZE_ALIGNED(NO_ANALYSIS_CHANNELS * sizeof(WORD32), BYTE_ALIGN_8); size_buffers += 2 * num_channel * 3 * IXHEAAC_GET_SIZE_ALIGNED(MAX_FREQ_COEFFS * sizeof(WORD16), BYTE_ALIGN_8); temp = IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_freq_band_data_struct), BYTE_ALIGN_8) + IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_sbr_prev_frame_data_struct), BYTE_ALIGN_8) + IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_sbr_channel_struct), BYTE_ALIGN_8) + IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_sbr_header_data_struct), BYTE_ALIGN_8); size_buffers += 2 * num_channel * temp; size_buffers += MAX_BS_ELEMENT * IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaac_drc_bs_data_struct *), BYTE_ALIGN_8); size_buffers += num_channel * IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_ps_dec_struct), BYTE_ALIGN_8); { WORD32 temp_size = 0; size_buffers += (num_channel * 2 * IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_sbr_frame_info_data_struct) + MAX_FREQ_COEFFS * sizeof(WORD32) * 2 + 8, BYTE_ALIGN_8)); temp_size += IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_pvc_data_struct), BYTE_ALIGN_8); temp_size += 2 * IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_esbr_hbe_txposer_struct), BYTE_ALIGN_8); temp_size += 2 * IXHEAAC_GET_SIZE_ALIGNED(MAX_HBE_PERSISTENT_SIZE, BYTE_ALIGN_8); temp_size += 2 * 2 * IXHEAAC_GET_SIZE_ALIGNED(MAX_QMF_BUF_LEN * sizeof(FLOAT32 *), BYTE_ALIGN_8); temp_size += 2 * 2 * MAX_QMF_BUF_LEN * IXHEAAC_GET_SIZE_ALIGNED(MAX_QMF_BUF_LEN * sizeof(FLOAT32), BYTE_ALIGN_8); temp_size += 2 * 2 * MAX_ENV_COLS * IXHEAAC_GET_SIZE_ALIGNED(MAX_QMF_BUF_LEN * sizeof(WORD32), BYTE_ALIGN_8); size_buffers += num_channel * temp_size; } return (size_buffers); } VOID ixheaacd_fill_aac_mem_tables( ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec) { ia_mem_info_struct *p_mem_info_aac; WORD32 num_channels; WORD32 channels; WORD32 buffer_size; if (p_obj_exhaacplus_dec->aac_config.ui_max_channels > 2) { num_channels = (p_obj_exhaacplus_dec->aac_config.ui_max_channels + 1); } else { num_channels = p_obj_exhaacplus_dec->aac_config.ui_max_channels; } channels = num_channels; buffer_size = ixheaacd_persistent_buffer_sizes(num_channels); { p_mem_info_aac = &p_obj_exhaacplus_dec->p_mem_info_aac[IA_ENHAACPLUS_DEC_PERSIST_IDX]; p_mem_info_aac->ui_size = IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_state_struct), BYTE_ALIGN_8) + channels * IXHEAAC_GET_SIZE_ALIGNED(sizeof(struct ia_aac_persistent_struct), BYTE_ALIGN_8) + buffer_size + channels * ixheaacd_getsize_sbr_persistent() + channels * 16 + ixheaacd_mps_persistent_buffer_sizes(); p_mem_info_aac->ui_size += IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_dec_data_struct), BYTE_ALIGN_8); p_mem_info_aac->ui_size += IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_audio_specific_config_struct), BYTE_ALIGN_8); p_mem_info_aac->ui_size += IXHEAAC_GET_SIZE_ALIGNED(MAX_HEADER_BUF_SIZE, BYTE_ALIGN_8); p_mem_info_aac->ui_alignment = 16; p_mem_info_aac->ui_type = IA_MEMTYPE_PERSIST; } { p_mem_info_aac = &p_obj_exhaacplus_dec->p_mem_info_aac[IA_ENHAACPLUS_DEC_SCRATCH_IDX]; p_mem_info_aac->ui_size = MAX_SCR_SIZE; p_mem_info_aac->ui_alignment = 8; p_mem_info_aac->ui_type = IA_MEMTYPE_SCRATCH; } { p_mem_info_aac = &p_obj_exhaacplus_dec->p_mem_info_aac[IA_ENHAACPLUS_DEC_INPUT_IDX]; p_mem_info_aac->ui_size = IA_MAX_INP_BUFFER_SIZE; p_mem_info_aac->ui_alignment = 8; p_mem_info_aac->ui_type = IA_MEMTYPE_INPUT; } { p_mem_info_aac = &p_obj_exhaacplus_dec->p_mem_info_aac[IA_ENHAACPLUS_DEC_OUTPUT_IDX]; p_mem_info_aac->ui_size = IA_ENHAACPLUS_DEC_OUT_BUF_SIZE; p_mem_info_aac->ui_alignment = 8; p_mem_info_aac->ui_type = IA_MEMTYPE_OUTPUT; } return; } IA_ERRORCODE ixheaacd_dec_table_api( ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec, WORD32 i_cmd, WORD32 i_idx, pVOID pv_value) { ia_heaac_mps_state_struct *pstr_mps_state = &p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle; pUWORD32 pui_value = pv_value; pUWORD32 *p_pui_value = pv_value; SIZE_T ui_get_vals[5]; pVOID *table_ptrs[8 + NUM_MPS_TABLES]; UWORD32 table_sizes[8 + NUM_MPS_TABLES] = { sizeof(ixheaacd_aac_huffmann_tables), sizeof(ixheaacd_aac_block_tables), sizeof(ixheaacd_imdct_tables), sizeof(ixheaacd_str_fft_n_transcendent_tables), sizeof(ixheaacd_aac_dec_env_calc_tables), sizeof(ixheaacd_aac_qmf_dec_tables), sizeof(ixheaacd_aac_dec_env_extr_tables), sizeof(ixheaacd_aac_dec_ps_tables), sizeof(ixheaacd_mps_dec_qmf_tables), sizeof(ixheaacd_mps_dec_common_tables), sizeof(ixheaacd_mps_dec_hybrid_tables), sizeof(ixheaacd_mps_dec_m1_m2_tables), sizeof(ixheaacd_mps_dec_decorr_tables), sizeof(ixheaacd_mps_dec_tp_process_tables), sizeof(ixheaacd_mps_dec_mdct2qmf_table), sizeof(ixheaacd_mps_dec_tonality_tables), sizeof(ixheaacd_mps_dec_bitdec_tables), sizeof(ixheaacd_mps_dec_blind_tables), sizeof(ixheaacd_mps_dec_mdct2qmf_tables), sizeof(ia_mps_dec_mdct2qmf_cos_table_struct), sizeof(ia_mps_dec_residual_aac_tables_struct)}; table_ptrs[0] = (pVOID *)&(p_obj_exhaacplus_dec->aac_tables.pstr_huffmann_tables); table_ptrs[1] = (pVOID *)&(p_obj_exhaacplus_dec->aac_tables.pstr_block_tables); table_ptrs[2] = (pVOID *)&(p_obj_exhaacplus_dec->aac_tables.pstr_imdct_tables); table_ptrs[3] = (pVOID *)&(p_obj_exhaacplus_dec->common_tables); table_ptrs[4] = (pVOID *)&p_obj_exhaacplus_dec->str_sbr_tables.env_calc_tables_ptr; table_ptrs[5] = (pVOID *)&p_obj_exhaacplus_dec->str_sbr_tables.qmf_dec_tables_ptr; table_ptrs[6] = (pVOID *)&p_obj_exhaacplus_dec->str_sbr_tables.env_extr_tables_ptr; table_ptrs[7] = (pVOID *)&p_obj_exhaacplus_dec->str_sbr_tables.ps_tables_ptr; table_ptrs[8] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.qmf_table_ptr); table_ptrs[9] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.common_table_ptr); table_ptrs[10] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.hybrid_table_ptr); table_ptrs[11] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.m1_m2_table_ptr); table_ptrs[12] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.decor_table_ptr); table_ptrs[13] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.tp_process_table_ptr); table_ptrs[14] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.mdct2qmf_table_ptr); table_ptrs[15] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.tonality_table_ptr); table_ptrs[16] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.bitdec_table_ptr); table_ptrs[17] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.blind_table_ptr); table_ptrs[18] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.mdct2qmfcos_table_ptr); table_ptrs[19] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.mdct2qmfcos_tab_ptr); table_ptrs[20] = (pVOID *)&(pstr_mps_state->ia_mps_dec_mps_table.aac_tab); if (i_idx < 0 || i_idx >= (NUM_AAC_TABLES + NUM_MPS_TABLES)) { return IA_XHEAAC_DEC_API_FATAL_INVALID_MEMTAB_INDEX; } ui_get_vals[0] = table_sizes[i_idx]; ui_get_vals[1] = 4; ui_get_vals[4] = (SIZE_T)(*table_ptrs[i_idx]); if (i_cmd == IA_API_CMD_SET_TABLE_PTR) { if (pv_value == 0) { return (IA_XHEAAC_DEC_API_FATAL_MEM_ALLOC); } if (((SIZE_T)pv_value) & 3) { return IA_XHEAAC_DEC_API_FATAL_MEM_ALIGN; } *table_ptrs[i_idx] = pv_value; if (i_idx == 0) { ixheaacd_huff_tables_create(&p_obj_exhaacplus_dec->aac_tables); } } else if (i_cmd == IA_API_CMD_GET_TABLE_PTR) { *p_pui_value = (UWORD32 *)((SIZE_T)( ui_get_vals[i_cmd - IA_API_CMD_GET_TABLE_INFO_SIZE])); } else { *pui_value = (WORD32)(ui_get_vals[i_cmd - IA_API_CMD_GET_TABLE_INFO_SIZE]); } return IA_NO_ERROR; } VOID ixheaacd_mps_payload(ia_handle_sbr_dec_inst_struct self, ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec) { struct ia_bit_buf_struct local_bit_buff; struct ia_bit_buf_struct *it_bit_buff; if (self->ptr_mps_data != NULL) { ixheaacd_create_init_bit_buf(&local_bit_buff, (UWORD8 *)self->ptr_mps_data, (self->left_mps_bits >> 3) + 1); } local_bit_buff.xaac_jmp_buf = &p_obj_exhaacplus_dec->p_state_aac->xaac_jmp_buf; it_bit_buff = &local_bit_buff; it_bit_buff->bit_pos = self->mps_bits_pos; it_bit_buff->cnt_bits = self->left_mps_bits; while (self->left_mps_bits >= 8) { ixheaacd_extension_payload( it_bit_buff, &self->left_mps_bits, &p_obj_exhaacplus_dec->p_state_aac->mps_dec_handle); } } IA_ERRORCODE ixheaacd_dec_init( ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec) { FLAG frame_status = 1; WORD32 frame_size_1; WORD32 sample_rate_1; WORD16 num_channels_1; WORD32 ps_detected = 0; UWORD8 *in_buffer; WORD16 *time_data; WORD ch_idx; WORD sbr_present_flag = 0; UWORD8 *mps_buffer; ia_aac_dec_state_struct *p_state_enhaacplus_dec; WORD32 error_code = IA_NO_ERROR; WORD32 persistent_used = 0; IA_ERRORCODE err_code = IA_NO_ERROR; struct ia_aac_persistent_struct *aac_persistent_mem; struct ia_sbr_pers_struct *sbr_persistent_mem; WORD32 ret_val; p_obj_exhaacplus_dec->p_state_aac = p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_PERSIST_IDX]; if (p_obj_exhaacplus_dec->p_state_aac->ui_init_done) { return IA_NO_ERROR; } p_obj_exhaacplus_dec->p_state_aac->preroll_config_present = 0; if (p_obj_exhaacplus_dec->p_state_aac != NULL) { ret_val = setjmp(p_obj_exhaacplus_dec->p_state_aac->xaac_jmp_buf); if (ret_val != 0) { p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed = p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes; p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = 0; return IA_NO_ERROR; } } time_data = (WORD16 *)(p_obj_exhaacplus_dec ->pp_mem_aac[IA_ENHAACPLUS_DEC_OUTPUT_IDX]); if (p_obj_exhaacplus_dec->aac_config.ui_flush_cmd == 0) { in_buffer = p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_INPUT_IDX]; } else { in_buffer = p_obj_exhaacplus_dec->p_state_aac->header_ptr; } p_state_enhaacplus_dec = p_obj_exhaacplus_dec->p_state_aac; p_state_enhaacplus_dec->aac_scratch_mem_v = p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_SCRATCH_IDX]; p_obj_exhaacplus_dec->p_state_aac->huffman_code_book_scl = p_obj_exhaacplus_dec->aac_tables.pstr_huffmann_tables ->huffman_code_book_scl; mps_buffer = p_obj_exhaacplus_dec->p_state_aac->mps_buffer; p_state_enhaacplus_dec->mps_header = -1; p_obj_exhaacplus_dec->p_state_aac->huffman_code_book_scl_index = p_obj_exhaacplus_dec->aac_tables.pstr_huffmann_tables ->huffman_code_book_scl_index; p_state_enhaacplus_dec->pstr_aac_tables = &p_obj_exhaacplus_dec->aac_tables; if (p_obj_exhaacplus_dec->p_state_aac->header_dec_done == 0) { p_obj_exhaacplus_dec->aac_config.header_dec_done = 0; p_state_enhaacplus_dec->mps_dec_handle.ldmps_config.ldmps_present_flag = 0; } if (p_obj_exhaacplus_dec->aac_config.header_dec_done == 0) { WORD32 channels; UWORD32 total_persistent_used = 0; p_obj_exhaacplus_dec->p_state_aac->p_config = &p_obj_exhaacplus_dec->aac_config; p_obj_exhaacplus_dec->p_state_aac->pstr_stream_sbr = (pVOID)((pWORD8)p_obj_exhaacplus_dec->p_state_aac + IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_state_struct), BYTE_ALIGN_8)); if (p_obj_exhaacplus_dec->aac_config.ui_max_channels > 2) { p_state_enhaacplus_dec->aac_persistent_mem_v = (pVOID)((pWORD8)p_obj_exhaacplus_dec->p_state_aac->pstr_stream_sbr + (MAX_BS_ELEMENT)*2 * IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_sbr_bitstream_struct), BYTE_ALIGN_8)); memset(p_obj_exhaacplus_dec->p_state_aac->pstr_stream_sbr, 0, (MAX_BS_ELEMENT)*2 * IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_sbr_bitstream_struct), BYTE_ALIGN_8)); } else { p_state_enhaacplus_dec->aac_persistent_mem_v = (pVOID)((pWORD8)p_obj_exhaacplus_dec->p_state_aac->pstr_stream_sbr + (2) * 2 * IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_sbr_bitstream_struct), BYTE_ALIGN_8)); memset(p_obj_exhaacplus_dec->p_state_aac->pstr_stream_sbr, 0, (2) * 2 * IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_aac_dec_sbr_bitstream_struct), BYTE_ALIGN_8)); } if (1 == p_obj_exhaacplus_dec->aac_config.ui_max_channels) channels = 1; else channels = 2; persistent_used = ixheaacd_set_aac_persistent_buffers( p_state_enhaacplus_dec->aac_persistent_mem_v, channels); p_state_enhaacplus_dec->sbr_persistent_mem_v = (pVOID)((pWORD8)p_state_enhaacplus_dec->aac_persistent_mem_v + IXHEAAC_GET_SIZE_ALIGNED(persistent_used, BYTE_ALIGN_8)); total_persistent_used += IXHEAAC_GET_SIZE_ALIGNED(persistent_used, BYTE_ALIGN_8); persistent_used = ixheaacd_getsize_sbr_persistent(); ixheaacd_set_sbr_persistent_buffers( p_state_enhaacplus_dec->sbr_persistent_mem_v, &persistent_used, channels, 1); p_state_enhaacplus_dec->heaac_mps_handle.mps_persistent_mem_v = (pVOID)((pWORD8)p_state_enhaacplus_dec->sbr_persistent_mem_v + IXHEAAC_GET_SIZE_ALIGNED(persistent_used, BYTE_ALIGN_8)); total_persistent_used += IXHEAAC_GET_SIZE_ALIGNED(persistent_used, BYTE_ALIGN_8); persistent_used = ixheaacd_getsize_mps_persistent(); ixheaacd_set_mps_persistent_buffers( &p_state_enhaacplus_dec->heaac_mps_handle, &persistent_used, channels, p_state_enhaacplus_dec->heaac_mps_handle.mps_persistent_mem_v); total_persistent_used += IXHEAAC_GET_SIZE_ALIGNED(persistent_used, BYTE_ALIGN_8); if (total_persistent_used > p_obj_exhaacplus_dec->p_mem_info_aac[IA_ENHAACPLUS_DEC_PERSIST_IDX].ui_size) { return IA_XHEAAC_DEC_INIT_FATAL_DEC_INIT_FAIL; } aac_persistent_mem = (struct ia_aac_persistent_struct *) p_state_enhaacplus_dec->aac_persistent_mem_v; if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD || p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) p_state_enhaacplus_dec->frame_len_flag = p_obj_exhaacplus_dec->aac_config.framesize_480; p_state_enhaacplus_dec->ptr_overlap_buf = aac_persistent_mem->overlap_buffer; p_state_enhaacplus_dec->bit_count = 0; p_state_enhaacplus_dec->ec_enable = p_obj_exhaacplus_dec->aac_config.ui_err_conceal; p_state_enhaacplus_dec->sync_status = 0; p_state_enhaacplus_dec->bs_format = ADTS_BSFORMAT; p_state_enhaacplus_dec->latm_initialized = 0; p_state_enhaacplus_dec->frame_size = 0; memset(&p_state_enhaacplus_dec->latm_struct_element, 0, sizeof(ixheaacd_latm_struct)); memset(&p_state_enhaacplus_dec->b_n_raw_data_blk, 0, sizeof(WORD32) * (9 + MAX_BS_ELEMENT)); p_state_enhaacplus_dec->sbr_present_flag = 0; for (ch_idx = 0; ch_idx < MAX_BS_ELEMENT; ch_idx++) { p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = 0; } memset(&p_state_enhaacplus_dec->ind_cc_info, 0, sizeof(ia_enhaacplus_dec_ind_cc)); p_state_enhaacplus_dec->last_frame_ok = 1; p_obj_exhaacplus_dec->aac_config.header_dec_done = 1; aac_persistent_mem->str_aac_decoder.pstr_aac_tables = &p_obj_exhaacplus_dec->aac_tables; aac_persistent_mem->str_aac_decoder.pstr_common_tables = p_obj_exhaacplus_dec->common_tables; p_obj_exhaacplus_dec->p_state_aac->sbr_persistent_mem_u = p_obj_exhaacplus_dec->p_state_aac->sbr_persistent_mem_v; p_obj_exhaacplus_dec->p_state_aac->sbr_scratch_mem_u = p_obj_exhaacplus_dec->p_state_aac->aac_scratch_mem_v; ixheaacd_set_sbr_persistent_table_pointer( p_obj_exhaacplus_dec->p_state_aac->sbr_persistent_mem_v, &p_obj_exhaacplus_dec->str_sbr_tables, p_obj_exhaacplus_dec->common_tables); ixheaacd_set_scratch_buffers( &p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle, p_state_enhaacplus_dec->aac_scratch_mem_v); } if (p_obj_exhaacplus_dec->p_state_aac->ui_input_over == 1) { return IA_XHEAAC_DEC_INIT_FATAL_EO_INPUT_REACHED; } if (p_obj_exhaacplus_dec->p_state_aac->header_dec_done == 0) { if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD || p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) p_state_enhaacplus_dec->frame_len_flag = p_obj_exhaacplus_dec->aac_config.framesize_480; aac_persistent_mem = (struct ia_aac_persistent_struct *) p_state_enhaacplus_dec->aac_persistent_mem_v; sbr_persistent_mem = (struct ia_sbr_pers_struct *) p_state_enhaacplus_dec->sbr_persistent_mem_v; if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->p_state_aac->first_frame = 1; } if (p_obj_exhaacplus_dec->aac_config.ui_samp_freq == 0) { WORD32 header_bytes_consumed, return_val; if (p_state_enhaacplus_dec->ui_in_bytes == 0) { p_state_enhaacplus_dec->i_bytes_consumed = 0; return IA_NO_ERROR; } if (1 == p_obj_exhaacplus_dec->aac_config.ui_frame_size) { p_state_enhaacplus_dec->frame_len_flag = 1; p_state_enhaacplus_dec->frame_length = 960; } else { p_state_enhaacplus_dec->frame_len_flag = 0; p_state_enhaacplus_dec->frame_length = 1024; } p_state_enhaacplus_dec->ui_init_done = 0; memset(&(p_state_enhaacplus_dec->eld_specific_config), 0, sizeof(ia_eld_specific_config_struct)); return_val = ixheaacd_aac_headerdecode( p_obj_exhaacplus_dec, (UWORD8 *)in_buffer, &header_bytes_consumed, aac_persistent_mem->str_aac_decoder.pstr_aac_tables ->pstr_huffmann_tables); if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD || p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD || p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LC) { *sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_header[0] = p_obj_exhaacplus_dec->p_state_aac->str_sbr_config; *sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_header[1] = p_obj_exhaacplus_dec->p_state_aac->str_sbr_config; } else { memset(&(p_state_enhaacplus_dec->eld_specific_config), 0, sizeof(ia_eld_specific_config_struct)); } if (return_val < 0) { if (return_val == (WORD32)IA_XHEAAC_DEC_INIT_FATAL_STREAM_CHAN_GT_MAX) { p_state_enhaacplus_dec->i_bytes_consumed = header_bytes_consumed; return return_val; } p_state_enhaacplus_dec->i_bytes_consumed = 1; return return_val; } if (return_val == IA_XHEAAC_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES) { p_state_enhaacplus_dec->i_bytes_consumed = header_bytes_consumed; return return_val; } p_state_enhaacplus_dec->i_bytes_consumed = header_bytes_consumed; if ((return_val == 0) && (p_obj_exhaacplus_dec->p_state_aac->audio_object_type == AOT_USAC)) { { WORD32 pcm_size = p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz; WORD8 *inbuffer = p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_INPUT_IDX]; WORD8 *outbuffer = p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_OUTPUT_IDX]; WORD32 out_bytes = 0; WORD32 frames_done = p_obj_exhaacplus_dec->p_state_aac->frame_counter; p_obj_exhaacplus_dec->p_state_aac->decode_create_done = 0; if (p_obj_exhaacplus_dec->p_state_aac->ui_input_over == 0) { error_code = ixheaacd_dec_main( p_obj_exhaacplus_dec, inbuffer, outbuffer, &out_bytes, frames_done, pcm_size, &p_obj_exhaacplus_dec->p_state_aac->num_of_output_ch); if (error_code) return error_code; p_obj_exhaacplus_dec->p_state_aac->frame_counter++; } else { out_bytes = 0; } p_obj_exhaacplus_dec->aac_config.ui_n_channels = p_obj_exhaacplus_dec->p_state_aac->num_of_output_ch; } if (return_val == 0) p_obj_exhaacplus_dec->p_state_aac->ui_init_done = 1; return return_val; } if (return_val == 0) { p_obj_exhaacplus_dec->p_state_aac->header_dec_done = 1; if (p_obj_exhaacplus_dec->aac_config.ui_flush_cmd == 0) { memcpy(p_state_enhaacplus_dec->header_ptr, in_buffer, header_bytes_consumed * sizeof(UWORD8)); p_state_enhaacplus_dec->header_length = header_bytes_consumed; } } if (p_obj_exhaacplus_dec->p_state_aac->header_dec_done != 1) return IA_XHEAAC_DEC_INIT_NONFATAL_HEADER_NOT_AT_START; if (p_state_enhaacplus_dec->dwnsmp_signal == 1 && p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) p_obj_exhaacplus_dec->aac_config.down_sample_flag = 1; if (p_state_enhaacplus_dec->sampling_rate == p_state_enhaacplus_dec->extension_samp_rate) { p_obj_exhaacplus_dec->aac_config.down_sample_flag = 1; } } else { p_obj_exhaacplus_dec->p_state_aac->header_dec_done = 1; p_state_enhaacplus_dec->i_bytes_consumed = 0; p_state_enhaacplus_dec->sampling_rate = p_obj_exhaacplus_dec->aac_config.ui_samp_freq; if (1 == p_obj_exhaacplus_dec->aac_config.ui_frame_size) { p_state_enhaacplus_dec->frame_len_flag = 1; p_state_enhaacplus_dec->frame_length = 960; } else { p_state_enhaacplus_dec->frame_len_flag = 0; p_state_enhaacplus_dec->frame_length = 1024; } } p_state_enhaacplus_dec->pstr_bit_buf = ixheaacd_create_bit_buf( &p_state_enhaacplus_dec->str_bit_buf, (UWORD8 *)in_buffer, p_obj_exhaacplus_dec->p_mem_info_aac[IA_ENHAACPLUS_DEC_INPUT_IDX] .ui_size); p_state_enhaacplus_dec->pstr_bit_buf->xaac_jmp_buf = &(p_state_enhaacplus_dec->xaac_jmp_buf); p_state_enhaacplus_dec->ptr_bit_stream = p_state_enhaacplus_dec->pstr_bit_buf; if (p_state_enhaacplus_dec->s_adts_hdr_present) { if (p_obj_exhaacplus_dec->aac_config.ld_decoder == 1) p_state_enhaacplus_dec->audio_object_type = 23; } if ((p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) || (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD)) if (p_state_enhaacplus_dec->s_adts_hdr_present) { if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) { p_state_enhaacplus_dec->eld_specific_config.ld_sbr_samp_rate = 1; p_state_enhaacplus_dec->eld_specific_config.ld_sbr_crc_flag = 0; p_state_enhaacplus_dec->eld_specific_config.ld_sbr_flag_present = 0; if (p_obj_exhaacplus_dec->aac_config.eld_sbr_present == 1) { p_state_enhaacplus_dec->eld_specific_config.ld_sbr_flag_present = 1; } } if (p_obj_exhaacplus_dec->aac_config.framesize_480) p_state_enhaacplus_dec->frame_length = 480; else p_state_enhaacplus_dec->frame_length = 512; } { for (ch_idx = 0; ch_idx < MAX_BS_ELEMENT; ch_idx++) { WORD32 channels; channels = 2; p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx] = ixheaacd_aac_decoder_init( p_state_enhaacplus_dec, p_state_enhaacplus_dec->pstr_stream_sbr[0], channels, p_state_enhaacplus_dec->aac_persistent_mem_v, p_state_enhaacplus_dec->frame_length); if (!p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]) { p_state_enhaacplus_dec->i_bytes_consumed = 1; return IA_XHEAAC_DEC_INIT_FATAL_DEC_INIT_FAIL; } } { p_state_enhaacplus_dec->pstr_drc_dec = &p_state_enhaacplus_dec->str_drc_dec_info; ixheaacd_drc_dec_create(p_state_enhaacplus_dec->pstr_drc_dec, 127, 127); } p_state_enhaacplus_dec->pstr_drc_dec->cut_factor = p_obj_exhaacplus_dec->aac_config.ui_drc_cut; p_state_enhaacplus_dec->pstr_drc_dec->boost_factor = p_obj_exhaacplus_dec->aac_config.ui_drc_boost; p_state_enhaacplus_dec->pstr_drc_dec->target_ref_level = p_obj_exhaacplus_dec->aac_config.ui_drc_target_level; p_state_enhaacplus_dec->pstr_drc_dec->prog_ref_level = p_obj_exhaacplus_dec->aac_config.ui_drc_target_level; if (1 == p_obj_exhaacplus_dec->aac_config.ui_drc_set) { if (p_obj_exhaacplus_dec->aac_config.ui_drc_heavy_comp == 1) { p_state_enhaacplus_dec->pstr_drc_dec->drc_on = 1; p_state_enhaacplus_dec->pstr_drc_dec->heavy_mode = 1; } else { p_state_enhaacplus_dec->pstr_drc_dec->heavy_mode = 0; if (p_state_enhaacplus_dec->pstr_drc_dec->target_ref_level > 127) p_state_enhaacplus_dec->pstr_drc_dec->target_ref_level = 127; if (p_state_enhaacplus_dec->pstr_drc_dec->target_ref_level < 0) { if (p_state_enhaacplus_dec->pstr_drc_dec->cut_factor > 0 || p_state_enhaacplus_dec->pstr_drc_dec->boost_factor > 0) p_state_enhaacplus_dec->pstr_drc_dec->drc_on = 1; else p_state_enhaacplus_dec->pstr_drc_dec->drc_on = 0; p_state_enhaacplus_dec->pstr_drc_dec->drc_dig_norm = 0; p_state_enhaacplus_dec->pstr_drc_dec->target_ref_level = 108; } else { p_state_enhaacplus_dec->pstr_drc_dec->drc_on = 1; p_state_enhaacplus_dec->pstr_drc_dec->drc_dig_norm = 1; } } } } } else { struct ia_bit_buf_struct temp_bit_buff = {0}; ia_adts_header_struct adts; struct ia_bit_buf_struct *it_bit_buff; WORD16 frame_size_2 = 0; WORD32 sample_rate_2 = 0; WORD32 sample_rate = 0; WORD type, i; WORD elements_number; if (p_state_enhaacplus_dec->audio_object_type == AOT_USAC) return IA_FATAL_ERROR; memset(&adts, 0, sizeof(ia_adts_header_struct)); for (i = 0; i < MAX_BS_ELEMENT + 1; i++) { p_obj_exhaacplus_dec->aac_config.element_type[i] = -1; } it_bit_buff = p_state_enhaacplus_dec->pstr_bit_buf; p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 0; p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = 0; p_state_enhaacplus_dec->ui_mps_out_bytes = 0; if (p_state_enhaacplus_dec->ui_in_bytes == 0) { p_state_enhaacplus_dec->i_bytes_consumed = 0; return IA_NO_ERROR; } if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD || p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) { if (p_obj_exhaacplus_dec->aac_config.ui_mp4_flag) p_state_enhaacplus_dec->frame_size = p_state_enhaacplus_dec->ui_in_bytes; } ixheaacd_create_init_bit_buf(it_bit_buff, in_buffer, p_state_enhaacplus_dec->ui_in_bytes); p_state_enhaacplus_dec->pstr_bit_buf->xaac_jmp_buf = &(p_state_enhaacplus_dec->xaac_jmp_buf); it_bit_buff->adts_header_present = p_state_enhaacplus_dec->s_adts_hdr_present; it_bit_buff->no_raw_data_blocks = (WORD8)p_state_enhaacplus_dec->b_n_raw_data_blk; it_bit_buff->protection_absent = p_state_enhaacplus_dec->protection_absent; memcpy(&temp_bit_buff, it_bit_buff, sizeof(struct ia_bit_buf_struct)); if (p_obj_exhaacplus_dec->aac_config.ui_max_channels > 2) elements_number = MAX_BS_ELEMENT; else elements_number = 2; for (i = 0; i < elements_number; i++) p_state_enhaacplus_dec->pstr_stream_sbr[i][0].no_elements = 0; { it_bit_buff->initial_cnt_bits = it_bit_buff->cnt_bits; } ixheaacd_byte_align( p_state_enhaacplus_dec->ptr_bit_stream, &p_state_enhaacplus_dec->pstr_aac_dec_info[0]->byte_align_bits); if (p_state_enhaacplus_dec->s_adts_hdr_present) { WORD32 error; if (p_state_enhaacplus_dec->b_n_raw_data_blk == 0) { error = ixheaacd_readifadts(p_state_enhaacplus_dec, it_bit_buff, &adts); if (error) return error; p_state_enhaacplus_dec->protection_absent = adts.protection_absent; if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD || p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) { p_state_enhaacplus_dec->frame_size = adts.aac_frame_length; if (p_obj_exhaacplus_dec->aac_config.framesize_480) p_state_enhaacplus_dec->frame_length = 480; else p_state_enhaacplus_dec->frame_length = 512; } } } if (p_state_enhaacplus_dec->bs_format == LOAS_BSFORMAT) { WORD32 result; WORD32 sync; WORD32 cnt_bits; sync = ixheaacd_read_bits_buf(it_bit_buff, 11); cnt_bits = it_bit_buff->cnt_bits; if (it_bit_buff->cnt_bits <= 24) { return IA_XHEAAC_DEC_INIT_NONFATAL_INSUFFICIENT_INPUT_BYTES; } while (sync != 0x2b7) { sync = ((sync & 0x3ff) << 1) | ixheaacd_read_bits_buf(it_bit_buff, 1); if (it_bit_buff->cnt_bits < 11) { ixheaacd_read_bidirection(it_bit_buff, -11); p_state_enhaacplus_dec->i_bytes_consumed = (cnt_bits - it_bit_buff->cnt_bits) / 8; return (IA_XHEAAC_DEC_INIT_NONFATAL_HEADER_NOT_AT_START); } } it_bit_buff->audio_mux_align = it_bit_buff->cnt_bits - 13; if (sync == 0x2b7) { result = ixheaacd_latm_audio_mux_element( it_bit_buff, &p_state_enhaacplus_dec->latm_struct_element, p_state_enhaacplus_dec, (ia_sampling_rate_info_struct *)&p_obj_exhaacplus_dec->aac_tables .pstr_huffmann_tables->str_sample_rate_info[0]); if (result < 0) { return result; } } } p_state_enhaacplus_dec->pstr_aac_dec_info[0]->byte_align_bits = it_bit_buff->cnt_bits; type = -1; ch_idx = 0; while ((type != 7)) { ia_aac_dec_scratch_struct aac_scratch_struct; memset(&aac_scratch_struct, 0, sizeof(aac_scratch_struct)); if (ch_idx >= elements_number) { p_state_enhaacplus_dec->i_bytes_consumed = 1; return IA_XHEAAC_DEC_INIT_FATAL_STREAM_CHAN_GT_MAX; } ixheaacd_allocate_aac_scr( &aac_scratch_struct, p_state_enhaacplus_dec->aac_scratch_mem_v, time_data, 1, p_obj_exhaacplus_dec->aac_config.ui_max_channels, p_state_enhaacplus_dec->audio_object_type); p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->p_ind_channel_info = &p_state_enhaacplus_dec->ind_cc_info; if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.first_frame = 1; } error_code = ixheaacd_aacdec_decodeframe( p_obj_exhaacplus_dec, &aac_scratch_struct, time_data, frame_status, &type, &ch_idx, 1, 2, p_obj_exhaacplus_dec->aac_config.element_instance_order, 0, 1, 0, p_obj_exhaacplus_dec->aac_config.ui_max_channels, 2, p_obj_exhaacplus_dec->p_state_aac->frame_length, p_obj_exhaacplus_dec->p_state_aac->frame_size, p_state_enhaacplus_dec->pstr_drc_dec, p_state_enhaacplus_dec->audio_object_type, p_state_enhaacplus_dec->ch_config, p_state_enhaacplus_dec->eld_specific_config, p_state_enhaacplus_dec->s_adts_hdr_present, &p_state_enhaacplus_dec->drc_dummy, p_state_enhaacplus_dec->ldmps_present, &p_state_enhaacplus_dec->slot_pos, mps_buffer, &p_state_enhaacplus_dec->mps_header, &p_state_enhaacplus_dec->ui_mps_out_bytes, 1, p_obj_exhaacplus_dec->aac_config.first_frame); if (p_state_enhaacplus_dec->pstr_drc_dec->drc_element_found == 1) { if (p_obj_exhaacplus_dec->aac_config.i_loud_ref_level < 0) { p_obj_exhaacplus_dec->aac_config.output_level = p_state_enhaacplus_dec->pstr_drc_dec->prog_ref_level; } else { p_obj_exhaacplus_dec->aac_config.output_level = p_obj_exhaacplus_dec->aac_config.i_loud_ref_level; } } memset(&(p_obj_exhaacplus_dec->p_state_aac->pstr_aac_dec_info[ch_idx] ->pstr_aac_dec_ch_info[0] ->str_ics_info.ltp), 0, sizeof(ltp_info)); memset(&(p_obj_exhaacplus_dec->p_state_aac->pstr_aac_dec_info[ch_idx] ->pstr_aac_dec_ch_info[0] ->str_ics_info.ltp2), 0, sizeof(ltp_info)); memset(&(p_obj_exhaacplus_dec->p_state_aac->pstr_aac_dec_info[ch_idx] ->pstr_aac_dec_ch_info[1] ->str_ics_info.ltp), 0, sizeof(ltp_info)); memset(&(p_obj_exhaacplus_dec->p_state_aac->pstr_aac_dec_info[ch_idx] ->pstr_aac_dec_ch_info[1] ->str_ics_info.ltp2), 0, sizeof(ltp_info)); { frame_size_1 = p_state_enhaacplus_dec->frame_length; sample_rate_1 = p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->sampling_rate; num_channels_1 = p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->channels; } if ((p_obj_exhaacplus_dec->aac_config.ui_max_channels <= 2) && (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 2)) { p_state_enhaacplus_dec->i_bytes_consumed = 1; return IA_XHEAAC_DEC_INIT_FATAL_UNIMPLEMENTED_CCE; } if (p_state_enhaacplus_dec->pstr_stream_sbr[0][0].no_elements) { sbr_present_flag = 1; p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 1; } if (error_code) { if (p_state_enhaacplus_dec->ui_input_over) { return IA_XHEAAC_DEC_INIT_FATAL_EO_INPUT_REACHED; } ixheaacd_updatebytesconsumed(p_state_enhaacplus_dec, it_bit_buff); return error_code; } if (p_state_enhaacplus_dec->s_adts_hdr_present) { if (adts.no_raw_data_blocks != 0) { if (adts.protection_absent == 0 && it_bit_buff->cnt_bits >= 16) { adts.crc_check = ixheaacd_read_bits_buf(it_bit_buff, 16); } } p_state_enhaacplus_dec->b_n_raw_data_blk--; } sample_rate_2 = sample_rate_1; frame_size_2 = frame_size_1; if (!p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] && p_state_enhaacplus_dec->pstr_stream_sbr[0][0].no_elements) { WORD32 harmonic_sbr_flag = 0; if ((p_obj_exhaacplus_dec->aac_config.flag_16khz_out == 1) && (sample_rate_1 == 8000)) { p_obj_exhaacplus_dec->aac_config.flag_16khz_out = 0; } p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = ixheaacd_init_sbr( sample_rate_1, frame_size_1, (FLAG *)&p_obj_exhaacplus_dec->aac_config.down_sample_flag, p_state_enhaacplus_dec->sbr_persistent_mem_v, p_state_enhaacplus_dec->ptr_overlap_buf, MAXNRSBRCHANNELS, (WORD)1, 1, frame_size_1 * 2, &harmonic_sbr_flag, NULL, p_state_enhaacplus_dec->str_sbr_config, p_state_enhaacplus_dec->audio_object_type, p_state_enhaacplus_dec->mps_dec_handle.ldmps_config .ldmps_present_flag, p_state_enhaacplus_dec->mps_dec_handle.ldmps_config .no_ldsbr_present); if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) { p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->xaac_jmp_buf = &(p_state_enhaacplus_dec->xaac_jmp_buf); } } else { } if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] && p_state_enhaacplus_dec->pstr_stream_sbr[0][0].no_elements) { ia_sbr_scr_struct sbr_scratch_struct; WORD16 num_channels_1_t = num_channels_1; ixheaacd_allocate_sbr_scr(&sbr_scratch_struct, p_state_enhaacplus_dec->aac_scratch_mem_v, time_data, 0, NULL, 0, 0); { WORD32 audio_object_type = p_state_enhaacplus_dec->audio_object_type; if (audio_object_type != AOT_ER_AAC_ELD && audio_object_type != AOT_ER_AAC_LD) { WORD32 i = 0; ia_dec_data_struct *pstr_dec_data = (ia_dec_data_struct *)p_state_enhaacplus_dec->pstr_dec_data; if (num_channels_1 == 1) { for (; i < 1024; i++) { pstr_dec_data->str_usac_data.time_sample_vector[0][i] = ((FLOAT32)time_data[i]); } p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[0] = &pstr_dec_data->str_usac_data.time_sample_vector[0][0]; p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[1] = &pstr_dec_data->str_usac_data.time_sample_vector[1][0]; } else if (num_channels_1 == 2) { for (; i < 1024; i++) { pstr_dec_data->str_usac_data.time_sample_vector[0][i] = ((FLOAT32)time_data[2 * i + 0]); pstr_dec_data->str_usac_data.time_sample_vector[1][i] = ((FLOAT32)time_data[2 * i + 1]); } p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[0] = &pstr_dec_data->str_usac_data.time_sample_vector[0][0]; p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[1] = &pstr_dec_data->str_usac_data.time_sample_vector[1][0]; } } } p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->ec_flag = p_obj_exhaacplus_dec->aac_config.ui_err_conceal; p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->esbr_hq = p_obj_exhaacplus_dec->aac_config.ui_hq_esbr; p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->enh_sbr = p_obj_exhaacplus_dec->aac_config.ui_enh_sbr; p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->enh_sbr_ps = p_obj_exhaacplus_dec->aac_config.ui_enh_sbr_ps; if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) { p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->xaac_jmp_buf = &(p_state_enhaacplus_dec->xaac_jmp_buf); } if (ixheaacd_applysbr(p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx], &p_state_enhaacplus_dec->pstr_stream_sbr[0][0], time_data, &num_channels_1, frame_status, p_obj_exhaacplus_dec->aac_config.down_sample_flag, 0, &sbr_scratch_struct, 1, 1, 0, NULL, NULL, p_state_enhaacplus_dec->eld_specific_config.ld_sbr_flag_present, p_state_enhaacplus_dec->audio_object_type, 1, p_state_enhaacplus_dec->ldmps_present, frame_size_1, p_state_enhaacplus_dec->heaac_mps_handle.heaac_mps_present, p_obj_exhaacplus_dec->aac_config.ui_err_conceal, p_obj_exhaacplus_dec->aac_config.first_frame) != SBRDEC_OK) { p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = 0; return -1; } else { if (!p_obj_exhaacplus_dec->aac_config.down_sample_flag) { sample_rate_1 *= 2; } if (p_state_enhaacplus_dec->eld_specific_config.ld_sbr_flag_present == 1) { p_obj_exhaacplus_dec->p_state_aac->mps_dec_handle.pre_mix_req = 1; ixheaacd_mps_payload( p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx], p_obj_exhaacplus_dec); } } { WORD32 audio_object_type = p_state_enhaacplus_dec->audio_object_type; if (audio_object_type != AOT_ER_AAC_ELD && audio_object_type != AOT_ER_AAC_LD) { WORD32 out_bytes = 0; ia_dec_data_struct *pstr_dec_data = (ia_dec_data_struct *)p_state_enhaacplus_dec->pstr_dec_data; ixheaacd_samples_sat((WORD8 *)time_data, 2048, 16, pstr_dec_data->str_usac_data.time_sample_vector, &out_bytes, 1); } } if (p_obj_exhaacplus_dec->aac_config.flag_downmix) { num_channels_1 = 1; } if (num_channels_1_t == 1 && num_channels_1 == 2) ps_detected = 1; } else { p_state_enhaacplus_dec->mps_dec_handle.ldmps_config.no_ldsbr_present = 1; } p_state_enhaacplus_dec->i_bytes_consumed = 0; p_state_enhaacplus_dec->pstr_bit_buf = it_bit_buff; { p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx] = ixheaacd_aac_decoder_init( p_state_enhaacplus_dec, p_state_enhaacplus_dec->pstr_stream_sbr[0], 2, p_state_enhaacplus_dec->aac_persistent_mem_v, p_state_enhaacplus_dec->frame_length); if (!p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]) { p_state_enhaacplus_dec->i_bytes_consumed = 1; return IA_XHEAAC_DEC_INIT_FATAL_DEC_INIT_FAIL; } if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) { WORD32 harmonic_sbr_flag = 0; p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = ixheaacd_init_sbr( sample_rate_2, frame_size_2, (FLAG *)&p_obj_exhaacplus_dec->aac_config.down_sample_flag, p_state_enhaacplus_dec->sbr_persistent_mem_v, p_state_enhaacplus_dec->ptr_overlap_buf, MAXNRSBRCHANNELS, 1, 1, frame_size_2 * 2, &harmonic_sbr_flag, NULL, p_state_enhaacplus_dec->str_sbr_config, p_state_enhaacplus_dec->audio_object_type, p_state_enhaacplus_dec->mps_dec_handle.ldmps_config .ldmps_present_flag, p_state_enhaacplus_dec->mps_dec_handle.ldmps_config .no_ldsbr_present); } if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) { p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->xaac_jmp_buf = &(p_state_enhaacplus_dec->xaac_jmp_buf); } } if (sample_rate < sample_rate_1) sample_rate = sample_rate_1; ch_idx++; if (p_state_enhaacplus_dec->audio_object_type >= ER_OBJECT_START && (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD || p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD || p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LC)) break; } { ia_adts_crc_info_struct *ptr_adts_crc_info = p_state_enhaacplus_dec->ptr_bit_stream->pstr_adts_crc_info; if (ptr_adts_crc_info->crc_active == 1) { if ((error_code = ixheaacd_adts_crc_check_crc(ptr_adts_crc_info))) { return error_code; } } } { VOID *temp; WORD prev_persistent_used_t; WORD prev_sbrpersistent_used_t; WORD ps_enable; WORD ch_idx_err = 0; WORD persistent_used_t = 0; WORD channel_check = 0; WORD cc_channel_check = 0; WORD max_ch_num = p_obj_exhaacplus_dec->aac_config.ui_max_channels; WORD32 harmonic_sbr_flag = 0; i = 0; p_obj_exhaacplus_dec->aac_config.ui_n_channels = ch_idx; while (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx_err] <= 3 && p_obj_exhaacplus_dec->aac_config.element_type[ch_idx_err] >= 0) { ch_idx_err++; } if (ch_idx_err == 0) { p_obj_exhaacplus_dec->p_state_aac->header_dec_done = 0; p_state_enhaacplus_dec->i_bytes_consumed = (WORD32)( it_bit_buff->ptr_read_next - it_bit_buff->ptr_bit_buf_base); return IA_XHEAAC_DEC_INIT_NONFATAL_DECODE_FRAME_ERROR; } if (ch_idx_err == 1) ps_enable = 1; else ps_enable = 0; while (p_obj_exhaacplus_dec->aac_config.element_type[i] >= 0 && p_obj_exhaacplus_dec->aac_config.element_type[i] <= 3) { WORD32 channel = 0; switch (p_obj_exhaacplus_dec->aac_config.element_type[i]) { case 0: case 3: channel = 1; break; case 1: channel = 2; break; case 2: if (max_ch_num > 2) { if (p_obj_exhaacplus_dec->aac_config.element_instance_order[i] != p_obj_exhaacplus_dec->aac_config.ui_coupling_channel) { i++; continue; } channel = 1; } else { i++; continue; } cc_channel_check++; break; default: return -1; } if (cc_channel_check > MAX_CC_CHANNEL_NUM) return IA_XHEAAC_DEC_EXE_FATAL_UNIMPLEMENTED_CCE; if (ps_enable == 1) { channel = 2; } if (p_obj_exhaacplus_dec->aac_config.element_type[i] != 2) { channel_check += channel; } if (channel_check > max_ch_num) { p_state_enhaacplus_dec->i_bytes_consumed = 1; return IA_XHEAAC_DEC_INIT_FATAL_STREAM_CHAN_GT_MAX; } temp = p_state_enhaacplus_dec->aac_persistent_mem_v; prev_persistent_used_t = persistent_used_t; ixheaacd_allocate_mem_persistent( p_obj_exhaacplus_dec, p_state_enhaacplus_dec, channel, &persistent_used_t, &prev_sbrpersistent_used_t, ps_enable); p_state_enhaacplus_dec->aac_persistent_mem_v = temp; p_state_enhaacplus_dec->last_frame_ok = 1; p_state_enhaacplus_dec->num_channel_last = 0; p_state_enhaacplus_dec->ui_init_done = 0; p_state_enhaacplus_dec->ui_input_over = 0; p_state_enhaacplus_dec->ptr_bit_stream = p_state_enhaacplus_dec->pstr_bit_buf; p_state_enhaacplus_dec->pstr_aac_dec_info[i] = 0; p_state_enhaacplus_dec->pstr_aac_dec_info[i] = ixheaacd_aac_decoder_init( p_state_enhaacplus_dec, p_state_enhaacplus_dec->pstr_stream_sbr[i], channel, (WORD8 *)p_state_enhaacplus_dec->aac_persistent_mem_v + prev_persistent_used_t, p_state_enhaacplus_dec->frame_length); if (!p_state_enhaacplus_dec->pstr_aac_dec_info[i]) { p_state_enhaacplus_dec->i_bytes_consumed = 1; return IA_XHEAAC_DEC_INIT_FATAL_DEC_INIT_FAIL; } p_state_enhaacplus_dec->str_sbr_dec_info[i] = ixheaacd_init_sbr( sample_rate_2, frame_size_2, (FLAG *)&p_obj_exhaacplus_dec->aac_config.down_sample_flag, p_state_enhaacplus_dec->sbr_persistent_mem_v, p_state_enhaacplus_dec->ptr_overlap_buf, channel, ps_enable, 1, frame_size_2 * 2, &harmonic_sbr_flag, NULL, p_state_enhaacplus_dec->str_sbr_config, p_state_enhaacplus_dec->audio_object_type, p_state_enhaacplus_dec->mps_dec_handle.ldmps_config .ldmps_present_flag, p_state_enhaacplus_dec->mps_dec_handle.ldmps_config .no_ldsbr_present); if (p_state_enhaacplus_dec->str_sbr_dec_info[i]) { p_state_enhaacplus_dec->str_sbr_dec_info[i]->xaac_jmp_buf = &(p_state_enhaacplus_dec->xaac_jmp_buf); } if ((sbr_present_flag && ((p_obj_exhaacplus_dec->p_state_aac->audio_object_type == AOT_AAC_LC) || (p_obj_exhaacplus_dec->p_state_aac->audio_object_type == AOT_SBR) || (p_obj_exhaacplus_dec->p_state_aac->audio_object_type == AOT_PS))) || ((p_state_enhaacplus_dec->mps_dec_handle.ldmps_config .ldmps_present_flag == 1) && (p_obj_exhaacplus_dec->p_state_aac->audio_object_type == AOT_ER_AAC_ELD))) p_obj_exhaacplus_dec->aac_config.flag_to_stereo = 1; copy_qmf_to_ldmps(&p_obj_exhaacplus_dec->p_state_aac->mps_dec_handle, p_state_enhaacplus_dec->sbr_persistent_mem_v); if (p_state_enhaacplus_dec->audio_object_type == AOT_AAC_LC && p_state_enhaacplus_dec->ui_mps_out_bytes != 0) { p_state_enhaacplus_dec->heaac_mps_handle.heaac_mps_present = 1; if (p_state_enhaacplus_dec->pstr_stream_sbr[0][0].no_elements) { p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle.mps_with_sbr = 1; } error_code = ixheaacd_aac_mps_init(p_obj_exhaacplus_dec, mps_buffer, p_state_enhaacplus_dec->ui_mps_out_bytes, sample_rate_1); if (error_code) return error_code; p_obj_exhaacplus_dec->aac_config.ui_n_channels = p_state_enhaacplus_dec->heaac_mps_handle.num_output_channels_at; if (p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle.mps_with_sbr == 1) { p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 1; } if (p_obj_exhaacplus_dec->aac_config.element_type[i + 1] >= 0 && p_obj_exhaacplus_dec->aac_config.element_type[i + 1] <= 3) { return IA_FATAL_ERROR; } break; } i++; } p_state_enhaacplus_dec->pers_mem_ptr = (WORD8 *)p_state_enhaacplus_dec->aac_persistent_mem_v + persistent_used_t; p_obj_exhaacplus_dec->aac_config.i_channel_mask = ixheaacd_get_channel_mask(p_obj_exhaacplus_dec); { num_channels_1 = 0; ch_idx = 0; while (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] >= 0 && p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] <= 3) { if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 0 || p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 3) num_channels_1 += 1; if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 1) num_channels_1 += 2; ch_idx++; } if (ch_idx == 2 && num_channels_1 == 2) { p_obj_exhaacplus_dec->aac_config.ui_channel_mode = 2; } if (ch_idx == 1) { if (num_channels_1 == 1) p_obj_exhaacplus_dec->aac_config.ui_channel_mode = 0; if (num_channels_1 == 2) p_obj_exhaacplus_dec->aac_config.ui_channel_mode = 1; } if (ps_detected == 1 && num_channels_1 == 1) num_channels_1 = 2; } } if (1 == p_obj_exhaacplus_dec->aac_config.downmix) num_channels_1 = 2; if (p_obj_exhaacplus_dec->aac_config.flag_downmix == 1) { num_channels_1 = 1; } if ((p_obj_exhaacplus_dec->aac_config.flag_to_stereo == 1) && (ch_idx == 1 || num_channels_1 <= 2)) { num_channels_1 = 2; } p_obj_exhaacplus_dec->aac_config.ui_n_channels = num_channels_1; p_obj_exhaacplus_dec->aac_config.ui_samp_freq = sample_rate; p_state_enhaacplus_dec->ui_init_done = 1; memcpy(it_bit_buff, &temp_bit_buff, sizeof(struct ia_bit_buf_struct)); p_state_enhaacplus_dec->b_n_raw_data_blk = 0; if (p_obj_exhaacplus_dec->p_state_aac->header_dec_done == 1) { p_obj_exhaacplus_dec->p_state_aac->header_dec_done = 0; } } return err_code; } VOID ixheaacd_fill_slot_order(ia_aac_dec_state_struct *p_state_enhaacplus_dec, WORD32 ch, WORD8 *ptr_is_cpe, WORD8 *ptr_tag_select, WORD32 *ptr_idx_no) { WORD32 i; WORD32 idx_no = *ptr_idx_no; WORD *p_slot_element = p_state_enhaacplus_dec->p_config->slot_element; WORD *p_element_type = p_state_enhaacplus_dec->p_config->element_type; WORD *p_element_instance_order = p_state_enhaacplus_dec->p_config->element_instance_order; for (i = 0; i < ch; i++) { if (ptr_is_cpe[i] == 0) { *p_slot_element++ = idx_no++; *p_element_type++ = 0; *p_element_instance_order++ = ptr_tag_select[i]; } } *ptr_idx_no = idx_no; } VOID ixheaacd_fill_prog_config_slots( ia_aac_dec_state_struct *p_state_enhaacplus_dec) { WORD32 idx_no = 0; ixheaacd_fill_slot_order( p_state_enhaacplus_dec, p_state_enhaacplus_dec->p_config->str_prog_config .num_front_channel_elements, p_state_enhaacplus_dec->p_config->str_prog_config.front_element_is_cpe, p_state_enhaacplus_dec->p_config->str_prog_config .front_element_tag_select, &idx_no); ixheaacd_fill_slot_order( p_state_enhaacplus_dec, p_state_enhaacplus_dec->p_config->str_prog_config .num_side_channel_elements, p_state_enhaacplus_dec->p_config->str_prog_config.side_element_is_cpe, p_state_enhaacplus_dec->p_config->str_prog_config.side_element_tag_select, &idx_no); ixheaacd_fill_slot_order( p_state_enhaacplus_dec, p_state_enhaacplus_dec->p_config->str_prog_config .num_back_channel_elements, p_state_enhaacplus_dec->p_config->str_prog_config.back_element_is_cpe, p_state_enhaacplus_dec->p_config->str_prog_config.back_element_tag_select, &idx_no); } IA_ERRORCODE ixheaacd_dec_execute( ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec) { ia_adts_header_struct adts = {0}; ia_aac_dec_state_struct *p_state_enhaacplus_dec; UWORD8 *in_buffer; WORD16 *time_data; WORD16 num_of_out_samples = 0; WORD16 frame_size = 0; WORD32 sample_rate_dec = 0; WORD32 sample_rate = 0; WORD16 num_ch = 0; struct ia_bit_buf_struct *it_bit_buff; UWORD8 *mps_buffer; WORD32 error_code = IA_NO_ERROR; WORD ch_idx1; WORD type; WORD total_channels = 0; WORD total_elements = 0; WORD16 *actual_out_buffer = NULL; WORD ps_enable; WORD esbr_mono_downmix = 0; WORD8 element_used[MAX_BS_ELEMENT]; WORD32 channel_coupling_flag = 0; SIZE_T bytes_for_sync; WORD32 audio_mux_length_bytes_last = 0; WORD32 ret_val; WORD32 mps_out_samples; p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 0; p_obj_exhaacplus_dec->aac_config.frame_status = 1; if (p_obj_exhaacplus_dec->p_state_aac != NULL) { ret_val = setjmp(p_obj_exhaacplus_dec->p_state_aac->xaac_jmp_buf); if (ret_val != 0) { p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed = p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes; p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = 0; p_obj_exhaacplus_dec->aac_config.frame_status = 0; return IA_NO_ERROR; } } time_data = (WORD16 *)(p_obj_exhaacplus_dec ->pp_mem_aac[IA_ENHAACPLUS_DEC_OUTPUT_IDX]); in_buffer = p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_INPUT_IDX]; p_state_enhaacplus_dec = p_obj_exhaacplus_dec->p_state_aac; p_state_enhaacplus_dec->aac_scratch_mem_v = p_obj_exhaacplus_dec->pp_mem_aac[IA_ENHAACPLUS_DEC_SCRATCH_IDX]; p_state_enhaacplus_dec->mps_header = -1; mps_buffer = p_state_enhaacplus_dec->mps_buffer; it_bit_buff = p_state_enhaacplus_dec->pstr_bit_buf; ch_idx1 = 0; p_state_enhaacplus_dec->i_bytes_consumed = 0; if (p_state_enhaacplus_dec->audio_object_type == AOT_USAC) { WORD32 pcm_size = p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz; WORD8 *inbuffer = (WORD8 *)(p_obj_exhaacplus_dec ->pp_mem_aac[IA_ENHAACPLUS_DEC_INPUT_IDX]); WORD8 *outbuffer = (WORD8 *)(p_obj_exhaacplus_dec ->pp_mem_aac[IA_ENHAACPLUS_DEC_OUTPUT_IDX]); WORD32 out_bytes = 0; WORD32 frames_done = p_obj_exhaacplus_dec->p_state_aac->frame_counter; ia_dec_data_struct *pstr_dec_data = (ia_dec_data_struct *)(p_obj_exhaacplus_dec->p_state_aac ->pstr_dec_data); if (pstr_dec_data->str_usac_data.down_samp_sbr != 0) return IA_FATAL_ERROR; if (p_obj_exhaacplus_dec->p_state_aac->ui_input_over == 0) { ia_audio_specific_config_struct *ptr_audio_specific_config = ((ia_audio_specific_config_struct *) p_obj_exhaacplus_dec->p_state_aac->ia_audio_specific_config); ptr_audio_specific_config->str_usac_config.str_usac_dec_config .preroll_counter = 0; { WORD32 iii = 0; for (iii = 0; iii < (MAX_AUDIO_PREROLLS + 1); iii++) { ((ia_dec_data_struct *)(p_obj_exhaacplus_dec->p_state_aac ->pstr_dec_data)) ->str_frame_data.str_audio_specific_config.str_usac_config .str_usac_dec_config.usac_ext_gain_payload_len[iii] = 0; ptr_audio_specific_config->str_usac_config.str_usac_dec_config .usac_ext_gain_payload_len[iii] = 0; // reinitilize the payload len buff ptr_audio_specific_config->str_usac_config.str_usac_dec_config .preroll_bytes[iii] = 0; } } ((ia_dec_data_struct *)(p_obj_exhaacplus_dec->p_state_aac->pstr_dec_data)) ->str_frame_data.str_audio_specific_config.str_usac_config .str_usac_dec_config.preroll_counter = 0; error_code = ixheaacd_dec_main( p_obj_exhaacplus_dec, inbuffer, outbuffer, &out_bytes, frames_done, pcm_size, &p_obj_exhaacplus_dec->p_state_aac->num_of_output_ch); if (error_code) { if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; } else { return error_code; } } p_obj_exhaacplus_dec->p_state_aac->frame_counter++; } else { out_bytes = 0; } if (pstr_dec_data->str_usac_data.ec_flag == 0) { if (p_state_enhaacplus_dec->bs_format != LOAS_BSFORMAT) { p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed = p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes; } } else { if (p_state_enhaacplus_dec->bs_format != LOAS_BSFORMAT) { if (pstr_dec_data->str_usac_data.frame_ok == 0) { p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed = p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes; pstr_dec_data->dec_bit_buf.cnt_bits = 0; } else { ia_dec_data_struct *pstr_dec_data = (ia_dec_data_struct *)p_obj_exhaacplus_dec->p_state_aac->pstr_dec_data; if (pstr_dec_data->dec_bit_buf.cnt_bits & 7) { pstr_dec_data->dec_bit_buf.cnt_bits -= (pstr_dec_data->dec_bit_buf.cnt_bits & 7); } if (pstr_dec_data->dec_bit_buf.cnt_bits == 0) { p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed = p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes; } else { p_obj_exhaacplus_dec->p_state_aac->i_bytes_consumed = p_obj_exhaacplus_dec->p_state_aac->ui_in_bytes - (pstr_dec_data->dec_bit_buf.cnt_bits >> 3); } } } } p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = out_bytes; p_obj_exhaacplus_dec->aac_config.ui_n_channels = p_obj_exhaacplus_dec->p_state_aac->num_of_output_ch; pstr_dec_data->str_usac_data.sbr_parse_err_flag = 0; return 0; } while (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx1] <= 3 && p_obj_exhaacplus_dec->aac_config.element_type[ch_idx1] >= 0) { if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx1] == 0 || p_obj_exhaacplus_dec->aac_config.element_type[ch_idx1] == 3) { total_channels += 1; total_elements += 1; } if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx1] == 1) { total_elements += 1; total_channels += 2; } if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx1] == 2) { total_elements += 1; } ch_idx1++; if (ch_idx1 > MAX_BS_ELEMENT) { if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) break; else return IA_FATAL_ERROR; } } if (ch_idx1 != 1) { ps_enable = 0; if (p_obj_exhaacplus_dec->aac_config.ui_max_channels > 2) { WORD32 scratch_pointer; scratch_pointer = (MAX_SCR_SIZE - SCR_INTER_SCR_SIZE); p_state_enhaacplus_dec->coup_ch_output = (WORD32 *)((WORD8 *) p_obj_exhaacplus_dec->p_state_aac->aac_scratch_mem_v + scratch_pointer); } } else { if (total_channels < (WORD)p_obj_exhaacplus_dec->aac_config.ui_n_channels) total_channels = p_obj_exhaacplus_dec->aac_config.ui_n_channels; ps_enable = 1; } p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = 0; p_obj_exhaacplus_dec->p_state_aac->ui_mps_out_bytes = 0; if (p_state_enhaacplus_dec->ui_in_bytes == 0) { UWORD32 i; WORD32 j; if (p_state_enhaacplus_dec->peak_lim_init == 1) { p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = (p_state_enhaacplus_dec->peak_limiter.attack_time_samples) * total_channels * sizeof(WORD16); for (j = 0; j < total_channels; j++) { for (i = 0; i < (p_state_enhaacplus_dec->peak_limiter.attack_time_samples - p_state_enhaacplus_dec->peak_limiter.delayed_input_index); i++) { *(time_data + total_channels * i + j) = ixheaac_round16( (WORD32)*(p_state_enhaacplus_dec->peak_limiter.delayed_input + (p_state_enhaacplus_dec->peak_limiter.delayed_input_index) * total_channels + total_channels * i + j)); } } for (j = 0; j < total_channels; j++) { for (i = 0; i < p_state_enhaacplus_dec->peak_limiter.delayed_input_index; i++) { *(time_data + (p_state_enhaacplus_dec->peak_limiter.attack_time_samples - p_state_enhaacplus_dec->peak_limiter.delayed_input_index) * total_channels + total_channels * i + j) = ixheaac_round16( (WORD32)*(p_state_enhaacplus_dec->peak_limiter.delayed_input + total_channels * i + j)); } } if (p_obj_exhaacplus_dec->aac_config.dup_stereo_flag) { for (i = 0; i < (p_state_enhaacplus_dec->peak_limiter.attack_time_samples); i++) { time_data[2 * i + 1] = time_data[2 * i + 0]; } } } else { p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = 0; } p_state_enhaacplus_dec->i_bytes_consumed = 0; return IA_NO_ERROR; } if (ch_idx1 == 0) { p_state_enhaacplus_dec->i_bytes_consumed = 1; if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; } else { return IA_XHEAAC_DEC_EXE_NONFATAL_DECODE_FRAME_ERROR; } } if (total_channels > (WORD)p_obj_exhaacplus_dec->aac_config.ui_max_channels) { p_state_enhaacplus_dec->i_bytes_consumed = 1; if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; } else { return IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_MAX_CHANNEL; } } if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD || p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD) { if (p_obj_exhaacplus_dec->aac_config.ui_mp4_flag) p_state_enhaacplus_dec->frame_size = p_state_enhaacplus_dec->ui_in_bytes; } if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LC) { if (p_obj_exhaacplus_dec->aac_config.ui_mp4_flag) p_state_enhaacplus_dec->frame_size = 1024; } { ixheaacd_create_init_bit_buf(it_bit_buff, in_buffer, p_state_enhaacplus_dec->ui_in_bytes); it_bit_buff->xaac_jmp_buf = &(p_state_enhaacplus_dec->xaac_jmp_buf); it_bit_buff->adts_header_present = p_state_enhaacplus_dec->s_adts_hdr_present; it_bit_buff->no_raw_data_blocks = (WORD8)p_state_enhaacplus_dec->b_n_raw_data_blk; it_bit_buff->protection_absent = p_state_enhaacplus_dec->protection_absent; if (p_state_enhaacplus_dec->s_adts_hdr_present) { if (p_state_enhaacplus_dec->b_n_raw_data_blk == 0) { WORD32 error; error = ixheaacd_readifadts(p_state_enhaacplus_dec, it_bit_buff, &adts); if (error) { if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; if (adts.samp_freq_index > 11) { adts.samp_freq_index = 11; } } else { return error; } } if ((WORD32)p_state_enhaacplus_dec->sampling_rate != (WORD32)((p_obj_exhaacplus_dec->aac_tables.pstr_huffmann_tables ->str_sample_rate_info[adts.samp_freq_index] .sampling_frequency))) { p_state_enhaacplus_dec->i_bytes_consumed = 0; if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; } else { return IA_XHEAAC_DEC_EXE_NONFATAL_CHANGED_ADTS_SF; } } } } bytes_for_sync = (SIZE_T)it_bit_buff->ptr_read_next; if (p_state_enhaacplus_dec->bs_format == LOAS_BSFORMAT) { WORD32 result, audio_mux_len_bytes_last; WORD32 cnt_bits = it_bit_buff->cnt_bits; WORD32 sync = ixheaacd_read_bits_buf(it_bit_buff, 11); UWORD32 curr_samp_rate = 0; if (p_state_enhaacplus_dec->latm_initialized) curr_samp_rate = p_state_enhaacplus_dec->latm_struct_element.layer_info[0][0] .asc.sampling_freq; while (sync != 0x2b7) { sync = ((sync & 0x3ff) << 1) | ixheaacd_read_bits_buf(it_bit_buff, 1); if (it_bit_buff->cnt_bits < 13) { ixheaacd_read_bidirection(it_bit_buff, -11); p_state_enhaacplus_dec->i_bytes_consumed = (cnt_bits - it_bit_buff->cnt_bits) / 8; if (p_state_enhaacplus_dec->i_bytes_consumed == 0) p_state_enhaacplus_dec->i_bytes_consumed = 1; if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; } else { return (IA_XHEAAC_DEC_INIT_NONFATAL_HEADER_NOT_AT_START); } } } it_bit_buff->audio_mux_align = it_bit_buff->cnt_bits - 13; audio_mux_len_bytes_last = ixheaacd_read_bits_buf(it_bit_buff, 13); audio_mux_length_bytes_last = audio_mux_len_bytes_last; bytes_for_sync = (SIZE_T)it_bit_buff->ptr_read_next - bytes_for_sync; if (it_bit_buff->cnt_bits < (audio_mux_len_bytes_last << 3)) { ixheaacd_read_bidirection(it_bit_buff, -(13 + 11)); p_state_enhaacplus_dec->i_bytes_consumed = (cnt_bits - it_bit_buff->cnt_bits) / 8; if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; } else { return IA_XHEAAC_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES; } } else { ixheaacd_read_bidirection(it_bit_buff, -(13)); } if (sync == 0x2b7) { result = ixheaacd_latm_audio_mux_element( it_bit_buff, &p_state_enhaacplus_dec->latm_struct_element, p_state_enhaacplus_dec, (ia_sampling_rate_info_struct *)&p_obj_exhaacplus_dec->aac_tables .pstr_huffmann_tables->str_sample_rate_info[0]); if (result < 0) { if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; } else { return result; } } if (!p_state_enhaacplus_dec->latm_initialized) { p_state_enhaacplus_dec->sampling_rate = p_state_enhaacplus_dec->latm_struct_element.layer_info[0][0].asc.sampling_freq; p_state_enhaacplus_dec->latm_initialized = 1; } else { if (p_state_enhaacplus_dec->sampling_rate != curr_samp_rate) { p_state_enhaacplus_dec->i_bytes_consumed = 0; if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; } else { return IA_XHEAAC_DEC_EXE_NONFATAL_CHANGED_ADTS_SF; } } } } } } if (total_elements == 2 && total_channels == 2 && (p_state_enhaacplus_dec->p_config->ui_pce_found_in_hdr == 1 || p_state_enhaacplus_dec->p_config->ui_pce_found_in_hdr == 3)) { ixheaacd_fill_prog_config_slots(p_state_enhaacplus_dec); } memset(element_used, 0, sizeof(WORD8) * MAX_BS_ELEMENT); if (it_bit_buff->cnt_bits <= 0) { it_bit_buff->cnt_bits = -1; ixheaacd_updatebytesconsumed(p_state_enhaacplus_dec, it_bit_buff); if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; } else { return (WORD16)((WORD32)IA_XHEAAC_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES); } } { it_bit_buff->initial_cnt_bits = it_bit_buff->cnt_bits; } if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD) { if (p_state_enhaacplus_dec->s_adts_hdr_present) p_state_enhaacplus_dec->frame_size = adts.aac_frame_length; } if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LC) { if (p_state_enhaacplus_dec->s_adts_hdr_present) p_state_enhaacplus_dec->frame_size = 1024; } if (p_state_enhaacplus_dec->pstr_drc_dec) { p_state_enhaacplus_dec->pstr_drc_dec->num_drc_elements = 0; p_state_enhaacplus_dec->pstr_drc_dec->state = 1; } if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { if (total_elements > MAX_BS_ELEMENT) { total_elements = MAX_BS_ELEMENT; } } WORD16 *intermediate_scr = (WORD16 *)(WORD8 *)p_state_enhaacplus_dec->aac_scratch_mem_v + (MAX_SCR_SIZE - SCR_INTER_SCR_SIZE - SCR_COUP_CH_OUT_SIZE); for (ch_idx1 = 0; ch_idx1 < total_elements; ch_idx1++) { WORD32 skip_full_decode = 0; WORD32 ch_idx = ch_idx1; WORD32 channel = 0; WORD ch_fac, slot_ele; if (p_state_enhaacplus_dec->audio_object_type < ER_OBJECT_START || (p_state_enhaacplus_dec->audio_object_type != AOT_ER_AAC_LD && p_state_enhaacplus_dec->audio_object_type != AOT_ER_AAC_ELD && p_state_enhaacplus_dec->audio_object_type != AOT_ER_AAC_LC)) { jmp_buf local; if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal == 1) { ret_val = setjmp(local); } if (ret_val == 0) { if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal == 1) { p_obj_exhaacplus_dec->p_state_aac->ptr_bit_stream->xaac_jmp_buf = &local; } error_code = ixheaacd_get_element_index_tag( p_obj_exhaacplus_dec, ch_idx1, &ch_idx, &channel, p_obj_exhaacplus_dec->aac_config.element_instance_order, total_elements, element_used, total_channels, p_state_enhaacplus_dec->pstr_drc_dec, &p_state_enhaacplus_dec->drc_dummy, mps_buffer, &p_state_enhaacplus_dec->mps_header, &p_state_enhaacplus_dec->ui_mps_out_bytes); } if (error_code || ret_val) { ixheaacd_updatebytesconsumed(p_state_enhaacplus_dec, it_bit_buff); if (it_bit_buff->cnt_bits < 0) { p_state_enhaacplus_dec->ui_out_bytes = 0; p_state_enhaacplus_dec->ui_mps_out_bytes = 0; p_state_enhaacplus_dec->b_n_raw_data_blk = 0; } p_state_enhaacplus_dec->i_bytes_consumed = 1; p_state_enhaacplus_dec->b_n_raw_data_blk = 0; if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; } else { return error_code; } } if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == ID_CPE) { if (channel != 2) { if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; channel = 2; } else { return IA_FATAL_ERROR; } } } else { if (channel != 1) { if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; channel = 1; } else { return IA_FATAL_ERROR; } } } } else { if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == ID_SCE) channel = 1; else channel = 2; } if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal && (error_code || ret_val)) { if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 0 || p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 3) { if (channel > 1) { channel = 1; } } if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 1) { if (channel > 2) { channel = 2; } } if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 2) { if (p_obj_exhaacplus_dec->aac_config.ui_max_channels > 2) { if (!(p_obj_exhaacplus_dec->aac_config.element_instance_order[ch_idx] != p_obj_exhaacplus_dec->aac_config.ui_coupling_channel)) { if (channel > 1) { channel = 1; } } } } if (ps_enable == 1) { if (channel > 2) { channel = 2; } } } ch_fac = total_channels; slot_ele = p_obj_exhaacplus_dec->aac_config.slot_element[ch_idx]; actual_out_buffer = time_data; if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] == 2) { p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->p_ind_channel_info = &p_state_enhaacplus_dec->ind_cc_info; if (p_obj_exhaacplus_dec->aac_config.element_instance_order[ch_idx] != p_obj_exhaacplus_dec->aac_config.ui_coupling_channel) { skip_full_decode = 1; ixheaacd_set_aac_persistent_buffers( p_state_enhaacplus_dec->pers_mem_ptr, channel); { struct ia_aac_persistent_struct *aac_persistent_mem = (struct ia_aac_persistent_struct *) p_state_enhaacplus_dec->pers_mem_ptr; aac_persistent_mem->str_aac_decoder.pstr_aac_tables = &p_obj_exhaacplus_dec->aac_tables; aac_persistent_mem->str_aac_decoder.pstr_common_tables = p_obj_exhaacplus_dec->common_tables; } p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx] = 0; p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = 0; p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx] = ixheaacd_aac_decoder_init( p_state_enhaacplus_dec, p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx], channel, p_state_enhaacplus_dec->pers_mem_ptr, p_state_enhaacplus_dec->frame_length ); if (!p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]) { p_state_enhaacplus_dec->i_bytes_consumed = 1; if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; } else { return IA_XHEAAC_DEC_INIT_FATAL_DEC_INIT_FAIL; } } p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->p_ind_channel_info = (WORD8 *)p_state_enhaacplus_dec->aac_scratch_mem_v + (P_IND_CH_INFO_OFFSET); } if (p_obj_exhaacplus_dec->aac_config.element_type[1] < 3 && p_obj_exhaacplus_dec->aac_config.element_type[1] > 0 && p_obj_exhaacplus_dec->aac_config.ui_max_channels > 2) { actual_out_buffer = (WORD16 *)(VOID *)p_state_enhaacplus_dec->coup_ch_output; } ch_fac = 1; slot_ele = 0; } type = -1; p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx][0].no_elements = 0; { WORD element_index_order1[MAX_BS_ELEMENT]; ia_aac_dec_scratch_struct aac_scratch_struct; memset(&aac_scratch_struct, 0, sizeof(aac_scratch_struct)); ixheaacd_allocate_aac_scr( &aac_scratch_struct, p_state_enhaacplus_dec->aac_scratch_mem_v, time_data, channel, p_obj_exhaacplus_dec->aac_config.ui_max_channels, p_state_enhaacplus_dec->audio_object_type); if (p_state_enhaacplus_dec->ch_config == 2 && channel == 1) { if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; } else { return IA_XHEAAC_DEC_EXE_NONFATAL_DECODE_FRAME_ERROR; } } error_code = ixheaacd_aacdec_decodeframe( p_obj_exhaacplus_dec, &aac_scratch_struct, actual_out_buffer, p_obj_exhaacplus_dec->aac_config.frame_status, &type, &ch_idx, 0, channel, element_index_order1, skip_full_decode, ch_fac, slot_ele, p_obj_exhaacplus_dec->aac_config.ui_max_channels, total_channels, p_obj_exhaacplus_dec->p_state_aac->frame_length, p_obj_exhaacplus_dec->p_state_aac->frame_size, p_state_enhaacplus_dec->pstr_drc_dec, p_state_enhaacplus_dec->audio_object_type, p_state_enhaacplus_dec->ch_config, p_state_enhaacplus_dec->eld_specific_config, p_state_enhaacplus_dec->s_adts_hdr_present, &p_state_enhaacplus_dec->drc_dummy, p_state_enhaacplus_dec->ldmps_present, &p_state_enhaacplus_dec->slot_pos, mps_buffer, &p_state_enhaacplus_dec->mps_header, &p_state_enhaacplus_dec->ui_mps_out_bytes, 0, p_obj_exhaacplus_dec->aac_config.first_frame); p_state_enhaacplus_dec->slot_pos -= (channel - 1); p_state_enhaacplus_dec->sbr_present = 0; if (p_obj_exhaacplus_dec->p_state_aac->qshift_adj[0] != LD_OBJ && p_state_enhaacplus_dec->frame_counter == 0) { ixheaacd_peak_limiter_init( &p_state_enhaacplus_dec->peak_limiter, total_channels, p_obj_exhaacplus_dec->p_state_aac->p_config->ui_samp_freq, &p_state_enhaacplus_dec->peak_limiter.buffer[0], &p_obj_exhaacplus_dec->p_state_aac->delay_in_samples); p_obj_exhaacplus_dec->p_state_aac->peak_lim_init = 1; } if (p_state_enhaacplus_dec->audio_object_type < ER_OBJECT_START || (p_state_enhaacplus_dec->audio_object_type != AOT_ER_AAC_LD && p_state_enhaacplus_dec->audio_object_type != AOT_ER_AAC_ELD && p_state_enhaacplus_dec->audio_object_type != AOT_ER_AAC_LC)) { if ((error_code == 0) && ((ch_idx1 + 1) == total_elements) && (type != ID_END)) { { p_state_enhaacplus_dec->i_bytes_consumed = (WORD32)( it_bit_buff->ptr_read_next - it_bit_buff->ptr_bit_buf_base); p_state_enhaacplus_dec->b_n_raw_data_blk = 0; if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; } else { return IA_XHEAAC_DEC_EXE_NONFATAL_ELE_INSTANCE_TAG_NOT_FOUND; } } } } num_ch = p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->channels; if (skip_full_decode == 0) { if (p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_ELD || p_state_enhaacplus_dec->audio_object_type == AOT_ER_AAC_LD) frame_size = p_state_enhaacplus_dec->frame_length; else { frame_size = p_state_enhaacplus_dec->frame_length; } sample_rate_dec = p_state_enhaacplus_dec->pstr_aac_dec_info[ch_idx]->sampling_rate; } } if (skip_full_decode == 1) { p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx][0].no_elements = 0; } if (p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx][0].no_elements != 0) { p_obj_exhaacplus_dec->aac_config.ui_sbr_mode = 1; } if (error_code) { if (p_state_enhaacplus_dec->ui_input_over) { if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; } else { return IA_XHEAAC_DEC_INIT_FATAL_EO_INPUT_REACHED; } } ixheaacd_updatebytesconsumed(p_state_enhaacplus_dec, it_bit_buff); p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes += p_state_enhaacplus_dec->num_of_out_samples * num_ch * sizeof(WORD16); if (error_code) { if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; } else { return error_code; } } } error_code = IA_NO_ERROR; if (p_obj_exhaacplus_dec->aac_config.ui_auto_sbr_upsample == 0) { if (p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx][0].no_elements == 0 && p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) { p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = 0; error_code = IA_XHEAAC_DEC_EXE_NONFATAL_SBR_TURNED_OFF; } } if ((!p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) && p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx][0].no_elements) { WORD32 harmonic_sbr_flag = 0; error_code = IA_XHEAAC_DEC_EXE_NONFATAL_SBR_TURNED_ON; p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = ixheaacd_init_sbr( sample_rate_dec, frame_size, (FLAG *)&p_obj_exhaacplus_dec->aac_config.down_sample_flag, p_state_enhaacplus_dec->sbr_persistent_mem_v, p_state_enhaacplus_dec->ptr_overlap_buf, ps_enable ? 2 : channel, ps_enable, 1, frame_size * 2, &harmonic_sbr_flag, NULL, p_state_enhaacplus_dec->str_sbr_config, p_state_enhaacplus_dec->audio_object_type, p_state_enhaacplus_dec->mps_dec_handle.ldmps_config .ldmps_present_flag, p_state_enhaacplus_dec->mps_dec_handle.ldmps_config.no_ldsbr_present); if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) { p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->xaac_jmp_buf = &(p_state_enhaacplus_dec->xaac_jmp_buf); } } { if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] && p_state_enhaacplus_dec->pstr_stream_sbr[0][0].no_elements) { ia_sbr_scr_struct sbr_scratch_struct; ixheaacd_allocate_sbr_scr(&sbr_scratch_struct, p_state_enhaacplus_dec->aac_scratch_mem_v, time_data, total_channels, p_obj_exhaacplus_dec->p_state_aac->qshift_adj, p_state_enhaacplus_dec->slot_pos, channel); p_state_enhaacplus_dec->sbr_present = 1; p_state_enhaacplus_dec->peak_lim_init = 0; if (p_obj_exhaacplus_dec->aac_config.ui_enh_sbr) { WORD32 audio_object_type = p_state_enhaacplus_dec->audio_object_type; if (audio_object_type != AOT_ER_AAC_ELD && audio_object_type != AOT_ER_AAC_LD) { WORD32 i = 0; ia_dec_data_struct* pstr_dec_data = (ia_dec_data_struct*)p_state_enhaacplus_dec->pstr_dec_data; if (ch_fac == 1) { for (; i < 1024; i++) { pstr_dec_data->str_usac_data.time_sample_vector[0][i] = (FLOAT32)time_data[i]; } p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[0] = &pstr_dec_data->str_usac_data.time_sample_vector[0][0]; p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[1] = &pstr_dec_data->str_usac_data.time_sample_vector[1][0]; } else if (ch_fac == 2) { for (; i < 1024; i++) { pstr_dec_data->str_usac_data.time_sample_vector[0][i] = (FLOAT32)time_data[2 * i + 0]; pstr_dec_data->str_usac_data.time_sample_vector[1][i] = (FLOAT32)time_data[2 * i + 1]; } p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[0] = &pstr_dec_data->str_usac_data.time_sample_vector[0][0]; p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[1] = &pstr_dec_data->str_usac_data.time_sample_vector[1][0]; } else if (ch_fac > 2) { if (channel == 1) { for (; i < 1024; i++) { pstr_dec_data->str_usac_data.time_sample_vector[0][i] = (FLOAT32)(time_data + slot_ele)[i* ch_fac]; } p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[0] = &pstr_dec_data->str_usac_data.time_sample_vector[0][0]; } else if (channel == 2) { for (; i < 1024; i++) { pstr_dec_data->str_usac_data.time_sample_vector[0][i] = (FLOAT32)(time_data + slot_ele)[ch_fac * i + 0]; pstr_dec_data->str_usac_data.time_sample_vector[1][i] = (FLOAT32)(time_data + slot_ele)[ch_fac * i + 1]; } p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[0] = &pstr_dec_data->str_usac_data.time_sample_vector[0][0]; p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->time_sample_buf[1] = &pstr_dec_data->str_usac_data.time_sample_vector[1][0]; } } } } p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->esbr_hq = p_obj_exhaacplus_dec->aac_config.ui_hq_esbr; p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->enh_sbr = p_obj_exhaacplus_dec->aac_config.ui_enh_sbr; p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->enh_sbr_ps = p_obj_exhaacplus_dec->aac_config.ui_enh_sbr_ps; if (p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) { p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]->xaac_jmp_buf = &(p_state_enhaacplus_dec->xaac_jmp_buf); } if (ixheaacd_applysbr(p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx], &p_state_enhaacplus_dec->pstr_stream_sbr[ch_idx][0], actual_out_buffer, &num_ch, p_obj_exhaacplus_dec->aac_config.frame_status, p_obj_exhaacplus_dec->aac_config.down_sample_flag, esbr_mono_downmix, &sbr_scratch_struct, ps_enable, ch_fac, slot_ele, NULL, &p_state_enhaacplus_dec->str_drc_dec_info, p_state_enhaacplus_dec->eld_specific_config.ld_sbr_flag_present, p_state_enhaacplus_dec->audio_object_type, 0, p_state_enhaacplus_dec->ldmps_present, frame_size, p_state_enhaacplus_dec->heaac_mps_handle.heaac_mps_present, p_obj_exhaacplus_dec->aac_config.ui_err_conceal, p_obj_exhaacplus_dec->aac_config.first_frame) != SBRDEC_OK) { p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] = 0; if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; } else { return -1; } } else { if (!p_obj_exhaacplus_dec->aac_config.down_sample_flag) { frame_size = (WORD16)(frame_size * 2); sample_rate_dec *= 2; } if (p_state_enhaacplus_dec->mps_dec_handle.ldmps_config .ldmps_present_flag == 1) { ixheaacd_mps_payload( p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx], p_obj_exhaacplus_dec); } } if (p_obj_exhaacplus_dec->aac_config.ui_enh_sbr) { WORD32 audio_object_type = p_state_enhaacplus_dec->audio_object_type; if (audio_object_type != AOT_ER_AAC_ELD && audio_object_type != AOT_ER_AAC_LD) { WORD32 out_bytes = 0; ia_dec_data_struct *pstr_dec_data = (ia_dec_data_struct *)p_state_enhaacplus_dec->pstr_dec_data; if (ch_fac <= 2) { ixheaacd_samples_sat((WORD8*)time_data, 2048, 16, pstr_dec_data->str_usac_data.time_sample_vector, &out_bytes, ch_fac); } else { ixheaacd_samples_sat_mc((WORD8*)(time_data + slot_ele), 2048, pstr_dec_data->str_usac_data.time_sample_vector, &out_bytes, channel, ch_fac); } } } p_state_enhaacplus_dec->mps_dec_handle.ldmps_config.no_ldsbr_present = 0; if (p_state_enhaacplus_dec->ui_mps_out_bytes > 0) { p_state_enhaacplus_dec->heaac_mps_handle.heaac_mps_present = 1; } } else { p_state_enhaacplus_dec->mps_dec_handle.ldmps_config.no_ldsbr_present = 1; } } if (p_state_enhaacplus_dec->mps_dec_handle.ldmps_config .ldmps_present_flag == 1 && p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx] && p_state_enhaacplus_dec->mps_dec_handle.mps_init_done == 1) { if (p_state_enhaacplus_dec->ec_enable) { if (!p_obj_exhaacplus_dec->aac_config.first_frame) { error_code = ixheaacd_ld_mps_apply(p_obj_exhaacplus_dec, actual_out_buffer); if (error_code) p_obj_exhaacplus_dec->aac_config.frame_status = 0; } } else { error_code = ixheaacd_ld_mps_apply(p_obj_exhaacplus_dec, actual_out_buffer); if (error_code) return error_code; } } if (sample_rate < sample_rate_dec) { sample_rate = sample_rate_dec; } if (p_state_enhaacplus_dec->sbr_present || p_obj_exhaacplus_dec->p_state_aac->qshift_adj[0] == LD_OBJ) { num_of_out_samples = frame_size; } else { num_of_out_samples = frame_size - MIN((WORD16)p_obj_exhaacplus_dec->p_state_aac->delay_in_samples, frame_size); } if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal && p_obj_exhaacplus_dec->aac_config.first_frame && (p_obj_exhaacplus_dec->p_state_aac->audio_object_type == AOT_ER_AAC_ELD || p_obj_exhaacplus_dec->p_state_aac->audio_object_type == AOT_ER_AAC_LD)) { num_of_out_samples = frame_size; } p_obj_exhaacplus_dec->aac_config.ui_samp_freq = sample_rate; p_state_enhaacplus_dec->num_channel_last = num_ch; p_state_enhaacplus_dec->num_of_out_samples = num_of_out_samples; if (p_state_enhaacplus_dec->mps_dec_handle.ldmps_config .ldmps_present_flag == 1 && p_state_enhaacplus_dec->mps_dec_handle.mps_init_done == 1 && p_state_enhaacplus_dec->str_sbr_dec_info[ch_idx]) { if (p_obj_exhaacplus_dec->p_state_aac->mps_dec_handle.output_buffer) { ixheaacd_samples_sat((WORD8 *)actual_out_buffer, num_of_out_samples, p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz, p_obj_exhaacplus_dec->p_state_aac->mps_dec_handle.output_buffer, &mps_out_samples, 2); p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = mps_out_samples; } num_ch = p_obj_exhaacplus_dec->p_state_aac->mps_dec_handle.out_ch_count; if (p_state_enhaacplus_dec->ec_enable) { if (p_obj_exhaacplus_dec->aac_config.first_frame) { p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = p_state_enhaacplus_dec->num_of_out_samples * num_ch * sizeof(WORD16); } } } else { if (p_obj_exhaacplus_dec->aac_config.element_type[ch_idx] != 2) { if (p_obj_exhaacplus_dec->aac_config.flag_to_stereo == 1 && channel == 1 && total_elements == 1 && num_ch == 1) { num_ch = 2; p_obj_exhaacplus_dec->aac_config.dup_stereo_flag = 1; } else { p_obj_exhaacplus_dec->aac_config.dup_stereo_flag = 0; } p_obj_exhaacplus_dec->aac_config.ui_n_channels = 2; p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes += p_state_enhaacplus_dec->num_of_out_samples * num_ch * sizeof(WORD16); } else { channel_coupling_flag = 1; } } if (p_state_enhaacplus_dec->sbr_present && total_channels > 2) { for (WORD32 j = 0; j < channel; j++) { for (WORD32 i = 0; i < frame_size; i++) { intermediate_scr[total_channels * i + j + p_state_enhaacplus_dec->slot_pos] = actual_out_buffer[total_channels * i + j + p_state_enhaacplus_dec->slot_pos]; } } } } if (p_state_enhaacplus_dec->sbr_present && total_channels > 2) { memcpy(time_data, intermediate_scr, sizeof(WORD16) * frame_size * total_channels); } { ia_adts_crc_info_struct *ptr_adts_crc_info = p_state_enhaacplus_dec->ptr_bit_stream->pstr_adts_crc_info; if (ptr_adts_crc_info->crc_active == 1) { if ((error_code = ixheaacd_adts_crc_check_crc(ptr_adts_crc_info))) { if (error_code) { if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { p_obj_exhaacplus_dec->aac_config.frame_status = 0; } else { return error_code; } } } } } p_obj_exhaacplus_dec->aac_config.ui_n_channels = total_channels; p_state_enhaacplus_dec->frame_counter++; WORD32 i, j; if (channel_coupling_flag) { error_code = ixheaacd_dec_ind_coupling(p_obj_exhaacplus_dec, p_state_enhaacplus_dec->coup_ch_output, num_of_out_samples, total_channels, time_data); if (error_code) return error_code; } for (i = 0; i < total_channels; i++) { if (p_obj_exhaacplus_dec->p_state_aac->qshift_adj[i + 1] == 0) p_obj_exhaacplus_dec->p_state_aac->qshift_adj[i + 1] = p_obj_exhaacplus_dec->p_state_aac->qshift_adj[0]; } if (p_obj_exhaacplus_dec->aac_config.flag_to_stereo == 1 && total_elements == 1 && num_ch == 2 && p_obj_exhaacplus_dec->aac_config.dup_stereo_flag == 1) { WORD i; if (!p_state_enhaacplus_dec->sbr_present && p_obj_exhaacplus_dec->p_state_aac->qshift_adj[0] != LD_OBJ) { for (i = 0; i < frame_size; i++) { *((WORD32 *)actual_out_buffer + 2 * i + 1) = *((WORD32 *)actual_out_buffer + 2 * i); } } else { for (i = 0; i < frame_size; i++) { *(actual_out_buffer + 2 * i + 1) = *(actual_out_buffer + 2 * i); } } } if (!p_state_enhaacplus_dec->sbr_present && p_obj_exhaacplus_dec->p_state_aac->peak_lim_init == 1 && p_obj_exhaacplus_dec->p_state_aac->qshift_adj[0] != LD_OBJ) { if (!p_obj_exhaacplus_dec->aac_config.peak_limiter_off) { ixheaacd_peak_limiter_process( &p_state_enhaacplus_dec->peak_limiter, time_data, frame_size, p_obj_exhaacplus_dec->p_state_aac->qshift_adj); } else { ixheaacd_scale_adjust(time_data, frame_size, p_obj_exhaacplus_dec->p_state_aac->qshift_adj, total_channels); } for (i = 0; i < frame_size * 2; i++) { for (j = 0; j < total_channels; j++) { *((WORD16 *)time_data + total_channels * i + j) = ixheaac_round16(*((WORD32 *)time_data + total_channels * i + j)); } } memmove( time_data, (time_data + total_channels * p_obj_exhaacplus_dec->p_state_aac->delay_in_samples), sizeof(WORD16) * num_of_out_samples * total_channels); p_obj_exhaacplus_dec->p_state_aac->delay_in_samples = p_obj_exhaacplus_dec->p_state_aac->delay_in_samples - MIN(p_obj_exhaacplus_dec->p_state_aac->delay_in_samples, (UWORD16)frame_size); } if (p_state_enhaacplus_dec->heaac_mps_handle.heaac_mps_present == 1) { ia_heaac_mps_state_struct *pstr_mps_state = &p_state_enhaacplus_dec->heaac_mps_handle; if (p_state_enhaacplus_dec->sbr_present == 0) { p_state_enhaacplus_dec->heaac_mps_handle.mps_decode = 1; } else { p_state_enhaacplus_dec->heaac_mps_handle.mps_with_sbr = 1; } if (!p_obj_exhaacplus_dec->aac_config.ui_enh_sbr) { p_state_enhaacplus_dec->heaac_mps_handle.mps_decode = 1; } if (p_state_enhaacplus_dec->heaac_mps_handle.mps_init_done == 1) { p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle.frame_ok = p_obj_exhaacplus_dec->aac_config.frame_status; p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle.ec_flag = p_obj_exhaacplus_dec->aac_config.ui_err_conceal; ixheaacd_heaac_mps_apply(p_obj_exhaacplus_dec, actual_out_buffer, mps_buffer, p_state_enhaacplus_dec->ui_mps_out_bytes); p_state_enhaacplus_dec->heaac_mps_handle.mps_decode = 1; p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = (pstr_mps_state->num_output_channels_at * pstr_mps_state->frame_length * (p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz >> 3)); p_obj_exhaacplus_dec->p_state_aac->heaac_mps_handle.first_frame = 0; } } if ((total_channels > 2) && (1 == p_obj_exhaacplus_dec->aac_config.downmix)) { ixheaacd_dec_downmix_to_stereo(p_obj_exhaacplus_dec, num_of_out_samples, total_elements, time_data, total_channels); total_channels = 2; p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = p_state_enhaacplus_dec->num_of_out_samples * 2 * sizeof(WORD16); } if (p_obj_exhaacplus_dec->aac_config.flag_downmix && total_channels == 2) { WORD32 out_ch = 1; WORD i; if (p_obj_exhaacplus_dec->aac_config.flag_to_stereo == 1) { out_ch = 2; } p_obj_exhaacplus_dec->aac_config.ui_n_channels = out_ch; p_obj_exhaacplus_dec->p_state_aac->ui_out_bytes = p_state_enhaacplus_dec->num_of_out_samples * out_ch * sizeof(WORD16); for (i = 0; i < num_of_out_samples; i++) { WORD16 temp; temp = (time_data[2 * i + 0] >> 1) + (time_data[2 * i + 1] >> 1); if (out_ch == 2) { time_data[2 * i + 0] = temp; time_data[2 * i + 1] = time_data[2 * i + 0]; } else { time_data[i] = temp; } } } if (p_state_enhaacplus_dec->s_adts_hdr_present) { if (adts.no_raw_data_blocks != 0) { if (adts.protection_absent == 0 && it_bit_buff->cnt_bits >= 16) { adts.crc_check = ixheaacd_read_bits_buf(it_bit_buff, 16); } } p_state_enhaacplus_dec->b_n_raw_data_blk--; } ixheaacd_updatebytesconsumed(p_state_enhaacplus_dec, it_bit_buff); if (p_state_enhaacplus_dec->bs_format == LOAS_BSFORMAT) p_state_enhaacplus_dec->i_bytes_consumed = (WORD32)(audio_mux_length_bytes_last + bytes_for_sync); if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal && p_obj_exhaacplus_dec->aac_config.first_frame) { p_obj_exhaacplus_dec->aac_config.first_frame = 0; } if (p_obj_exhaacplus_dec->aac_config.ui_err_conceal) { if (p_obj_exhaacplus_dec->aac_config.frame_status != 1) { p_state_enhaacplus_dec->i_bytes_consumed = p_state_enhaacplus_dec->ui_in_bytes; } return IA_NO_ERROR; } else { return error_code; } }