xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_dynamic_bits.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 <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 
ia_enhaacplus_enc_calc_side_info_bits(WORD32 sfb_cnt,WORD32 block_type)52 static WORD32 ia_enhaacplus_enc_calc_side_info_bits(WORD32 sfb_cnt, WORD32 block_type) {
53   WORD32 seg_len_bits = (block_type == SHORT_WINDOW ? 3 : 5);
54   WORD32 escape_val = (block_type == SHORT_WINDOW ? 7 : 31);
55   WORD32 side_info_bits, tmp;
56 
57   side_info_bits = CODE_BCK_BITS;
58   tmp = sfb_cnt;
59 
60   while (tmp >= 0) {
61     side_info_bits += seg_len_bits;
62     tmp -= escape_val;
63   }
64 
65   return (side_info_bits);
66 }
67 
ia_enhaacplus_enc_build_bit_look_up(const WORD16 * ptr_quant_spec,const WORD32 max_sfb,const WORD32 * ptr_sfb_offset,const UWORD16 * sfb_max,WORD32 bit_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG][CODE_BCK_ESC_NDX+1],ixheaace_section_info * pstr_section_info,ixheaace_huffman_tables * pstr_huffman_tbl,WORD32 aot)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     WORD32 aot) {
74   WORD8 i;
75 
76   for (i = 0; i < max_sfb; i++) {
77     WORD32 sfb_width, max_val;
78 
79     pstr_section_info[i].sfb_cnt = 1;
80     pstr_section_info[i].sfb_start = i;
81 
82     switch (aot) {
83       case AOT_AAC_LC:
84       case AOT_SBR:
85       case AOT_PS:
86         pstr_section_info[i].section_bits = INVALID_BITCOUNT_LC;
87         break;
88 
89       case AOT_AAC_LD:
90       case AOT_AAC_ELD:
91         pstr_section_info[i].section_bits = INVALID_BITCOUNT_LD;
92         break;
93     }
94 
95     pstr_section_info[i].code_book = -1;
96 
97     sfb_width = ptr_sfb_offset[i + 1] - ptr_sfb_offset[i];
98 
99     max_val = sfb_max[i];
100 
101     ia_enhaacplus_enc_bitcount(ptr_quant_spec + ptr_sfb_offset[i], sfb_width, max_val,
102                                bit_look_up[i], pstr_huffman_tbl, aot);
103   }
104 }
105 
ia_enhaacplus_enc_find_best_book(const WORD32 * ptr_bit_cnt,WORD8 * ptr_codebook,WORD32 aot)106 static WORD32 ia_enhaacplus_enc_find_best_book(const WORD32 *ptr_bit_cnt, WORD8 *ptr_codebook,
107                                                WORD32 aot) {
108   WORD32 min_bits = 0, temp1, temp2;
109   WORD8 temp_book = CODE_BCK_ESC_NDX;
110   WORD8 j;
111 
112   switch (aot) {
113     case AOT_AAC_LC:
114     case AOT_SBR:
115     case AOT_PS:
116       min_bits = INVALID_BITCOUNT_LC;
117       break;
118 
119     case AOT_AAC_LD:
120     case AOT_AAC_ELD:
121       min_bits = INVALID_BITCOUNT_LD;
122       break;
123   }
124 
125   for (j = 0; j <= CODE_BCK_ESC_NDX; j += 2) {
126     temp1 = *ptr_bit_cnt++;
127     temp2 = *ptr_bit_cnt++;
128     if (temp1 < min_bits) {
129       min_bits = temp1;
130       temp_book = j;
131     }
132     if (temp2 < min_bits) {
133       min_bits = temp2;
134       temp_book = j + 1;
135     }
136   }
137 
138   *ptr_codebook = temp_book;
139   return min_bits;
140 }
141 
ia_enhaacplus_enc_find_min_merge_bits(const WORD32 * ptr_bit_cnt1,const WORD32 * ptr_bit_cnt2,WORD32 aot)142 static WORD32 ia_enhaacplus_enc_find_min_merge_bits(const WORD32 *ptr_bit_cnt1,
143                                                     const WORD32 *ptr_bit_cnt2, WORD32 aot) {
144   WORD32 min_bits = 0, j, temp1, temp2, temp3, temp4;
145 
146   switch (aot) {
147     case AOT_AAC_LC:
148     case AOT_SBR:
149     case AOT_PS:
150       min_bits = INVALID_BITCOUNT_LC;
151       break;
152 
153     case AOT_AAC_LD:
154     case AOT_AAC_ELD:
155       min_bits = INVALID_BITCOUNT_LD;
156       break;
157   }
158 
159   for (j = CODE_BCK_ESC_NDX; j >= 0; j -= 2) {
160     temp1 = *ptr_bit_cnt1++;
161     temp2 = *ptr_bit_cnt2++;
162     temp3 = *ptr_bit_cnt1++;
163 
164     temp1 = temp1 + temp2;
165 
166     min_bits = MIN(temp1, min_bits);
167     temp4 = *ptr_bit_cnt2++;
168     temp1 = temp3 + temp4;
169 
170     min_bits = MIN(temp1, min_bits);
171   }
172 
173   return min_bits;
174 }
175 
ia_enhaacplus_enc_merge_bit_look_up(WORD32 * ptr_bit_cnt1,const WORD32 * ptr_bit_cnt2,WORD32 aot)176 static VOID ia_enhaacplus_enc_merge_bit_look_up(WORD32 *ptr_bit_cnt1, const WORD32 *ptr_bit_cnt2,
177                                                 WORD32 aot) {
178   WORD32 j, temp1, temp2, temp3, temp4;
179   WORD32 invalid_bitcnt = 0;
180 
181   switch (aot) {
182     case AOT_AAC_LC:
183     case AOT_SBR:
184     case AOT_PS:
185       invalid_bitcnt = INVALID_BITCOUNT_LC;
186       break;
187 
188     case AOT_AAC_LD:
189     case AOT_AAC_ELD:
190       invalid_bitcnt = INVALID_BITCOUNT_LD;
191       break;
192   }
193   for (j = 0; j <= CODE_BCK_ESC_NDX; j += 2) {
194     temp1 = ptr_bit_cnt1[j];
195     temp2 = ptr_bit_cnt2[j];
196     temp3 = ptr_bit_cnt1[j + 1];
197 
198     ptr_bit_cnt1[j] = MIN(temp1 + temp2, invalid_bitcnt);
199     temp4 = ptr_bit_cnt2[j + 1];
200     ptr_bit_cnt1[j + 1] = MIN(temp3 + temp4, invalid_bitcnt);
201   }
202 }
203 
ia_enhaacplus_enc_find_max_merge(const WORD32 merge_gain_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG],const ixheaace_section_info * section,const WORD32 max_sfb,WORD32 * max_ndx)204 static WORD32 ia_enhaacplus_enc_find_max_merge(
205     const WORD32 merge_gain_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG],
206     const ixheaace_section_info *section, const WORD32 max_sfb, WORD32 *max_ndx) {
207   WORD32 i, max_merge_gain = 0;
208 
209   for (i = 0; i + section[i].sfb_cnt < max_sfb; i += section[i].sfb_cnt) {
210     if (merge_gain_look_up[i] > max_merge_gain) {
211       max_merge_gain = merge_gain_look_up[i];
212       *max_ndx = i;
213     }
214   }
215 
216   return (max_merge_gain);
217 }
218 
ia_enhaacplus_enc_calc_merge_gain(const ixheaace_section_info * pstr_section_info,WORD32 bit_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG][CODE_BCK_ESC_NDX+1],const WORD32 * pstr_side_info_tab,const WORD32 idx1,const WORD32 idx2,WORD32 aot)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     const WORD32 *pstr_side_info_tab, const WORD32 idx1, const WORD32 idx2, WORD32 aot) {
223   WORD32 split_bits;
224   WORD32 merge_bits;
225   WORD32 merge_gain;
226 
227   split_bits = pstr_section_info[idx1].section_bits + pstr_section_info[idx2].section_bits;
228 
229   merge_bits =
230       pstr_side_info_tab[pstr_section_info[idx1].sfb_cnt + pstr_section_info[idx2].sfb_cnt] +
231       ia_enhaacplus_enc_find_min_merge_bits(bit_look_up[idx1], bit_look_up[idx2], aot);
232 
233   merge_gain = split_bits - merge_bits;
234 
235   return merge_gain;
236 }
237 
ia_enhaacplus_enc_gm_stage0(ixheaace_section_info * pstr_section,WORD32 bit_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG][CODE_BCK_ESC_NDX+1],const WORD32 max_sfb,WORD32 aot)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     const WORD32 max_sfb, WORD32 aot) {
242   WORD32 i = 0;
243   WORD32 invalid_bitcnt = 0;
244 
245   switch (aot) {
246     case AOT_AAC_LC:
247     case AOT_SBR:
248     case AOT_PS:
249       invalid_bitcnt = INVALID_BITCOUNT_LC;
250       break;
251 
252     case AOT_AAC_LD:
253     case AOT_AAC_ELD:
254 
255       invalid_bitcnt = INVALID_BITCOUNT_LD;
256       break;
257   }
258   while (i < max_sfb) {
259     if (pstr_section[i].section_bits == invalid_bitcnt) {
260       pstr_section[i].section_bits = (WORD16)ia_enhaacplus_enc_find_best_book(
261           bit_look_up[i], &(pstr_section[i].code_book), aot);
262     }
263     i++;
264   }
265 }
266 
ia_enhaacplus_enc_gm_stage1(ixheaace_section_info * pstr_section_info,WORD32 bit_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG][CODE_BCK_ESC_NDX+1],const WORD32 max_sfb,const WORD32 * ptr_side_info_tab,WORD32 aot)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     const WORD32 max_sfb, const WORD32 *ptr_side_info_tab, WORD32 aot) {
271   WORD32 merge_start = 0, merge_end;
272 
273   do {
274     for (merge_end = merge_start + 1; merge_end < max_sfb; merge_end++) {
275       if (pstr_section_info[merge_start].code_book != pstr_section_info[merge_end].code_book) {
276         break;
277       }
278 
279       pstr_section_info[merge_start].sfb_cnt++;
280 
281       pstr_section_info[merge_start].section_bits += pstr_section_info[merge_end].section_bits;
282 
283       ia_enhaacplus_enc_merge_bit_look_up(bit_look_up[merge_start], bit_look_up[merge_end], aot);
284     }
285 
286     pstr_section_info[merge_start].section_bits +=
287         (WORD16)ptr_side_info_tab[pstr_section_info[merge_start].sfb_cnt];
288 
289     pstr_section_info[merge_end - 1].sfb_start = pstr_section_info[merge_start].sfb_start;
290 
291     merge_start = merge_end;
292 
293   } while (merge_start < max_sfb);
294 }
295 
ia_enhaacplus_enc_gm_stage2(ixheaace_section_info * pstr_section_info,WORD32 merge_gain_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG],WORD32 bit_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG][CODE_BCK_ESC_NDX+1],const WORD32 max_sfb,const WORD32 * ptr_side_info_tab,WORD32 aot)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     const WORD32 max_sfb, const WORD32 *ptr_side_info_tab, WORD32 aot) {
301   WORD32 i;
302 
303   for (i = 0; i + pstr_section_info[i].sfb_cnt < max_sfb; i += pstr_section_info[i].sfb_cnt) {
304     merge_gain_look_up[i] =
305         ia_enhaacplus_enc_calc_merge_gain(pstr_section_info, bit_look_up, ptr_side_info_tab, i,
306                                           i + pstr_section_info[i].sfb_cnt, aot);
307   }
308 
309   while (TRUE) {
310     WORD32 max_merge_gain = 0, max_idx = 0, max_idx_next = 0, max_idx_last = 0;
311 
312     max_merge_gain = ia_enhaacplus_enc_find_max_merge(merge_gain_look_up, pstr_section_info,
313                                                       max_sfb, &max_idx);
314 
315     if (max_merge_gain <= 0) {
316       break;
317     }
318 
319     max_idx_next = max_idx + pstr_section_info[max_idx].sfb_cnt;
320 
321     pstr_section_info[max_idx].sfb_cnt += pstr_section_info[max_idx_next].sfb_cnt;
322 
323     pstr_section_info[max_idx].section_bits +=
324         pstr_section_info[max_idx_next].section_bits - (WORD16)max_merge_gain;
325 
326     ia_enhaacplus_enc_merge_bit_look_up(bit_look_up[max_idx], bit_look_up[max_idx_next], aot);
327 
328     if (max_idx != 0) {
329       max_idx_last = pstr_section_info[max_idx - 1].sfb_start;
330 
331       merge_gain_look_up[max_idx_last] = ia_enhaacplus_enc_calc_merge_gain(
332           pstr_section_info, bit_look_up, ptr_side_info_tab, max_idx_last, max_idx, aot);
333     }
334 
335     max_idx_next = max_idx + pstr_section_info[max_idx].sfb_cnt;
336 
337     pstr_section_info[max_idx_next - 1].sfb_start = pstr_section_info[max_idx].sfb_start;
338 
339     if (max_idx_next < max_sfb) {
340       merge_gain_look_up[max_idx] = ia_enhaacplus_enc_calc_merge_gain(
341           pstr_section_info, bit_look_up, ptr_side_info_tab, max_idx, max_idx_next, aot);
342     }
343   }
344 }
345 
ia_enhaacplus_enc_noiseless_counter(ixheaace_section_data * pstr_section_data,WORD32 merge_gain_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG],WORD32 bit_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG][CODE_BCK_ESC_NDX+1],const WORD16 * ptr_quant_spec,const UWORD16 * ptr_max_val_in_sfb,const WORD32 * ptr_sfb_offset,const WORD32 block_type,WORD32 * ptr_side_info_tab_long,WORD32 * ptr_side_info_tab_short,ixheaace_huffman_tables * pstr_huffman_tbl,WORD32 aot)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     ixheaace_huffman_tables *pstr_huffman_tbl, WORD32 aot) {
353   WORD32 grp_idx;
354   WORD32 *ptr_side_info_tab = 0;
355   ixheaace_section_info *pstr_section_info;
356   WORD32 i;
357 
358   for (i = 0; i < MAXIMUM_SCALE_FACTOR_BAND_LONG; i++) {
359     memset(bit_look_up[i], 0, (CODE_BCK_ESC_NDX + 1) * sizeof(bit_look_up[0][0]));
360   }
361 
362   /* counting previous operations */
363   switch (block_type) {
364     case LONG_WINDOW:
365     case START_WINDOW:
366     case STOP_WINDOW:
367 
368       ptr_side_info_tab = ptr_side_info_tab_long;
369       break;
370     case SHORT_WINDOW:
371 
372       ptr_side_info_tab = ptr_side_info_tab_short;
373       break;
374     default:
375       return IA_EXHEAACE_EXE_FATAL_INVALID_BLOCK_TYPE;
376   }
377 
378   pstr_section_data->num_of_sections = 0;
379   pstr_section_data->huffman_bits = 0;
380   pstr_section_data->side_info_bits = 0;
381 
382   if (pstr_section_data->max_sfb_per_grp == 0) {
383     return IA_NO_ERROR;
384   }
385 
386   for (grp_idx = 0; grp_idx < pstr_section_data->sfb_cnt;
387        grp_idx += pstr_section_data->sfb_per_group) {
388     pstr_section_info = pstr_section_data->section + pstr_section_data->num_of_sections;
389 
390     ia_enhaacplus_enc_build_bit_look_up(ptr_quant_spec, pstr_section_data->max_sfb_per_grp,
391                                         ptr_sfb_offset + grp_idx, ptr_max_val_in_sfb + grp_idx,
392                                         bit_look_up, pstr_section_info, pstr_huffman_tbl, aot);
393 
394     ia_enhaacplus_enc_gm_stage0(pstr_section_info, bit_look_up,
395                                 pstr_section_data->max_sfb_per_grp, aot);
396 
397     ia_enhaacplus_enc_gm_stage1(pstr_section_info, bit_look_up,
398                                 pstr_section_data->max_sfb_per_grp, ptr_side_info_tab, aot);
399 
400     ia_enhaacplus_enc_gm_stage2(pstr_section_info, merge_gain_look_up, bit_look_up,
401                                 pstr_section_data->max_sfb_per_grp, ptr_side_info_tab, aot);
402 
403     for (i = 0; i < pstr_section_data->max_sfb_per_grp; i += pstr_section_info[i].sfb_cnt) {
404       ia_enhaacplus_enc_find_best_book(bit_look_up[i], &(pstr_section_info[i].code_book), aot);
405 
406       pstr_section_info[i].sfb_start += (WORD8)grp_idx;
407 
408       pstr_section_data->huffman_bits +=
409           pstr_section_info[i].section_bits - ptr_side_info_tab[pstr_section_info[i].sfb_cnt];
410 
411       pstr_section_data->side_info_bits += ptr_side_info_tab[pstr_section_info[i].sfb_cnt];
412 
413       pstr_section_data->section[pstr_section_data->num_of_sections++] = pstr_section_info[i];
414     }
415   }
416   return IA_NO_ERROR;
417 }
418 
ia_enhaacplus_enc_bit_count_scalefactor_delta(WORD32 delta,ixheaace_huffman_tables * pstr_huffman_tbl)419 static WORD32 ia_enhaacplus_enc_bit_count_scalefactor_delta(
420     WORD32 delta, ixheaace_huffman_tables *pstr_huffman_tbl) {
421   return pstr_huffman_tbl->huff_ltabscf[delta + CODE_BCK_SCF_LAV];
422 }
423 
ia_enhaacplus_enc_scf_count(const WORD16 * ptr_scale_fac,const UWORD16 * ptr_max_val_in_sfb,ixheaace_section_data * pstr_section_data,ixheaace_huffman_tables * pstr_huffman_tbl)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                                                 ixheaace_huffman_tables *pstr_huffman_tbl) {
428   WORD32 sect_idx1 = 0;
429   WORD32 sfb_idx1 = 0;
430   WORD32 scf_idx = 0;
431   WORD32 sect_idx2 = 0;
432   WORD32 sfb_idx2 = 0;
433 
434   WORD32 last_val_scf = 0;
435   WORD32 delta_scf = 0;
436   WORD32 found = 0;
437   WORD32 scf_skip_counter = 0;
438 
439   pstr_section_data->scale_fac_bits = 0;
440 
441   if (ptr_scale_fac == 0) {
442     return IA_EXHEAACE_EXE_FATAL_INVALID_SCALE_FACTOR_GAIN;
443   }
444   last_val_scf = 0;
445   pstr_section_data->first_scf = 0;
446 
447   for (sect_idx1 = 0; sect_idx1 < pstr_section_data->num_of_sections; sect_idx1++) {
448     if (pstr_section_data->section[sect_idx1].code_book != CODE_BCK_ZERO_NO) {
449       pstr_section_data->first_scf = pstr_section_data->section[sect_idx1].sfb_start;
450 
451       last_val_scf = ptr_scale_fac[pstr_section_data->first_scf];
452       break;
453     }
454   }
455 
456   for (sect_idx1 = 0; sect_idx1 < pstr_section_data->num_of_sections; sect_idx1++) {
457     if ((pstr_section_data->section[sect_idx1].code_book != CODE_BCK_ZERO_NO) &&
458         (pstr_section_data->section[sect_idx1].code_book != CODE_BCK_PNS_NO)) {
459       for (sfb_idx1 = pstr_section_data->section[sect_idx1].sfb_start;
460            sfb_idx1 < pstr_section_data->section[sect_idx1].sfb_start +
461                           pstr_section_data->section[sect_idx1].sfb_cnt;
462            sfb_idx1++) {
463         if (ptr_max_val_in_sfb[sfb_idx1] == 0) {
464           found = 0;
465 
466           if (scf_skip_counter == 0) {
467             if (sfb_idx1 == (pstr_section_data->section[sect_idx1].sfb_start +
468                              pstr_section_data->section[sect_idx1].sfb_cnt - 1)) {
469               found = 0;
470             } else {
471               for (scf_idx = (sfb_idx1 + 1);
472                    scf_idx < pstr_section_data->section[sect_idx1].sfb_start +
473                                  pstr_section_data->section[sect_idx1].sfb_cnt;
474                    scf_idx++) {
475                 if (ptr_max_val_in_sfb[scf_idx] != 0) {
476                   found = 1;
477 
478                   if ((abs32(ptr_scale_fac[scf_idx] - last_val_scf)) < CODE_BCK_SCF_LAV) {
479                     delta_scf = 0;
480                   } else {
481                     delta_scf = -(ptr_scale_fac[sfb_idx1] - last_val_scf);
482 
483                     last_val_scf = ptr_scale_fac[sfb_idx1];
484                     scf_skip_counter = 0;
485                   }
486                   break;
487                 }
488                 /* count scalefactor skip */
489                 scf_skip_counter = scf_skip_counter + 1;
490               }
491             }
492 
493             /* search for the next ptr_max_val_in_sfb[] != 0 in all other sections */
494             for (sect_idx2 = (sect_idx1 + 1);
495                  (sect_idx2 < pstr_section_data->num_of_sections) && (found == 0); sect_idx2++) {
496               if ((pstr_section_data->section[sect_idx2].code_book != CODE_BCK_ZERO_NO) &&
497                   (pstr_section_data->section[sect_idx2].code_book != CODE_BCK_PNS_NO)) {
498                 for (sfb_idx2 = pstr_section_data->section[sect_idx2].sfb_start;
499                      sfb_idx2 < pstr_section_data->section[sect_idx2].sfb_start +
500                                     pstr_section_data->section[sect_idx2].sfb_cnt;
501                      sfb_idx2++) {
502                   if (ptr_max_val_in_sfb[sfb_idx2] != 0) {
503                     found = 1;
504 
505                     if ((abs32(ptr_scale_fac[sfb_idx2] - last_val_scf)) < CODE_BCK_SCF_LAV) {
506                       delta_scf = 0;
507                     } else {
508                       delta_scf = -(ptr_scale_fac[sfb_idx1] - last_val_scf);
509 
510                       last_val_scf = ptr_scale_fac[sfb_idx1];
511                       scf_skip_counter = 0;
512                     }
513                     break;
514                   }
515 
516                   scf_skip_counter = scf_skip_counter + 1;
517                 }
518               }
519             }
520 
521             if (found == 0) {
522               delta_scf = 0;
523               scf_skip_counter = 0;
524             }
525           } else {
526             delta_scf = 0;
527 
528             scf_skip_counter = scf_skip_counter - 1;
529           }
530         } else {
531           delta_scf = -(ptr_scale_fac[sfb_idx1] - last_val_scf);
532 
533           last_val_scf = ptr_scale_fac[sfb_idx1];
534         }
535 
536         pstr_section_data->scale_fac_bits +=
537             ia_enhaacplus_enc_bit_count_scalefactor_delta(delta_scf, pstr_huffman_tbl);
538       }
539     }
540   }
541   return IA_NO_ERROR;
542 }
543 
ia_enhaacplus_enc_dyn_bitcount(const WORD16 * ptr_quant_spec,const UWORD16 * ptr_max_val_in_sfb,const WORD16 * ptr_scale_fac,const WORD32 block_type,const WORD32 sfb_cnt,const WORD32 max_sfb_per_grp,const WORD32 sfb_per_grp,const WORD32 * ptr_sfb_offset,ixheaace_section_data * pstr_section_data,WORD32 * ptr_side_info_tab_long,WORD32 * ptr_side_info_tab_short,ixheaace_huffman_tables * ptr_huffman_tbl,WORD32 * ptr_scratch_buf,WORD32 aot,WORD32 * bit_cnt)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     WORD32 *ptr_scratch_buf, WORD32 aot, WORD32 *bit_cnt) {
551   IA_ERRORCODE err_code;
552   WORD32(*ptr_bit_look_up)
553   [CODE_BCK_ESC_NDX + 1] = (WORD32(*)[CODE_BCK_ESC_NDX + 1]) ptr_scratch_buf;
554   WORD32 *ptr_merge_gain_look_up =
555       ptr_scratch_buf + MAXIMUM_SCALE_FACTOR_BAND_LONG * (CODE_BCK_ESC_NDX + 1);
556   *bit_cnt = 0;
557   pstr_section_data->block_type = block_type;
558   pstr_section_data->sfb_cnt = sfb_cnt;
559   pstr_section_data->sfb_per_group = sfb_per_grp;
560 
561   pstr_section_data->total_groups_cnt = sfb_cnt / sfb_per_grp;
562 
563   pstr_section_data->max_sfb_per_grp = max_sfb_per_grp;
564 
565   err_code = ia_enhaacplus_enc_noiseless_counter(
566       pstr_section_data, ptr_merge_gain_look_up, ptr_bit_look_up, ptr_quant_spec,
567       ptr_max_val_in_sfb, ptr_sfb_offset, block_type, ptr_side_info_tab_long,
568       ptr_side_info_tab_short, ptr_huffman_tbl, aot);
569 
570   if (err_code != IA_NO_ERROR) {
571     return err_code;
572   }
573 
574   err_code = ia_enhaacplus_enc_scf_count(ptr_scale_fac, ptr_max_val_in_sfb, pstr_section_data,
575                                          ptr_huffman_tbl);
576 
577   if (err_code != IA_NO_ERROR) {
578     return err_code;
579   }
580 
581   *bit_cnt = (pstr_section_data->huffman_bits + pstr_section_data->side_info_bits +
582               pstr_section_data->scale_fac_bits);
583   return IA_NO_ERROR;
584 }
585 
ia_enhaacplus_enc_bitcount_init(WORD32 * side_info_tab_long,WORD32 * side_info_tab_short)586 VOID ia_enhaacplus_enc_bitcount_init(WORD32 *side_info_tab_long, WORD32 *side_info_tab_short) {
587   WORD32 i;
588 
589   /* side_info_tab_long[] */
590   for (i = 0; i <= MAXIMUM_SCALE_FACTOR_BAND_LONG; i++) {
591     side_info_tab_long[i] = ia_enhaacplus_enc_calc_side_info_bits(i, LONG_WINDOW);
592   }
593 
594   /* side_info_tab_short[] */
595   for (i = 0; i <= MAXIMUM_SCALE_FACTOR_BAND_SHORT; i++) {
596     side_info_tab_short[i] = ia_enhaacplus_enc_calc_side_info_bits(i, SHORT_WINDOW);
597   }
598 }
599