xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_enc_init.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 <string.h>
22 #include "ixheaac_type_def.h"
23 #include "ixheaac_constants.h"
24 #include "ixheaace_aac_constants.h"
25 #include "impd_drc_common_enc.h"
26 #include "impd_drc_uni_drc.h"
27 #include "impd_drc_tables.h"
28 #include "impd_drc_api.h"
29 #include "ixheaace_api.h"
30 #include "ixheaac_error_standards.h"
31 #include "ixheaace_error_codes.h"
32 #include "ixheaace_psy_const.h"
33 #include "ixheaace_tns.h"
34 #include "ixheaace_tns_params.h"
35 #include "ixheaace_rom.h"
36 #include "ixheaace_common_rom.h"
37 #include "ixheaace_bitbuffer.h"
38 #include "ixheaac_basic_ops32.h"
39 #include "ixheaac_basic_ops40.h"
40 #include "ixheaac_basic_ops.h"
41 #include "ixheaace_adjust_threshold_data.h"
42 
43 #include "ixheaace_dynamic_bits.h"
44 #include "ixheaace_qc_data.h"
45 #include "ixheaace_channel_map.h"
46 #include "ixheaace_block_switch.h"
47 #include "ixheaace_psy_data.h"
48 #include "ixheaace_interface.h"
49 #include "ixheaace_write_bitstream.h"
50 #include "ixheaace_psy_configuration.h"
51 #include "ixheaace_psy_mod.h"
52 #include "ixheaace_stereo_preproc.h"
53 #include "ixheaace_enc_main.h"
54 #include "ixheaace_qc_util.h"
55 #include "ixheaace_config_params.h"
56 #include "ixheaace_common_utils.h"
57 #define ALIGNMENT_DEFINE __attribute__((aligned(8)))
58 
ixheaace_calculate_bandwidth(const WORD32 sample_rate,const WORD32 channel_bit_rate,const WORD32 num_ch,WORD32 aot)59 static WORD32 ixheaace_calculate_bandwidth(const WORD32 sample_rate,
60                                            const WORD32 channel_bit_rate, const WORD32 num_ch,
61                                            WORD32 aot) {
62   WORD32 bandwidth = -1;
63   const ixheaace_bandwidth_table *pstr_bandwidth_table = NULL;
64   WORD32 bandwidth_table_size = 0;
65   if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
66     pstr_bandwidth_table = bandwidth_table_lc;
67     bandwidth_table_size = sizeof(bandwidth_table_lc) / sizeof(ixheaace_bandwidth_table);
68   } else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) {
69     switch (sample_rate) {
70       case 48000:
71       case 64000:
72       case 88200:
73       case 96000:
74         pstr_bandwidth_table = bandwidth_table_ld_48000;
75         bandwidth_table_size =
76             sizeof(bandwidth_table_ld_48000) / sizeof(ixheaace_bandwidth_table);
77         break;
78       case 44100:
79         pstr_bandwidth_table = bandwidth_table_ld_44100;
80         bandwidth_table_size =
81             sizeof(bandwidth_table_ld_44100) / sizeof(ixheaace_bandwidth_table);
82         break;
83       case 32000:
84         pstr_bandwidth_table = bandwidth_table_ld_32000;
85         bandwidth_table_size =
86             sizeof(bandwidth_table_ld_32000) / sizeof(ixheaace_bandwidth_table);
87         break;
88       case 24000:
89         pstr_bandwidth_table = bandwidth_table_ld_24000;
90         bandwidth_table_size =
91             sizeof(bandwidth_table_ld_24000) / sizeof(ixheaace_bandwidth_table);
92         break;
93       case 8000:
94       case 11025:
95       case 12000:
96       case 16000:
97       case 22050:
98         pstr_bandwidth_table = bandwidth_table_ld_22050;
99         bandwidth_table_size =
100             sizeof(bandwidth_table_ld_22050) / sizeof(ixheaace_bandwidth_table);
101         break;
102     }
103   }
104   for (WORD32 i = 0; i < bandwidth_table_size - 1; i++) {
105     if (channel_bit_rate >= 96000) {
106       if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
107         bandwidth = 20000;
108       } else {
109         if (num_ch == 1) {
110           bandwidth = 19000;
111         } else {
112           bandwidth = 22000;
113         }
114       }
115       break;
116     } else if (channel_bit_rate >= pstr_bandwidth_table[i].channel_bit_rate &&
117                channel_bit_rate < pstr_bandwidth_table[i + 1].channel_bit_rate) {
118       if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
119         bandwidth = (num_ch == 1) ? pstr_bandwidth_table[i].bandwidth_mono
120                                   : pstr_bandwidth_table[i].bandwidth_stereo;
121         bandwidth = bandwidth - (pstr_bandwidth_table[i].channel_bit_rate / 32);
122         break;
123       } else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) {
124         WORD32 start_bandwidth, end_bandwidth, start_bitrate, end_bitrate;
125         FLOAT32 bandwidth_fac;
126         start_bandwidth = (num_ch == 1) ? pstr_bandwidth_table[i].bandwidth_mono
127                                         : pstr_bandwidth_table[i].bandwidth_stereo;
128         start_bandwidth = start_bandwidth - (pstr_bandwidth_table[i].channel_bit_rate / 32);
129         end_bandwidth = (num_ch == 1) ? pstr_bandwidth_table[i + 1].bandwidth_mono
130                                       : pstr_bandwidth_table[i + 1].bandwidth_stereo;
131         end_bandwidth = end_bandwidth - (pstr_bandwidth_table[i + 1].channel_bit_rate / 32);
132         start_bitrate = pstr_bandwidth_table[i].channel_bit_rate;
133         end_bitrate = pstr_bandwidth_table[i + 1].channel_bit_rate;
134         bandwidth_fac =
135             (FLOAT32)((channel_bit_rate - start_bitrate) / (end_bitrate - start_bitrate));
136         bandwidth = (WORD32)(bandwidth_fac * (end_bandwidth - start_bandwidth) + start_bandwidth);
137         break;
138       }
139     }
140   }
141   return bandwidth;
142 }
143 
ixheaace_determine_bandwidth(const WORD32 proposed_bandwidth,const WORD32 bitrate,const WORD32 sample_rate,const WORD32 channels,WORD32 * const bandwidth,WORD32 aot)144 static VOID ixheaace_determine_bandwidth(const WORD32 proposed_bandwidth, const WORD32 bitrate,
145                                          const WORD32 sample_rate, const WORD32 channels,
146                                          WORD32 *const bandwidth, WORD32 aot) {
147   WORD32 channel_bit_rate = bitrate / channels;
148   if (proposed_bandwidth == 0) {
149     *bandwidth = ixheaace_calculate_bandwidth(sample_rate, channel_bit_rate, channels, aot);
150   } else {
151     *bandwidth = MIN(proposed_bandwidth, MIN(20000, sample_rate >> 1));
152   }
153   *bandwidth = MIN(*bandwidth, sample_rate / 2);
154 }
155 
ia_enhaacplus_enc_aac_enc_pers_size(WORD32 num_aac_chan,WORD32 aot)156 WORD32 ia_enhaacplus_enc_aac_enc_pers_size(WORD32 num_aac_chan, WORD32 aot) {
157   WORD32 num_bytes;
158   num_bytes = IXHEAAC_GET_SIZE_ALIGNED(sizeof(iexheaac_encoder_str), BYTE_ALIGN_8);
159   num_bytes += (num_aac_chan *
160     IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_psy_out_channel), BYTE_ALIGN_8));
161   num_bytes += (num_aac_chan *
162     IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_psy_data), BYTE_ALIGN_8));
163   num_bytes += (num_aac_chan *
164     IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_temporal_noise_shaping_data), BYTE_ALIGN_8));
165   if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
166     num_bytes += (num_aac_chan *
167       IXHEAAC_GET_SIZE_ALIGNED(BLK_SWITCH_OFFSET_LC_128 * sizeof(FLOAT32), BYTE_ALIGN_8));
168   } else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) {
169     num_bytes += (num_aac_chan *
170       IXHEAAC_GET_SIZE_ALIGNED(BLK_SWITCH_OFFSET_LD * sizeof(FLOAT32), BYTE_ALIGN_8));
171   }
172 
173   num_bytes += (num_aac_chan *
174     IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_qc_out_channel), BYTE_ALIGN_8));
175   return num_bytes;
176 }
177 
ia_enhaacplus_enc_aac_enc_scr_size(VOID)178 WORD32 ia_enhaacplus_enc_aac_enc_scr_size(VOID) {
179   return IXHEAAC_GET_SIZE_ALIGNED(sizeof(iaace_scratch), BYTE_ALIGN_8);
180 }
181 
ia_enhaacplus_enc_set_shared_bufs(iaace_scratch * scr,WORD32 ** shared_buf1,WORD32 ** shared_buf2,WORD32 ** shared_buf3,WORD8 ** shared_buf5)182 VOID ia_enhaacplus_enc_set_shared_bufs(iaace_scratch *scr, WORD32 **shared_buf1,
183                                        WORD32 **shared_buf2, WORD32 **shared_buf3,
184                                        WORD8 **shared_buf5) {
185   iaace_scratch *pstr_aac_enc_scratch = scr;
186   /* Fill addresses of shared buffers */
187   pstr_aac_enc_scratch->shared_buffer1 = *shared_buf1;
188   pstr_aac_enc_scratch->shared_buffer_2 = *shared_buf2;
189   pstr_aac_enc_scratch->shared_buffer3 = *shared_buf3;
190   pstr_aac_enc_scratch->shared_buffer5 = (WORD8 *)*shared_buf5;
191 }
192 
ia_enhaacplus_enc_aac_init_default_config(iaace_config * config,WORD32 aot)193 VOID ia_enhaacplus_enc_aac_init_default_config(iaace_config *config, WORD32 aot) {
194   memset(config, 0, sizeof(iaace_config));
195 
196   /* default configurations */
197   config->bit_rate = AAC_BITRATE_DEFAULT_VALUE;
198   config->band_width = 0;
199   if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
200     config->inv_quant = 0;
201     config->bitreservoir_size = BITRESERVOIR_SIZE_CONFIG_PARAM_DEFAULT_VALUE_LC;
202   } else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) {
203     config->inv_quant = 2;
204     config->bitreservoir_size = BITRESERVOIR_SIZE_CONFIG_PARAM_DEFAULT_VALUE_LD;
205   }
206   config->use_tns = 0;
207   config->flag_framelength_small =
208       USE_FRAMELENGTH_SMALL_PARAM_DEFAULT_VALUE;  // assume framelength large
209 }
210 
ia_enhaacplus_enc_aac_set_scratch_ptr(iexheaac_encoder_str * pstr_exheaac_encoder,iaace_scratch * pstr_scr)211 static VOID ia_enhaacplus_enc_aac_set_scratch_ptr(iexheaac_encoder_str *pstr_exheaac_encoder,
212                                                   iaace_scratch *pstr_scr) {
213   pstr_exheaac_encoder->pstr_aac_scratch = pstr_scr;
214 }
215 
ia_enhaacplus_enc_init_aac_tabs(ixheaace_aac_tables * pstr_aac_tabs)216 VOID ia_enhaacplus_enc_init_aac_tabs(ixheaace_aac_tables *pstr_aac_tabs) {
217   pstr_aac_tabs->pstr_mdct_tab = (ixheaace_mdct_tables *)&ixheaace_enc_mdct_tab;
218   pstr_aac_tabs->pstr_huff_tab = (ixheaace_huffman_tables *)&ixheaace_enc_huff_tab;
219   pstr_aac_tabs->pstr_psycho_tab = (ixheaace_psycho_tables *)&ixheaace_enc_psycho_tab;
220   pstr_aac_tabs->pstr_quant_tab = (ixheaace_quant_tables *)&ixheaace_enc_quant_tab;
221   pstr_aac_tabs->pstr_tns_tab =
222       (ixheaace_temporal_noise_shaping_tables *)&ixheaace_enhaacplus_enc_tns_tab;
223 }
224 
ia_enhaacplus_enc_aac_set_persist_buf(WORD8 * ptr_base,WORD32 num_chan,WORD32 aot)225 static VOID ia_enhaacplus_enc_aac_set_persist_buf(WORD8 *ptr_base, WORD32 num_chan, WORD32 aot) {
226   iexheaac_encoder_str *pstr_exheaac_encoder;
227   WORD8 *ptr_curr_mem = ptr_base +
228     IXHEAAC_GET_SIZE_ALIGNED(sizeof(iexheaac_encoder_str), BYTE_ALIGN_8);
229   WORD32 i;
230 
231   pstr_exheaac_encoder = (iexheaac_encoder_str *)ptr_base;
232 
233   for (i = 0; i < num_chan; i++) {
234     pstr_exheaac_encoder->psy_out.psy_out_ch[i] = (ixheaace_psy_out_channel *)(ptr_curr_mem);
235     ptr_curr_mem = ptr_curr_mem +
236       IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_psy_out_channel), BYTE_ALIGN_8);
237   }
238 
239   for (i = 0; i < num_chan; i++) {
240     pstr_exheaac_encoder->psy_kernel.psy_data[i] = (ixheaace_psy_data *)(ptr_curr_mem);
241     ptr_curr_mem = ptr_curr_mem +
242       IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_psy_data), BYTE_ALIGN_8);
243   }
244 
245   for (i = 0; i < num_chan; i++) {
246     pstr_exheaac_encoder->psy_kernel.temporal_noise_shaping_data[i] =
247         (ixheaace_temporal_noise_shaping_data *)(ptr_curr_mem);
248     ptr_curr_mem = ptr_curr_mem +
249       IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_temporal_noise_shaping_data), BYTE_ALIGN_8);
250   }
251 
252   for (i = 0; i < num_chan; i++) {
253     switch (aot) {
254       case AOT_AAC_LC:
255       case AOT_SBR:
256       case AOT_PS:
257         pstr_exheaac_encoder->psy_kernel.psy_data[i]->ptr_mdct_delay_buf =
258             (FLOAT32 *)(ptr_curr_mem);
259         ptr_curr_mem = ptr_curr_mem +
260           IXHEAAC_GET_SIZE_ALIGNED(sizeof(FLOAT32) * BLK_SWITCH_OFFSET_LC_128, BYTE_ALIGN_8);
261         break;
262 
263       case AOT_AAC_LD:
264       case AOT_AAC_ELD:
265         pstr_exheaac_encoder->psy_kernel.psy_data[i]->ptr_mdct_delay_buf =
266             (FLOAT32 *)(ptr_curr_mem);
267         ptr_curr_mem = ptr_curr_mem +
268           IXHEAAC_GET_SIZE_ALIGNED(sizeof(FLOAT32) * BLK_SWITCH_OFFSET_LD, BYTE_ALIGN_8);
269         break;
270     }
271   }
272 
273   for (i = 0; i < num_chan; i++) {
274     pstr_exheaac_encoder->qc_out.qc_channel[i] = (ixheaace_qc_out_channel *)(ptr_curr_mem);
275     ptr_curr_mem = ptr_curr_mem +
276       IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_qc_out_channel), BYTE_ALIGN_8);
277   }
278 }
279 
ia_enhaacplus_enc_aac_enc_open(iexheaac_encoder_str ** ppstr_exheaac_encoder,const iaace_config config,iaace_scratch * pstr_aac_scratch,ixheaace_aac_tables * pstr_aac_tabs,WORD32 ele_type,WORD32 element_instance_tag,WORD32 aot)280 IA_ERRORCODE ia_enhaacplus_enc_aac_enc_open(iexheaac_encoder_str **ppstr_exheaac_encoder,
281                                             const iaace_config config,
282                                             iaace_scratch *pstr_aac_scratch,
283                                             ixheaace_aac_tables *pstr_aac_tabs, WORD32 ele_type,
284                                             WORD32 element_instance_tag, WORD32 aot) {
285   IA_ERRORCODE error = IA_NO_ERROR;
286   WORD32 profile = 1;
287   ixheaace_element_info *pstr_element_info = NULL;
288   iexheaac_encoder_str *pstr_exheaac_encoder;
289   WORD32 frame_len_long = FRAME_LEN_1024;
290   switch (aot) {
291     case AOT_AAC_LC:
292     case AOT_SBR:
293     case AOT_PS:
294       if (config.flag_framelength_small) {
295         frame_len_long = FRAME_LEN_960;
296       } else {
297         frame_len_long = FRAME_LEN_1024;
298       }
299       break;
300 
301     case AOT_AAC_LD:
302     case AOT_AAC_ELD:
303       if (config.flag_framelength_small) {
304         frame_len_long = FRAME_LEN_480;
305       } else {
306         frame_len_long = FRAME_LEN_512;
307       }
308       break;
309   }
310 
311   if ((config.num_in_channels < 1) || (config.num_out_channels > IXHEAACE_MAX_CH_IN_BS_ELE) ||
312     (config.num_out_channels < 1) || (config.num_in_channels < config.num_out_channels)) {
313     return IA_EXHEAACE_INIT_FATAL_INVALID_NUM_CHANNELS_IN_ELE;
314   }
315   if ((config.bit_rate != 0) && ((config.bit_rate / config.num_out_channels < 8000) ||
316     (config.bit_rate / config.num_out_channels > 576000))) {
317     error = IA_EXHEAACE_INIT_FATAL_BITRATE_NOT_SUPPORTED;
318   }
319   if (error != IA_NO_ERROR) {
320     return error;
321   }
322 
323   pstr_exheaac_encoder = *ppstr_exheaac_encoder;
324 
325   memset(pstr_exheaac_encoder, 0, sizeof(iexheaac_encoder_str));
326 
327   ia_enhaacplus_enc_aac_set_scratch_ptr(pstr_exheaac_encoder, pstr_aac_scratch);
328 
329   ia_enhaacplus_enc_aac_set_persist_buf((WORD8 *)pstr_exheaac_encoder, config.num_out_channels,
330                                         aot);
331 
332   /* check sample rate */
333 
334   switch (config.core_sample_rate) {
335     case 8000:
336     case 11025:
337     case 12000:
338     case 16000:
339     case 22050:
340     case 24000:
341     case 32000:
342     case 44100:
343     case 48000:
344     case 64000:
345     case 88200:
346     case 96000:
347       break;
348 
349     default:
350       return IA_EXHEAACE_INIT_FATAL_INVALID_CORE_SAMPLE_RATE;
351       break;
352   }
353 
354   pstr_exheaac_encoder->config = config;
355 
356   error = ia_enhaacplus_enc_init_element_info(config.num_out_channels,
357                                               &pstr_exheaac_encoder->element_info, ele_type,
358                                               element_instance_tag);
359   if (error != IA_NO_ERROR) {
360     return error;
361   }
362 
363   pstr_element_info = &pstr_exheaac_encoder->element_info;
364 
365   /* allocate the Psy aud Psy Out structure */
366 
367   error = (ia_enhaacplus_enc_psy_new(
368       &pstr_exheaac_encoder->psy_kernel, pstr_element_info->n_channels_in_el,
369       pstr_exheaac_encoder->pstr_aac_scratch->shared_buffer_2, frame_len_long));
370 
371   if (error != IA_NO_ERROR) {
372     return error;
373   }
374 
375   WORD32 tns_mask = config.use_tns;
376   if (config.full_bandwidth) {
377     pstr_exheaac_encoder->config.band_width = config.core_sample_rate >> 2;
378   } else {
379     ixheaace_determine_bandwidth(pstr_exheaac_encoder->config.band_width, config.bit_rate,
380                                  config.core_sample_rate, pstr_element_info->n_channels_in_el,
381                                  &pstr_exheaac_encoder->config.band_width, aot);
382   }
383   pstr_exheaac_encoder->bandwidth_90_dB = (WORD32)pstr_exheaac_encoder->config.band_width;
384   if (ele_type == ID_LFE) {
385     tns_mask = 0;
386   }
387 
388   error = ia_enhaacplus_enc_psy_main_init(
389       &pstr_exheaac_encoder->psy_kernel, config.core_sample_rate, config.bit_rate,
390       pstr_element_info->n_channels_in_el, tns_mask, pstr_exheaac_encoder->bandwidth_90_dB, aot,
391       pstr_aac_tabs, frame_len_long);
392   if (error != IA_NO_ERROR) {
393     return error;
394   }
395 
396   /* allocate the Q&C Out structure */
397   error = ia_enhaacplus_enc_qc_out_new(
398       &pstr_exheaac_encoder->qc_out, pstr_element_info->n_channels_in_el,
399       pstr_exheaac_encoder->pstr_aac_scratch->shared_buffer1,
400       pstr_exheaac_encoder->pstr_aac_scratch->shared_buffer3, frame_len_long);
401 
402   if (error != IA_NO_ERROR) {
403     return error;
404   }
405 
406   /* allocate the Q&C kernel */
407   error = ia_enhaacplus_enc_qc_new(&pstr_exheaac_encoder->qc_kernel,
408                                    pstr_exheaac_encoder->pstr_aac_scratch->shared_buffer_2,
409                                    frame_len_long);
410   if (error != IA_NO_ERROR) {
411     return error;
412   }
413 
414   ixheaace_qc_init qc_init;
415 
416   qc_init.pstr_element_info = &pstr_exheaac_encoder->element_info;
417 
418   if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
419     if (config.flag_framelength_small) {
420       qc_init.max_bits = MAXIMUM_CHANNEL_BITS_960 * pstr_element_info->n_channels_in_el;
421     } else {
422       qc_init.max_bits = MAXIMUM_CHANNEL_BITS_1024 * pstr_element_info->n_channels_in_el;
423     }
424 
425     qc_init.bit_res = qc_init.max_bits;
426   }
427 
428   qc_init.average_bits = (config.bit_rate * frame_len_long) / config.core_sample_rate;
429 
430   if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) {
431     if (pstr_exheaac_encoder->config.bitreservoir_size != -1) {
432       qc_init.max_bits = (pstr_exheaac_encoder->config.bitreservoir_size * 8) *
433                          pstr_element_info->n_channels_in_el;
434       if (qc_init.max_bits > qc_init.average_bits) {
435         qc_init.bit_res = (pstr_exheaac_encoder->config.bitreservoir_size * 8) *
436                           pstr_element_info->n_channels_in_el;
437       } else {
438         qc_init.max_bits = qc_init.average_bits;
439         qc_init.bit_res = 0;
440       }
441     } else {
442       qc_init.max_bits = qc_init.average_bits;
443       qc_init.bit_res = 0;
444     }
445   }
446 
447   qc_init.padding.padding_rest = config.core_sample_rate;
448 
449   qc_init.mean_pe = ((FLOAT32)10 * frame_len_long * pstr_exheaac_encoder->bandwidth_90_dB * 2) /
450                     config.core_sample_rate;
451 
452   switch (aot) {
453     case AOT_AAC_LC:
454     case AOT_SBR:
455     case AOT_PS:
456       if (config.flag_framelength_small) {
457         qc_init.max_bit_fac =
458             (float)(MAXIMUM_CHANNEL_BITS_960 * pstr_element_info->n_channels_in_el) /
459             (float)(qc_init.average_bits ? qc_init.average_bits : 1);
460       } else {
461         qc_init.max_bit_fac =
462             (float)(MAXIMUM_CHANNEL_BITS_1024 * pstr_element_info->n_channels_in_el) /
463             (float)(qc_init.average_bits ? qc_init.average_bits : 1);
464       }
465       break;
466 
467     case AOT_AAC_LD:
468     case AOT_AAC_ELD:
469       if (config.flag_framelength_small) {
470         qc_init.max_bit_fac = (FLOAT32)((MAXIMUM_CHANNEL_BITS_480)*pstr_element_info
471                                             ->n_channels_in_el);  // no anc data in aacld
472       } else {
473         qc_init.max_bit_fac = (FLOAT32)((MAXIMUM_CHANNEL_BITS_512)*pstr_element_info
474                                             ->n_channels_in_el);  // no anc data in aacld
475       }
476       qc_init.max_bit_fac =
477           qc_init.max_bit_fac / (qc_init.average_bits ? qc_init.average_bits : 1);
478       break;
479   }
480 
481   qc_init.bitrate = config.bit_rate;
482   qc_init.inv_quant = config.inv_quant;
483 
484   error = ia_enhaacplus_enc_qc_init(&pstr_exheaac_encoder->qc_kernel, aot, &qc_init,
485                                     config.flag_framelength_small);
486   if (error != IA_NO_ERROR) {
487     return error;
488   }
489 
490   /* init bitstream encoder */
491   pstr_exheaac_encoder->bse_init.num_channels = pstr_element_info->n_channels_in_el;
492   pstr_exheaac_encoder->bse_init.bitrate = config.bit_rate;
493   pstr_exheaac_encoder->bse_init.sample_rate = config.core_sample_rate;
494   pstr_exheaac_encoder->bse_init.profile = profile;
495 
496   if (config.num_in_channels > config.num_out_channels) {
497     pstr_exheaac_encoder->downmix = 1;
498     pstr_exheaac_encoder->downmix_fac = config.num_in_channels / config.num_out_channels;
499   }
500 
501   if (pstr_element_info->el_type == ID_CPE &&
502       (config.core_sample_rate <= 24000 &&
503        (config.bit_rate / pstr_element_info->n_channels_in_el * 2) < 60000)) {
504     FLOAT32 scf_used_ratio = (FLOAT32)pstr_exheaac_encoder->psy_kernel.psy_conf_long.sfb_active /
505                              pstr_exheaac_encoder->psy_kernel.psy_conf_long.sfb_cnt;
506 
507     error = iaace_init_stereo_pre_processing(&(pstr_exheaac_encoder->str_stereo_pre_pro),
508                                              pstr_element_info->n_channels_in_el, config.bit_rate,
509                                              config.core_sample_rate, scf_used_ratio);
510   }
511 
512   if (error != IA_NO_ERROR) {
513     return error;
514   }
515 
516   *ppstr_exheaac_encoder = pstr_exheaac_encoder;
517 
518   return IA_NO_ERROR;
519 }
520