xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_qc_util.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
1*15dc779aSAndroid Build Coastguard Worker /******************************************************************************
2*15dc779aSAndroid Build Coastguard Worker  *                                                                            *
3*15dc779aSAndroid Build Coastguard Worker  * Copyright (C) 2023 The Android Open Source Project
4*15dc779aSAndroid Build Coastguard Worker  *
5*15dc779aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
6*15dc779aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
7*15dc779aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at:
8*15dc779aSAndroid Build Coastguard Worker  *
9*15dc779aSAndroid Build Coastguard Worker  * http://www.apache.org/licenses/LICENSE-2.0
10*15dc779aSAndroid Build Coastguard Worker  *
11*15dc779aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
12*15dc779aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
13*15dc779aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*15dc779aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
15*15dc779aSAndroid Build Coastguard Worker  * limitations under the License.
16*15dc779aSAndroid Build Coastguard Worker  *
17*15dc779aSAndroid Build Coastguard Worker  *****************************************************************************
18*15dc779aSAndroid Build Coastguard Worker  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*15dc779aSAndroid Build Coastguard Worker  */
20*15dc779aSAndroid Build Coastguard Worker 
21*15dc779aSAndroid Build Coastguard Worker #include <string.h>
22*15dc779aSAndroid Build Coastguard Worker 
23*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_type_def.h"
24*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_constants.h"
25*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_common_enc.h"
26*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_uni_drc.h"
27*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_tables.h"
28*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_api.h"
29*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_api.h"
30*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_aac_constants.h"
31*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_error_codes.h"
32*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_error_standards.h"
33*15dc779aSAndroid Build Coastguard Worker #include <stdlib.h>
34*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_psy_const.h"
35*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_tns.h"
36*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_tns_params.h"
37*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_rom.h"
38*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_common_rom.h"
39*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_quant.h"
40*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_block_switch.h"
41*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_bitbuffer.h"
42*15dc779aSAndroid Build Coastguard Worker 
43*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops32.h"
44*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops16.h"
45*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops40.h"
46*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops.h"
47*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_psy_const.h"
48*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_tns.h"
49*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_psy_data.h"
50*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_interface.h"
51*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_adjust_threshold_data.h"
52*15dc779aSAndroid Build Coastguard Worker 
53*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_dynamic_bits.h"
54*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_qc_data.h"
55*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_adjust_threshold.h"
56*15dc779aSAndroid Build Coastguard Worker 
57*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_sf_estimation.h"
58*15dc779aSAndroid Build Coastguard Worker 
59*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_static_bits.h"
60*15dc779aSAndroid Build Coastguard Worker 
61*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_bits_count.h"
62*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_channel_map.h"
63*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_write_bitstream.h"
64*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_psy_configuration.h"
65*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_psy_mod.h"
66*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_tns_params.h"
67*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_stereo_preproc.h"
68*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_enc_main.h"
69*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_qc_util.h"
70*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_common_utils.h"
71*15dc779aSAndroid Build Coastguard Worker 
ia_enhaacplus_enc_calc_frame_len(WORD32 bit_rate,WORD32 sample_rate,FRAME_LEN_RESULT_MODE mode,WORD32 long_frame_len)72*15dc779aSAndroid Build Coastguard Worker static WORD32 ia_enhaacplus_enc_calc_frame_len(WORD32 bit_rate, WORD32 sample_rate,
73*15dc779aSAndroid Build Coastguard Worker                                                FRAME_LEN_RESULT_MODE mode,
74*15dc779aSAndroid Build Coastguard Worker                                                WORD32 long_frame_len) {
75*15dc779aSAndroid Build Coastguard Worker   WORD32 result;
76*15dc779aSAndroid Build Coastguard Worker 
77*15dc779aSAndroid Build Coastguard Worker   result = ((long_frame_len) >> 3) * (bit_rate);
78*15dc779aSAndroid Build Coastguard Worker 
79*15dc779aSAndroid Build Coastguard Worker   switch (mode) {
80*15dc779aSAndroid Build Coastguard Worker     case FRAME_LEN_BYTES_MODULO:
81*15dc779aSAndroid Build Coastguard Worker       result %= sample_rate;
82*15dc779aSAndroid Build Coastguard Worker       break;
83*15dc779aSAndroid Build Coastguard Worker     case FRAME_LEN_BYTES_INT:
84*15dc779aSAndroid Build Coastguard Worker       result /= sample_rate;
85*15dc779aSAndroid Build Coastguard Worker       break;
86*15dc779aSAndroid Build Coastguard Worker     default:
87*15dc779aSAndroid Build Coastguard Worker       break;
88*15dc779aSAndroid Build Coastguard Worker   }
89*15dc779aSAndroid Build Coastguard Worker 
90*15dc779aSAndroid Build Coastguard Worker   return result;
91*15dc779aSAndroid Build Coastguard Worker }
92*15dc779aSAndroid Build Coastguard Worker 
ia_enhaacplus_enc_frame_padding(WORD32 bit_rate,WORD32 sample_rate,WORD32 * ptr_padding_rest,WORD32 frame_len_long)93*15dc779aSAndroid Build Coastguard Worker static WORD32 ia_enhaacplus_enc_frame_padding(WORD32 bit_rate, WORD32 sample_rate,
94*15dc779aSAndroid Build Coastguard Worker                                               WORD32 *ptr_padding_rest, WORD32 frame_len_long) {
95*15dc779aSAndroid Build Coastguard Worker   WORD32 padding_on;
96*15dc779aSAndroid Build Coastguard Worker   WORD32 difference;
97*15dc779aSAndroid Build Coastguard Worker 
98*15dc779aSAndroid Build Coastguard Worker   padding_on = 0;
99*15dc779aSAndroid Build Coastguard Worker 
100*15dc779aSAndroid Build Coastguard Worker   difference = ia_enhaacplus_enc_calc_frame_len(bit_rate, sample_rate, FRAME_LEN_BYTES_MODULO,
101*15dc779aSAndroid Build Coastguard Worker                                                 frame_len_long);
102*15dc779aSAndroid Build Coastguard Worker 
103*15dc779aSAndroid Build Coastguard Worker   *ptr_padding_rest -= difference;
104*15dc779aSAndroid Build Coastguard Worker 
105*15dc779aSAndroid Build Coastguard Worker   if (*ptr_padding_rest <= 0) {
106*15dc779aSAndroid Build Coastguard Worker     padding_on = 1;
107*15dc779aSAndroid Build Coastguard Worker 
108*15dc779aSAndroid Build Coastguard Worker     *ptr_padding_rest += sample_rate;
109*15dc779aSAndroid Build Coastguard Worker   }
110*15dc779aSAndroid Build Coastguard Worker 
111*15dc779aSAndroid Build Coastguard Worker   return padding_on;
112*15dc779aSAndroid Build Coastguard Worker }
113*15dc779aSAndroid Build Coastguard Worker 
ia_enhaacplus_enc_qc_out_new(ixheaace_qc_out * pstr_qc_out,WORD32 num_channels,WORD32 * ptr_shared_buffer1,WORD32 * ptr_shared_buffer3,WORD32 long_frame_len)114*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE ia_enhaacplus_enc_qc_out_new(ixheaace_qc_out *pstr_qc_out, WORD32 num_channels,
115*15dc779aSAndroid Build Coastguard Worker                                           WORD32 *ptr_shared_buffer1, WORD32 *ptr_shared_buffer3,
116*15dc779aSAndroid Build Coastguard Worker                                           WORD32 long_frame_len)
117*15dc779aSAndroid Build Coastguard Worker 
118*15dc779aSAndroid Build Coastguard Worker {
119*15dc779aSAndroid Build Coastguard Worker   WORD32 i;
120*15dc779aSAndroid Build Coastguard Worker 
121*15dc779aSAndroid Build Coastguard Worker   for (i = 0; i < num_channels; i++) {
122*15dc779aSAndroid Build Coastguard Worker     pstr_qc_out->qc_channel[i]->quant_spec = &((WORD16 *)ptr_shared_buffer1)[i * long_frame_len];
123*15dc779aSAndroid Build Coastguard Worker 
124*15dc779aSAndroid Build Coastguard Worker     memset(pstr_qc_out->qc_channel[i]->quant_spec, 0,
125*15dc779aSAndroid Build Coastguard Worker            sizeof(*pstr_qc_out->qc_channel[i]->quant_spec) * long_frame_len);
126*15dc779aSAndroid Build Coastguard Worker 
127*15dc779aSAndroid Build Coastguard Worker     pstr_qc_out->qc_channel[i]->max_val_in_sfb =
128*15dc779aSAndroid Build Coastguard Worker         &((UWORD16 *)&ptr_shared_buffer3[(long_frame_len + long_frame_len / 2) +
129*15dc779aSAndroid Build Coastguard Worker                                          IXHEAACE_MAX_CH_IN_BS_ELE *
130*15dc779aSAndroid Build Coastguard Worker                                              MAXIMUM_GROUPED_SCALE_FACTOR_BAND /
131*15dc779aSAndroid Build Coastguard Worker                                              2])[i * MAXIMUM_GROUPED_SCALE_FACTOR_BAND];
132*15dc779aSAndroid Build Coastguard Worker     memset(
133*15dc779aSAndroid Build Coastguard Worker         pstr_qc_out->qc_channel[i]->max_val_in_sfb, 0,
134*15dc779aSAndroid Build Coastguard Worker         sizeof(*pstr_qc_out->qc_channel[i]->max_val_in_sfb) * MAXIMUM_GROUPED_SCALE_FACTOR_BAND);
135*15dc779aSAndroid Build Coastguard Worker 
136*15dc779aSAndroid Build Coastguard Worker     pstr_qc_out->qc_channel[i]->scalefactor = &((WORD16 *)&ptr_shared_buffer3[(
137*15dc779aSAndroid Build Coastguard Worker         long_frame_len + long_frame_len / 2)])[i * MAXIMUM_GROUPED_SCALE_FACTOR_BAND];
138*15dc779aSAndroid Build Coastguard Worker 
139*15dc779aSAndroid Build Coastguard Worker     memset(pstr_qc_out->qc_channel[i]->scalefactor, 0,
140*15dc779aSAndroid Build Coastguard Worker            sizeof(*pstr_qc_out->qc_channel[i]->scalefactor) * MAXIMUM_GROUPED_SCALE_FACTOR_BAND);
141*15dc779aSAndroid Build Coastguard Worker   }
142*15dc779aSAndroid Build Coastguard Worker 
143*15dc779aSAndroid Build Coastguard Worker   if (pstr_qc_out == NULL) {
144*15dc779aSAndroid Build Coastguard Worker     return IA_EXHEAACE_INIT_FATAL_AAC_INIT_FAILED;
145*15dc779aSAndroid Build Coastguard Worker   }
146*15dc779aSAndroid Build Coastguard Worker   return IA_NO_ERROR;
147*15dc779aSAndroid Build Coastguard Worker }
148*15dc779aSAndroid Build Coastguard Worker 
ia_enhaacplus_enc_qc_new(ixheaace_qc_state * pstr_qc_state,WORD32 * ptr_shared_buffer_2,WORD32 long_frame_len)149*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE ia_enhaacplus_enc_qc_new(ixheaace_qc_state *pstr_qc_state,
150*15dc779aSAndroid Build Coastguard Worker                                       WORD32 *ptr_shared_buffer_2, WORD32 long_frame_len
151*15dc779aSAndroid Build Coastguard Worker ) {
152*15dc779aSAndroid Build Coastguard Worker   memset(pstr_qc_state, 0, sizeof(ixheaace_qc_state));
153*15dc779aSAndroid Build Coastguard Worker   pstr_qc_state->qc_scr.shared_buffer_2 =
154*15dc779aSAndroid Build Coastguard Worker       (ptr_shared_buffer_2 + long_frame_len * IXHEAACE_MAX_CH_IN_BS_ELE + 16);
155*15dc779aSAndroid Build Coastguard Worker 
156*15dc779aSAndroid Build Coastguard Worker   return IA_NO_ERROR;
157*15dc779aSAndroid Build Coastguard Worker }
158*15dc779aSAndroid Build Coastguard Worker 
ia_enhaacplus_enc_qc_init(ixheaace_qc_state * pstr_qc_state,WORD32 aot,ixheaace_qc_init * pstr_init,FLAG flag_framelength_small)159*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE ia_enhaacplus_enc_qc_init(ixheaace_qc_state *pstr_qc_state, WORD32 aot,
160*15dc779aSAndroid Build Coastguard Worker                                        ixheaace_qc_init *pstr_init, FLAG flag_framelength_small) {
161*15dc779aSAndroid Build Coastguard Worker   IA_ERRORCODE error = IA_NO_ERROR;
162*15dc779aSAndroid Build Coastguard Worker   pstr_qc_state->num_channels = pstr_init->pstr_element_info->n_channels_in_el;
163*15dc779aSAndroid Build Coastguard Worker   pstr_qc_state->max_bits_tot = pstr_init->max_bits;
164*15dc779aSAndroid Build Coastguard Worker   switch (aot) {
165*15dc779aSAndroid Build Coastguard Worker     case AOT_AAC_LC:
166*15dc779aSAndroid Build Coastguard Worker     case AOT_SBR:
167*15dc779aSAndroid Build Coastguard Worker     case AOT_PS:
168*15dc779aSAndroid Build Coastguard Worker       pstr_qc_state->bit_res_tot = pstr_init->bit_res - pstr_init->average_bits;
169*15dc779aSAndroid Build Coastguard Worker       break;
170*15dc779aSAndroid Build Coastguard Worker 
171*15dc779aSAndroid Build Coastguard Worker     case AOT_AAC_LD:
172*15dc779aSAndroid Build Coastguard Worker     case AOT_AAC_ELD:
173*15dc779aSAndroid Build Coastguard Worker       if (pstr_init->bit_res) {
174*15dc779aSAndroid Build Coastguard Worker         pstr_qc_state->bit_res_tot = pstr_init->bit_res - pstr_init->average_bits;
175*15dc779aSAndroid Build Coastguard Worker       } else {
176*15dc779aSAndroid Build Coastguard Worker         pstr_qc_state->bit_res_tot = 0;
177*15dc779aSAndroid Build Coastguard Worker       }
178*15dc779aSAndroid Build Coastguard Worker       break;
179*15dc779aSAndroid Build Coastguard Worker   }
180*15dc779aSAndroid Build Coastguard Worker   pstr_qc_state->average_bits_tot = pstr_init->average_bits;
181*15dc779aSAndroid Build Coastguard Worker   pstr_qc_state->max_bit_fac = pstr_init->max_bit_fac;
182*15dc779aSAndroid Build Coastguard Worker   pstr_qc_state->padding.padding_rest = pstr_init->padding.padding_rest;
183*15dc779aSAndroid Build Coastguard Worker 
184*15dc779aSAndroid Build Coastguard Worker   pstr_qc_state->quality_level = pstr_init->inv_quant;
185*15dc779aSAndroid Build Coastguard Worker   if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
186*15dc779aSAndroid Build Coastguard Worker     pstr_qc_state->glob_stat_bits = 3; /* for ID_END */
187*15dc779aSAndroid Build Coastguard Worker   }
188*15dc779aSAndroid Build Coastguard Worker   error = ia_enhaacplus_enc_init_element_bits(
189*15dc779aSAndroid Build Coastguard Worker       &pstr_qc_state->element_bits, *pstr_init->pstr_element_info, pstr_init->bitrate,
190*15dc779aSAndroid Build Coastguard Worker       pstr_init->average_bits, aot, pstr_qc_state->glob_stat_bits, pstr_init->bit_res,
191*15dc779aSAndroid Build Coastguard Worker       flag_framelength_small);
192*15dc779aSAndroid Build Coastguard Worker 
193*15dc779aSAndroid Build Coastguard Worker   if (error != IA_NO_ERROR) {
194*15dc779aSAndroid Build Coastguard Worker     return error;
195*15dc779aSAndroid Build Coastguard Worker   }
196*15dc779aSAndroid Build Coastguard Worker   iaace_adj_thr_init(&pstr_qc_state->str_adj_thr, pstr_init->mean_pe,
197*15dc779aSAndroid Build Coastguard Worker                      pstr_qc_state->element_bits.ch_bitrate, aot);
198*15dc779aSAndroid Build Coastguard Worker 
199*15dc779aSAndroid Build Coastguard Worker   ia_enhaacplus_enc_bitcount_init((WORD32 *)pstr_qc_state->side_info_tab_long,
200*15dc779aSAndroid Build Coastguard Worker                                   (WORD32 *)pstr_qc_state->side_info_tab_short);
201*15dc779aSAndroid Build Coastguard Worker 
202*15dc779aSAndroid Build Coastguard Worker   return IA_NO_ERROR;
203*15dc779aSAndroid Build Coastguard Worker }
204*15dc779aSAndroid Build Coastguard Worker 
ia_enhaacplus_enc_update_bit_reservoir(ixheaace_qc_state * pstr_qc_kernel,ixheaace_qc_out * pstr_qc_out)205*15dc779aSAndroid Build Coastguard Worker VOID ia_enhaacplus_enc_update_bit_reservoir(ixheaace_qc_state *pstr_qc_kernel,
206*15dc779aSAndroid Build Coastguard Worker                                             ixheaace_qc_out *pstr_qc_out)
207*15dc779aSAndroid Build Coastguard Worker 
208*15dc779aSAndroid Build Coastguard Worker {
209*15dc779aSAndroid Build Coastguard Worker   ixheaace_element_bits *pstr_el_bits;
210*15dc779aSAndroid Build Coastguard Worker 
211*15dc779aSAndroid Build Coastguard Worker   pstr_qc_kernel->bit_res_tot = 0;
212*15dc779aSAndroid Build Coastguard Worker 
213*15dc779aSAndroid Build Coastguard Worker   pstr_el_bits = &pstr_qc_kernel->element_bits;
214*15dc779aSAndroid Build Coastguard Worker 
215*15dc779aSAndroid Build Coastguard Worker   if (pstr_el_bits->average_bits > 0) {
216*15dc779aSAndroid Build Coastguard Worker     /* constant bitrate */
217*15dc779aSAndroid Build Coastguard Worker     pstr_el_bits->bit_res_level +=
218*15dc779aSAndroid Build Coastguard Worker         pstr_el_bits->average_bits -
219*15dc779aSAndroid Build Coastguard Worker         (pstr_qc_out->qc_element.static_bits_used + pstr_qc_out->qc_element.dyn_bits_used +
220*15dc779aSAndroid Build Coastguard Worker          pstr_qc_out->qc_element.anc_bits_used + pstr_qc_out->qc_element.fill_bits);
221*15dc779aSAndroid Build Coastguard Worker 
222*15dc779aSAndroid Build Coastguard Worker     pstr_qc_kernel->bit_res_tot += pstr_el_bits->bit_res_level;
223*15dc779aSAndroid Build Coastguard Worker   } else {
224*15dc779aSAndroid Build Coastguard Worker     /* variable bitrate */
225*15dc779aSAndroid Build Coastguard Worker     pstr_el_bits->bit_res_level = pstr_el_bits->max_bits;
226*15dc779aSAndroid Build Coastguard Worker     pstr_qc_kernel->bit_res_tot = pstr_qc_kernel->max_bits_tot;
227*15dc779aSAndroid Build Coastguard Worker   }
228*15dc779aSAndroid Build Coastguard Worker }
229*15dc779aSAndroid Build Coastguard Worker 
ia_enhaacplus_enc_finalize_bit_consumption(ixheaace_qc_state * pstr_qc_kernel,ixheaace_qc_out * pstr_qc_out,WORD32 flag_last_element,WORD32 cnt_bits,WORD32 * tot_fill_bits,iexheaac_encoder_str ** pstr_aac_enc,WORD32 num_bs_elements,WORD32 aot)230*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE ia_enhaacplus_enc_finalize_bit_consumption(ixheaace_qc_state *pstr_qc_kernel,
231*15dc779aSAndroid Build Coastguard Worker                                                         ixheaace_qc_out *pstr_qc_out,
232*15dc779aSAndroid Build Coastguard Worker                                                         WORD32 flag_last_element, WORD32 cnt_bits,
233*15dc779aSAndroid Build Coastguard Worker                                                         WORD32 *tot_fill_bits,
234*15dc779aSAndroid Build Coastguard Worker                                                         iexheaac_encoder_str **pstr_aac_enc,
235*15dc779aSAndroid Build Coastguard Worker                                                         WORD32 num_bs_elements, WORD32 aot) {
236*15dc779aSAndroid Build Coastguard Worker   WORD32 n_full_fill_elem, diff_bits;
237*15dc779aSAndroid Build Coastguard Worker   WORD32 total_fill_bits = 0;
238*15dc779aSAndroid Build Coastguard Worker 
239*15dc779aSAndroid Build Coastguard Worker   const WORD32 max_fill_elem_bits = 7 + 270 * 8;
240*15dc779aSAndroid Build Coastguard Worker   WORD32 tfb_flag = 0;
241*15dc779aSAndroid Build Coastguard Worker   WORD32 tfb_flag1 = 0;
242*15dc779aSAndroid Build Coastguard Worker   WORD32 tfb_flag2 = 0;
243*15dc779aSAndroid Build Coastguard Worker 
244*15dc779aSAndroid Build Coastguard Worker   pstr_qc_out->tot_static_bits_used = (flag_last_element ? pstr_qc_kernel->glob_stat_bits : 0);
245*15dc779aSAndroid Build Coastguard Worker 
246*15dc779aSAndroid Build Coastguard Worker   pstr_qc_out->tot_dyn_bits_used = 0;
247*15dc779aSAndroid Build Coastguard Worker   pstr_qc_out->tot_anc_bits_used = 0;
248*15dc779aSAndroid Build Coastguard Worker   pstr_qc_out->total_fill_bits = 0;
249*15dc779aSAndroid Build Coastguard Worker   pstr_qc_out->tot_static_bits_used += pstr_qc_out->qc_element.static_bits_used;
250*15dc779aSAndroid Build Coastguard Worker   pstr_qc_out->tot_dyn_bits_used += pstr_qc_out->qc_element.dyn_bits_used;
251*15dc779aSAndroid Build Coastguard Worker   pstr_qc_out->tot_anc_bits_used += pstr_qc_out->qc_element.anc_bits_used;
252*15dc779aSAndroid Build Coastguard Worker   pstr_qc_out->total_fill_bits += pstr_qc_out->qc_element.fill_bits;
253*15dc779aSAndroid Build Coastguard Worker 
254*15dc779aSAndroid Build Coastguard Worker   /* Accumulate total fill bits */
255*15dc779aSAndroid Build Coastguard Worker   *tot_fill_bits += pstr_qc_out->qc_element.fill_bits;
256*15dc779aSAndroid Build Coastguard Worker   if (flag_last_element) {
257*15dc779aSAndroid Build Coastguard Worker     WORD32 i, j, temp_resv;
258*15dc779aSAndroid Build Coastguard Worker     WORD32 bit_resv_spc[(MAXIMUM_BS_ELE << 1) + 1];
259*15dc779aSAndroid Build Coastguard Worker     WORD32 bit_resv_spc_sort[(MAXIMUM_BS_ELE << 1) + 1] = {0, 1,  2,  3,  4,  5,  6,  7, 8,
260*15dc779aSAndroid Build Coastguard Worker                                                            9, 10, 11, 12, 13, 14, 15, 16};
261*15dc779aSAndroid Build Coastguard Worker 
262*15dc779aSAndroid Build Coastguard Worker     total_fill_bits = *tot_fill_bits;
263*15dc779aSAndroid Build Coastguard Worker 
264*15dc779aSAndroid Build Coastguard Worker     /* Distribute fill bits among all channel elements for next frame */
265*15dc779aSAndroid Build Coastguard Worker     if (total_fill_bits > 0) {
266*15dc779aSAndroid Build Coastguard Worker       /* Generate array of vacancies in bit reservoirs */
267*15dc779aSAndroid Build Coastguard Worker       for (i = 0, temp_resv = 0; i < num_bs_elements; i++, temp_resv++) {
268*15dc779aSAndroid Build Coastguard Worker         bit_resv_spc[temp_resv] = (pstr_aac_enc[i]->qc_kernel.element_bits.max_bit_res_bits -
269*15dc779aSAndroid Build Coastguard Worker                                    pstr_aac_enc[i]->qc_kernel.element_bits.bit_res_level);
270*15dc779aSAndroid Build Coastguard Worker 
271*15dc779aSAndroid Build Coastguard Worker         /* CPE gets double the weight of SCE, so split CPE reservoir into two */
272*15dc779aSAndroid Build Coastguard Worker         if (pstr_aac_enc[i]->qc_kernel.num_channels == 2) {
273*15dc779aSAndroid Build Coastguard Worker           bit_resv_spc[temp_resv + 1] = bit_resv_spc[temp_resv] >> 1;
274*15dc779aSAndroid Build Coastguard Worker           bit_resv_spc[temp_resv] -= bit_resv_spc[temp_resv + 1];
275*15dc779aSAndroid Build Coastguard Worker           temp_resv++;
276*15dc779aSAndroid Build Coastguard Worker         }
277*15dc779aSAndroid Build Coastguard Worker       }
278*15dc779aSAndroid Build Coastguard Worker 
279*15dc779aSAndroid Build Coastguard Worker       /* Sort bit_resv_spc[] in descending order of levels and
280*15dc779aSAndroid Build Coastguard Worker       store the order in bit_resv_spc_sort[] */
281*15dc779aSAndroid Build Coastguard Worker       for (i = (temp_resv - 1); i > 0; i--) {
282*15dc779aSAndroid Build Coastguard Worker         for (j = 0; j < i; j++) {
283*15dc779aSAndroid Build Coastguard Worker           if (bit_resv_spc[bit_resv_spc_sort[j]] < bit_resv_spc[bit_resv_spc_sort[j + 1]]) {
284*15dc779aSAndroid Build Coastguard Worker             WORD32 tmp_var = bit_resv_spc_sort[j];
285*15dc779aSAndroid Build Coastguard Worker             bit_resv_spc_sort[j] = bit_resv_spc_sort[j + 1];
286*15dc779aSAndroid Build Coastguard Worker             bit_resv_spc_sort[j + 1] = tmp_var;
287*15dc779aSAndroid Build Coastguard Worker           }
288*15dc779aSAndroid Build Coastguard Worker         }
289*15dc779aSAndroid Build Coastguard Worker       }
290*15dc779aSAndroid Build Coastguard Worker 
291*15dc779aSAndroid Build Coastguard Worker       /* One dummy full reservoir at the end to help in bit distribution */
292*15dc779aSAndroid Build Coastguard Worker       bit_resv_spc[temp_resv] = 0;
293*15dc779aSAndroid Build Coastguard Worker       bit_resv_spc_sort[temp_resv] = temp_resv;
294*15dc779aSAndroid Build Coastguard Worker 
295*15dc779aSAndroid Build Coastguard Worker       /* Distribute fill bits among reservoirs in the order of bit_resv_spc_sort[]:
296*15dc779aSAndroid Build Coastguard Worker       - Bring up [0] to the level of [1]
297*15dc779aSAndroid Build Coastguard Worker       - Next bring up [0] and [1] to the level of [2]...and so on */
298*15dc779aSAndroid Build Coastguard Worker       for (i = 1; ((i < (temp_resv + 1)) && (total_fill_bits > 0)); i++) {
299*15dc779aSAndroid Build Coastguard Worker         if (((bit_resv_spc[bit_resv_spc_sort[0]] - bit_resv_spc[bit_resv_spc_sort[i]]) * i) <=
300*15dc779aSAndroid Build Coastguard Worker             total_fill_bits) {
301*15dc779aSAndroid Build Coastguard Worker           total_fill_bits -=
302*15dc779aSAndroid Build Coastguard Worker               ((bit_resv_spc[bit_resv_spc_sort[0]] - bit_resv_spc[bit_resv_spc_sort[i]]) * i);
303*15dc779aSAndroid Build Coastguard Worker           for (j = 0; j < i; j++) {
304*15dc779aSAndroid Build Coastguard Worker             bit_resv_spc[bit_resv_spc_sort[j]] = bit_resv_spc[bit_resv_spc_sort[i]];
305*15dc779aSAndroid Build Coastguard Worker           }
306*15dc779aSAndroid Build Coastguard Worker         } else {
307*15dc779aSAndroid Build Coastguard Worker           WORD32 div_bs_ele;
308*15dc779aSAndroid Build Coastguard Worker 
309*15dc779aSAndroid Build Coastguard Worker           div_bs_ele = (WORD32)(total_fill_bits / i);
310*15dc779aSAndroid Build Coastguard Worker           total_fill_bits -= (div_bs_ele * i);
311*15dc779aSAndroid Build Coastguard Worker 
312*15dc779aSAndroid Build Coastguard Worker           for (j = 0; j < i; j++) {
313*15dc779aSAndroid Build Coastguard Worker             bit_resv_spc[bit_resv_spc_sort[j]] -= div_bs_ele;
314*15dc779aSAndroid Build Coastguard Worker           }
315*15dc779aSAndroid Build Coastguard Worker 
316*15dc779aSAndroid Build Coastguard Worker           for (j = 0; ((j < i) && (total_fill_bits > 0)); j++) {
317*15dc779aSAndroid Build Coastguard Worker             bit_resv_spc[bit_resv_spc_sort[j]]--;
318*15dc779aSAndroid Build Coastguard Worker             total_fill_bits--;
319*15dc779aSAndroid Build Coastguard Worker           }
320*15dc779aSAndroid Build Coastguard Worker         }
321*15dc779aSAndroid Build Coastguard Worker       }
322*15dc779aSAndroid Build Coastguard Worker 
323*15dc779aSAndroid Build Coastguard Worker       /* Supply additional bits added for coding next frame */
324*15dc779aSAndroid Build Coastguard Worker       for (i = 0, temp_resv = 0; i < num_bs_elements; i++, temp_resv++) {
325*15dc779aSAndroid Build Coastguard Worker         WORD32 add_bits;
326*15dc779aSAndroid Build Coastguard Worker 
327*15dc779aSAndroid Build Coastguard Worker         add_bits = (pstr_aac_enc[i]->qc_kernel.element_bits.max_bit_res_bits -
328*15dc779aSAndroid Build Coastguard Worker                     pstr_aac_enc[i]->qc_kernel.element_bits.bit_res_level) -
329*15dc779aSAndroid Build Coastguard Worker                    bit_resv_spc[temp_resv];
330*15dc779aSAndroid Build Coastguard Worker 
331*15dc779aSAndroid Build Coastguard Worker         /* Because CPE reservoir has been split into two */
332*15dc779aSAndroid Build Coastguard Worker         if (pstr_aac_enc[i]->qc_kernel.num_channels == 2) {
333*15dc779aSAndroid Build Coastguard Worker           temp_resv++;
334*15dc779aSAndroid Build Coastguard Worker           add_bits -= bit_resv_spc[temp_resv];
335*15dc779aSAndroid Build Coastguard Worker         }
336*15dc779aSAndroid Build Coastguard Worker 
337*15dc779aSAndroid Build Coastguard Worker         /* These will be in addition to the avg. bitrate for the next frame */
338*15dc779aSAndroid Build Coastguard Worker         pstr_aac_enc[i]->qc_kernel.element_bits.carry_bits = add_bits;
339*15dc779aSAndroid Build Coastguard Worker       }
340*15dc779aSAndroid Build Coastguard Worker 
341*15dc779aSAndroid Build Coastguard Worker       /* Update remaining fill bits */
342*15dc779aSAndroid Build Coastguard Worker       *tot_fill_bits = total_fill_bits;
343*15dc779aSAndroid Build Coastguard Worker     }
344*15dc779aSAndroid Build Coastguard Worker 
345*15dc779aSAndroid Build Coastguard Worker     n_full_fill_elem = (total_fill_bits - 1) / max_fill_elem_bits;
346*15dc779aSAndroid Build Coastguard Worker 
347*15dc779aSAndroid Build Coastguard Worker     if (n_full_fill_elem) {
348*15dc779aSAndroid Build Coastguard Worker       total_fill_bits -= n_full_fill_elem * max_fill_elem_bits;
349*15dc779aSAndroid Build Coastguard Worker     }
350*15dc779aSAndroid Build Coastguard Worker 
351*15dc779aSAndroid Build Coastguard Worker     if (total_fill_bits > 0) {
352*15dc779aSAndroid Build Coastguard Worker       /* minimum Fillelement contains 7 (TAG + byte cnt) bits */
353*15dc779aSAndroid Build Coastguard Worker       total_fill_bits = MAX(7, total_fill_bits);
354*15dc779aSAndroid Build Coastguard Worker 
355*15dc779aSAndroid Build Coastguard Worker       /* fill element size equals n*8 + 7 */
356*15dc779aSAndroid Build Coastguard Worker       total_fill_bits += ((8 - (total_fill_bits - 7) % 8) % 8);
357*15dc779aSAndroid Build Coastguard Worker 
358*15dc779aSAndroid Build Coastguard Worker       switch (total_fill_bits) {
359*15dc779aSAndroid Build Coastguard Worker         case 7:
360*15dc779aSAndroid Build Coastguard Worker           tfb_flag2 = 1;
361*15dc779aSAndroid Build Coastguard Worker           break;
362*15dc779aSAndroid Build Coastguard Worker 
363*15dc779aSAndroid Build Coastguard Worker         case 15:
364*15dc779aSAndroid Build Coastguard Worker           tfb_flag1 = 1;
365*15dc779aSAndroid Build Coastguard Worker           break;
366*15dc779aSAndroid Build Coastguard Worker 
367*15dc779aSAndroid Build Coastguard Worker         default:
368*15dc779aSAndroid Build Coastguard Worker           tfb_flag = 1;
369*15dc779aSAndroid Build Coastguard Worker           break;
370*15dc779aSAndroid Build Coastguard Worker       }
371*15dc779aSAndroid Build Coastguard Worker     }
372*15dc779aSAndroid Build Coastguard Worker 
373*15dc779aSAndroid Build Coastguard Worker     total_fill_bits += n_full_fill_elem * max_fill_elem_bits;
374*15dc779aSAndroid Build Coastguard Worker 
375*15dc779aSAndroid Build Coastguard Worker     pstr_qc_out->align_bits =
376*15dc779aSAndroid Build Coastguard Worker         7 - (cnt_bits + pstr_qc_out->tot_dyn_bits_used + pstr_qc_out->tot_static_bits_used +
377*15dc779aSAndroid Build Coastguard Worker              pstr_qc_out->tot_anc_bits_used + +total_fill_bits - 1) %
378*15dc779aSAndroid Build Coastguard Worker                 8;
379*15dc779aSAndroid Build Coastguard Worker     if (((pstr_qc_out->align_bits + total_fill_bits - *tot_fill_bits) == 8) &&
380*15dc779aSAndroid Build Coastguard Worker         (total_fill_bits > 8)) {
381*15dc779aSAndroid Build Coastguard Worker       total_fill_bits -= 8;
382*15dc779aSAndroid Build Coastguard Worker     }
383*15dc779aSAndroid Build Coastguard Worker 
384*15dc779aSAndroid Build Coastguard Worker     diff_bits = (pstr_qc_out->align_bits + total_fill_bits) - *tot_fill_bits;
385*15dc779aSAndroid Build Coastguard Worker 
386*15dc779aSAndroid Build Coastguard Worker     if (diff_bits) {
387*15dc779aSAndroid Build Coastguard Worker       if (diff_bits < 0) {
388*15dc779aSAndroid Build Coastguard Worker         return IA_EXHEAACE_EXE_FATAL_INVALID_BIT_CONSUMPTION;
389*15dc779aSAndroid Build Coastguard Worker       } else {
390*15dc779aSAndroid Build Coastguard Worker         {
391*15dc779aSAndroid Build Coastguard Worker           if (cnt_bits + pstr_qc_out->tot_static_bits_used + pstr_qc_out->tot_dyn_bits_used +
392*15dc779aSAndroid Build Coastguard Worker                   pstr_qc_out->tot_anc_bits_used + total_fill_bits >
393*15dc779aSAndroid Build Coastguard Worker               12288) {
394*15dc779aSAndroid Build Coastguard Worker             if ((diff_bits > 8) && (total_fill_bits > 8)) {
395*15dc779aSAndroid Build Coastguard Worker               if (tfb_flag || tfb_flag1) {
396*15dc779aSAndroid Build Coastguard Worker                 total_fill_bits -= 8;
397*15dc779aSAndroid Build Coastguard Worker               }
398*15dc779aSAndroid Build Coastguard Worker               if (tfb_flag2) {
399*15dc779aSAndroid Build Coastguard Worker                 total_fill_bits -= 7;
400*15dc779aSAndroid Build Coastguard Worker               }
401*15dc779aSAndroid Build Coastguard Worker             }
402*15dc779aSAndroid Build Coastguard Worker           } else {
403*15dc779aSAndroid Build Coastguard Worker             if (pstr_qc_kernel->element_bits.bit_res_level - diff_bits > 0) {
404*15dc779aSAndroid Build Coastguard Worker               pstr_qc_kernel->element_bits.bit_res_level -= diff_bits;
405*15dc779aSAndroid Build Coastguard Worker               pstr_qc_kernel->bit_res_tot = pstr_qc_kernel->element_bits.bit_res_level;
406*15dc779aSAndroid Build Coastguard Worker             } else {
407*15dc779aSAndroid Build Coastguard Worker               if ((diff_bits > 8) && (total_fill_bits > 8) && (tfb_flag)) {
408*15dc779aSAndroid Build Coastguard Worker                 total_fill_bits -= 8;
409*15dc779aSAndroid Build Coastguard Worker               } else if ((diff_bits > 8) && (total_fill_bits > 8) && (tfb_flag1)) {
410*15dc779aSAndroid Build Coastguard Worker                 total_fill_bits -= 8;
411*15dc779aSAndroid Build Coastguard Worker               } else if ((diff_bits > 8) && (total_fill_bits > 8) && (tfb_flag2)) {
412*15dc779aSAndroid Build Coastguard Worker                 total_fill_bits -= 7;
413*15dc779aSAndroid Build Coastguard Worker               }
414*15dc779aSAndroid Build Coastguard Worker             }
415*15dc779aSAndroid Build Coastguard Worker           }
416*15dc779aSAndroid Build Coastguard Worker         }
417*15dc779aSAndroid Build Coastguard Worker       }
418*15dc779aSAndroid Build Coastguard Worker     }
419*15dc779aSAndroid Build Coastguard Worker     switch (aot) {
420*15dc779aSAndroid Build Coastguard Worker       case AOT_AAC_LC:
421*15dc779aSAndroid Build Coastguard Worker       case AOT_SBR:
422*15dc779aSAndroid Build Coastguard Worker       case AOT_PS:
423*15dc779aSAndroid Build Coastguard Worker         *tot_fill_bits = total_fill_bits;
424*15dc779aSAndroid Build Coastguard Worker         break;
425*15dc779aSAndroid Build Coastguard Worker 
426*15dc779aSAndroid Build Coastguard Worker       case AOT_AAC_LD:
427*15dc779aSAndroid Build Coastguard Worker       case AOT_AAC_ELD:
428*15dc779aSAndroid Build Coastguard Worker         pstr_qc_out->total_fill_bits = total_fill_bits;
429*15dc779aSAndroid Build Coastguard Worker         *tot_fill_bits = 0;
430*15dc779aSAndroid Build Coastguard Worker         break;
431*15dc779aSAndroid Build Coastguard Worker     }
432*15dc779aSAndroid Build Coastguard Worker   }  // if flag_last_element
433*15dc779aSAndroid Build Coastguard Worker   else {
434*15dc779aSAndroid Build Coastguard Worker     pstr_qc_out->align_bits = 0;
435*15dc779aSAndroid Build Coastguard Worker   }
436*15dc779aSAndroid Build Coastguard Worker 
437*15dc779aSAndroid Build Coastguard Worker   if ((pstr_qc_out->tot_dyn_bits_used + pstr_qc_out->tot_static_bits_used +
438*15dc779aSAndroid Build Coastguard Worker        pstr_qc_out->tot_anc_bits_used + pstr_qc_out->total_fill_bits + pstr_qc_out->align_bits) >
439*15dc779aSAndroid Build Coastguard Worker       pstr_qc_kernel->max_bits_tot) {
440*15dc779aSAndroid Build Coastguard Worker   }
441*15dc779aSAndroid Build Coastguard Worker 
442*15dc779aSAndroid Build Coastguard Worker   return IA_NO_ERROR;
443*15dc779aSAndroid Build Coastguard Worker }
444*15dc779aSAndroid Build Coastguard Worker 
ia_enhaacplus_enc_adjust_bitrate(ixheaace_qc_state * pstr_qc_state,WORD32 bit_rate,WORD32 sample_rate,WORD32 flag_last_element,WORD32 frame_len_long)445*15dc779aSAndroid Build Coastguard Worker VOID ia_enhaacplus_enc_adjust_bitrate(ixheaace_qc_state *pstr_qc_state, WORD32 bit_rate,
446*15dc779aSAndroid Build Coastguard Worker                                       WORD32 sample_rate, WORD32 flag_last_element,
447*15dc779aSAndroid Build Coastguard Worker                                       WORD32 frame_len_long)
448*15dc779aSAndroid Build Coastguard Worker 
449*15dc779aSAndroid Build Coastguard Worker {
450*15dc779aSAndroid Build Coastguard Worker   WORD32 padding_on;
451*15dc779aSAndroid Build Coastguard Worker   WORD32 frame_len;
452*15dc779aSAndroid Build Coastguard Worker   WORD32 code_bits;
453*15dc779aSAndroid Build Coastguard Worker   WORD32 code_bits_last;
454*15dc779aSAndroid Build Coastguard Worker 
455*15dc779aSAndroid Build Coastguard Worker   padding_on = ia_enhaacplus_enc_frame_padding(
456*15dc779aSAndroid Build Coastguard Worker       bit_rate, sample_rate, &pstr_qc_state->padding.padding_rest, frame_len_long);
457*15dc779aSAndroid Build Coastguard Worker 
458*15dc779aSAndroid Build Coastguard Worker   frame_len = padding_on + ia_enhaacplus_enc_calc_frame_len(bit_rate, sample_rate,
459*15dc779aSAndroid Build Coastguard Worker                                                             FRAME_LEN_BYTES_INT, frame_len_long);
460*15dc779aSAndroid Build Coastguard Worker 
461*15dc779aSAndroid Build Coastguard Worker   frame_len <<= 3;
462*15dc779aSAndroid Build Coastguard Worker 
463*15dc779aSAndroid Build Coastguard Worker   if (flag_last_element) {
464*15dc779aSAndroid Build Coastguard Worker     code_bits_last = pstr_qc_state->average_bits_tot - pstr_qc_state->glob_stat_bits;
465*15dc779aSAndroid Build Coastguard Worker 
466*15dc779aSAndroid Build Coastguard Worker     code_bits = frame_len - pstr_qc_state->glob_stat_bits;
467*15dc779aSAndroid Build Coastguard Worker   } else {
468*15dc779aSAndroid Build Coastguard Worker     code_bits_last = pstr_qc_state->average_bits_tot;
469*15dc779aSAndroid Build Coastguard Worker 
470*15dc779aSAndroid Build Coastguard Worker     code_bits = frame_len;
471*15dc779aSAndroid Build Coastguard Worker   }
472*15dc779aSAndroid Build Coastguard Worker 
473*15dc779aSAndroid Build Coastguard Worker   /* calculate bits for every channel element */
474*15dc779aSAndroid Build Coastguard Worker   if (code_bits != code_bits_last) {
475*15dc779aSAndroid Build Coastguard Worker     WORD32 total_bits = 0;
476*15dc779aSAndroid Build Coastguard Worker 
477*15dc779aSAndroid Build Coastguard Worker     pstr_qc_state->element_bits.average_bits =
478*15dc779aSAndroid Build Coastguard Worker         (WORD32)(pstr_qc_state->element_bits.relative_bits * code_bits);
479*15dc779aSAndroid Build Coastguard Worker 
480*15dc779aSAndroid Build Coastguard Worker     total_bits += pstr_qc_state->element_bits.average_bits;
481*15dc779aSAndroid Build Coastguard Worker 
482*15dc779aSAndroid Build Coastguard Worker     pstr_qc_state->element_bits.average_bits += code_bits - total_bits;
483*15dc779aSAndroid Build Coastguard Worker   }
484*15dc779aSAndroid Build Coastguard Worker 
485*15dc779aSAndroid Build Coastguard Worker   pstr_qc_state->average_bits_tot = frame_len;
486*15dc779aSAndroid Build Coastguard Worker 
487*15dc779aSAndroid Build Coastguard Worker   /* Bits carried over from previous frame due to distribution of fill bits */
488*15dc779aSAndroid Build Coastguard Worker   pstr_qc_state->element_bits.average_bits += pstr_qc_state->element_bits.carry_bits;
489*15dc779aSAndroid Build Coastguard Worker   pstr_qc_state->average_bits_tot += pstr_qc_state->element_bits.carry_bits;
490*15dc779aSAndroid Build Coastguard Worker 
491*15dc779aSAndroid Build Coastguard Worker   /* Flush for current frame */
492*15dc779aSAndroid Build Coastguard Worker   pstr_qc_state->element_bits.carry_bits = 0;
493*15dc779aSAndroid Build Coastguard Worker }
494*15dc779aSAndroid Build Coastguard Worker 
ia_enhaacplus_aac_limitbitrate(WORD32 core_sampling_rate,WORD32 frame_length,WORD32 num_channels,WORD32 bit_rate)495*15dc779aSAndroid Build Coastguard Worker WORD32 ia_enhaacplus_aac_limitbitrate(WORD32 core_sampling_rate, WORD32 frame_length,
496*15dc779aSAndroid Build Coastguard Worker                                       WORD32 num_channels, WORD32 bit_rate) {
497*15dc779aSAndroid Build Coastguard Worker   WORD32 prev_bit_rate, shift = 0, iter = 0;
498*15dc779aSAndroid Build Coastguard Worker   WORD32 max_ch_bits = MAXIMUM_CHANNEL_BITS_1024;
499*15dc779aSAndroid Build Coastguard Worker 
500*15dc779aSAndroid Build Coastguard Worker   while ((frame_length & ~((1 << (shift + 1)) - 1)) == frame_length &&
501*15dc779aSAndroid Build Coastguard Worker          (core_sampling_rate & ~((1 << (shift + 1)) - 1)) == core_sampling_rate) {
502*15dc779aSAndroid Build Coastguard Worker     shift++;
503*15dc779aSAndroid Build Coastguard Worker   }
504*15dc779aSAndroid Build Coastguard Worker 
505*15dc779aSAndroid Build Coastguard Worker   max_ch_bits = MAXIMUM_CHANNEL_BITS_1024 * frame_length / MAX_FRAME_LEN;
506*15dc779aSAndroid Build Coastguard Worker 
507*15dc779aSAndroid Build Coastguard Worker   do {
508*15dc779aSAndroid Build Coastguard Worker     prev_bit_rate = bit_rate;
509*15dc779aSAndroid Build Coastguard Worker 
510*15dc779aSAndroid Build Coastguard Worker     bit_rate = MAX(bit_rate, ((((40 * num_channels) + TRANSPORT_BITS) * (core_sampling_rate)) /
511*15dc779aSAndroid Build Coastguard Worker                               frame_length));
512*15dc779aSAndroid Build Coastguard Worker     bit_rate = MIN(bit_rate, ((num_channels * max_ch_bits) * (core_sampling_rate >> shift)) /
513*15dc779aSAndroid Build Coastguard Worker                                  (frame_length >> shift));
514*15dc779aSAndroid Build Coastguard Worker 
515*15dc779aSAndroid Build Coastguard Worker   } while (prev_bit_rate != bit_rate && iter++ < 3);
516*15dc779aSAndroid Build Coastguard Worker 
517*15dc779aSAndroid Build Coastguard Worker   return bit_rate;
518*15dc779aSAndroid Build Coastguard Worker }
519