xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_mps_param_extract.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
1 /******************************************************************************
2  *                                                                            *
3  * Copyright (C) 2023 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19  */
20 
21 #include <string.h>
22 #include <math.h>
23 #include "ixheaac_type_def.h"
24 #include "impd_drc_common_enc.h"
25 #include "impd_drc_uni_drc.h"
26 #include "impd_drc_tables.h"
27 #include "impd_drc_api.h"
28 #include "ixheaace_api.h"
29 #include "ixheaac_error_standards.h"
30 #include "ixheaace_error_codes.h"
31 #include "ixheaace_mps_common_fix.h"
32 #include "ixheaace_mps_defines.h"
33 #include "ixheaace_bitbuffer.h"
34 #include "ixheaace_mps_common_define.h"
35 #include "ixheaace_mps_param_extract.h"
36 #include "ixheaace_mps_buf.h"
37 #include "ixheaace_mps_lib.h"
38 #include "ixheaace_mps_bitstream.h"
39 #include "ixheaace_mps_struct_def.h"
40 #include "ixheaace_mps_sac_polyphase.h"
41 #include "ixheaace_mps_sac_nlc_enc.h"
42 #include "ixheaace_mps_sac_hybfilter.h"
43 #include "ixheaace_mps_spatial_bitstream.h"
44 #include "ixheaace_mps_tree.h"
45 #include "ixheaace_mps_rom.h"
46 #include "ixheaace_mps_vector_functions.h"
47 #include "ixheaac_constants.h"
48 #include "ixheaace_aac_constants.h"
49 #include "ixheaac_basic_ops32.h"
50 #include "ixheaac_basic_ops40.h"
51 #include "ixheaac_basic_ops.h"
52 
ixheaace_mps_212_get_icc_correlation_coherence_border(const WORD32 aot,const WORD32 use_coherence_only)53 static UWORD8 ixheaace_mps_212_get_icc_correlation_coherence_border(
54     const WORD32 aot, const WORD32 use_coherence_only) {
55   ixheaace_mps_box_subband_setup pstr_box_subband_setup;
56 
57   if (aot == AOT_AAC_ELD) {
58     pstr_box_subband_setup.p_subband_2_parameter_index_ld = (UWORD8 *)subband_2_parameter_ld;
59     pstr_box_subband_setup.icc_correlation_coherence_border = 5;
60   } else {
61     pstr_box_subband_setup.p_subband_2_parameter_index_ld = (UWORD8 *)subband_2_parameter_usac;
62     pstr_box_subband_setup.icc_correlation_coherence_border = 8;
63   }
64 
65   return ((use_coherence_only) ? 0 : pstr_box_subband_setup.icc_correlation_coherence_border);
66 }
67 
ixheaace_mps_212_calc_correlation_vec(FLOAT32 * const data,const FLOAT32 * const data_real,const FLOAT32 * const power_data_1,const FLOAT32 * const power_data_2,const WORD32 icc_correlation_coherence_border)68 static VOID ixheaace_mps_212_calc_correlation_vec(FLOAT32 *const data,
69                                                   const FLOAT32 *const data_real,
70                                                   const FLOAT32 *const power_data_1,
71                                                   const FLOAT32 *const power_data_2,
72                                                   const WORD32 icc_correlation_coherence_border) {
73   WORD32 idx;
74   FLOAT32 p_12;
75 
76   for (idx = 0; idx < icc_correlation_coherence_border; idx++) {
77     p_12 = power_data_1[idx] * power_data_2[idx];
78     if (p_12 > 0.0f) {
79       p_12 = 1.0f / ((FLOAT32)sqrt(p_12));
80       data[idx] = data_real[idx] * p_12;
81     } else {
82       data[idx] = 0.9995f;
83     }
84   }
85 }
86 
ixheaace_mps_212_calc_coherence_vec(FLOAT32 * const data,const FLOAT32 * const data_real,const FLOAT32 * const data_imag,const FLOAT32 * const power_data_1,const FLOAT32 * const power_data_2,const WORD32 icc_correlation_coherence_border)87 static VOID ixheaace_mps_212_calc_coherence_vec(FLOAT32 *const data,
88                                                 const FLOAT32 *const data_real,
89                                                 const FLOAT32 *const data_imag,
90                                                 const FLOAT32 *const power_data_1,
91                                                 const FLOAT32 *const power_data_2,
92                                                 const WORD32 icc_correlation_coherence_border) {
93   WORD32 idx;
94   FLOAT32 coh, p_12, p_12_ri;
95 
96   for (idx = 0; idx < icc_correlation_coherence_border; idx++) {
97     p_12_ri = (FLOAT32)(sqrt(data_real[idx] * data_real[idx] + data_imag[idx] * data_imag[idx]));
98     p_12 = power_data_1[idx] * power_data_2[idx];
99 
100     if (p_12 > 0.0f) {
101       p_12 = 1.0f / ((FLOAT32)sqrt(p_12));
102       coh = p_12_ri * p_12;
103       data[idx] = coh;
104     } else {
105       data[idx] = 0.9995f;
106     }
107   }
108 }
109 
ixheaace_mps_212_quantize_coef(const FLOAT32 * const input,const WORD32 num_bands,const FLOAT32 * const quant_table,const WORD32 idx_offset,const WORD32 num_quant_steps,WORD8 * const quant_out)110 static VOID ixheaace_mps_212_quantize_coef(const FLOAT32 *const input, const WORD32 num_bands,
111                                            const FLOAT32 *const quant_table,
112                                            const WORD32 idx_offset, const WORD32 num_quant_steps,
113                                            WORD8 *const quant_out) {
114   WORD32 band;
115   WORD32 forward = (quant_table[1] >= quant_table[0]);
116 
117   for (band = 0; band < num_bands; band++) {
118     FLOAT32 q_val;
119     FLOAT32 cur_val = input[band];
120     WORD32 upper = num_quant_steps - 1;
121     WORD32 lower = 0;
122     if (forward) {
123       while (upper - lower > 1) {
124         WORD32 idx = (lower + upper) >> 1;
125         q_val = quant_table[idx];
126         if (cur_val <= q_val) {
127           upper = idx;
128         } else {
129           lower = idx;
130         }
131       }
132 
133       if ((cur_val - quant_table[lower]) > (quant_table[upper] - cur_val)) {
134         quant_out[band] = (WORD8)(upper - idx_offset);
135       } else {
136         quant_out[band] = (WORD8)(lower - idx_offset);
137       }
138     } else {
139       while (upper - lower > 1) {
140         WORD32 idx = (lower + upper) >> 1;
141         q_val = quant_table[idx];
142         if (cur_val >= q_val) {
143           upper = idx;
144         } else {
145           lower = idx;
146         }
147       }
148 
149       if ((cur_val - quant_table[lower]) < (quant_table[upper] - cur_val)) {
150         quant_out[band] = (WORD8)(upper - idx_offset);
151       } else {
152         quant_out[band] = (WORD8)(lower - idx_offset);
153       }
154     }
155     if (quant_out[band] != 0) {
156       quant_out[band] = quant_out[band];
157     }
158   }
159 }
160 
ixheaace_mps_212_calc_parameter_band_to_hybrid_band_offset(const WORD32 num_hybrid_bands,UWORD8 * ptr_parameter_band_2_hybrid_band_offset,WORD32 aot)161 VOID ixheaace_mps_212_calc_parameter_band_to_hybrid_band_offset(
162     const WORD32 num_hybrid_bands, UWORD8 *ptr_parameter_band_2_hybrid_band_offset, WORD32 aot) {
163   ixheaace_mps_box_subband_setup pstr_box_subband_setup;
164   if (aot == AOT_AAC_ELD) {
165     pstr_box_subband_setup.p_subband_2_parameter_index_ld = (UWORD8 *)subband_2_parameter_ld;
166     pstr_box_subband_setup.icc_correlation_coherence_border = 5;
167   } else {
168     pstr_box_subband_setup.p_subband_2_parameter_index_ld = (UWORD8 *)subband_2_parameter_usac;
169     pstr_box_subband_setup.icc_correlation_coherence_border = 8;
170   }
171 
172   const UWORD8 *p_subband_2_parameter_index;
173 
174   UWORD8 idx;
175   WORD32 band;
176 
177   p_subband_2_parameter_index = pstr_box_subband_setup.p_subband_2_parameter_index_ld;
178 
179   for (band = 0, idx = NUM_QMF_BANDS - 1; idx > NUM_QMF_BANDS - num_hybrid_bands; idx--) {
180     if (p_subband_2_parameter_index[idx - 1] - p_subband_2_parameter_index[idx]) {
181       ptr_parameter_band_2_hybrid_band_offset[band++] = (NUM_QMF_BANDS - idx);
182     }
183   }
184   ptr_parameter_band_2_hybrid_band_offset[band++] = (NUM_QMF_BANDS - idx);
185 }
186 
187 IA_ERRORCODE
ixheaace_mps_212_init_tto_box(ixheaace_mps_pstr_tto_box pstr_tto_box,const ixheaace_mps_tto_box_config * const pstr_tto_box_config,UWORD8 * ptr_parameter_band_2_hybrid_band_offset,WORD32 aot)188 ixheaace_mps_212_init_tto_box(ixheaace_mps_pstr_tto_box pstr_tto_box,
189                               const ixheaace_mps_tto_box_config *const pstr_tto_box_config,
190                               UWORD8 *ptr_parameter_band_2_hybrid_band_offset, WORD32 aot) {
191   IA_ERRORCODE error = IA_NO_ERROR;
192 
193   {
194     memset(pstr_tto_box, 0, sizeof(ixheaace_mps_tto_box));
195     pstr_tto_box->use_coarse_quant_cld_flag = pstr_tto_box_config->use_coarse_quant_cld_flag;
196     pstr_tto_box->use_coarse_quant_icc_flag = pstr_tto_box_config->use_coarse_quant_icc_flag;
197     pstr_tto_box->box_quant_mode = pstr_tto_box_config->box_quant_mode;
198     pstr_tto_box->icc_correlation_coherence_border =
199         ixheaace_mps_212_get_icc_correlation_coherence_border(
200             aot, pstr_tto_box_config->b_use_coherence_icc_only);
201     pstr_tto_box->num_hybrid_bands_max = pstr_tto_box_config->num_hybrid_bands_max;
202     if (aot == 39) {
203       pstr_tto_box->num_parameter_bands = IXHEAACE_MPS_SAC_BANDS_ld;
204     } else {
205       pstr_tto_box->num_parameter_bands = IXHEAACE_MPS_SAC_BANDS_usac;
206     }
207     pstr_tto_box->ptr_parameter_band_2_hybrid_band_offset =
208         ptr_parameter_band_2_hybrid_band_offset;
209     pstr_tto_box->frame_keep_flag = pstr_tto_box_config->frame_keep_flag;
210     pstr_tto_box->n_cld_quant_steps = pstr_tto_box->use_coarse_quant_cld_flag
211                                           ? IXHEAACE_MPS_MAX_CLD_QUANT_COARSE
212                                           : IXHEAACE_MPS_MAX_CLD_QUANT_FINE;
213     pstr_tto_box->n_cld_quant_offset = pstr_tto_box->use_coarse_quant_cld_flag
214                                            ? IXHEAACE_MPS_OFFSET_CLD_QUANT_COARSE
215                                            : IXHEAACE_MPS_OFFSET_CLD_QUANT_FINE;
216     pstr_tto_box->n_icc_quant_steps = pstr_tto_box->use_coarse_quant_icc_flag
217                                           ? IXHEAACE_MPS_MAX_ICC_QUANT_COARSE
218                                           : IXHEAACE_MPS_MAX_ICC_QUANT_FINE;
219     pstr_tto_box->n_icc_quant_offset = pstr_tto_box->use_coarse_quant_icc_flag
220                                            ? IXHEAACE_MPS_OFFSET_ICC_QUANT_COARSE
221                                            : IXHEAACE_MPS_OFFSET_ICC_QUANT_FINE;
222     pstr_tto_box->p_icc_quant_table =
223         pstr_tto_box->use_coarse_quant_icc_flag ? icc_quant_table_coarse : icc_quant_table_fine;
224     pstr_tto_box->p_cld_quant_table_enc = pstr_tto_box->use_coarse_quant_cld_flag
225                                               ? cld_quant_table_coarse_enc
226                                               : cld_quant_table_fine_enc;
227 
228     if ((pstr_tto_box->box_quant_mode != IXHEAACE_MPS_QUANTMODE_FINE) &&
229         (pstr_tto_box->box_quant_mode != IXHEAACE_MPS_QUANTMODE_EBQ1) &&
230         (pstr_tto_box->box_quant_mode != IXHEAACE_MPS_QUANTMODE_EBQ2)) {
231       return IA_EXHEAACE_INIT_FATAL_MPS_INIT_FAILED;
232     }
233   }
234   return error;
235 }
236 
ixheaace_mps_212_apply_tto_box(ixheaace_mps_pstr_tto_box pstr_tto_box,const WORD32 num_time_slots,const WORD32 start_time_slot,const WORD32 num_hybrid_bands,ixheaace_cmplx_str pp_hybrid_data_1[MAX_ANA_TIME_SLOT][MAX_QMF_BANDS],ixheaace_cmplx_str pp_hybrid_data_2[MAX_ANA_TIME_SLOT][MAX_QMF_BANDS],WORD8 * const ptr_icc,UWORD8 * const pb_icc_quant_coarse,WORD8 * const ptr_cld,UWORD8 * const pb_cld_quant_coarse,const WORD32 b_use_bb_cues)237 IA_ERRORCODE ixheaace_mps_212_apply_tto_box(
238     ixheaace_mps_pstr_tto_box pstr_tto_box, const WORD32 num_time_slots,
239     const WORD32 start_time_slot, const WORD32 num_hybrid_bands,
240     ixheaace_cmplx_str pp_hybrid_data_1[MAX_ANA_TIME_SLOT][MAX_QMF_BANDS],
241     ixheaace_cmplx_str pp_hybrid_data_2[MAX_ANA_TIME_SLOT][MAX_QMF_BANDS], WORD8 *const ptr_icc,
242     UWORD8 *const pb_icc_quant_coarse, WORD8 *const ptr_cld, UWORD8 *const pb_cld_quant_coarse,
243     const WORD32 b_use_bb_cues) {
244   IA_ERRORCODE error = IA_NO_ERROR;
245 
246   WORD32 j, band;
247   FLOAT32 power_hybrid_data_1[MAX_NUM_PARAM_BANDS] = {0};
248   FLOAT32 power_hybrid_data_2[MAX_NUM_PARAM_BANDS] = {0};
249   FLOAT32 prod_hybrid_data_real[MAX_NUM_PARAM_BANDS] = {0};
250   FLOAT32 prod_hybrid_data_imag[MAX_NUM_PARAM_BANDS] = {0};
251   const WORD32 num_param_bands = pstr_tto_box->num_parameter_bands;
252   const WORD32 use_box_quant_mode =
253       (pstr_tto_box->box_quant_mode == IXHEAACE_MPS_QUANTMODE_EBQ1) ||
254       (pstr_tto_box->box_quant_mode == IXHEAACE_MPS_QUANTMODE_EBQ2);
255 
256   if ((num_hybrid_bands < 0) || (num_hybrid_bands > pstr_tto_box->num_hybrid_bands_max)) {
257     return IA_EXHEAACE_CONFIG_NONFATAL_MPS_INVALID_CONFIG;
258   }
259 
260   for (j = 0, band = 0; band < num_param_bands; band++) {
261     FLOAT32 data_1, data_2;
262     data_1 = 0;
263     data_2 = 0;
264     for (; j < pstr_tto_box->ptr_parameter_band_2_hybrid_band_offset[band]; j++) {
265       data_1 += ixheaace_mps_212_sum_up_cplx_pow_2_dim_2(pp_hybrid_data_1, start_time_slot,
266                                                          num_time_slots, j, j + 1);
267       data_2 += ixheaace_mps_212_sum_up_cplx_pow_2_dim_2(pp_hybrid_data_2, start_time_slot,
268                                                          num_time_slots, j, j + 1);
269     }
270 
271     power_hybrid_data_1[band] = data_1;
272     power_hybrid_data_2[band] = data_2;
273   }
274   for (j = 0, band = 0; band < num_param_bands; band++) {
275     FLOAT32 data_real, data_imag;
276     data_real = data_imag = 0;
277     for (; j < pstr_tto_box->ptr_parameter_band_2_hybrid_band_offset[band]; j++) {
278       ixheaace_cmplx_str scalar_prod;
279       ixheaace_mps_212_cplx_scalar_product(&scalar_prod, pp_hybrid_data_1, pp_hybrid_data_2,
280                                            start_time_slot, num_time_slots, j, j + 1);
281       data_real += scalar_prod.re;
282       data_imag += scalar_prod.im;
283     }
284     prod_hybrid_data_real[band] = data_real;
285     prod_hybrid_data_imag[band] = data_imag;
286   }
287 
288   ixheaace_mps_212_calc_correlation_vec(pstr_tto_box->icc, prod_hybrid_data_real,
289                                         power_hybrid_data_1, power_hybrid_data_2,
290                                         pstr_tto_box->icc_correlation_coherence_border);
291 
292   ixheaace_mps_212_calc_coherence_vec(
293       &pstr_tto_box->icc[pstr_tto_box->icc_correlation_coherence_border],
294       &prod_hybrid_data_real[pstr_tto_box->icc_correlation_coherence_border],
295       &prod_hybrid_data_imag[pstr_tto_box->icc_correlation_coherence_border],
296       &power_hybrid_data_1[pstr_tto_box->icc_correlation_coherence_border],
297       &power_hybrid_data_2[pstr_tto_box->icc_correlation_coherence_border],
298       num_param_bands - pstr_tto_box->icc_correlation_coherence_border);
299   if (error) {
300     return error;
301   }
302   if (!use_box_quant_mode) {
303     FLOAT32 power_1, power_2, cld;
304     FLOAT32 max_pow = 30.0f;
305 
306     for (band = 0; band < num_param_bands; band++) {
307       power_1 = (FLOAT32)log(power_hybrid_data_1[band] / 2.0f);
308       power_2 = (FLOAT32)log(power_hybrid_data_2[band] / 2.0f);
309       power_1 = MAX(MIN(power_1, max_pow), -max_pow);
310       power_2 = MAX(MIN(power_2, max_pow), -max_pow);
311       cld = (INV_LN_10_10 * (power_1 - power_2));
312       pstr_tto_box->cld[band] = cld;
313     }
314   }
315 
316   if (b_use_bb_cues) {
317     FLOAT32 temp;
318     temp = 0;
319     for (band = 0; band < num_param_bands; band++) {
320       temp += pstr_tto_box->cld[band];
321     }
322     temp /= num_param_bands;
323     for (band = 0; band < num_param_bands; band++) {
324       pstr_tto_box->cld[band] = temp;
325     }
326   }
327 
328   ixheaace_mps_212_quantize_coef(
329       pstr_tto_box->icc, num_param_bands, pstr_tto_box->p_icc_quant_table,
330       pstr_tto_box->n_icc_quant_offset, pstr_tto_box->n_icc_quant_steps, ptr_icc);
331 
332   *pb_icc_quant_coarse = pstr_tto_box->use_coarse_quant_icc_flag;
333 
334   if (!use_box_quant_mode) {
335     ixheaace_mps_212_quantize_coef(
336         pstr_tto_box->cld, num_param_bands, pstr_tto_box->p_cld_quant_table_enc,
337         pstr_tto_box->n_cld_quant_offset, pstr_tto_box->n_cld_quant_steps, ptr_cld);
338   } else {
339     memset(ptr_cld, 0, num_param_bands * sizeof(WORD8));
340   }
341   *pb_cld_quant_coarse = pstr_tto_box->use_coarse_quant_cld_flag;
342 
343   return error;
344 }
345