/src/libxaac/encoder/ixheaace_dynamic_bits.c
Line | Count | Source (jump to first uncovered line) |
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 <limits.h> |
22 | | #include <stddef.h> |
23 | | #include <stdlib.h> |
24 | | #include <string.h> |
25 | | #include "ixheaac_type_def.h" |
26 | | #include "ixheaac_constants.h" |
27 | | #include "impd_drc_common_enc.h" |
28 | | #include "impd_drc_uni_drc.h" |
29 | | #include "impd_drc_tables.h" |
30 | | #include "impd_drc_api.h" |
31 | | #include "ixheaace_api.h" |
32 | | #include "ixheaace_aac_constants.h" |
33 | | #include "ixheaac_error_standards.h" |
34 | | #include "ixheaace_error_codes.h" |
35 | | |
36 | | #include "ixheaac_basic_ops32.h" |
37 | | #include "ixheaac_basic_ops16.h" |
38 | | #include "ixheaac_basic_ops40.h" |
39 | | #include "ixheaac_basic_ops.h" |
40 | | |
41 | | #include "ixheaace_psy_const.h" |
42 | | #include "ixheaace_tns.h" |
43 | | #include "ixheaace_tns_params.h" |
44 | | #include "ixheaace_rom.h" |
45 | | #include "ixheaace_common_rom.h" |
46 | | #include "ixheaace_bitbuffer.h" |
47 | | #include "ixheaace_bits_count.h" |
48 | | |
49 | | #include "ixheaace_dynamic_bits.h" |
50 | | #include "ixheaace_common_utils.h" |
51 | | |
52 | 528k | static WORD32 ia_enhaacplus_enc_calc_side_info_bits(WORD32 sfb_cnt, WORD32 block_type) { |
53 | 528k | WORD32 seg_len_bits = (block_type == SHORT_WINDOW ? 3 : 5); |
54 | 528k | WORD32 escape_val = (block_type == SHORT_WINDOW ? 7 : 31); |
55 | 528k | WORD32 side_info_bits, tmp; |
56 | | |
57 | 528k | side_info_bits = CODE_BCK_BITS; |
58 | 528k | tmp = sfb_cnt; |
59 | | |
60 | 1.30M | while (tmp >= 0) { |
61 | 777k | side_info_bits += seg_len_bits; |
62 | 777k | tmp -= escape_val; |
63 | 777k | } |
64 | | |
65 | 528k | return (side_info_bits); |
66 | 528k | } |
67 | | |
68 | | static VOID ia_enhaacplus_enc_build_bit_look_up( |
69 | | const WORD16 *ptr_quant_spec, const WORD32 max_sfb, const WORD32 *ptr_sfb_offset, |
70 | | const UWORD16 *sfb_max, |
71 | | WORD32 bit_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG][CODE_BCK_ESC_NDX + 1], |
72 | | ixheaace_section_info *pstr_section_info, ixheaace_huffman_tables *pstr_huffman_tbl, |
73 | 750k | WORD32 aot) { |
74 | 750k | WORD8 i; |
75 | | |
76 | 16.8M | for (i = 0; i < max_sfb; i++) { |
77 | 16.1M | WORD32 sfb_width, max_val; |
78 | | |
79 | 16.1M | pstr_section_info[i].sfb_cnt = 1; |
80 | 16.1M | pstr_section_info[i].sfb_start = i; |
81 | | |
82 | 16.1M | switch (aot) { |
83 | 3.22M | case AOT_AAC_LC: |
84 | 10.6M | case AOT_SBR: |
85 | 11.6M | case AOT_PS: |
86 | 11.6M | pstr_section_info[i].section_bits = INVALID_BITCOUNT_LC; |
87 | 11.6M | break; |
88 | | |
89 | 749k | case AOT_AAC_LD: |
90 | 4.47M | case AOT_AAC_ELD: |
91 | 4.47M | pstr_section_info[i].section_bits = INVALID_BITCOUNT_LD; |
92 | 4.47M | break; |
93 | 16.1M | } |
94 | | |
95 | 16.1M | pstr_section_info[i].code_book = -1; |
96 | | |
97 | 16.1M | sfb_width = ptr_sfb_offset[i + 1] - ptr_sfb_offset[i]; |
98 | | |
99 | 16.1M | max_val = sfb_max[i]; |
100 | | |
101 | 16.1M | ia_enhaacplus_enc_bitcount(ptr_quant_spec + ptr_sfb_offset[i], sfb_width, max_val, |
102 | 16.1M | bit_look_up[i], pstr_huffman_tbl, aot); |
103 | 16.1M | } |
104 | 750k | } |
105 | | |
106 | | static WORD32 ia_enhaacplus_enc_find_best_book(const WORD32 *ptr_bit_cnt, WORD8 *ptr_codebook, |
107 | 18.2M | WORD32 aot) { |
108 | 18.2M | WORD32 min_bits = 0, temp1, temp2; |
109 | 18.2M | WORD8 temp_book = CODE_BCK_ESC_NDX; |
110 | 18.2M | WORD8 j; |
111 | | |
112 | 18.2M | switch (aot) { |
113 | 3.61M | case AOT_AAC_LC: |
114 | 11.9M | case AOT_SBR: |
115 | 13.2M | case AOT_PS: |
116 | 13.2M | min_bits = INVALID_BITCOUNT_LC; |
117 | 13.2M | break; |
118 | | |
119 | 823k | case AOT_AAC_LD: |
120 | 4.96M | case AOT_AAC_ELD: |
121 | 4.96M | min_bits = INVALID_BITCOUNT_LD; |
122 | 4.96M | break; |
123 | 18.2M | } |
124 | | |
125 | 127M | for (j = 0; j <= CODE_BCK_ESC_NDX; j += 2) { |
126 | 109M | temp1 = *ptr_bit_cnt++; |
127 | 109M | temp2 = *ptr_bit_cnt++; |
128 | 109M | if (temp1 < min_bits) { |
129 | 16.2M | min_bits = temp1; |
130 | 16.2M | temp_book = j; |
131 | 16.2M | } |
132 | 109M | if (temp2 < min_bits) { |
133 | 9.04M | min_bits = temp2; |
134 | 9.04M | temp_book = j + 1; |
135 | 9.04M | } |
136 | 109M | } |
137 | | |
138 | 18.2M | *ptr_codebook = temp_book; |
139 | 18.2M | return min_bits; |
140 | 18.2M | } |
141 | | |
142 | | static WORD32 ia_enhaacplus_enc_find_min_merge_bits(const WORD32 *ptr_bit_cnt1, |
143 | 7.14M | const WORD32 *ptr_bit_cnt2, WORD32 aot) { |
144 | 7.14M | WORD32 min_bits = 0, j, temp1, temp2, temp3, temp4; |
145 | | |
146 | 7.14M | switch (aot) { |
147 | 1.38M | case AOT_AAC_LC: |
148 | 4.10M | case AOT_SBR: |
149 | 4.94M | case AOT_PS: |
150 | 4.94M | min_bits = INVALID_BITCOUNT_LC; |
151 | 4.94M | break; |
152 | | |
153 | 326k | case AOT_AAC_LD: |
154 | 2.19M | case AOT_AAC_ELD: |
155 | 2.19M | min_bits = INVALID_BITCOUNT_LD; |
156 | 2.19M | break; |
157 | 7.14M | } |
158 | | |
159 | 49.9M | for (j = CODE_BCK_ESC_NDX; j >= 0; j -= 2) { |
160 | 42.8M | temp1 = *ptr_bit_cnt1++; |
161 | 42.8M | temp2 = *ptr_bit_cnt2++; |
162 | 42.8M | temp3 = *ptr_bit_cnt1++; |
163 | | |
164 | 42.8M | temp1 = temp1 + temp2; |
165 | | |
166 | 42.8M | min_bits = MIN(temp1, min_bits); |
167 | 42.8M | temp4 = *ptr_bit_cnt2++; |
168 | 42.8M | temp1 = temp3 + temp4; |
169 | | |
170 | 42.8M | min_bits = MIN(temp1, min_bits); |
171 | 42.8M | } |
172 | | |
173 | 7.14M | return min_bits; |
174 | 7.14M | } |
175 | | |
176 | | static VOID ia_enhaacplus_enc_merge_bit_look_up(WORD32 *ptr_bit_cnt1, const WORD32 *ptr_bit_cnt2, |
177 | 14.0M | WORD32 aot) { |
178 | 14.0M | WORD32 j, temp1, temp2, temp3, temp4; |
179 | 14.0M | WORD32 invalid_bitcnt = 0; |
180 | | |
181 | 14.0M | switch (aot) { |
182 | 2.83M | case AOT_AAC_LC: |
183 | 9.35M | case AOT_SBR: |
184 | 10.1M | case AOT_PS: |
185 | 10.1M | invalid_bitcnt = INVALID_BITCOUNT_LC; |
186 | 10.1M | break; |
187 | | |
188 | 675k | case AOT_AAC_LD: |
189 | 3.97M | case AOT_AAC_ELD: |
190 | 3.97M | invalid_bitcnt = INVALID_BITCOUNT_LD; |
191 | 3.97M | break; |
192 | 14.0M | } |
193 | 98.5M | for (j = 0; j <= CODE_BCK_ESC_NDX; j += 2) { |
194 | 84.4M | temp1 = ptr_bit_cnt1[j]; |
195 | 84.4M | temp2 = ptr_bit_cnt2[j]; |
196 | 84.4M | temp3 = ptr_bit_cnt1[j + 1]; |
197 | | |
198 | 84.4M | ptr_bit_cnt1[j] = MIN(temp1 + temp2, invalid_bitcnt); |
199 | 84.4M | temp4 = ptr_bit_cnt2[j + 1]; |
200 | 84.4M | ptr_bit_cnt1[j + 1] = MIN(temp3 + temp4, invalid_bitcnt); |
201 | 84.4M | } |
202 | 14.0M | } |
203 | | |
204 | | static WORD32 ia_enhaacplus_enc_find_max_merge( |
205 | | const WORD32 merge_gain_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG], |
206 | 2.87M | const ixheaace_section_info *section, const WORD32 max_sfb, WORD32 *max_ndx) { |
207 | 2.87M | WORD32 i, max_merge_gain = 0; |
208 | | |
209 | 20.9M | for (i = 0; i + section[i].sfb_cnt < max_sfb; i += section[i].sfb_cnt) { |
210 | 18.0M | if (merge_gain_look_up[i] > max_merge_gain) { |
211 | 3.74M | max_merge_gain = merge_gain_look_up[i]; |
212 | 3.74M | *max_ndx = i; |
213 | 3.74M | } |
214 | 18.0M | } |
215 | | |
216 | 2.87M | return (max_merge_gain); |
217 | 2.87M | } |
218 | | |
219 | | static WORD32 ia_enhaacplus_enc_calc_merge_gain( |
220 | | const ixheaace_section_info *pstr_section_info, |
221 | | WORD32 bit_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG][CODE_BCK_ESC_NDX + 1], |
222 | 7.14M | const WORD32 *pstr_side_info_tab, const WORD32 idx1, const WORD32 idx2, WORD32 aot) { |
223 | 7.14M | WORD32 split_bits; |
224 | 7.14M | WORD32 merge_bits; |
225 | 7.14M | WORD32 merge_gain; |
226 | | |
227 | 7.14M | split_bits = pstr_section_info[idx1].section_bits + pstr_section_info[idx2].section_bits; |
228 | | |
229 | 7.14M | merge_bits = |
230 | 7.14M | pstr_side_info_tab[pstr_section_info[idx1].sfb_cnt + pstr_section_info[idx2].sfb_cnt] + |
231 | 7.14M | ia_enhaacplus_enc_find_min_merge_bits(bit_look_up[idx1], bit_look_up[idx2], aot); |
232 | | |
233 | 7.14M | merge_gain = split_bits - merge_bits; |
234 | | |
235 | 7.14M | return merge_gain; |
236 | 7.14M | } |
237 | | |
238 | | static VOID ia_enhaacplus_enc_gm_stage0( |
239 | | ixheaace_section_info *pstr_section, |
240 | | WORD32 bit_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG][CODE_BCK_ESC_NDX + 1], |
241 | 750k | const WORD32 max_sfb, WORD32 aot) { |
242 | 750k | WORD32 i = 0; |
243 | 750k | WORD32 invalid_bitcnt = 0; |
244 | | |
245 | 750k | switch (aot) { |
246 | 160k | case AOT_AAC_LC: |
247 | 507k | case AOT_SBR: |
248 | 564k | case AOT_PS: |
249 | 564k | invalid_bitcnt = INVALID_BITCOUNT_LC; |
250 | 564k | break; |
251 | | |
252 | 32.4k | case AOT_AAC_LD: |
253 | 186k | case AOT_AAC_ELD: |
254 | | |
255 | 186k | invalid_bitcnt = INVALID_BITCOUNT_LD; |
256 | 186k | break; |
257 | 750k | } |
258 | 16.8M | while (i < max_sfb) { |
259 | 16.1M | if (pstr_section[i].section_bits == invalid_bitcnt) { |
260 | 16.1M | pstr_section[i].section_bits = (WORD16)ia_enhaacplus_enc_find_best_book( |
261 | 16.1M | bit_look_up[i], &(pstr_section[i].code_book), aot); |
262 | 16.1M | } |
263 | 16.1M | i++; |
264 | 16.1M | } |
265 | 750k | } |
266 | | |
267 | | static VOID ia_enhaacplus_enc_gm_stage1( |
268 | | ixheaace_section_info *pstr_section_info, |
269 | | WORD32 bit_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG][CODE_BCK_ESC_NDX + 1], |
270 | 750k | const WORD32 max_sfb, const WORD32 *ptr_side_info_tab, WORD32 aot) { |
271 | 750k | WORD32 merge_start = 0, merge_end; |
272 | | |
273 | 4.19M | do { |
274 | 16.1M | for (merge_end = merge_start + 1; merge_end < max_sfb; merge_end++) { |
275 | 15.3M | if (pstr_section_info[merge_start].code_book != pstr_section_info[merge_end].code_book) { |
276 | 3.43M | break; |
277 | 3.43M | } |
278 | | |
279 | 11.9M | pstr_section_info[merge_start].sfb_cnt++; |
280 | | |
281 | 11.9M | pstr_section_info[merge_start].section_bits += pstr_section_info[merge_end].section_bits; |
282 | | |
283 | 11.9M | ia_enhaacplus_enc_merge_bit_look_up(bit_look_up[merge_start], bit_look_up[merge_end], aot); |
284 | 11.9M | } |
285 | | |
286 | 4.19M | pstr_section_info[merge_start].section_bits += |
287 | 4.19M | (WORD16)ptr_side_info_tab[pstr_section_info[merge_start].sfb_cnt]; |
288 | | |
289 | 4.19M | pstr_section_info[merge_end - 1].sfb_start = pstr_section_info[merge_start].sfb_start; |
290 | | |
291 | 4.19M | merge_start = merge_end; |
292 | | |
293 | 4.19M | } while (merge_start < max_sfb); |
294 | 750k | } |
295 | | |
296 | | static VOID ia_enhaacplus_enc_gm_stage2( |
297 | | ixheaace_section_info *pstr_section_info, |
298 | | WORD32 merge_gain_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG], |
299 | | WORD32 bit_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG][CODE_BCK_ESC_NDX + 1], |
300 | 750k | const WORD32 max_sfb, const WORD32 *ptr_side_info_tab, WORD32 aot) { |
301 | 750k | WORD32 i; |
302 | | |
303 | 4.19M | for (i = 0; i + pstr_section_info[i].sfb_cnt < max_sfb; i += pstr_section_info[i].sfb_cnt) { |
304 | 3.43M | merge_gain_look_up[i] = |
305 | 3.43M | ia_enhaacplus_enc_calc_merge_gain(pstr_section_info, bit_look_up, ptr_side_info_tab, i, |
306 | 3.43M | i + pstr_section_info[i].sfb_cnt, aot); |
307 | 3.43M | } |
308 | | |
309 | 2.87M | while (TRUE) { |
310 | 2.87M | WORD32 max_merge_gain = 0, max_idx = 0, max_idx_next = 0, max_idx_last = 0; |
311 | | |
312 | 2.87M | max_merge_gain = ia_enhaacplus_enc_find_max_merge(merge_gain_look_up, pstr_section_info, |
313 | 2.87M | max_sfb, &max_idx); |
314 | | |
315 | 2.87M | if (max_merge_gain <= 0) { |
316 | 750k | break; |
317 | 750k | } |
318 | | |
319 | 2.12M | max_idx_next = max_idx + pstr_section_info[max_idx].sfb_cnt; |
320 | | |
321 | 2.12M | pstr_section_info[max_idx].sfb_cnt += pstr_section_info[max_idx_next].sfb_cnt; |
322 | | |
323 | 2.12M | pstr_section_info[max_idx].section_bits += |
324 | 2.12M | pstr_section_info[max_idx_next].section_bits - (WORD16)max_merge_gain; |
325 | | |
326 | 2.12M | ia_enhaacplus_enc_merge_bit_look_up(bit_look_up[max_idx], bit_look_up[max_idx_next], aot); |
327 | | |
328 | 2.12M | if (max_idx != 0) { |
329 | 1.76M | max_idx_last = pstr_section_info[max_idx - 1].sfb_start; |
330 | | |
331 | 1.76M | merge_gain_look_up[max_idx_last] = ia_enhaacplus_enc_calc_merge_gain( |
332 | 1.76M | pstr_section_info, bit_look_up, ptr_side_info_tab, max_idx_last, max_idx, aot); |
333 | 1.76M | } |
334 | | |
335 | 2.12M | max_idx_next = max_idx + pstr_section_info[max_idx].sfb_cnt; |
336 | | |
337 | 2.12M | pstr_section_info[max_idx_next - 1].sfb_start = pstr_section_info[max_idx].sfb_start; |
338 | | |
339 | 2.12M | if (max_idx_next < max_sfb) { |
340 | 1.93M | merge_gain_look_up[max_idx] = ia_enhaacplus_enc_calc_merge_gain( |
341 | 1.93M | pstr_section_info, bit_look_up, ptr_side_info_tab, max_idx, max_idx_next, aot); |
342 | 1.93M | } |
343 | 2.12M | } |
344 | 750k | } |
345 | | |
346 | | static IA_ERRORCODE ia_enhaacplus_enc_noiseless_counter( |
347 | | ixheaace_section_data *pstr_section_data, |
348 | | WORD32 merge_gain_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG], |
349 | | WORD32 bit_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG][CODE_BCK_ESC_NDX + 1], |
350 | | const WORD16 *ptr_quant_spec, const UWORD16 *ptr_max_val_in_sfb, const WORD32 *ptr_sfb_offset, |
351 | | const WORD32 block_type, WORD32 *ptr_side_info_tab_long, WORD32 *ptr_side_info_tab_short, |
352 | 551k | ixheaace_huffman_tables *pstr_huffman_tbl, WORD32 aot) { |
353 | 551k | WORD32 grp_idx; |
354 | 551k | WORD32 *ptr_side_info_tab = 0; |
355 | 551k | ixheaace_section_info *pstr_section_info; |
356 | 551k | WORD32 i; |
357 | | |
358 | 28.6M | for (i = 0; i < MAXIMUM_SCALE_FACTOR_BAND_LONG; i++) { |
359 | 28.1M | memset(bit_look_up[i], 0, (CODE_BCK_ESC_NDX + 1) * sizeof(bit_look_up[0][0])); |
360 | 28.1M | } |
361 | | |
362 | | /* counting previous operations */ |
363 | 551k | switch (block_type) { |
364 | 403k | case LONG_WINDOW: |
365 | 433k | case START_WINDOW: |
366 | 460k | case STOP_WINDOW: |
367 | | |
368 | 460k | ptr_side_info_tab = ptr_side_info_tab_long; |
369 | 460k | break; |
370 | 90.6k | case SHORT_WINDOW: |
371 | | |
372 | 90.6k | ptr_side_info_tab = ptr_side_info_tab_short; |
373 | 90.6k | break; |
374 | 0 | default: |
375 | 0 | return IA_EXHEAACE_EXE_FATAL_INVALID_BLOCK_TYPE; |
376 | 551k | } |
377 | | |
378 | 551k | pstr_section_data->num_of_sections = 0; |
379 | 551k | pstr_section_data->huffman_bits = 0; |
380 | 551k | pstr_section_data->side_info_bits = 0; |
381 | | |
382 | 551k | if (pstr_section_data->max_sfb_per_grp == 0) { |
383 | 58.7k | return IA_NO_ERROR; |
384 | 58.7k | } |
385 | | |
386 | 1.24M | for (grp_idx = 0; grp_idx < pstr_section_data->sfb_cnt; |
387 | 750k | grp_idx += pstr_section_data->sfb_per_group) { |
388 | 750k | pstr_section_info = pstr_section_data->section + pstr_section_data->num_of_sections; |
389 | | |
390 | 750k | ia_enhaacplus_enc_build_bit_look_up(ptr_quant_spec, pstr_section_data->max_sfb_per_grp, |
391 | 750k | ptr_sfb_offset + grp_idx, ptr_max_val_in_sfb + grp_idx, |
392 | 750k | bit_look_up, pstr_section_info, pstr_huffman_tbl, aot); |
393 | | |
394 | 750k | ia_enhaacplus_enc_gm_stage0(pstr_section_info, bit_look_up, |
395 | 750k | pstr_section_data->max_sfb_per_grp, aot); |
396 | | |
397 | 750k | ia_enhaacplus_enc_gm_stage1(pstr_section_info, bit_look_up, |
398 | 750k | pstr_section_data->max_sfb_per_grp, ptr_side_info_tab, aot); |
399 | | |
400 | 750k | ia_enhaacplus_enc_gm_stage2(pstr_section_info, merge_gain_look_up, bit_look_up, |
401 | 750k | pstr_section_data->max_sfb_per_grp, ptr_side_info_tab, aot); |
402 | | |
403 | 2.81M | for (i = 0; i < pstr_section_data->max_sfb_per_grp; i += pstr_section_info[i].sfb_cnt) { |
404 | 2.06M | ia_enhaacplus_enc_find_best_book(bit_look_up[i], &(pstr_section_info[i].code_book), aot); |
405 | | |
406 | 2.06M | pstr_section_info[i].sfb_start += (WORD8)grp_idx; |
407 | | |
408 | 2.06M | pstr_section_data->huffman_bits += |
409 | 2.06M | pstr_section_info[i].section_bits - ptr_side_info_tab[pstr_section_info[i].sfb_cnt]; |
410 | | |
411 | 2.06M | pstr_section_data->side_info_bits += ptr_side_info_tab[pstr_section_info[i].sfb_cnt]; |
412 | | |
413 | 2.06M | pstr_section_data->section[pstr_section_data->num_of_sections++] = pstr_section_info[i]; |
414 | 2.06M | } |
415 | 750k | } |
416 | 492k | return IA_NO_ERROR; |
417 | 551k | } |
418 | | |
419 | | static WORD32 ia_enhaacplus_enc_bit_count_scalefactor_delta( |
420 | 7.85M | WORD32 delta, ixheaace_huffman_tables *pstr_huffman_tbl) { |
421 | 7.85M | return pstr_huffman_tbl->huff_ltabscf[delta + CODE_BCK_SCF_LAV]; |
422 | 7.85M | } |
423 | | |
424 | | static IA_ERRORCODE ia_enhaacplus_enc_scf_count(const WORD16 *ptr_scale_fac, |
425 | | const UWORD16 *ptr_max_val_in_sfb, |
426 | | ixheaace_section_data *pstr_section_data, |
427 | 551k | ixheaace_huffman_tables *pstr_huffman_tbl) { |
428 | 551k | WORD32 sect_idx1 = 0; |
429 | 551k | WORD32 sfb_idx1 = 0; |
430 | 551k | WORD32 scf_idx = 0; |
431 | 551k | WORD32 sect_idx2 = 0; |
432 | 551k | WORD32 sfb_idx2 = 0; |
433 | | |
434 | 551k | WORD32 last_val_scf = 0; |
435 | 551k | WORD32 delta_scf = 0; |
436 | 551k | WORD32 found = 0; |
437 | 551k | WORD32 scf_skip_counter = 0; |
438 | | |
439 | 551k | pstr_section_data->scale_fac_bits = 0; |
440 | | |
441 | 551k | if (ptr_scale_fac == 0) { |
442 | 0 | return IA_EXHEAACE_EXE_FATAL_INVALID_SCALE_FACTOR_GAIN; |
443 | 0 | } |
444 | 551k | last_val_scf = 0; |
445 | 551k | pstr_section_data->first_scf = 0; |
446 | | |
447 | 786k | for (sect_idx1 = 0; sect_idx1 < pstr_section_data->num_of_sections; sect_idx1++) { |
448 | 591k | if (pstr_section_data->section[sect_idx1].code_book != CODE_BCK_ZERO_NO) { |
449 | 356k | pstr_section_data->first_scf = pstr_section_data->section[sect_idx1].sfb_start; |
450 | | |
451 | 356k | last_val_scf = ptr_scale_fac[pstr_section_data->first_scf]; |
452 | 356k | break; |
453 | 356k | } |
454 | 591k | } |
455 | | |
456 | 2.61M | for (sect_idx1 = 0; sect_idx1 < pstr_section_data->num_of_sections; sect_idx1++) { |
457 | 2.06M | if ((pstr_section_data->section[sect_idx1].code_book != CODE_BCK_ZERO_NO) && |
458 | 2.06M | (pstr_section_data->section[sect_idx1].code_book != CODE_BCK_PNS_NO)) { |
459 | 1.41M | for (sfb_idx1 = pstr_section_data->section[sect_idx1].sfb_start; |
460 | 9.27M | sfb_idx1 < pstr_section_data->section[sect_idx1].sfb_start + |
461 | 9.27M | pstr_section_data->section[sect_idx1].sfb_cnt; |
462 | 7.85M | sfb_idx1++) { |
463 | 7.85M | if (ptr_max_val_in_sfb[sfb_idx1] == 0) { |
464 | 462k | found = 0; |
465 | | |
466 | 462k | if (scf_skip_counter == 0) { |
467 | 328k | if (sfb_idx1 == (pstr_section_data->section[sect_idx1].sfb_start + |
468 | 328k | pstr_section_data->section[sect_idx1].sfb_cnt - 1)) { |
469 | 35.3k | found = 0; |
470 | 292k | } else { |
471 | 292k | for (scf_idx = (sfb_idx1 + 1); |
472 | 435k | scf_idx < pstr_section_data->section[sect_idx1].sfb_start + |
473 | 435k | pstr_section_data->section[sect_idx1].sfb_cnt; |
474 | 426k | scf_idx++) { |
475 | 426k | if (ptr_max_val_in_sfb[scf_idx] != 0) { |
476 | 283k | found = 1; |
477 | | |
478 | 283k | if ((abs32(ptr_scale_fac[scf_idx] - last_val_scf)) < CODE_BCK_SCF_LAV) { |
479 | 282k | delta_scf = 0; |
480 | 282k | } else { |
481 | 844 | delta_scf = -(ptr_scale_fac[sfb_idx1] - last_val_scf); |
482 | | |
483 | 844 | last_val_scf = ptr_scale_fac[sfb_idx1]; |
484 | 844 | scf_skip_counter = 0; |
485 | 844 | } |
486 | 283k | break; |
487 | 283k | } |
488 | | /* count scalefactor skip */ |
489 | 143k | scf_skip_counter = scf_skip_counter + 1; |
490 | 143k | } |
491 | 292k | } |
492 | | |
493 | | /* search for the next ptr_max_val_in_sfb[] != 0 in all other sections */ |
494 | 328k | for (sect_idx2 = (sect_idx1 + 1); |
495 | 348k | (sect_idx2 < pstr_section_data->num_of_sections) && (found == 0); sect_idx2++) { |
496 | 20.1k | if ((pstr_section_data->section[sect_idx2].code_book != CODE_BCK_ZERO_NO) && |
497 | 20.1k | (pstr_section_data->section[sect_idx2].code_book != CODE_BCK_PNS_NO)) { |
498 | 17.7k | for (sfb_idx2 = pstr_section_data->section[sect_idx2].sfb_start; |
499 | 18.3k | sfb_idx2 < pstr_section_data->section[sect_idx2].sfb_start + |
500 | 18.3k | pstr_section_data->section[sect_idx2].sfb_cnt; |
501 | 18.3k | sfb_idx2++) { |
502 | 18.3k | if (ptr_max_val_in_sfb[sfb_idx2] != 0) { |
503 | 17.7k | found = 1; |
504 | | |
505 | 17.7k | if ((abs32(ptr_scale_fac[sfb_idx2] - last_val_scf)) < CODE_BCK_SCF_LAV) { |
506 | 17.4k | delta_scf = 0; |
507 | 17.4k | } else { |
508 | 333 | delta_scf = -(ptr_scale_fac[sfb_idx1] - last_val_scf); |
509 | | |
510 | 333 | last_val_scf = ptr_scale_fac[sfb_idx1]; |
511 | 333 | scf_skip_counter = 0; |
512 | 333 | } |
513 | 17.7k | break; |
514 | 17.7k | } |
515 | | |
516 | 612 | scf_skip_counter = scf_skip_counter + 1; |
517 | 612 | } |
518 | 17.7k | } |
519 | 20.1k | } |
520 | | |
521 | 328k | if (found == 0) { |
522 | 26.7k | delta_scf = 0; |
523 | 26.7k | scf_skip_counter = 0; |
524 | 26.7k | } |
525 | 328k | } else { |
526 | 133k | delta_scf = 0; |
527 | | |
528 | 133k | scf_skip_counter = scf_skip_counter - 1; |
529 | 133k | } |
530 | 7.39M | } else { |
531 | 7.39M | delta_scf = -(ptr_scale_fac[sfb_idx1] - last_val_scf); |
532 | | |
533 | 7.39M | last_val_scf = ptr_scale_fac[sfb_idx1]; |
534 | 7.39M | } |
535 | | |
536 | 7.85M | pstr_section_data->scale_fac_bits += |
537 | 7.85M | ia_enhaacplus_enc_bit_count_scalefactor_delta(delta_scf, pstr_huffman_tbl); |
538 | 7.85M | } |
539 | 1.41M | } |
540 | 2.06M | } |
541 | 551k | return IA_NO_ERROR; |
542 | 551k | } |
543 | | |
544 | | IA_ERRORCODE ia_enhaacplus_enc_dyn_bitcount( |
545 | | const WORD16 *ptr_quant_spec, const UWORD16 *ptr_max_val_in_sfb, const WORD16 *ptr_scale_fac, |
546 | | const WORD32 block_type, const WORD32 sfb_cnt, const WORD32 max_sfb_per_grp, |
547 | | const WORD32 sfb_per_grp, const WORD32 *ptr_sfb_offset, |
548 | | ixheaace_section_data *pstr_section_data, WORD32 *ptr_side_info_tab_long, |
549 | | WORD32 *ptr_side_info_tab_short, ixheaace_huffman_tables *ptr_huffman_tbl, |
550 | 551k | WORD32 *ptr_scratch_buf, WORD32 aot, WORD32 *bit_cnt) { |
551 | 551k | IA_ERRORCODE err_code; |
552 | 551k | WORD32(*ptr_bit_look_up) |
553 | 551k | [CODE_BCK_ESC_NDX + 1] = (WORD32(*)[CODE_BCK_ESC_NDX + 1]) ptr_scratch_buf; |
554 | 551k | WORD32 *ptr_merge_gain_look_up = |
555 | 551k | ptr_scratch_buf + MAXIMUM_SCALE_FACTOR_BAND_LONG * (CODE_BCK_ESC_NDX + 1); |
556 | 551k | *bit_cnt = 0; |
557 | 551k | pstr_section_data->block_type = block_type; |
558 | 551k | pstr_section_data->sfb_cnt = sfb_cnt; |
559 | 551k | pstr_section_data->sfb_per_group = sfb_per_grp; |
560 | | |
561 | 551k | pstr_section_data->total_groups_cnt = sfb_cnt / sfb_per_grp; |
562 | | |
563 | 551k | pstr_section_data->max_sfb_per_grp = max_sfb_per_grp; |
564 | | |
565 | 551k | err_code = ia_enhaacplus_enc_noiseless_counter( |
566 | 551k | pstr_section_data, ptr_merge_gain_look_up, ptr_bit_look_up, ptr_quant_spec, |
567 | 551k | ptr_max_val_in_sfb, ptr_sfb_offset, block_type, ptr_side_info_tab_long, |
568 | 551k | ptr_side_info_tab_short, ptr_huffman_tbl, aot); |
569 | | |
570 | 551k | if (err_code != IA_NO_ERROR) { |
571 | 0 | return err_code; |
572 | 0 | } |
573 | | |
574 | 551k | err_code = ia_enhaacplus_enc_scf_count(ptr_scale_fac, ptr_max_val_in_sfb, pstr_section_data, |
575 | 551k | ptr_huffman_tbl); |
576 | | |
577 | 551k | if (err_code != IA_NO_ERROR) { |
578 | 0 | return err_code; |
579 | 0 | } |
580 | | |
581 | 551k | *bit_cnt = (pstr_section_data->huffman_bits + pstr_section_data->side_info_bits + |
582 | 551k | pstr_section_data->scale_fac_bits); |
583 | 551k | return IA_NO_ERROR; |
584 | 551k | } |
585 | | |
586 | 7.77k | VOID ia_enhaacplus_enc_bitcount_init(WORD32 *side_info_tab_long, WORD32 *side_info_tab_short) { |
587 | 7.77k | WORD32 i; |
588 | | |
589 | | /* side_info_tab_long[] */ |
590 | 412k | for (i = 0; i <= MAXIMUM_SCALE_FACTOR_BAND_LONG; i++) { |
591 | 404k | side_info_tab_long[i] = ia_enhaacplus_enc_calc_side_info_bits(i, LONG_WINDOW); |
592 | 404k | } |
593 | | |
594 | | /* side_info_tab_short[] */ |
595 | 132k | for (i = 0; i <= MAXIMUM_SCALE_FACTOR_BAND_SHORT; i++) { |
596 | 124k | side_info_tab_short[i] = ia_enhaacplus_enc_calc_side_info_bits(i, SHORT_WINDOW); |
597 | 124k | } |
598 | 7.77k | } |