From 1b703a5eeafe755c59aaa8db2e76845571af1a56 Mon Sep 17 00:00:00 2001 From: Sushanth Patil Date: Fri, 9 Aug 2019 13:38:16 +0530 Subject: [PATCH] Optimisation changes in mps apply function Added changes to remove redundant computation loops in ixheaacd_mps_synt_calc,mps hybrid analysis & synthesis functions based on number of non-zero qmf bands. --- decoder/ixheaacd_mps_dec.c | 24 ++++++++++++++++-------- decoder/ixheaacd_mps_dec.h | 11 ++++------- decoder/ixheaacd_mps_hybrid_filt.c | 2 +- decoder/ixheaacd_mps_parse.c | 3 +-- decoder/ixheaacd_mps_poly_filt.c | 13 +++++++------ decoder/ixheaacd_mps_pre_mix.c | 6 +++--- decoder/ixheaacd_mps_temp_process.c | 13 +++++++++++-- decoder/ixheaacd_mps_temp_reshape.c | 8 ++++---- decoder/ixheaacd_process.c | 7 +++++++ decoder/ixheaacd_sbr_dec.c | 10 +++++++++- decoder/ixheaacd_sbr_dec.h | 1 + decoder/ixheaacd_sbrdec_initfuncs.c | 1 + 12 files changed, 65 insertions(+), 34 deletions(-) diff --git a/decoder/ixheaacd_mps_dec.c b/decoder/ixheaacd_mps_dec.c index 98f6646..4446b51 100644 --- a/decoder/ixheaacd_mps_dec.c +++ b/decoder/ixheaacd_mps_dec.c @@ -71,6 +71,8 @@ #include "ixheaacd_mps_huff_tab.h" #include "ixheaacd_error_standards.h" +#define max(a,b) (((a) > (b)) ? (a) : (b)) + extern const ia_huff_pt0_nodes_struct ixheaacd_huff_part0_nodes; extern const ia_huff_ipd_nodes_struct ixheaacd_huff_ipd_nodes; extern const ia_huff_lav_nodes_struct ixheaacd_huff_lav_idx_nodes; @@ -126,7 +128,7 @@ WORD32 ixheaacd_mps_create(ia_mps_dec_state_struct* self, WORD32 bs_frame_len, if ((self->residual_coding) && (self->res_bands > 0)) ixheaacd_mps_qmf_hybrid_analysis_init(&self->hyb_filt_state[1]); - err_code = ixheaacd_mps_decor_init(&(self->mps_decor), self->hyb_band_count, + err_code = ixheaacd_mps_decor_init(&(self->mps_decor), self->hyb_band_count_max, self->config->bs_decorr_config); if (err_code != IA_NO_ERROR) return err_code; @@ -163,12 +165,12 @@ static const FLOAT32 ixheaacd_tsd_mul_im[] = { VOID ixheaacd_mps_qmf_hyb_analysis(ia_mps_dec_state_struct* self) { ixheaacd_mps_qmf_hybrid_analysis(&self->hyb_filt_state[0], self->qmf_in[0], - self->qmf_band_count, self->time_slots, + self->band_count[0], self->time_slots, self->hyb_in[0]); if ((self->residual_coding) && (self->res_bands > 0)) { ixheaacd_mps_qmf_hybrid_analysis(&self->hyb_filt_state[self->in_ch_count], - self->qmf_in[1], self->qmf_band_count, + self->qmf_in[1], self->band_count[1], self->time_slots, self->hyb_res); } } @@ -178,7 +180,7 @@ VOID ixheaacd_mps_qmf_hyb_synthesis(ia_mps_dec_state_struct* self) { for (ch = 0; ch < self->out_ch_count; ch++) { ixheaacd_mps_qmf_hybrid_synthesis(self->hyb_dir_out[ch], - self->qmf_band_count, self->time_slots, + self->band_count[0], self->time_slots, self->qmf_out_dir[ch]); } } @@ -235,7 +237,7 @@ VOID ixheaacd_mps_mix_res_decor(ia_mps_dec_state_struct* self) { WORD32 ts, qs, row, indx; for (ts = 0; ts < self->time_slots; ts++) { - for (qs = 0; qs < self->hyb_band_count; qs++) { + for (qs = 0; qs < self->hyb_band_count_max; qs++) { indx = self->hyb_band_to_processing_band_table[qs]; for (row = 0; row < self->dir_sig_count; row++) { @@ -281,14 +283,19 @@ WORD32 ixheaacd_mps_apply(ia_mps_dec_state_struct* self, WORD32 time_slots = self->time_slots; WORD32 in_ch_count = self->in_ch_count + self->res_ch_count; WORD32 err = 0; - + self->hyb_band_count[0] = self->band_count[0] - QMF_BANDS_TO_HYBRID + 10; + self->hyb_band_count[1] = self->band_count[1] - QMF_BANDS_TO_HYBRID + 10; + self->hyb_band_count_max = + max(self->hyb_band_count[0], self->hyb_band_count[1]); + self->mps_decor.decor_nrg_smooth.num_bins = self->hyb_band_count_max; + self->mps_decor.num_bins = self->hyb_band_count_max; self->output_buffer = output_buffer; assert(self->present_time_slot + time_slots <= self->time_slots); for (ts = 0; ts < time_slots; ts++) { for (ch = 0; ch < in_ch_count; ch++) { - for (qs = 0; qs < self->qmf_band_count; qs++) { + for (qs = 0; qs < self->band_count[ch]; qs++) { self->qmf_in[ch][self->present_time_slot + ts][qs].re = self->input_gain * input_buffer[2 * ch][ts][qs]; self->qmf_in[ch][self->present_time_slot + ts][qs].im = @@ -306,12 +313,13 @@ WORD32 ixheaacd_mps_apply(ia_mps_dec_state_struct* self, err = ixheaacd_mps_frame_decode(self); if (err != 0) return err; - ixheaacd_mps_qmf_hyb_analysis(self); ixheaacd_pre_and_mix_matrix_calculation(self); ixheaacd_mps_pre_matrix_mix_matrix_smoothing(self); + ixheaacd_mps_qmf_hyb_analysis(self); + err = ixheaacd_mps_apply_pre_matrix(self); if (err < 0) return err; diff --git a/decoder/ixheaacd_mps_dec.h b/decoder/ixheaacd_mps_dec.h index 66d34f4..77b140e 100644 --- a/decoder/ixheaacd_mps_dec.h +++ b/decoder/ixheaacd_mps_dec.h @@ -189,7 +189,6 @@ typedef struct ia_mps_dec_state_struct { WORD32 time_slots; WORD32 present_time_slot; - WORD32 frame_len; WORD32 temp_shape_enable_ch_stp[2]; WORD32 temp_shape_enable_ch_ges[2]; @@ -197,9 +196,11 @@ typedef struct ia_mps_dec_state_struct { FLOAT32 env_shape_data[2][MAX_TIME_SLOTS]; WORD8 parse_nxt_frame; - + WORD32 band_count[MAX_M1_INPUT]; + WORD32 synth_count; WORD32 qmf_band_count; - WORD32 hyb_band_count; + WORD32 hyb_band_count[MAX_M1_INPUT]; + WORD32 hyb_band_count_max; const WORD32 *hyb_band_to_processing_band_table; WORD32 res_ch_count; @@ -342,10 +343,6 @@ VOID ixheaacd_pre_and_mix_matrix_calculation(ia_mps_dec_state_struct *self); WORD32 ixheaacd_mps_apply_pre_matrix(ia_mps_dec_state_struct *self); WORD32 ixheaacd_mps_apply_mix_matrix(ia_mps_dec_state_struct *self); -VOID ixheaacd_mps_config(ia_mps_dec_state_struct *self, WORD32 frame_len, - WORD32 residual_coding, - ia_usac_dec_mps_config_struct *mps212_config); - WORD32 ixheaacd_mps_frame_decode(ia_mps_dec_state_struct *self); WORD32 ixheaacd_mps_header_decode(ia_mps_dec_state_struct *self); diff --git a/decoder/ixheaacd_mps_hybrid_filt.c b/decoder/ixheaacd_mps_hybrid_filt.c index f76df28..190ddb2 100644 --- a/decoder/ixheaacd_mps_hybrid_filt.c +++ b/decoder/ixheaacd_mps_hybrid_filt.c @@ -243,7 +243,7 @@ VOID ixheaacd_mps_qmf_hybrid_analysis( } } - for (k = 0; k < num_bands - lf_qmf_bands; k++) { + for (k = 0; k < MAX_NUM_QMF_BANDS_SAC / 2 - lf_qmf_bands; k++) { for (n = 0; n < hf_samples_shift; n++) { handle->hf_buffer[k][n].re = handle->hf_buffer[k][n + num_samples].re; handle->hf_buffer[k][n].im = handle->hf_buffer[k][n + num_samples].im; diff --git a/decoder/ixheaacd_mps_parse.c b/decoder/ixheaacd_mps_parse.c index 81a8592..46baada 100644 --- a/decoder/ixheaacd_mps_parse.c +++ b/decoder/ixheaacd_mps_parse.c @@ -994,10 +994,9 @@ WORD32 ixheaacd_mps_frame_decode(ia_mps_dec_state_struct *self) { WORD32 ixheaacd_mps_header_decode(ia_mps_dec_state_struct *self) { self->time_slots = self->frame_length; - self->frame_len = self->time_slots * self->qmf_band_count; self->bs_param_bands = ixheaacd_freq_res_table[self->config->bs_freq_res]; - self->hyb_band_count = self->qmf_band_count - QMF_BANDS_TO_HYBRID + 10; + self->hyb_band_count_max = self->qmf_band_count - QMF_BANDS_TO_HYBRID + 10; switch (self->bs_param_bands) { case 4: diff --git a/decoder/ixheaacd_mps_poly_filt.c b/decoder/ixheaacd_mps_poly_filt.c index 315f0c7..2f3c325 100644 --- a/decoder/ixheaacd_mps_poly_filt.c +++ b/decoder/ixheaacd_mps_poly_filt.c @@ -134,9 +134,9 @@ VOID ixheaacd_mps_synt_out_calc_dec(WORD32 resolution, WORD32 *out, VOID ixheaacd_mps_synt_calc(ia_mps_dec_state_struct *self) { WORD32 k, l, ts, ch; WORD64 acc; - WORD32 ptr_in[128]; - WORD32 fin_re[128]; - WORD32 fin_im[128]; + WORD32 ptr_in[128] = {0}; + WORD32 fin_re[128] = {0}; + WORD32 fin_im[128] = {0}; FLOAT32 temp; WORD32 *state, *tmp_state, *out; const WORD32 *filt_coeff; @@ -152,18 +152,19 @@ VOID ixheaacd_mps_synt_calc(ia_mps_dec_state_struct *self) { for (ts = 0; ts < self->time_slots; ts++) { ixheaacd_float_to_int32(&self->qmf_out_dir[ch][ts][0].re, ptr_in, 10, - resolution * 2); + self->synth_count * 2); filt_coeff = ixheaacd_mps_polyphase_filter_coeff_fix; state -= (2 * resolution); (*ixheaacd_mps_synt_pre_twiddle)(ptr_in, ixheaacd_mps_pre_re, - ixheaacd_mps_pre_im, resolution); + ixheaacd_mps_pre_im, self->synth_count); (*ixheaacd_mps_complex_fft_64)(ptr_in, fin_re, fin_im, resolution); (*ixheaacd_mps_synt_post_twiddle)(ptr_in, ixheaacd_mps_post_re, - ixheaacd_mps_post_im, resolution); + ixheaacd_mps_post_im, + self->synth_count); (*ixheaacd_mps_complex_fft_64)(ptr_in, &fin_re[1], &fin_im[1], resolution); diff --git a/decoder/ixheaacd_mps_pre_mix.c b/decoder/ixheaacd_mps_pre_mix.c index 0e5fa92..9bb08e1 100644 --- a/decoder/ixheaacd_mps_pre_mix.c +++ b/decoder/ixheaacd_mps_pre_mix.c @@ -381,7 +381,7 @@ WORD32 ixheaacd_mps_apply_pre_matrix(ia_mps_dec_state_struct *self) { self->v[row][ts][qs].im = sum_imag; } } - for (qs = 2; qs < self->hyb_band_count; qs++) { + for (qs = 2; qs < self->hyb_band_count[0]; qs++) { WORD32 sign = 1; WORD32 indx = self->hyb_band_to_processing_band_table[qs]; for (row = 0; row < (self->dir_sig_count + self->decor_sig_count); @@ -469,7 +469,7 @@ WORD32 ixheaacd_mps_apply_mix_matrix(ia_mps_dec_state_struct *self) { } for (ts = 0; ts < self->time_slots; ts++) { - for (qs = 0; qs < self->hyb_band_count; qs++) { + for (qs = 0; qs < self->hyb_band_count_max; qs++) { WORD32 indx = self->hyb_band_to_processing_band_table[qs]; for (row = 0; row < self->out_ch_count; row++) { FLOAT32 sum_re_dir = 0; @@ -521,7 +521,7 @@ WORD32 ixheaacd_mps_apply_mix_matrix(ia_mps_dec_state_struct *self) { self->hyb_diff_out[row][ts][qs].im = sum_im_diff; } } - for (qs = 2; qs < self->hyb_band_count; qs++) { + for (qs = 2; qs < self->hyb_band_count_max; qs++) { WORD32 indx = self->hyb_band_to_processing_band_table[qs]; for (row = 0; row < self->out_ch_count; row++) { FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re; diff --git a/decoder/ixheaacd_mps_temp_process.c b/decoder/ixheaacd_mps_temp_process.c index 736996c..964735a 100644 --- a/decoder/ixheaacd_mps_temp_process.c +++ b/decoder/ixheaacd_mps_temp_process.c @@ -182,7 +182,7 @@ static VOID ixheaacd_mps_subbandtp(ia_mps_dec_state_struct* self, WORD32 ts) { no_scaling = !self->temp_shape_enable_ch_stp[ch]; if (no_scaling == 1) { - for (n = 0; n < self->hyb_band_count; n++) { + for (n = 0; n < self->hyb_band_count_max; n++) { self->hyb_dir_out[ch][ts][n].re += self->hyb_diff_out[ch][ts][n].re; self->hyb_dir_out[ch][ts][n].im += self->hyb_diff_out[ch][ts][n].im; } @@ -202,7 +202,7 @@ static VOID ixheaacd_mps_subbandtp(ia_mps_dec_state_struct* self, WORD32 ts) { self->hyb_dir_out[ch][ts][n].im += (self->hyb_diff_out[ch][ts][n].im * temp); } - for (; n < self->hyb_band_count; n++) { + for (; n < self->hyb_band_count_max; n++) { temp = (FLOAT32)(scale[ch]); self->hyb_dir_out[ch][ts][n].re += (self->hyb_diff_out[ch][ts][n].re * temp); @@ -216,6 +216,8 @@ static VOID ixheaacd_mps_subbandtp(ia_mps_dec_state_struct* self, WORD32 ts) { WORD32 ixheaacd_mps_temp_process(ia_mps_dec_state_struct* self) { WORD32 ch, ts, hyb; WORD32 err = 0; + ia_sbr_frame_info_data_struct* ptr_frame_data = + (ia_sbr_frame_info_data_struct*)self->p_sbr_frame[0]; for (ch = 0; ch < self->out_ch_count; ch++) { for (ts = 0; ts < self->time_slots; ts++) { @@ -239,6 +241,13 @@ WORD32 ixheaacd_mps_temp_process(ia_mps_dec_state_struct* self) { if (err) return err; } + if (ptr_frame_data->mps_sbr_flag) { + self->synth_count = + ptr_frame_data->pstr_sbr_header->pstr_freq_band_data->sub_band_end; + } else { + self->synth_count = self->band_count[0]; + } + ixheaacd_mps_synt_calc(self); return err; } \ No newline at end of file diff --git a/decoder/ixheaacd_mps_temp_reshape.c b/decoder/ixheaacd_mps_temp_reshape.c index fd8e62c..1797539 100644 --- a/decoder/ixheaacd_mps_temp_reshape.c +++ b/decoder/ixheaacd_mps_temp_reshape.c @@ -67,7 +67,7 @@ static VOID ixheaacd_mps_est_normalized_envelope(ia_mps_dec_state_struct *self, case DIR_DIFF_IN: ch_offset = 0; for (ii = 0; ii < self->time_slots; ii++) { - for (jj = 0; jj < self->hyb_band_count; jj++) { + for (jj = 0; jj < self->hyb_band_count_max; jj++) { slot_energy[ii] [ixheaacd_hybrid_band_71_to_processing_band_20_map[jj]] += ((self->hyb_dir_out[ch][ii][jj].re + @@ -84,7 +84,7 @@ static VOID ixheaacd_mps_est_normalized_envelope(ia_mps_dec_state_struct *self, case DOWNMIX_IN: ch_offset = self->out_ch_count; for (ii = 0; ii < self->time_slots; ii++) { - for (jj = 0; jj < self->hyb_band_count; jj++) { + for (jj = 0; jj < self->hyb_band_count_max; jj++) { slot_energy[ii] [ixheaacd_hybrid_band_71_to_processing_band_20_map[jj]] += self->hyb_in[ch][ii][jj].re * self->hyb_in[ch][ii][jj].re + @@ -168,7 +168,7 @@ VOID ixheaacd_mps_time_env_shaping(ia_mps_dec_state_struct *self) { amp_direct = 0; amp_diff = 0; - for (jj = band_start; jj < self->hyb_band_count; jj++) { + for (jj = band_start; jj < self->hyb_band_count_max; jj++) { amp_direct += self->hyb_dir_out[ch][time_slot][jj].re * self->hyb_dir_out[ch][time_slot][jj].re + self->hyb_dir_out[ch][time_slot][jj].im * @@ -184,7 +184,7 @@ VOID ixheaacd_mps_time_env_shaping(ia_mps_dec_state_struct *self) { ratio = min(max((gain + amp_ratio * (gain - 1)), 1 / LAMDA), LAMDA); - for (jj = band_start; jj < self->hyb_band_count; jj++) { + for (jj = band_start; jj < self->hyb_band_count_max; jj++) { self->hyb_dir_out[ch][time_slot][jj].re *= ratio; self->hyb_dir_out[ch][time_slot][jj].im *= ratio; } diff --git a/decoder/ixheaacd_process.c b/decoder/ixheaacd_process.c index 7ace0ca..672f4c6 100644 --- a/decoder/ixheaacd_process.c +++ b/decoder/ixheaacd_process.c @@ -383,6 +383,13 @@ WORD32 ixheaacd_usac_process(ia_dec_data_struct *pstr_dec_data, pstr_usac_data->usac_independency_flg, it_bit_buff); if (err) return err; + p_state_aac_dec->mps_dec_handle.band_count[0] = + pstr_usac_data->pstr_esbr_dec->pstr_sbr_channel[0] + ->str_sbr_dec.band_count; + p_state_aac_dec->mps_dec_handle.band_count[1] = + pstr_usac_data->pstr_esbr_dec->pstr_sbr_channel[1] + ->str_sbr_dec.band_count; + for (ch = 0; ch < nr_core_coder_channels; ch++) { ptr_inp[2 * ch] = pstr_usac_data->pstr_esbr_dec->pstr_sbr_channel[ch] diff --git a/decoder/ixheaacd_sbr_dec.c b/decoder/ixheaacd_sbr_dec.c index 671f4d6..d0bac14 100644 --- a/decoder/ixheaacd_sbr_dec.c +++ b/decoder/ixheaacd_sbr_dec.c @@ -735,7 +735,6 @@ WORD32 ixheaacd_sbr_dec(ia_sbr_dec_struct *ptr_sbr_dec, WORD16 *ptr_time_data, ptr_sbr_dec->p_hbe_txposer->max_stretch); } } - ixheaacd_qmf_enrg_calc(ptr_sbr_dec, upsample_ratio_idx, low_pow_flag); if (!mps_sbr_flag && apply_processing) { WORD32 err_code = 0; @@ -752,6 +751,7 @@ WORD32 ixheaacd_sbr_dec(ia_sbr_dec_struct *ptr_sbr_dec, WORD16 *ptr_time_data, ptr_pvc_data->pvc_rate = ptr_header_data->upsamp_fac; if (sbr_mode == PVC_SBR) { + ixheaacd_qmf_enrg_calc(ptr_sbr_dec, upsample_ratio_idx, low_pow_flag); err_code = ixheaacd_pvc_process( ptr_pvc_data, ptr_header_data->pstr_freq_band_data->sub_band_start, ptr_frame_data->str_pvc_frame_info.border_vec[0], @@ -788,6 +788,12 @@ WORD32 ixheaacd_sbr_dec(ia_sbr_dec_struct *ptr_sbr_dec, WORD16 *ptr_time_data, } } + if (!mps_sbr_flag) { + ptr_sbr_dec->band_count = + ptr_header_data->pstr_freq_band_data->sub_band_end; + } else + ptr_sbr_dec->band_count = ptr_sbr_dec->str_codec_qmf_bank.no_channels; + ixheaacd_esbr_synthesis_filt_block( ptr_sbr_dec, ptr_header_data, ptr_frame_data, apply_processing, pp_qmf_buf_real, pp_qmf_buf_imag, stereo_config_idx, sbr_tables_ptr, @@ -1135,6 +1141,8 @@ WORD32 ixheaacd_esbr_dec(ia_sbr_dec_struct *ptr_sbr_dec, memset(ptr_sbr_dec->sbr_qmf_out_imag[i], 0, 64 * sizeof(FLOAT32)); } + ptr_sbr_dec->band_count = ptr_sbr_dec->str_codec_qmf_bank.no_channels; + ixheaacd_esbr_synthesis_filt_block( ptr_sbr_dec, ptr_header_data, ptr_frame_data, apply_processing, pp_qmf_buf_real, pp_qmf_buf_imag, stereo_config_idx, ptr_sbr_tables, diff --git a/decoder/ixheaacd_sbr_dec.h b/decoder/ixheaacd_sbr_dec.h index 0461d39..8bafa92 100644 --- a/decoder/ixheaacd_sbr_dec.h +++ b/decoder/ixheaacd_sbr_dec.h @@ -67,6 +67,7 @@ typedef struct { ia_sbr_scale_fact_struct str_sbr_scale_fact; WORD32 max_samp_val; + WORD32 band_count; ia_esbr_hbe_txposer_struct *p_hbe_txposer; FLOAT32 core_sample_buf[2624]; diff --git a/decoder/ixheaacd_sbrdec_initfuncs.c b/decoder/ixheaacd_sbrdec_initfuncs.c index f779c84..2793fe5 100644 --- a/decoder/ixheaacd_sbrdec_initfuncs.c +++ b/decoder/ixheaacd_sbrdec_initfuncs.c @@ -543,6 +543,7 @@ ia_handle_sbr_dec_inst_struct ixheaacd_init_sbr( audio_object_type); ptr_header_data[i]->status = 1; + ptr_sbr_dec[i]->band_count = 64; if (err) { return NULL;