diff options
author | Akshay Ragir <akshay.ragir@ittiam.com> | 2023-11-27 14:03:47 +0530 |
---|---|---|
committer | Divya B M <89966460+divya-bm@users.noreply.github.com> | 2023-11-27 20:00:46 +0530 |
commit | 86eb72d8eb5c8c2cc0a667a8646068d11e0bbae3 (patch) | |
tree | 7441be07838aae33ca5eed7e8ed9824ee942bcdb | |
parent | cc7ce80ec3b6044b26b851c98a7a10952f0e22f8 (diff) | |
download | libxaac-86eb72d8eb5c8c2cc0a667a8646068d11e0bbae3.tar.gz |
Fix for the Global-buffer-overflow READ 4 in iaace_estimate_scfs_chan
These changes handle the 960 frame length
support for SBR and PS profiles.
Bug: ossFuzz: 64532
Test: poc in bug
-rw-r--r-- | encoder/ixheaace_api.c | 4 | ||||
-rw-r--r-- | encoder/ixheaace_sbr_env_est.c | 195 | ||||
-rw-r--r-- | encoder/ixheaace_sbr_qmf_enc.c | 9 | ||||
-rw-r--r-- | encoder/ixheaace_sbr_qmf_enc.h | 3 | ||||
-rw-r--r-- | encoder/ixheaace_sf_estimation.c | 2 |
5 files changed, 109 insertions, 104 deletions
diff --git a/encoder/ixheaace_api.c b/encoder/ixheaace_api.c index fee5c9e..bd4c3f3 100644 --- a/encoder/ixheaace_api.c +++ b/encoder/ixheaace_api.c @@ -785,6 +785,10 @@ static VOID ixheaace_validate_config_params(ixheaace_input_config *pstr_input_co pstr_input_config->frame_length = LEN_SUPERFRAME; } } + if ((pstr_input_config->frame_length == FRAME_LEN_960) && + (pstr_input_config->esbr_flag == 1)) { + pstr_input_config->esbr_flag = 0; + } } } diff --git a/encoder/ixheaace_sbr_env_est.c b/encoder/ixheaace_sbr_env_est.c index 7f3cc83..4011802 100644 --- a/encoder/ixheaace_sbr_env_est.c +++ b/encoder/ixheaace_sbr_env_est.c @@ -1918,115 +1918,108 @@ IA_ERRORCODE ixheaace_extract_sbr_envelope(FLOAT32 *ptr_in_time, FLOAT32 *ptr_co while (ch < n_in_channels) { ixheaace_str_sbr_extr_env *pstr_sbr_extract_env = &(pstr_env_ch[ch]->str_sbr_extract_env); - if (pstr_ps_enc) { - ixheaace_sbr_analysis_filtering( - ptr_in_time ? ptr_in_time + ch : NULL, IXHEAACE_MAX_CH_IN_BS_ELE, - pstr_sbr_extract_env->ptr_r_buffer, pstr_sbr_extract_env->ptr_i_buffer, - &pstr_env_ch[ch]->str_sbr_qmf, ptr_sbr_tab->ptr_qmf_tab, - pstr_env_ch[ch]->str_sbr_qmf.num_time_slots * pstr_env_ch[ch]->str_sbr_qmf.rate, - pstr_sbr_cfg->is_ld_sbr, (FLOAT32 *)ptr_sbr_scratch); - } else { - ixheaace_sbr_analysis_filtering( - ptr_in_time ? ptr_in_time + ch : NULL, time_sn_stride, - pstr_sbr_extract_env->ptr_r_buffer, pstr_sbr_extract_env->ptr_i_buffer, - &pstr_env_ch[ch]->str_sbr_qmf, ptr_sbr_tab->ptr_qmf_tab, - pstr_env_ch[ch]->str_sbr_qmf.num_time_slots * pstr_env_ch[ch]->str_sbr_qmf.rate, - pstr_sbr_cfg->is_ld_sbr, (FLOAT32 *)ptr_sbr_scratch); - if ((1 == n_in_channels) && (USAC_SBR == pstr_sbr_cfg->sbr_codec) && - (pstr_sbr_hdr->sbr_pvc_active)) { - ixheaace_pvc_scratch *pstr_pvc_scr = (ixheaace_pvc_scratch *)ptr_sbr_scratch; - WORD32 ts, bd; - FLOAT32 nrg_0, nrg_1; - FLOAT32 *ptr_r_0, *ptr_r_1, *ptr_i_0, *ptr_i_1; - FLOAT32 *ptr_r_2, *ptr_r_3, *ptr_i_2, *ptr_i_3, nrg_2, nrg_3; - WORD32 pvc_rate = pstr_env_enc->pstr_pvc_enc->pvc_param.pvc_rate; - - // update header_active to send SBR header when previous PVC mode is different from - // current frame's - if (pstr_env_enc->str_sbr_hdr.sbr_pvc_mode != - pstr_env_enc->pstr_pvc_enc->pvc_param.pvc_mode) { - pstr_sbr_bs->header_active = 1; - } - - switch (pvc_rate) { - case 2: { - for (ts = 0; ts < IXHEAACE_ESBR_PVC_NUM_TS; ts++) { - ptr_r_0 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts]; - ptr_r_1 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts + 1]; - ptr_i_0 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts]; - ptr_i_1 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts + 1]; - - for (bd = 0; bd < MAX_QMF_TIME_SLOTS; bd++) { - nrg_0 = ptr_r_0[bd] * ptr_r_0[bd] + ptr_i_0[bd] * ptr_i_0[bd]; - nrg_1 = ptr_r_1[bd] * ptr_r_1[bd] + ptr_i_1[bd] * ptr_i_1[bd]; - pstr_pvc_scr->pvc_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + bd] = - (nrg_0 + nrg_1) / 2.0f; - } - WORD32 num_low_bands = MAX_QMF_TIME_SLOTS >> 1; - for (bd = 0; bd < num_low_bands; bd++) { - pstr_pvc_scr->pvc_qmf_low[ts * num_low_bands + bd] = - pstr_pvc_scr->pvc_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + bd]; - } + ixheaace_sbr_analysis_filtering( + ptr_in_time ? ptr_in_time + ch : NULL, time_sn_stride, + pstr_sbr_extract_env->ptr_r_buffer, pstr_sbr_extract_env->ptr_i_buffer, + &pstr_env_ch[ch]->str_sbr_qmf, ptr_sbr_tab->ptr_qmf_tab, + pstr_env_ch[ch]->str_sbr_qmf.num_time_slots * pstr_env_ch[ch]->str_sbr_qmf.rate, + pstr_sbr_cfg->is_ld_sbr, (FLOAT32 *)ptr_sbr_scratch, + (pstr_ps_enc != NULL && flag_framelength_small)); + + if ((1 == n_in_channels) && (USAC_SBR == pstr_sbr_cfg->sbr_codec) && + (pstr_sbr_hdr->sbr_pvc_active)) { + ixheaace_pvc_scratch *pstr_pvc_scr = (ixheaace_pvc_scratch *)ptr_sbr_scratch; + WORD32 ts, bd; + FLOAT32 nrg_0, nrg_1; + FLOAT32 *ptr_r_0, *ptr_r_1, *ptr_i_0, *ptr_i_1; + FLOAT32 *ptr_r_2, *ptr_r_3, *ptr_i_2, *ptr_i_3, nrg_2, nrg_3; + WORD32 pvc_rate = pstr_env_enc->pstr_pvc_enc->pvc_param.pvc_rate; + + // update header_active to send SBR header when previous PVC mode is different from + // current frame's + if (pstr_env_enc->str_sbr_hdr.sbr_pvc_mode != + pstr_env_enc->pstr_pvc_enc->pvc_param.pvc_mode) { + pstr_sbr_bs->header_active = 1; + } + + switch (pvc_rate) { + case 2: { + for (ts = 0; ts < IXHEAACE_ESBR_PVC_NUM_TS; ts++) { + ptr_r_0 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts]; + ptr_r_1 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts + 1]; + ptr_i_0 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts]; + ptr_i_1 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts + 1]; + + for (bd = 0; bd < MAX_QMF_TIME_SLOTS; bd++) { + nrg_0 = ptr_r_0[bd] * ptr_r_0[bd] + ptr_i_0[bd] * ptr_i_0[bd]; + nrg_1 = ptr_r_1[bd] * ptr_r_1[bd] + ptr_i_1[bd] * ptr_i_1[bd]; + pstr_pvc_scr->pvc_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + bd] = + (nrg_0 + nrg_1) / 2.0f; } - break; - } - case 4: { - for (ts = 0; ts < IXHEAACE_ESBR_PVC_NUM_TS; ts++) { - ptr_r_0 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts]; - ptr_r_1 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts + 1]; - ptr_r_2 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts + 2]; - ptr_r_3 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts + 3]; - ptr_i_0 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts]; - ptr_i_1 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts + 1]; - ptr_i_2 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts + 2]; - ptr_i_3 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts + 3]; - - for (bd = 0; bd < MAX_QMF_TIME_SLOTS; bd++) { - nrg_0 = ptr_r_0[bd] * ptr_r_0[bd] + ptr_i_0[bd] * ptr_i_0[bd]; - nrg_1 = ptr_r_1[bd] * ptr_r_1[bd] + ptr_i_1[bd] * ptr_i_1[bd]; - nrg_2 = ptr_r_2[bd] * ptr_r_2[bd] + ptr_i_2[bd] * ptr_i_2[bd]; - nrg_3 = ptr_r_3[bd] * ptr_r_3[bd] + ptr_i_3[bd] * ptr_i_3[bd]; - pstr_pvc_scr->pvc_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + bd] = - (nrg_0 + nrg_1 + nrg_2 + nrg_3) / 4.0f; - } - WORD32 num_low_bands = (MAX_QMF_TIME_SLOTS >> 2); - for (bd = 0; bd < num_low_bands; bd++) { - pstr_pvc_scr->pvc_qmf_low[ts * num_low_bands + bd] = - pstr_pvc_scr->pvc_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + bd]; - } + WORD32 num_low_bands = MAX_QMF_TIME_SLOTS >> 1; + for (bd = 0; bd < num_low_bands; bd++) { + pstr_pvc_scr->pvc_qmf_low[ts * num_low_bands + bd] = + pstr_pvc_scr->pvc_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + bd]; } - break; } + break; } - pstr_env_enc->pstr_pvc_enc->pvc_param.usac_indep_flag = pstr_sbr_bs->usac_indep_flag; - err_code = ixheaace_pvc_encode_frame( - pstr_env_enc->pstr_pvc_enc, (UWORD8)pstr_env_enc->str_sbr_hdr.sbr_pvc_mode, - pstr_pvc_scr->pvc_qmf_low, pstr_pvc_scr->pvc_qmf_high, - pstr_sbr_cfg->ptr_v_k_master[0], - pstr_sbr_cfg->ptr_v_k_master[pstr_sbr_cfg->num_master] - 1); - if (err_code) { - return err_code; + case 4: { + for (ts = 0; ts < IXHEAACE_ESBR_PVC_NUM_TS; ts++) { + ptr_r_0 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts]; + ptr_r_1 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts + 1]; + ptr_r_2 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts + 2]; + ptr_r_3 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts + 3]; + ptr_i_0 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts]; + ptr_i_1 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts + 1]; + ptr_i_2 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts + 2]; + ptr_i_3 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts + 3]; + + for (bd = 0; bd < MAX_QMF_TIME_SLOTS; bd++) { + nrg_0 = ptr_r_0[bd] * ptr_r_0[bd] + ptr_i_0[bd] * ptr_i_0[bd]; + nrg_1 = ptr_r_1[bd] * ptr_r_1[bd] + ptr_i_1[bd] * ptr_i_1[bd]; + nrg_2 = ptr_r_2[bd] * ptr_r_2[bd] + ptr_i_2[bd] * ptr_i_2[bd]; + nrg_3 = ptr_r_3[bd] * ptr_r_3[bd] + ptr_i_3[bd] * ptr_i_3[bd]; + pstr_pvc_scr->pvc_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + bd] = + (nrg_0 + nrg_1 + nrg_2 + nrg_3) / 4.0f; + } + WORD32 num_low_bands = (MAX_QMF_TIME_SLOTS >> 2); + for (bd = 0; bd < num_low_bands; bd++) { + pstr_pvc_scr->pvc_qmf_low[ts * num_low_bands + bd] = + pstr_pvc_scr->pvc_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + bd]; + } + } + break; } - - memcpy(&pstr_env_ch[ch]->enc_env_data.pvc_info, &pstr_env_enc->pstr_pvc_enc->pvc_bs_info, - sizeof(ixheaace_pvc_bs_info)); + } + pstr_env_enc->pstr_pvc_enc->pvc_param.usac_indep_flag = pstr_sbr_bs->usac_indep_flag; + err_code = ixheaace_pvc_encode_frame( + pstr_env_enc->pstr_pvc_enc, (UWORD8)pstr_env_enc->str_sbr_hdr.sbr_pvc_mode, + pstr_pvc_scr->pvc_qmf_low, pstr_pvc_scr->pvc_qmf_high, + pstr_sbr_cfg->ptr_v_k_master[0], + pstr_sbr_cfg->ptr_v_k_master[pstr_sbr_cfg->num_master] - 1); + if (err_code) { + return err_code; } - // COPY generated spectrum for inter-TES encoder - if ((USAC_SBR == pstr_sbr_cfg->sbr_codec) && (1 == pstr_sbr_hdr->sbr_inter_tes_active)) { - WORD32 ts, num_ts, delay; - num_ts = pstr_env_ch[ch]->str_sbr_qmf.num_time_slots; + memcpy(&pstr_env_ch[ch]->enc_env_data.pvc_info, &pstr_env_enc->pstr_pvc_enc->pvc_bs_info, + sizeof(ixheaace_pvc_bs_info)); + } - ixheaace_str_inter_tes_params *pstr_tes_enc = &pstr_env_ch[ch]->str_inter_tes_enc; - delay = pstr_tes_enc->op_delay + pstr_tes_enc->codec_delay + IXHEAACE_SBR_HF_ADJ_OFFSET; - ts = 0; - while (ts < num_ts) { - memcpy(pstr_tes_enc->qmf_buf_real[delay + ts], pstr_sbr_extract_env->ptr_r_buffer[ts], - IXHEAACE_QMF_CHANNELS * sizeof(pstr_tes_enc->qmf_buf_real[0][0])); - memcpy(pstr_tes_enc->qmf_buf_imag[delay + ts], pstr_sbr_extract_env->ptr_i_buffer[ts], - IXHEAACE_QMF_CHANNELS * sizeof(pstr_tes_enc->qmf_buf_imag[0][0])); - ts++; - } + // COPY generated spectrum for inter-TES encoder + if ((USAC_SBR == pstr_sbr_cfg->sbr_codec) && (1 == pstr_sbr_hdr->sbr_inter_tes_active)) { + WORD32 ts, num_ts, delay; + num_ts = pstr_env_ch[ch]->str_sbr_qmf.num_time_slots; + + ixheaace_str_inter_tes_params *pstr_tes_enc = &pstr_env_ch[ch]->str_inter_tes_enc; + delay = pstr_tes_enc->op_delay + pstr_tes_enc->codec_delay + IXHEAACE_SBR_HF_ADJ_OFFSET; + ts = 0; + while (ts < num_ts) { + memcpy(pstr_tes_enc->qmf_buf_real[delay + ts], pstr_sbr_extract_env->ptr_r_buffer[ts], + IXHEAACE_QMF_CHANNELS * sizeof(pstr_tes_enc->qmf_buf_real[0][0])); + memcpy(pstr_tes_enc->qmf_buf_imag[delay + ts], pstr_sbr_extract_env->ptr_i_buffer[ts], + IXHEAACE_QMF_CHANNELS * sizeof(pstr_tes_enc->qmf_buf_imag[0][0])); + ts++; } } diff --git a/encoder/ixheaace_sbr_qmf_enc.c b/encoder/ixheaace_sbr_qmf_enc.c index 281ba31..cfe485f 100644 --- a/encoder/ixheaace_sbr_qmf_enc.c +++ b/encoder/ixheaace_sbr_qmf_enc.c @@ -801,7 +801,8 @@ VOID ixheaace_sbr_analysis_filtering(const FLOAT32 *ptr_time_in, WORD32 time_sn_ FLOAT32 **ptr_ana_r, FLOAT32 **ptr_ana_i, ixheaace_pstr_sbr_qmf_filter_bank pstr_qmf_bank, ixheaace_str_qmf_tabs *pstr_qmf_tab, WORD32 num_qmf_subsamp, - WORD32 is_ld_sbr, FLOAT32 *ptr_sbr_scratch) { + WORD32 is_ld_sbr, FLOAT32 *ptr_sbr_scratch, + WORD32 is_ps_960) { WORD32 i, k; const FLOAT32 *ptr_pf_l, *ptr_pf_r; FLOAT32 *ptr_fp1, *ptr_fp2, *ptr_tmp; @@ -939,6 +940,12 @@ VOID ixheaace_sbr_analysis_filtering(const FLOAT32 *ptr_time_in, WORD32 time_sn_ pstr_qmf_bank->offset_r = pstr_qmf_bank->ptr_ref_coeff_r - ptr_start_coeff_r; pstr_qmf_bank->flag = flag; } + if (is_ps_960 == 1) { + memset(&ptr_ana_r[num_qmf_subsamp][0], 0, sizeof(ptr_ana_r[num_qmf_subsamp][0]) * + IXHEAACE_QMF_CHANNELS * (IXHEAACE_QMF_TIME_SLOTS - num_qmf_subsamp)); + memset(&ptr_ana_i[num_qmf_subsamp][0], 0, sizeof(ptr_ana_i[num_qmf_subsamp][0]) * + IXHEAACE_QMF_CHANNELS * (IXHEAACE_QMF_TIME_SLOTS - num_qmf_subsamp)); + } } VOID ixheaace_get_energy_from_cplx_qmf( diff --git a/encoder/ixheaace_sbr_qmf_enc.h b/encoder/ixheaace_sbr_qmf_enc.h index 5a1dcd6..a7d4f48 100644 --- a/encoder/ixheaace_sbr_qmf_enc.h +++ b/encoder/ixheaace_sbr_qmf_enc.h @@ -62,7 +62,8 @@ VOID ixheaace_sbr_analysis_filtering(const FLOAT32 *ptr_time_in, WORD32 time_sn_ FLOAT32 **ptr_ana_r, FLOAT32 **ptr_ana_i, ixheaace_pstr_sbr_qmf_filter_bank pstr_qmf_bank, ixheaace_str_qmf_tabs *pstr_qmf_tab, WORD32 num_qmf_subsamp, - WORD32 is_ld_sbr, FLOAT32 *ptr_sbr_scratch); + WORD32 is_ld_sbr, FLOAT32 *ptr_sbr_scratch, + WORD32 is_ps_960); VOID ixheaace_create_qmf_bank(ixheaace_pstr_sbr_qmf_filter_bank pstr_sbr_qmf_handle, ixheaace_str_sbr_tabs *pstr_sbr_tab, WORD32 is_ld_sbr); diff --git a/encoder/ixheaace_sf_estimation.c b/encoder/ixheaace_sf_estimation.c index cbd67d0..17d48ba 100644 --- a/encoder/ixheaace_sf_estimation.c +++ b/encoder/ixheaace_sf_estimation.c @@ -684,7 +684,7 @@ VOID iaace_estimate_scfs_chan( min_sf_max_quant[i] = (WORD16)floor(C1_SF + C2_SF * log(max_spec)); scf_int = MAX(scf_int, min_sf_max_quant[i]); scf_int = MAX(scf_int, MIN_GAIN_INDEX_AAC); - scf_int = MIN(scf_int, (MAX_GAIN_INDEX_AAC - SCF_COUNT_LIMIT_AAC)); + scf_int = MIN(scf_int, (MAX_GAIN_INDEX_AAC - SCF_COUNT_LIMIT_AAC - 1)); for (j = 0; j < pstr_psy_out_chan->sfb_offsets[i + 1] - pstr_psy_out_chan->sfb_offsets[i]; j++) { ptr_exp_spec[pstr_psy_out_chan->sfb_offsets[i] + j] = (FLOAT32)( |