xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_qc_main_hp.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 <math.h>
22 #include <stdlib.h>
23 
24 #include "ixheaac_type_def.h"
25 #include "ixheaac_constants.h"
26 #include "ixheaace_aac_constants.h"
27 
28 #include "ixheaac_error_standards.h"
29 #include "ixheaace_error_codes.h"
30 #include "ixheaace_psy_const.h"
31 #include "ixheaace_tns.h"
32 #include "ixheaace_tns_params.h"
33 #include "ixheaace_rom.h"
34 #include "ixheaace_common_rom.h"
35 #include "ixheaace_quant.h"
36 #include "ixheaace_block_switch.h"
37 #include "ixheaace_bitbuffer.h"
38 
39 #include "ixheaac_basic_ops32.h"
40 #include "ixheaac_basic_ops16.h"
41 #include "ixheaac_basic_ops40.h"
42 #include "ixheaac_basic_ops.h"
43 
44 #include "ixheaace_tns.h"
45 #include "ixheaace_psy_data.h"
46 #include "ixheaace_interface.h"
47 #include "ixheaace_adjust_threshold_data.h"
48 
49 #include "ixheaace_dynamic_bits.h"
50 #include "ixheaace_qc_data.h"
51 #include "ixheaace_adjust_threshold.h"
52 
53 #include "ixheaace_sf_estimation.h"
54 
55 #include "ixheaace_static_bits.h"
56 
57 #include "ixheaace_bits_count.h"
58 
59 #include "ixheaace_channel_map.h"
60 #include "ixheaace_write_bitstream.h"
61 #include "ixheaace_psy_configuration.h"
62 #include "ixheaace_psy_mod.h"
63 #include "ixheaace_tns_params.h"
64 #include "ixheaace_stereo_preproc.h"
65 #include "ixheaace_enc_main.h"
66 #include "ixheaace_qc_util.h"
67 #include "ixheaace_common_utils.h"
68 
ia_enhaacplus_enc_qc_main(ixheaace_qc_state * pstr_qc_state,WORD32 num_channels,ixheaace_element_bits * pstr_el_bits,ixheaace_psy_out_channel ** psy_out_ch,ixheaace_psy_out_element * pstr_psy_out_element,ixheaace_qc_out_channel ** pstr_qc_out_ch,ixheaace_qc_out_element * pstr_qc_out_element,WORD32 ancillary_data_bytes,ixheaace_aac_tables * pstr_aac_tables,WORD32 adts_flag,WORD32 aot,WORD32 stat_bits_flag,WORD32 flag_last_element,WORD32 frame_len_long,WORD8 * ptr_scratch,WORD32 * is_quant_spec_zero,WORD32 * is_gain_limited)69 IA_ERRORCODE ia_enhaacplus_enc_qc_main(
70     ixheaace_qc_state *pstr_qc_state, WORD32 num_channels, ixheaace_element_bits *pstr_el_bits,
71     ixheaace_psy_out_channel **psy_out_ch,
72     ixheaace_psy_out_element *pstr_psy_out_element,
73     ixheaace_qc_out_channel **pstr_qc_out_ch,
74     ixheaace_qc_out_element *pstr_qc_out_element, WORD32 ancillary_data_bytes,
75     ixheaace_aac_tables *pstr_aac_tables, WORD32 adts_flag, WORD32 aot, WORD32 stat_bits_flag,
76     WORD32 flag_last_element, WORD32 frame_len_long, WORD8 *ptr_scratch,
77     WORD32 *is_quant_spec_zero, WORD32 *is_gain_limited) {
78   IA_ERRORCODE err_code;
79   WORD32 ch;
80   WORD32 i = 0;
81   WORD32 k = 0;
82   WORD32 j = 0;
83   WORD32 iterations = 0;
84   WORD32 constraints_fulfilled;
85   WORD32 ch_dyn_bits;
86   WORD32 max_ch_dyn_bits[IXHEAACE_MAX_CH_IN_BS_ELE];
87   FLOAT32 ch_bit_dist[IXHEAACE_MAX_CH_IN_BS_ELE];
88   ixheaace_qc_stack *ptr_stack = (ixheaace_qc_stack *)ptr_scratch;
89   ptr_scratch += sizeof(ixheaace_qc_stack);
90 
91   ia_adj_thr_elem_struct *pstr_adj_thr_elem = &pstr_qc_state->str_adj_thr.str_adj_thr_ele;
92   WORD32 gain;
93 
94   if (pstr_el_bits->bit_res_level < 0) {
95     return IA_EXHEAACE_EXE_FATAL_INVALID_BIT_RES_LEVEL;
96   }
97 
98   if (pstr_el_bits->bit_res_level > pstr_el_bits->max_bit_res_bits) {
99     return IA_EXHEAACE_EXE_FATAL_INVALID_BIT_RES_LEVEL;
100   }
101   pstr_qc_out_element->static_bits_used =
102       ia_enhaacplus_enc_count_static_bitdemand(psy_out_ch, pstr_psy_out_element, num_channels,
103                                                aot, adts_flag, stat_bits_flag, flag_last_element);
104 
105   if (ancillary_data_bytes) {
106     pstr_qc_out_element->anc_bits_used =
107         7 + 8 * (ancillary_data_bytes + (ancillary_data_bytes >= 15));
108   } else {
109     pstr_qc_out_element->anc_bits_used = 0;
110   }
111 
112   for (ch = 0; ch < num_channels; ch++) {
113     iaace_calc_form_fac_per_chan(ptr_stack->sfb_form_fac[ch],
114                                  ptr_stack->sfb_num_relevant_lines[ch], psy_out_ch[ch],
115                                  ptr_stack->sfb_ld_energy[ch]);
116   }
117 
118   iaace_adjust_threshold(
119       &pstr_qc_state->str_adj_thr, pstr_adj_thr_elem, psy_out_ch, ch_bit_dist,
120       pstr_qc_out_element,
121       pstr_el_bits->average_bits - pstr_qc_out_element->static_bits_used -
122           pstr_qc_out_element->anc_bits_used,
123       pstr_el_bits->bit_res_level, pstr_el_bits->max_bit_res_bits,
124       pstr_qc_out_element->static_bits_used + pstr_qc_out_element->anc_bits_used,
125       &pstr_qc_state->max_bit_fac, ptr_stack->sfb_num_relevant_lines[0],
126       ptr_stack->sfb_ld_energy[0], num_channels, 0, aot, ptr_scratch);
127 
128   iaace_estimate_scfs_chan(psy_out_ch, pstr_qc_out_ch, ptr_stack->sfb_form_fac,
129                            ptr_stack->sfb_num_relevant_lines, num_channels, 0, frame_len_long);
130 
131   for (ch = 0; ch < num_channels; ch++) {
132     max_ch_dyn_bits[ch] =
133         (pstr_el_bits->average_bits + pstr_el_bits->bit_res_level - 7 -
134          pstr_qc_out_element->static_bits_used - pstr_qc_out_element->anc_bits_used);
135 
136     max_ch_dyn_bits[ch] = (WORD32)floor(ch_bit_dist[ch] * (FLOAT32)(max_ch_dyn_bits[ch]));
137   }
138 
139   pstr_qc_out_element->dyn_bits_used = 0;
140 
141   for (ch = 0; ch < num_channels; ch++) {
142     /* now loop until bitstream constraints (ch_dyn_bits < maxChDynBits)
143        are fulfilled */
144     WORD32 spec_idx, sfb_offs, sfb;
145     iterations = 0;
146     gain = 0;
147     for (spec_idx = 0; spec_idx < frame_len_long; spec_idx++) {
148       ptr_stack->exp_spec[spec_idx] = (FLOAT32)psy_out_ch[ch]->ptr_spec_coeffs[spec_idx];
149       ptr_stack->mdct_spec_float[spec_idx] = (FLOAT32)psy_out_ch[ch]->ptr_spec_coeffs[spec_idx];
150     }
151     do {
152       WORD32 max_val;
153       constraints_fulfilled = 1;
154       WORD32 quant_spec_is_zero = 1;
155       if (iterations > 0) {
156         for (sfb_offs = 0; sfb_offs < psy_out_ch[ch]->sfb_count;
157              sfb_offs += psy_out_ch[ch]->sfb_per_group) {
158           for (sfb = 0; sfb < psy_out_ch[ch]->max_sfb_per_grp; sfb++) {
159             WORD32 scalefactor = pstr_qc_out_ch[ch]->scalefactor[sfb + sfb_offs];
160             gain = MAX(gain, pstr_qc_out_ch[ch]->global_gain - scalefactor);
161             iaace_quantize_lines(
162                 pstr_qc_out_ch[ch]->global_gain - scalefactor,
163                 psy_out_ch[ch]->sfb_offsets[sfb_offs + sfb + 1] -
164                     psy_out_ch[ch]->sfb_offsets[sfb_offs + sfb],
165                 ptr_stack->exp_spec + psy_out_ch[ch]->sfb_offsets[sfb_offs + sfb],
166                 pstr_qc_out_ch[ch]->quant_spec + psy_out_ch[ch]->sfb_offsets[sfb_offs + sfb],
167                 ptr_stack->mdct_spec_float + psy_out_ch[ch]->sfb_offsets[sfb_offs + sfb]);
168           }
169         }
170       }
171 
172       max_val = iaace_calc_max_val_in_sfb(
173           psy_out_ch[ch]->sfb_count, psy_out_ch[ch]->max_sfb_per_grp,
174           psy_out_ch[ch]->sfb_per_group,
175           psy_out_ch[ch]->sfb_offsets, pstr_qc_out_ch[ch]->quant_spec,
176           pstr_qc_out_ch[ch]->max_val_in_sfb);
177 
178       if (max_val > MAXIMUM_QUANT) {
179         constraints_fulfilled = 0;
180       }
181 
182       for (k = 0; ((k < psy_out_ch[ch]->sfb_count) && (quant_spec_is_zero));
183            k += psy_out_ch[ch]->sfb_per_group) {
184         for (i = 0; ((i < psy_out_ch[ch]->max_sfb_per_grp) && (quant_spec_is_zero)); i++) {
185           for (j = psy_out_ch[ch]->sfb_offsets[i+k]; j < psy_out_ch[ch]->sfb_offsets[i+k+1]; j++)
186           {
187             if (pstr_qc_out_ch[ch]->quant_spec[j] != 0) {
188               quant_spec_is_zero = 0;
189               break;
190             }
191           }
192         }
193       }
194       err_code = ia_enhaacplus_enc_dyn_bitcount(
195           pstr_qc_out_ch[ch]->quant_spec, pstr_qc_out_ch[ch]->max_val_in_sfb,
196           pstr_qc_out_ch[ch]->scalefactor, psy_out_ch[ch]->window_sequence,
197           psy_out_ch[ch]->sfb_count, psy_out_ch[ch]->max_sfb_per_grp,
198           psy_out_ch[ch]->sfb_per_group,
199           psy_out_ch[ch]->sfb_offsets, &pstr_qc_out_ch[ch]->section_data,
200           pstr_qc_state->side_info_tab_long, pstr_qc_state->side_info_tab_short,
201           pstr_aac_tables->pstr_huff_tab, pstr_qc_state->qc_scr.shared_buffer_2, aot,
202           &ch_dyn_bits);
203 
204       if (err_code != IA_NO_ERROR) {
205         return err_code;
206       }
207 
208       if (ch_dyn_bits >= max_ch_dyn_bits[ch]) {
209         constraints_fulfilled = 0;
210       }
211 
212       if (quant_spec_is_zero == 1) {
213         constraints_fulfilled = 1;
214         /*Bit consuption is exceding bit reservoir, there is no scope left for bit consumption
215           reduction, as spectrum is zero. Hence breaking the quantization loop. */
216         if (iterations > 0) {
217           *is_quant_spec_zero = 1;
218           ch_dyn_bits = max_ch_dyn_bits[ch];
219         }
220       }
221       if ((gain == MAX_GAIN_INDEX) && (constraints_fulfilled == 0)) {
222         /* Bit consuption is exceding bit reservoir, there is no scope left for bit consumption
223            reduction, as gain has reached the maximum value. Hence breaking the quantization
224            loop. */
225         constraints_fulfilled = 1;
226         *is_gain_limited = 1;
227         ch_dyn_bits = max_ch_dyn_bits[ch];
228       }
229       if (!constraints_fulfilled) {
230         pstr_qc_out_ch[ch]->global_gain++;
231       }
232       iterations++;
233 
234     } while (!constraints_fulfilled);
235 
236     pstr_qc_out_element->dyn_bits_used += ch_dyn_bits;
237 
238     pstr_qc_out_ch[ch]->grouping_mask = psy_out_ch[ch]->grouping_mask;
239     pstr_qc_out_ch[ch]->win_shape = psy_out_ch[ch]->window_shape;
240   }
241 
242   pstr_adj_thr_elem->dyn_bits_last = pstr_qc_out_element->dyn_bits_used;
243   {
244     WORD32 bit_res_space = pstr_el_bits->max_bit_res_bits - pstr_el_bits->bit_res_level;
245     WORD32 delta_bit_res = pstr_el_bits->average_bits - (pstr_qc_out_element->static_bits_used +
246                                                          pstr_qc_out_element->dyn_bits_used +
247                                                          pstr_qc_out_element->anc_bits_used);
248 
249     pstr_qc_out_element->fill_bits = MAX(0, (delta_bit_res - bit_res_space));
250   }
251 
252   return IA_NO_ERROR;
253 }
254 
iaace_calc_max_val_in_sfb(WORD32 sfb_count,WORD32 max_sfb_per_grp,WORD32 ptr_sfb_per_grp,WORD32 * ptr_sfb_offset,WORD16 * ptr_quant_spec,UWORD16 * ptr_max_value)255 WORD32 iaace_calc_max_val_in_sfb(WORD32 sfb_count, WORD32 max_sfb_per_grp, WORD32 ptr_sfb_per_grp,
256                                  WORD32 *ptr_sfb_offset, WORD16 *ptr_quant_spec,
257                                  UWORD16 *ptr_max_value) {
258   WORD32 sfb;
259   WORD32 max = 0;
260   WORD32 sfb_offs;
261 
262   for (sfb_offs = 0; sfb_offs < sfb_count; sfb_offs += ptr_sfb_per_grp) {
263     for (sfb = 0; sfb < max_sfb_per_grp; sfb++) {
264       WORD32 line;
265       WORD32 local_max = 0;
266       for (line = ptr_sfb_offset[sfb + sfb_offs]; line < ptr_sfb_offset[sfb + sfb_offs + 1];
267            line++) {
268         if (abs(ptr_quant_spec[line]) > local_max) {
269           local_max = abs(ptr_quant_spec[line]);
270         }
271       }
272       ptr_max_value[sfb_offs + sfb] = (UWORD16)local_max;
273       if (local_max > max) {
274         max = local_max;
275       }
276     }
277   }
278 
279   return max;
280 }
281