/src/libxaac/encoder/ixheaace_qc_main_hp.c
Line | Count | Source |
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 | | |
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 | 293k | WORD32 *is_quant_spec_zero, WORD32 *is_gain_limited) { |
78 | 293k | IA_ERRORCODE err_code; |
79 | 293k | WORD32 ch; |
80 | 293k | WORD32 i = 0; |
81 | 293k | WORD32 k = 0; |
82 | 293k | WORD32 j = 0; |
83 | 293k | WORD32 iterations = 0; |
84 | 293k | WORD32 constraints_fulfilled; |
85 | 293k | WORD32 ch_dyn_bits; |
86 | 293k | WORD32 max_ch_dyn_bits[IXHEAACE_MAX_CH_IN_BS_ELE]; |
87 | 293k | FLOAT32 ch_bit_dist[IXHEAACE_MAX_CH_IN_BS_ELE]; |
88 | 293k | ixheaace_qc_stack *ptr_stack = (ixheaace_qc_stack *)ptr_scratch; |
89 | 293k | ptr_scratch += sizeof(ixheaace_qc_stack); |
90 | | |
91 | 293k | ia_adj_thr_elem_struct *pstr_adj_thr_elem = &pstr_qc_state->str_adj_thr.str_adj_thr_ele; |
92 | 293k | WORD32 gain; |
93 | | |
94 | 293k | if (pstr_el_bits->bit_res_level < 0) { |
95 | 282 | return IA_EXHEAACE_EXE_FATAL_INVALID_BIT_RES_LEVEL; |
96 | 282 | } |
97 | | |
98 | 293k | if (pstr_el_bits->bit_res_level > pstr_el_bits->max_bit_res_bits) { |
99 | 0 | return IA_EXHEAACE_EXE_FATAL_INVALID_BIT_RES_LEVEL; |
100 | 0 | } |
101 | 293k | pstr_qc_out_element->static_bits_used = |
102 | 293k | ia_enhaacplus_enc_count_static_bitdemand(psy_out_ch, pstr_psy_out_element, num_channels, |
103 | 293k | aot, adts_flag, stat_bits_flag, flag_last_element); |
104 | | |
105 | 293k | if (ancillary_data_bytes) { |
106 | 186k | pstr_qc_out_element->anc_bits_used = |
107 | 186k | 7 + 8 * (ancillary_data_bytes + (ancillary_data_bytes >= 15)); |
108 | 186k | } else { |
109 | 107k | pstr_qc_out_element->anc_bits_used = 0; |
110 | 107k | } |
111 | | |
112 | 724k | for (ch = 0; ch < num_channels; ch++) { |
113 | 430k | iaace_calc_form_fac_per_chan(ptr_stack->sfb_form_fac[ch], |
114 | 430k | ptr_stack->sfb_num_relevant_lines[ch], psy_out_ch[ch], |
115 | 430k | ptr_stack->sfb_ld_energy[ch]); |
116 | 430k | } |
117 | | |
118 | 293k | iaace_adjust_threshold( |
119 | 293k | &pstr_qc_state->str_adj_thr, pstr_adj_thr_elem, psy_out_ch, ch_bit_dist, |
120 | 293k | pstr_qc_out_element, |
121 | 293k | pstr_el_bits->average_bits - pstr_qc_out_element->static_bits_used - |
122 | 293k | pstr_qc_out_element->anc_bits_used, |
123 | 293k | pstr_el_bits->bit_res_level, pstr_el_bits->max_bit_res_bits, |
124 | 293k | pstr_qc_out_element->static_bits_used + pstr_qc_out_element->anc_bits_used, |
125 | 293k | &pstr_qc_state->max_bit_fac, ptr_stack->sfb_num_relevant_lines[0], |
126 | 293k | ptr_stack->sfb_ld_energy[0], num_channels, 0, aot, ptr_scratch); |
127 | | |
128 | 293k | iaace_estimate_scfs_chan(psy_out_ch, pstr_qc_out_ch, ptr_stack->sfb_form_fac, |
129 | 293k | ptr_stack->sfb_num_relevant_lines, num_channels, 0, frame_len_long); |
130 | | |
131 | 724k | for (ch = 0; ch < num_channels; ch++) { |
132 | 430k | max_ch_dyn_bits[ch] = |
133 | 430k | (pstr_el_bits->average_bits + pstr_el_bits->bit_res_level - 7 - |
134 | 430k | pstr_qc_out_element->static_bits_used - pstr_qc_out_element->anc_bits_used); |
135 | | |
136 | 430k | max_ch_dyn_bits[ch] = (WORD32)floor(ch_bit_dist[ch] * (FLOAT32)(max_ch_dyn_bits[ch])); |
137 | 430k | } |
138 | | |
139 | 293k | pstr_qc_out_element->dyn_bits_used = 0; |
140 | | |
141 | 724k | for (ch = 0; ch < num_channels; ch++) { |
142 | | /* now loop until bitstream constraints (ch_dyn_bits < maxChDynBits) |
143 | | are fulfilled */ |
144 | 430k | WORD32 spec_idx, sfb_offs, sfb; |
145 | 430k | iterations = 0; |
146 | 430k | gain = 0; |
147 | 344M | for (spec_idx = 0; spec_idx < frame_len_long; spec_idx++) { |
148 | 344M | ptr_stack->exp_spec[spec_idx] = (FLOAT32)psy_out_ch[ch]->ptr_spec_coeffs[spec_idx]; |
149 | 344M | ptr_stack->mdct_spec_float[spec_idx] = (FLOAT32)psy_out_ch[ch]->ptr_spec_coeffs[spec_idx]; |
150 | 344M | } |
151 | 467k | do { |
152 | 467k | WORD32 max_val; |
153 | 467k | constraints_fulfilled = 1; |
154 | 467k | WORD32 quant_spec_is_zero = 1; |
155 | 467k | if (iterations > 0) { |
156 | 101k | for (sfb_offs = 0; sfb_offs < psy_out_ch[ch]->sfb_count; |
157 | 65.7k | sfb_offs += psy_out_ch[ch]->sfb_per_group) { |
158 | 1.12M | for (sfb = 0; sfb < psy_out_ch[ch]->max_sfb_per_grp; sfb++) { |
159 | 1.06M | WORD32 scalefactor = pstr_qc_out_ch[ch]->scalefactor[sfb + sfb_offs]; |
160 | 1.06M | gain = MAX(gain, pstr_qc_out_ch[ch]->global_gain - scalefactor); |
161 | 1.06M | iaace_quantize_lines( |
162 | 1.06M | pstr_qc_out_ch[ch]->global_gain - scalefactor, |
163 | 1.06M | psy_out_ch[ch]->sfb_offsets[sfb_offs + sfb + 1] - |
164 | 1.06M | psy_out_ch[ch]->sfb_offsets[sfb_offs + sfb], |
165 | 1.06M | ptr_stack->exp_spec + psy_out_ch[ch]->sfb_offsets[sfb_offs + sfb], |
166 | 1.06M | pstr_qc_out_ch[ch]->quant_spec + psy_out_ch[ch]->sfb_offsets[sfb_offs + sfb], |
167 | 1.06M | ptr_stack->mdct_spec_float + psy_out_ch[ch]->sfb_offsets[sfb_offs + sfb]); |
168 | 1.06M | } |
169 | 65.7k | } |
170 | 36.1k | } |
171 | | |
172 | 467k | max_val = iaace_calc_max_val_in_sfb( |
173 | 467k | psy_out_ch[ch]->sfb_count, psy_out_ch[ch]->max_sfb_per_grp, |
174 | 467k | psy_out_ch[ch]->sfb_per_group, |
175 | 467k | psy_out_ch[ch]->sfb_offsets, pstr_qc_out_ch[ch]->quant_spec, |
176 | 467k | pstr_qc_out_ch[ch]->max_val_in_sfb); |
177 | | |
178 | 467k | if (max_val > MAXIMUM_QUANT) { |
179 | 4.98k | constraints_fulfilled = 0; |
180 | 4.98k | } |
181 | | |
182 | 1.00M | for (k = 0; ((k < psy_out_ch[ch]->sfb_count) && (quant_spec_is_zero)); |
183 | 538k | k += psy_out_ch[ch]->sfb_per_group) { |
184 | 4.40M | for (i = 0; ((i < psy_out_ch[ch]->max_sfb_per_grp) && (quant_spec_is_zero)); i++) { |
185 | 50.9M | for (j = psy_out_ch[ch]->sfb_offsets[i+k]; j < psy_out_ch[ch]->sfb_offsets[i+k+1]; j++) |
186 | 47.4M | { |
187 | 47.4M | if (pstr_qc_out_ch[ch]->quant_spec[j] != 0) { |
188 | 311k | quant_spec_is_zero = 0; |
189 | 311k | break; |
190 | 311k | } |
191 | 47.4M | } |
192 | 3.86M | } |
193 | 538k | } |
194 | 467k | err_code = ia_enhaacplus_enc_dyn_bitcount( |
195 | 467k | pstr_qc_out_ch[ch]->quant_spec, pstr_qc_out_ch[ch]->max_val_in_sfb, |
196 | 467k | pstr_qc_out_ch[ch]->scalefactor, psy_out_ch[ch]->window_sequence, |
197 | 467k | psy_out_ch[ch]->sfb_count, psy_out_ch[ch]->max_sfb_per_grp, |
198 | 467k | psy_out_ch[ch]->sfb_per_group, |
199 | 467k | psy_out_ch[ch]->sfb_offsets, &pstr_qc_out_ch[ch]->section_data, |
200 | 467k | pstr_qc_state->side_info_tab_long, pstr_qc_state->side_info_tab_short, |
201 | 467k | pstr_aac_tables->pstr_huff_tab, pstr_qc_state->qc_scr.shared_buffer_2, aot, |
202 | 467k | &ch_dyn_bits); |
203 | | |
204 | 467k | if (err_code != IA_NO_ERROR) { |
205 | 0 | return err_code; |
206 | 0 | } |
207 | | |
208 | 467k | if (ch_dyn_bits >= max_ch_dyn_bits[ch]) { |
209 | 31.2k | constraints_fulfilled = 0; |
210 | 31.2k | } |
211 | | |
212 | 467k | if (quant_spec_is_zero == 1) { |
213 | 155k | 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 | 155k | if (iterations > 0) { |
217 | 448 | *is_quant_spec_zero = 1; |
218 | 448 | ch_dyn_bits = max_ch_dyn_bits[ch]; |
219 | 448 | } |
220 | 155k | } |
221 | 467k | 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 | 0 | constraints_fulfilled = 1; |
226 | 0 | *is_gain_limited = 1; |
227 | 0 | ch_dyn_bits = max_ch_dyn_bits[ch]; |
228 | 0 | } |
229 | 467k | if (!constraints_fulfilled) { |
230 | 36.1k | pstr_qc_out_ch[ch]->global_gain++; |
231 | 36.1k | } |
232 | 467k | iterations++; |
233 | | |
234 | 467k | } while (!constraints_fulfilled); |
235 | | |
236 | 430k | pstr_qc_out_element->dyn_bits_used += ch_dyn_bits; |
237 | | |
238 | 430k | pstr_qc_out_ch[ch]->grouping_mask = psy_out_ch[ch]->grouping_mask; |
239 | 430k | pstr_qc_out_ch[ch]->win_shape = psy_out_ch[ch]->window_shape; |
240 | 430k | } |
241 | | |
242 | 293k | pstr_adj_thr_elem->dyn_bits_last = pstr_qc_out_element->dyn_bits_used; |
243 | 293k | { |
244 | 293k | WORD32 bit_res_space = pstr_el_bits->max_bit_res_bits - pstr_el_bits->bit_res_level; |
245 | 293k | WORD32 delta_bit_res = pstr_el_bits->average_bits - (pstr_qc_out_element->static_bits_used + |
246 | 293k | pstr_qc_out_element->dyn_bits_used + |
247 | 293k | pstr_qc_out_element->anc_bits_used); |
248 | | |
249 | 293k | pstr_qc_out_element->fill_bits = MAX(0, (delta_bit_res - bit_res_space)); |
250 | 293k | } |
251 | | |
252 | 293k | return IA_NO_ERROR; |
253 | 293k | } |
254 | | |
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 | 467k | UWORD16 *ptr_max_value) { |
258 | 467k | WORD32 sfb; |
259 | 467k | WORD32 max = 0; |
260 | 467k | WORD32 sfb_offs; |
261 | | |
262 | 1.19M | for (sfb_offs = 0; sfb_offs < sfb_count; sfb_offs += ptr_sfb_per_grp) { |
263 | 13.7M | for (sfb = 0; sfb < max_sfb_per_grp; sfb++) { |
264 | 13.0M | WORD32 line; |
265 | 13.0M | WORD32 local_max = 0; |
266 | 189M | for (line = ptr_sfb_offset[sfb + sfb_offs]; line < ptr_sfb_offset[sfb + sfb_offs + 1]; |
267 | 176M | line++) { |
268 | 176M | if (abs(ptr_quant_spec[line]) > local_max) { |
269 | 8.90M | local_max = abs(ptr_quant_spec[line]); |
270 | 8.90M | } |
271 | 176M | } |
272 | 13.0M | ptr_max_value[sfb_offs + sfb] = (UWORD16)local_max; |
273 | 13.0M | if (local_max > max) { |
274 | 392k | max = local_max; |
275 | 392k | } |
276 | 13.0M | } |
277 | 723k | } |
278 | | |
279 | 467k | return max; |
280 | 467k | } |