xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_api.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 <stdlib.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include "ixheaac_type_def.h"
25 #include "ixheaac_constants.h"
26 #include "ixheaace_aac_constants.h"
27 #include "ixheaac_basic_ops32.h"
28 #include "ixheaac_basic_ops16.h"
29 #include "ixheaac_basic_ops40.h"
30 #include "ixheaac_basic_ops.h"
31 /* standard */
32 #include "ixheaac_error_standards.h"
33 
34 #include "ixheaace_config_params.h"
35 
36 /* library */
37 #include "ixheaace_definitions.h"
38 #include "ixheaace_error_codes.h"
39 
40 #include "iusace_bitbuffer.h"
41 
42 /* DRC */
43 #include "impd_drc_common_enc.h"
44 #include "impd_drc_uni_drc.h"
45 #include "impd_drc_tables.h"
46 #include "impd_drc_api.h"
47 #include "impd_drc_uni_drc_eq.h"
48 #include "impd_drc_uni_drc_filter_bank.h"
49 #include "impd_drc_gain_enc.h"
50 #include "impd_drc_struct_def.h"
51 #include "impd_drc_enc.h"
52 
53 #include "ixheaace_sbr_header.h"
54 #include "ixheaace_sbr_def.h"
55 #include "ixheaace_resampler.h"
56 
57 #include "ixheaace_psy_const.h"
58 #include "ixheaace_tns.h"
59 #include "ixheaace_tns_params.h"
60 #include "ixheaace_rom.h"
61 #include "ixheaace_common_rom.h"
62 #include "ixheaace_bitbuffer.h"
63 
64 #include "ixheaace_sbr_rom.h"
65 #include "ixheaace_common_rom.h"
66 #include "ixheaace_sbr_main.h"
67 #include "ixheaace_definitions.h"
68 #include "ixheaace_api.h"
69 #include "ixheaace_memory_standards.h"
70 #include "iusace_block_switch_const.h"
71 #include "iusace_block_switch_struct_def.h"
72 #include "iusace_cnst.h"
73 #include "iusace_tns_usac.h"
74 #include "iusace_psy_mod.h"
75 #include "iusace_config.h"
76 #include "iusace_arith_enc.h"
77 #include "ixheaace_version_number.h"
78 
79 #include "ixheaace_adjust_threshold_data.h"
80 #include "ixheaace_dynamic_bits.h"
81 #include "ixheaace_qc_data.h"
82 #include "ixheaace_channel_map.h"
83 #include "ixheaace_block_switch.h"
84 #include "ixheaace_psy_data.h"
85 #include "ixheaace_interface.h"
86 #include "ixheaace_write_bitstream.h"
87 #include "ixheaace_psy_configuration.h"
88 #include "ixheaace_common_rom.h"
89 
90 #include "ixheaace_psy_mod.h"
91 #include "iusace_fd_qc_util.h"
92 #include "iusace_fd_quant.h"
93 #include "iusace_ms.h"
94 #include "iusace_signal_classifier.h"
95 #include "ixheaace_sbr_header.h"
96 
97 #include "ixheaace_config.h"
98 #include "ixheaace_asc_write.h"
99 #include "iusace_main.h"
100 #include "ixheaace_stereo_preproc.h"
101 #include "ixheaace_enc_main.h"
102 #include "ixheaace_qc_util.h"
103 
104 // MPS header
105 #include "ixheaace_mps_common_fix.h"
106 #include "ixheaace_mps_defines.h"
107 #include "ixheaace_mps_common_define.h"
108 
109 #include "ixheaace_mps_struct_def.h"
110 #include "ixheaace_mps_sac_polyphase.h"
111 #include "ixheaace_mps_sac_hybfilter.h"
112 #include "ixheaace_mps_bitstream.h"
113 #include "ixheaace_mps_spatial_bitstream.h"
114 
115 #include "ixheaace_mps_buf.h"
116 #include "ixheaace_mps_lib.h"
117 #include "ixheaace_mps_main_structure.h"
118 #include "ixheaace_mps_onset_detect.h"
119 
120 #include "ixheaace_mps_param_extract.h"
121 
122 #include "ixheaace_mps_static_gain.h"
123 #include "ixheaace_mps_filter.h"
124 #include "ixheaace_mps_delay.h"
125 #include "ixheaace_mps_dmx_tdom_enh.h"
126 #include "ixheaace_mps_main_structure.h"
127 #include "ixheaace_mps_tools_rom.h"
128 #include "ixheaace_mps_qmf.h"
129 #include "ixheaace_mps_tree.h"
130 #include "ixheaace_mps_frame_windowing.h"
131 
132 #include "ixheaace_mps_structure.h"
133 #include "ixheaace_mps_memory.h"
134 #include "ixheaace_mps_enc.h"
135 #include "ixheaace_struct_def.h"
136 #include "ixheaace_api_defs.h"
137 
138 #include "ixheaace_write_adts_adif.h"
139 #include "ixheaace_loudness_measurement.h"
140 #include "iusace_psy_utils.h"
141 
iusace_scratch_size(VOID)142 static WORD32 iusace_scratch_size(VOID) {
143   WORD32 scr_size;
144   scr_size = IXHEAAC_GET_SIZE_ALIGNED(USACE_MAX_SCR_SIZE, BYTE_ALIGN_8);
145   return scr_size;
146 }
147 
iusace_calc_pers_buf_sizes(ixheaace_api_struct * pstr_api_struct)148 static WORD32 iusace_calc_pers_buf_sizes(ixheaace_api_struct *pstr_api_struct) {
149   WORD32 pers_size = 0;
150   ia_usac_encoder_config_struct *pstr_config = &pstr_api_struct->config[0].usac_config;
151 
152   pers_size += IXHEAAC_GET_SIZE_ALIGNED(pstr_config->channels * sizeof(FLOAT32 *), BYTE_ALIGN_8);
153   pers_size += IXHEAAC_GET_SIZE_ALIGNED(pstr_config->channels * sizeof(FLOAT32 *), BYTE_ALIGN_8);
154   pers_size += IXHEAAC_GET_SIZE_ALIGNED(pstr_config->channels * sizeof(FLOAT32 *), BYTE_ALIGN_8);
155   pers_size += IXHEAAC_GET_SIZE_ALIGNED(pstr_config->channels * sizeof(FLOAT32 *), BYTE_ALIGN_8);
156 
157   pers_size +=
158       (IXHEAAC_GET_SIZE_ALIGNED((2 * pstr_config->ccfl * sizeof(FLOAT32)), BYTE_ALIGN_8) *
159        pstr_config->channels);
160   pers_size += (IXHEAAC_GET_SIZE_ALIGNED((2 * pstr_config->drc_frame_size * sizeof(FLOAT32)),
161                                           BYTE_ALIGN_8) *
162                 pstr_config->channels);
163 
164   pers_size +=
165       (IXHEAAC_GET_SIZE_ALIGNED((2 * pstr_config->ccfl * sizeof(FLOAT64)), BYTE_ALIGN_8) *
166        pstr_config->channels);
167 
168   pers_size += (IXHEAAC_GET_SIZE_ALIGNED((pstr_config->ccfl * sizeof(FLOAT64)), BYTE_ALIGN_8) *
169                 pstr_config->channels);
170 
171   pers_size +=
172       (IXHEAAC_GET_SIZE_ALIGNED((2 * pstr_config->ccfl * sizeof(FLOAT64)), BYTE_ALIGN_8) *
173        pstr_config->channels);
174 
175   pers_size +=
176       (IXHEAAC_GET_SIZE_ALIGNED((3 * pstr_config->ccfl * sizeof(FLOAT64)), BYTE_ALIGN_8) *
177        pstr_config->channels);
178 
179   if (pstr_config->tns_select != 0) {
180     pers_size +=
181         (IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_tns_info), BYTE_ALIGN_8) * pstr_config->channels);
182   }
183 
184   pers_size += (IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_usac_td_encoder_struct), BYTE_ALIGN_8) *
185                 pstr_config->channels);
186   return pers_size;
187 }
188 
ia_enhaacplus_enc_sizeof_delay_buffer(FLAG flag_framelength_small,WORD32 aot,WORD32 resamp_idx,WORD32 delay_buf_size,FLAG mps_enable)189 static WORD32 ia_enhaacplus_enc_sizeof_delay_buffer(FLAG flag_framelength_small, WORD32 aot,
190                                                     WORD32 resamp_idx, WORD32 delay_buf_size,
191                                                     FLAG mps_enable) {
192   WORD32 downsample_fac;
193   if (resamp_idx > 1) {
194     downsample_fac = resamp_idx / 2;
195   } else {
196     downsample_fac = 1;
197   }
198   // Set the downsampler delay
199   WORD32 max_downsamp_delay, max_upsamp_delay;
200   if (resamp_idx == 2)  // 8:3
201   {
202     max_downsamp_delay = MAXIMUM_DS_8_1_FILTER_DELAY;
203     max_upsamp_delay = MAXIMUM_DS_1_3_FILTER_DELAY;
204   } else if (resamp_idx == 3)  // 2:1
205   {
206     max_downsamp_delay = MAXIMUM_DS_2_1_FILTER_DELAY;
207     max_upsamp_delay = 0;
208   } else if (resamp_idx == 4)  // 4:1
209   {
210     max_downsamp_delay = MAXIMUM_DS_4_1_FILTER_DELAY;
211     max_upsamp_delay = 0;
212   } else {
213     max_downsamp_delay = MAXIMUM_DS_2_1_FILTER_DELAY;
214     max_upsamp_delay = 0;
215   }
216 
217   if (aot == AOT_SBR || aot == AOT_PS) {
218     if (flag_framelength_small)
219       return (FRAME_LEN_960 * (1 << downsample_fac) + max_upsamp_delay + max_downsamp_delay +
220               INPUT_DELAY_LC) *
221              IXHEAACE_MAX_CH_IN_BS_ELE * delay_buf_size;
222     else
223       return (FRAME_LEN_1024 * (1 << downsample_fac) + max_upsamp_delay + max_downsamp_delay +
224               INPUT_DELAY_LC) *
225              IXHEAACE_MAX_CH_IN_BS_ELE * delay_buf_size;
226   } else if (aot == AOT_AAC_LC) {
227     if (flag_framelength_small)
228       return (FRAME_LEN_960 * 2 + MAXIMUM_DS_2_1_FILTER_DELAY + INPUT_DELAY_LC) *
229              IXHEAACE_MAX_CH_IN_BS_ELE * delay_buf_size;
230     else
231       return (FRAME_LEN_1024 * 2 + MAXIMUM_DS_2_1_FILTER_DELAY + INPUT_DELAY_LC) *
232              IXHEAACE_MAX_CH_IN_BS_ELE * delay_buf_size;
233   } else if (aot == AOT_USAC) {
234     return (FRAME_LEN_1024 * (1 << downsample_fac) + max_upsamp_delay + max_downsamp_delay +
235             INPUT_DELAY_LC) *
236            IXHEAACE_MAX_CH_IN_BS_ELE * delay_buf_size;
237   } else if (aot == AOT_AAC_LD) {
238     if (flag_framelength_small)
239       return (FRAME_LEN_480 * 2 + MAXIMUM_DS_2_1_FILTER_DELAY + INPUT_DELAY_LD_480) *
240              IXHEAACE_MAX_CH_IN_BS_ELE * delay_buf_size;
241     else
242       return (FRAME_LEN_512 * 2 + MAXIMUM_DS_2_1_FILTER_DELAY + INPUT_DELAY_LD_512) *
243              IXHEAACE_MAX_CH_IN_BS_ELE * delay_buf_size;
244   } else if (aot == AOT_AAC_ELD) {
245     if (flag_framelength_small) {
246       if (mps_enable) {
247         return (FRAME_LEN_480 * (1 << downsample_fac) + max_upsamp_delay + max_downsamp_delay +
248                 INPUT_DELAY_ELDV2_480) *
249                IXHEAACE_MAX_CH_IN_BS_ELE * delay_buf_size;
250       } else {
251         return (FRAME_LEN_480 * (1 << downsample_fac) + max_upsamp_delay + max_downsamp_delay +
252                 INPUT_DELAY_ELD_480) *
253                IXHEAACE_MAX_CH_IN_BS_ELE * delay_buf_size;
254       }
255     } else {
256       if (mps_enable) {
257         return (FRAME_LEN_512 * (1 << downsample_fac) + max_upsamp_delay + max_downsamp_delay +
258                 INPUT_DELAY_ELDV2_512) *
259                IXHEAACE_MAX_CH_IN_BS_ELE * delay_buf_size;
260       } else {
261         return (FRAME_LEN_512 * (1 << downsample_fac) + max_upsamp_delay + max_downsamp_delay +
262                 INPUT_DELAY_ELD_512) *
263                IXHEAACE_MAX_CH_IN_BS_ELE * delay_buf_size;
264       }
265     }
266   } else {
267     // return LC Delay buffer size by default
268     return (FRAME_LEN_1024 * 2 + MAXIMUM_DS_2_1_FILTER_DELAY + INPUT_DELAY_LC) *
269            IXHEAACE_MAX_CH_IN_BS_ELE * delay_buf_size;
270   }
271 }
272 
ia_enhaacplus_enc_find_slots_for_elements(WORD32 i_channel_mask,WORD32 * slots_for_elements,WORD32 i_num_coupling_chan)273 static VOID ia_enhaacplus_enc_find_slots_for_elements(WORD32 i_channel_mask,
274                                                       WORD32 *slots_for_elements,
275                                                       WORD32 i_num_coupling_chan) {
276   WORD32 slot = 0, i;
277 
278   if ((i_channel_mask & 0x3)) {
279     slots_for_elements[FRONT_LEFT_RIGHT] = slot;
280     slot += 2;
281   }
282 
283   if ((i_channel_mask & 0x4)) {
284     slots_for_elements[FRONT_CENTER] = slot;
285     slot += 1;
286   }
287 
288   if ((i_channel_mask & 0x8)) {
289     slots_for_elements[LFE_CHANNEL] = slot;
290     slot += 1;
291   }
292 
293   if ((i_channel_mask & 0x30)) {
294     slots_for_elements[BACK_LEFT_RIGHT] = slot;
295     slot += 2;
296   }
297 
298   if ((i_channel_mask & 0x100)) {
299     slots_for_elements[REAR_CENTER] = slot;
300     slot += 1;
301   }
302 
303   if (i_num_coupling_chan != 0) {
304     for (i = 0; i < i_num_coupling_chan; i++) {
305       slots_for_elements[COUPLING_CH + i] = slot;
306       slot += 1;
307     }
308   }
309 
310   return;
311 }
312 
ia_enhaacplus_enc_find_channel_config(WORD32 * num_bs_elements,WORD32 * chan_config,WORD32 * element_type,WORD32 * element_slot,WORD32 * element_instance_tag,WORD32 i_num_coupling_chan,WORD32 i_channel_mask)313 static VOID ia_enhaacplus_enc_find_channel_config(WORD32 *num_bs_elements, WORD32 *chan_config,
314                                                   WORD32 *element_type, WORD32 *element_slot,
315                                                   WORD32 *element_instance_tag,
316                                                   WORD32 i_num_coupling_chan,
317                                                   WORD32 i_channel_mask) {
318   WORD32 i;
319   WORD32 slots_for_elements[2 * MAXIMUM_BS_ELE];
320   *num_bs_elements = 0;
321 
322   ia_enhaacplus_enc_find_slots_for_elements(i_channel_mask, slots_for_elements,
323                                             i_num_coupling_chan);
324 
325   if ((i_channel_mask & 0x4)) {
326     /*Front Center Present*/
327     chan_config[*num_bs_elements] = 1;
328     element_type[*num_bs_elements] = ID_SCE;
329     element_slot[*num_bs_elements] = slots_for_elements[FRONT_CENTER];
330     element_instance_tag[*num_bs_elements] = 0;
331     (*num_bs_elements)++;
332   }
333 
334   if ((i_channel_mask & 0x3)) {
335     /*Front Left and Right Present*/
336     chan_config[*num_bs_elements] = 2;
337     element_type[*num_bs_elements] = ID_CPE;
338     element_slot[*num_bs_elements] = slots_for_elements[FRONT_LEFT_RIGHT];
339     element_instance_tag[*num_bs_elements] = 0;
340     (*num_bs_elements)++;
341   }
342 
343   if ((i_channel_mask & 0x30)) {
344     /*Back Left and Right Present*/
345     chan_config[*num_bs_elements] = 2;
346     element_type[*num_bs_elements] = ID_CPE;
347     element_slot[*num_bs_elements] = slots_for_elements[BACK_LEFT_RIGHT];
348     element_instance_tag[*num_bs_elements] = 1;
349     (*num_bs_elements)++;
350   }
351 
352   if ((i_channel_mask & 0x100)) {
353     /* Rear Center Present*/
354     chan_config[*num_bs_elements] = 1;
355     element_type[*num_bs_elements] = ID_SCE;
356     element_slot[*num_bs_elements] = slots_for_elements[REAR_CENTER];
357     element_instance_tag[*num_bs_elements] = 1;
358     (*num_bs_elements)++;
359   }
360 
361   if ((i_channel_mask & 0x8)) {
362     /*LFE channel Present*/
363     chan_config[*num_bs_elements] = 1;
364     element_type[*num_bs_elements] = ID_LFE;
365     element_slot[*num_bs_elements] = slots_for_elements[LFE_CHANNEL];
366     element_instance_tag[*num_bs_elements] = 0;
367     (*num_bs_elements)++;
368   }
369 
370   if (i_num_coupling_chan != 0) {
371     for (i = 0; i < i_num_coupling_chan; i++) {
372       /*Coupling Channel Present*/
373       chan_config[*num_bs_elements] = 1;
374       element_type[*num_bs_elements] = ID_CCE;
375       element_slot[*num_bs_elements] = slots_for_elements[COUPLING_CH + i];
376       element_instance_tag[*num_bs_elements] = i_num_coupling_chan - i - 1;
377       (*num_bs_elements)++;
378     }
379   }
380 }
381 
ia_enhaacplus_enc_allocate_bitrate_between_channels(ixheaace_api_struct * pstr_api_struct,WORD32 * bitrate,WORD32 inp_bitrate)382 static VOID ia_enhaacplus_enc_allocate_bitrate_between_channels(
383     ixheaace_api_struct *pstr_api_struct, WORD32 *bitrate, WORD32 inp_bitrate) {
384   WORD32 ele_idx;
385   WORD32 num_lfe = 0, num_mono = 0, num_stereo = 0;
386   WORD32 bitrate_per_stereo, bitrate_per_mono;
387   for (ele_idx = 0; ele_idx < pstr_api_struct->config[0].num_bs_elements; ele_idx++) {
388     switch (pstr_api_struct->config[ele_idx].element_type) {
389       case ID_SCE:
390       case ID_CCE:
391         num_mono++;
392         break;
393       case ID_CPE:
394         num_stereo++;
395         break;
396       case ID_LFE:
397         num_lfe++;
398         break;
399       default:
400         return;
401     }
402   }
403   bitrate_per_stereo = (WORD32)((inp_bitrate - (num_lfe)*8000) / (num_mono * 0.625 + num_stereo));
404   bitrate_per_mono = (WORD32)(0.625 * bitrate_per_stereo);
405   for (ele_idx = 0; ele_idx < pstr_api_struct->config[0].num_bs_elements; ele_idx++) {
406     switch (pstr_api_struct->config[ele_idx].element_type) {
407       case ID_SCE:
408       case ID_CCE:
409         bitrate[ele_idx] = bitrate_per_mono;
410         break;
411       case ID_CPE:
412         bitrate[ele_idx] = bitrate_per_stereo;
413         break;
414       case ID_LFE:
415         bitrate[ele_idx] = 8000;
416         break;
417       default:
418         return;
419     }
420   }
421 }
422 
ixheaace_validate_channel_mask(WORD32 ch_mask,WORD32 num_ch)423 static IA_ERRORCODE ixheaace_validate_channel_mask(WORD32 ch_mask, WORD32 num_ch) {
424   IA_ERRORCODE err_code = IA_NO_ERROR;
425   // If ch_mask not supported, return error
426   WORD32 temp_mask;
427   switch (num_ch) {
428     case 1:
429       temp_mask = CH_MASK_CENTER_FRONT;
430       break;
431     case 2:
432       temp_mask = CH_MASK_LEFT_RIGHT_FRONT;
433       break;
434     case 3:
435       temp_mask = CH_MASK_CENTER_FRONT | CH_MASK_LEFT_RIGHT_FRONT;
436       break;
437     case 4:
438       temp_mask = CH_MASK_CENTER_FRONT | CH_MASK_LEFT_RIGHT_FRONT | CH_MASK_REAR_CENTER;
439       break;
440     case 5:
441       temp_mask = CH_MASK_CENTER_FRONT | CH_MASK_LEFT_RIGHT_FRONT | CH_MASK_LEFT_RIGHT_BACK;
442       break;
443     case 6:
444       temp_mask =
445           CH_MASK_CENTER_FRONT | CH_MASK_LEFT_RIGHT_FRONT | CH_MASK_LEFT_RIGHT_BACK | CH_MASK_LFE;
446       break;
447     default:
448       temp_mask = 0;
449       break;
450   }
451   if (ch_mask != temp_mask) {
452     err_code =  IA_EXHEAACE_CONFIG_FATAL_CHANNELS_MASK;
453   }
454   return err_code;
455 }
456 
ixheaace_set_default_channel_mask(WORD32 * ch_mask,WORD32 num_ch)457 static VOID ixheaace_set_default_channel_mask(WORD32 *ch_mask, WORD32 num_ch) {
458   switch (num_ch) {
459   case 1:
460     *ch_mask = CH_MASK_CENTER_FRONT;
461     break;
462   case 2:
463     *ch_mask = CH_MASK_LEFT_RIGHT_FRONT;
464     break;
465   case 3:
466     *ch_mask = (CH_MASK_CENTER_FRONT | CH_MASK_LEFT_RIGHT_FRONT);
467     break;
468   case 4:
469     *ch_mask = (CH_MASK_CENTER_FRONT | CH_MASK_LEFT_RIGHT_FRONT | CH_MASK_REAR_CENTER);
470     break;
471   case 5:
472     *ch_mask = (CH_MASK_CENTER_FRONT | CH_MASK_LEFT_RIGHT_FRONT | CH_MASK_LEFT_RIGHT_BACK);
473     break;
474   case 6:
475     *ch_mask =
476       (CH_MASK_CENTER_FRONT | CH_MASK_LEFT_RIGHT_FRONT | CH_MASK_LEFT_RIGHT_BACK | CH_MASK_LFE);
477     break;
478   }
479 }
480 
ixheaace_set_default_config(ixheaace_api_struct * pstr_api_struct,ixheaace_input_config * pstr_input_config)481 static VOID ixheaace_set_default_config(ixheaace_api_struct *pstr_api_struct,
482                                         ixheaace_input_config *pstr_input_config) {
483   ia_usac_encoder_config_struct *pstr_usac_config = &pstr_api_struct->config[0].usac_config;
484   WORD32 i;
485 
486   for (i = 0; i < MAXIMUM_BS_ELE; i++) {
487     ia_enhaacplus_enc_aac_init_default_config(&pstr_api_struct->config[i].aac_config,
488                                               pstr_input_config->aot);
489 
490     pstr_api_struct->config[i].i_channels = NUM_CHANNELS_CONFIG_PARAM_DEFAULT_VALUE;
491     pstr_api_struct->config[i].sample_rate = AAC_SAMP_FREQ_CONFIG_PARAM_DEFAULT_VALUE;
492     pstr_api_struct->config[i].native_sample_rate = AAC_SAMP_FREQ_CONFIG_PARAM_DEFAULT_VALUE;
493     pstr_api_struct->config[i].i_n_memtabs = NUM_MEMTABS_CONFIG_PARAM_DEFAULT_VALUE;
494     pstr_api_struct->config[i].aac_classic = AAC_CLASSIC_CONFIG_PARAM_DEFAULT_VALUE;
495     pstr_api_struct->config[i].use_parametric_stereo = USE_PS_CONFIG_PARAM_DEFAULT_VALUE;
496     pstr_api_struct->config[i].chmode_nchannels = CHMODE_NUM_CHANNELS_CONFIG_PARAM_DEFAULT_VALUE;
497     pstr_api_struct->config[i].chmode = CHMODE_CONFIG_PARAM_DEFAULT_VALUE; /*stereo*/
498     pstr_api_struct->config[i].adts_flag = ADTS_FLAG_CONFIG_PARAM_DEFAULT_VALUE;
499     pstr_api_struct->config[i].num_bs_elements = NUM_BS_ELEMENTS_CONFIG_PARAM_DEFAULT_VALUE;
500     pstr_api_struct->config[i].i_channels_mask = CHANNEL_MASK_CONFIG_PARAM_DEFAULT_VALUE;
501     pstr_api_struct->config[i].i_num_coupling_chan =
502         NUM_COUPLING_CHANNEL_CONFIG_PARAM_DEFAULT_VALUE;
503     pstr_api_struct->config[i].element_type = ELEMENT_TYPE_CONFIG_PARAM_DEFAULT_VALUE;
504     pstr_api_struct->config[i].element_slot = ELEMENT_SLOT_CONFIG_PARAM_DEFAULT_VALUE;
505     pstr_api_struct->config[i].num_bs_elements = NUM_BS_ELEMENTS_CONFIG_PARAM_DEFAULT_VALUE;
506     pstr_api_struct->config[i].element_instance_tag =
507         ELEMENT_INSTANCE_TAG_CONFIG_PARAM_DEFAULT_VALUE;
508     pstr_api_struct->config[i].aac_config.calc_crc = AAC_CFG_CALC_CRC_CONFIG_PARAM_DEFAULT_VALUE;
509     pstr_api_struct->config[i].aac_config.full_bandwidth =
510         AAC_CFG_FULL_BW_CONFIG_PARAM_DEFAULT_VALUE;
511     pstr_api_struct->config[i].eldsbr_found = ELDSBR_FOUND_CONFIG_PARAM_DEFAULT_VALUE;
512     pstr_api_struct->config[i].use_mps = USE_MPS_PARAM_DEFAULT_VALUE;
513     pstr_api_struct->config[i].mps_tree_config = USE_MPS_TREE_CONFIG_PARAM_DEFAULT_VALUE;
514   }
515   if (pstr_input_config->aot == AOT_USAC) {
516     memset(pstr_usac_config, 0, sizeof(*pstr_usac_config));
517     pstr_usac_config->channels = NUM_CHANNELS_CONFIG_PARAM_DEFAULT_VALUE;
518     pstr_usac_config->sample_rate = USAC_SAMP_FREQ_CONFIG_PARAM_DEFAULT_VALUE;
519     pstr_usac_config->core_sample_rate = USAC_SAMP_FREQ_CONFIG_PARAM_DEFAULT_VALUE;
520     pstr_usac_config->native_sample_rate = USAC_SAMP_FREQ_CONFIG_PARAM_DEFAULT_VALUE;
521     pstr_usac_config->sbr_pvc_active = USAC_SBR_PVC_DEFAULT_VALUE;
522     pstr_usac_config->sbr_inter_tes_active = USAC_SBR_INTER_TES_DEFAULT_VALUE;
523     pstr_usac_config->sbr_harmonic = USAC_SBR_HARMONIC_DEFAULT_VALUE;
524     pstr_usac_config->bit_rate = USAC_BITRATE_DEFAULT_VALUE;
525     pstr_usac_config->use_fill_element = USAC_FILL_ELEMENT_DEFAULT_VALUE;
526     pstr_usac_config->use_drc_element = USAC_DRC_DEFAULT_VALUE;
527     pstr_usac_config->cmplx_pred_flag = USAC_COMPLEX_PREDECTION_DEFAULT_VALUE;
528     pstr_usac_config->tns_select = USAC_TNS_DEFAULT_VALUE;
529     pstr_usac_config->flag_noiseFilling = USAC_FLAG_NOISE_FILLING_DEFAULT_VALUE;
530     pstr_usac_config->use_acelp_only = USAC_DEFAULT_ACELP_FLAG_VALUE;
531     pstr_usac_config->is_first_frame = USAC_FIRST_FRAME_FLAG_DEFAULT_VALUE;
532     pstr_usac_config->num_preroll_frames = CC_NUM_PREROLL_FRAMES;
533     pstr_usac_config->stream_id = USAC_DEFAULT_STREAM_ID_VALUE;
534   }
535   /* Initialize table pointers */
536   ia_enhaacplus_enc_init_aac_tabs(&(pstr_api_struct->pstr_aac_tabs));
537   ia_enhaacplus_enc_init_sbr_tabs(&(pstr_api_struct->spectral_band_replication_tabs));
538   pstr_api_struct->common_tabs.pstr_common_tab =
539       (ixheaace_common_tables *)&ia_enhaacplus_enc_common_tab;
540 }
541 
ixheaace_validate_config_params(ixheaace_input_config * pstr_input_config)542 static IA_ERRORCODE ixheaace_validate_config_params(ixheaace_input_config *pstr_input_config) {
543   IA_ERRORCODE err_code = IA_NO_ERROR;
544   if (pstr_input_config->aot != AOT_AAC_ELD && pstr_input_config->aot != AOT_AAC_LC &&
545       pstr_input_config->aot != AOT_AAC_LD && pstr_input_config->aot != AOT_PS &&
546       pstr_input_config->aot != AOT_SBR && pstr_input_config->aot != AOT_USAC) {
547     pstr_input_config->aot = AOT_AAC_LC;
548   }
549   pstr_input_config->i_native_samp_freq = pstr_input_config->i_samp_freq;
550   pstr_input_config->i_samp_freq = iusace_map_sample_rate(pstr_input_config->i_samp_freq);
551 
552   if ((pstr_input_config->i_channels < MIN_NUM_CORE_CODER_CHANNELS) ||
553       (pstr_input_config->i_channels > MAX_NUM_CORE_CODER_CHANNELS)) {
554     pstr_input_config->i_channels = 1;
555   }
556   if (pstr_input_config->esbr_flag != 1 && pstr_input_config->esbr_flag != 0) {
557     pstr_input_config->esbr_flag = 0;
558   }
559   if ((pstr_input_config->esbr_flag == 1) &&
560       ((pstr_input_config->aot != AOT_SBR) && (pstr_input_config->aot != AOT_PS) &&
561        (pstr_input_config->aot != AOT_USAC))) {
562     pstr_input_config->esbr_flag = 0;
563   }
564   if (pstr_input_config->i_use_mps != 1 && pstr_input_config->i_use_mps != 0) {
565     pstr_input_config->i_use_mps = 0;
566   }
567 
568   if ((pstr_input_config->i_channels != 2) && (pstr_input_config->i_channels != 6)) {
569     pstr_input_config->i_use_mps = 0;
570   }
571   if (pstr_input_config->aot != AOT_AAC_ELD && pstr_input_config->aot != AOT_USAC) {
572     pstr_input_config->i_use_mps = 0;
573   }
574   if (pstr_input_config->aot == AOT_USAC && pstr_input_config->i_use_mps == 1) {
575     if (pstr_input_config->ccfl_idx < SBR_8_3) {
576       pstr_input_config->ccfl_idx = SBR_2_1;
577     }
578   }
579   if (AOT_USAC == pstr_input_config->aot) {
580     if ((pstr_input_config->i_channels != 2) || (pstr_input_config->i_samp_freq > 48000)) {
581       // Num qmf bands is mapped only till 48000. Hence, disable mps if fs > 48000 or if input
582       // channels is not 2
583       pstr_input_config->i_use_mps = 0;
584     }
585   }
586   if (pstr_input_config->i_use_mps == 1) {
587     if (pstr_input_config->i_channels == 2) {
588       if (pstr_input_config->i_mps_tree_config != TREE_212) {
589         pstr_input_config->i_mps_tree_config = TREE_212;
590       }
591     } else {
592       if (pstr_input_config->i_mps_tree_config != TREE_5151 &&
593           pstr_input_config->i_mps_tree_config != TREE_5152 &&
594           pstr_input_config->i_mps_tree_config != TREE_525) {
595         pstr_input_config->i_mps_tree_config = TREE_5151;
596       }
597     }
598   } else {
599     pstr_input_config->i_mps_tree_config = INVALID_TREE_CONFIG;
600   }
601   if (pstr_input_config->aot == AOT_USAC || pstr_input_config->aot == AOT_AAC_ELD ||
602       pstr_input_config->aot == AOT_AAC_LD) {
603     pstr_input_config->i_use_adts = 0;
604     pstr_input_config->i_use_es = 1;
605   }
606   if (pstr_input_config->aot == AOT_USAC) {
607     if (pstr_input_config->codec_mode != USAC_SWITCHED &&
608         pstr_input_config->codec_mode != USAC_ONLY_FD &&
609         pstr_input_config->codec_mode != USAC_ONLY_TD) {
610       pstr_input_config->codec_mode = USAC_ONLY_FD;
611     }
612     if (pstr_input_config->ccfl_idx < NO_SBR_CCFL_768 || pstr_input_config->ccfl_idx > SBR_4_1) {
613       pstr_input_config->ccfl_idx = NO_SBR_CCFL_1024;  // default value
614     }
615     if ((pstr_input_config->ccfl_idx == SBR_4_1) && (pstr_input_config->i_samp_freq < 32000))
616     {
617       if (pstr_input_config->i_samp_freq >= 16000)
618       {
619         pstr_input_config->ccfl_idx = SBR_2_1;
620       }
621       else
622       {
623         pstr_input_config->ccfl_idx = NO_SBR_CCFL_1024;
624       }
625     }
626     if (pstr_input_config->cplx_pred != 1 && pstr_input_config->cplx_pred != 0) {
627       pstr_input_config->cplx_pred = 0;
628     }
629     if (pstr_input_config->use_drc_element != 0 && pstr_input_config->use_drc_element != 1) {
630       pstr_input_config->use_drc_element = 0;
631     }
632 
633     if (pstr_input_config->hq_esbr != 0 && pstr_input_config->hq_esbr != 1) {
634       pstr_input_config->hq_esbr = 0;
635     }
636     if (pstr_input_config->harmonic_sbr != 0 && pstr_input_config->harmonic_sbr != 1) {
637       pstr_input_config->harmonic_sbr = 0;
638     }
639     if (pstr_input_config->pvc_active != 0 && pstr_input_config->pvc_active != 1) {
640       pstr_input_config->pvc_active = 0;
641     }
642     if (pstr_input_config->inter_tes_active != 0 && pstr_input_config->inter_tes_active != 1) {
643       pstr_input_config->inter_tes_active = 0;
644     }
645     if ((pstr_input_config->ccfl_idx != 3 && pstr_input_config->ccfl_idx != 4)) {
646       pstr_input_config->harmonic_sbr = 0;
647     }
648     if (pstr_input_config->harmonic_sbr != 1) {
649       pstr_input_config->hq_esbr = 0;
650     }
651     if (pstr_input_config->i_bitrate != 64000 && pstr_input_config->i_bitrate != 96000) {
652       pstr_input_config->i_bitrate = USAC_BITRATE_DEFAULT_VALUE;
653     }
654     {
655       if (pstr_input_config->i_bitrate < MINIMUM_BITRATE * pstr_input_config->i_channels) {
656         pstr_input_config->i_bitrate = MINIMUM_BITRATE * pstr_input_config->i_channels;
657       }
658       if (pstr_input_config->ccfl_idx == NO_SBR_CCFL_768 ||
659           pstr_input_config->ccfl_idx == NO_SBR_CCFL_1024) {
660         if (pstr_input_config->i_bitrate >
661             (WORD32)(6 * pstr_input_config->i_samp_freq * pstr_input_config->i_channels)) {
662           pstr_input_config->i_bitrate =
663               (6 * pstr_input_config->i_samp_freq * pstr_input_config->i_channels);
664         }
665       } else if (pstr_input_config->ccfl_idx == SBR_8_3) {
666         if (pstr_input_config->i_bitrate >
667             (WORD32)(6 * ((pstr_input_config->i_samp_freq * 3) / 8) *
668                      pstr_input_config->i_channels)) {
669           pstr_input_config->i_bitrate =
670               (6 * ((pstr_input_config->i_samp_freq * 3) / 8) * pstr_input_config->i_channels);
671         }
672       } else if (pstr_input_config->ccfl_idx == SBR_2_1) {
673         if (pstr_input_config->i_bitrate >
674             (WORD32)(6 * (pstr_input_config->i_samp_freq / 2) * pstr_input_config->i_channels)) {
675           pstr_input_config->i_bitrate =
676               (6 * (pstr_input_config->i_samp_freq / 2) * pstr_input_config->i_channels);
677         }
678       } else if (pstr_input_config->ccfl_idx == SBR_4_1) {
679         if (pstr_input_config->i_bitrate >
680             (WORD32)(6 * (pstr_input_config->i_samp_freq / 4) * pstr_input_config->i_channels)) {
681           pstr_input_config->i_bitrate =
682               (6 * (pstr_input_config->i_samp_freq / 4) * pstr_input_config->i_channels);
683         }
684       }
685     }
686 
687     {
688       if ((pstr_input_config->codec_mode == USAC_SWITCHED ||
689            pstr_input_config->codec_mode == USAC_ONLY_TD) && pstr_input_config->esbr_flag &&
690           pstr_input_config->i_samp_freq > 24000) {
691         if (pstr_input_config->ccfl_idx == NO_SBR_CCFL_768) {
692           pstr_input_config->ccfl_idx = SBR_8_3;  // Use 8:3 eSBR
693         }
694         if (pstr_input_config->ccfl_idx == NO_SBR_CCFL_1024) {
695           pstr_input_config->ccfl_idx = SBR_2_1;  // Use 2:1 eSBR
696         }
697       }
698 
699       if (pstr_input_config->codec_mode == USAC_ONLY_FD &&
700           pstr_input_config->i_samp_freq > 24000 && pstr_input_config->esbr_flag &&
701           pstr_input_config->i_bitrate <= MAX_USAC_ESBR_BITRATE) {
702         if (pstr_input_config->ccfl_idx == NO_SBR_CCFL_768) {
703           pstr_input_config->ccfl_idx = SBR_8_3;  // Use 8:3 eSBR
704         }
705         if (pstr_input_config->ccfl_idx == NO_SBR_CCFL_1024) {
706           pstr_input_config->ccfl_idx = SBR_2_1;  // Use 2:1 eSBR
707         }
708       }
709 
710       if (pstr_input_config->ccfl_idx == NO_SBR_CCFL_768 ||
711           pstr_input_config->ccfl_idx == SBR_8_3) {
712         pstr_input_config->frame_length = LEN_SUPERFRAME_768;
713       } else {
714         pstr_input_config->frame_length = LEN_SUPERFRAME;
715       }
716     }
717     if (pstr_input_config->random_access_interval < MIN_RAP_INTERVAL_IN_MS) {
718       pstr_input_config->random_access_interval = DEFAULT_RAP_INTERVAL_IN_MS;
719     }
720     if (pstr_input_config->method_def > MAX_METHOD_DEFINITION_TYPE) {
721       pstr_input_config->method_def = METHOD_DEFINITION_PROGRAM_LOUDNESS;
722     }
723     if (pstr_input_config->measurement_system != MEASUREMENT_SYSTEM_BS_1770_3) {
724       pstr_input_config->measurement_system = MEASUREMENT_SYSTEM_BS_1770_3;
725     }
726     if (pstr_input_config->measured_loudness > MAX_METHOD_VALUE ||
727         pstr_input_config->measured_loudness < MIN_METHOD_VALUE) {
728       pstr_input_config->measured_loudness = DEFAULT_METHOD_VALUE;
729     }
730     if (pstr_input_config->sample_peak_level > MAX_SAMPLE_PEAK_LEVEL ||
731         pstr_input_config->sample_peak_level < MIN_SAMPLE_PEAK_LEVEL) {
732       pstr_input_config->sample_peak_level = DEFAULT_SAMPLE_PEAK_VALUE;
733     }
734     if (pstr_input_config->use_drc_element) {
735       ia_drc_input_config *pstr_drc_cfg = (ia_drc_input_config *)pstr_input_config->pv_drc_cfg;
736       err_code = impd_drc_validate_config_params(pstr_drc_cfg);
737       if (err_code & IA_FATAL_ERROR) {
738         return err_code;
739       }
740       if (err_code) {
741         pstr_input_config->use_drc_element = 0;
742         err_code = IA_NO_ERROR;
743       }
744     }
745   } else {
746     pstr_input_config->cplx_pred = 0;
747     pstr_input_config->harmonic_sbr = 0;
748     pstr_input_config->pvc_active = 0;
749     pstr_input_config->inter_tes_active = 0;
750     pstr_input_config->use_drc_element = 0;
751     pstr_input_config->hq_esbr = 0;
752     if (pstr_input_config->i_channels != 2 && pstr_input_config->aot == AOT_PS) {
753       pstr_input_config->aot = AOT_SBR;
754     }
755     if (pstr_input_config->aac_config.use_tns != 1 &&
756         pstr_input_config->aac_config.use_tns != 0) {
757       pstr_input_config->aac_config.use_tns = 0;
758     }
759     if (pstr_input_config->aac_config.noise_filling != 1 &&
760         pstr_input_config->aac_config.noise_filling != 0) {
761       pstr_input_config->aac_config.noise_filling = 0;
762     }
763     if (pstr_input_config->i_use_adts != 1 && pstr_input_config->i_use_adts != 0) {
764       pstr_input_config->i_use_adts = 0;
765       pstr_input_config->i_use_es = 1;
766     }
767     if (pstr_input_config->aac_config.full_bandwidth != 1 &&
768         pstr_input_config->aac_config.full_bandwidth != 0) {
769       pstr_input_config->aac_config.full_bandwidth = 0;
770     }
771     {
772       if (pstr_input_config->i_bitrate < MINIMUM_BITRATE * pstr_input_config->i_channels) {
773         pstr_input_config->i_bitrate = MINIMUM_BITRATE * pstr_input_config->i_channels;
774       }
775       if (pstr_input_config->i_bitrate >
776           (WORD32)(6 * pstr_input_config->i_samp_freq * pstr_input_config->i_channels)) {
777         pstr_input_config->i_bitrate =
778             (6 * pstr_input_config->i_samp_freq * pstr_input_config->i_channels);
779       }
780     }
781 
782     {
783       if (pstr_input_config->aot == AOT_AAC_LC || pstr_input_config->aot == AOT_SBR ||
784           pstr_input_config->aot == AOT_PS) {
785         if (pstr_input_config->frame_length != LEN_SUPERFRAME &&
786             pstr_input_config->frame_length != FRAME_LEN_960) {
787           pstr_input_config->frame_length = LEN_SUPERFRAME;
788         }
789       } else if (pstr_input_config->aot == AOT_AAC_LD || pstr_input_config->aot == AOT_AAC_ELD) {
790         if (pstr_input_config->frame_length != FRAME_LEN_512 &&
791             pstr_input_config->frame_length != FRAME_LEN_480) {
792           pstr_input_config->frame_length = FRAME_LEN_512;
793         }
794       } else {
795         pstr_input_config->frame_length = LEN_SUPERFRAME;
796       }
797     }
798     if ((pstr_input_config->frame_length == FRAME_LEN_960) &&
799         (pstr_input_config->esbr_flag == 1)) {
800       pstr_input_config->esbr_flag = 0;
801     }
802   }
803   return err_code;
804 }
805 
ixheaace_set_config_params(ixheaace_api_struct * pstr_api_struct,ixheaace_input_config * pstr_input_config)806 static IA_ERRORCODE ixheaace_set_config_params(ixheaace_api_struct *pstr_api_struct,
807                                                ixheaace_input_config *pstr_input_config) {
808   WORD32 ele_idx;
809   IA_ERRORCODE err_code = IA_NO_ERROR;
810   ia_usac_encoder_config_struct *pstr_usac_config = &pstr_api_struct->config[0].usac_config;
811   err_code = ixheaace_validate_config_params(pstr_input_config);
812   if (err_code) {
813     return err_code;
814   }
815 
816   if (pstr_input_config->ui_pcm_wd_sz != 16) {
817     return (IA_EXHEAACE_CONFIG_FATAL_PCM_WDSZ);
818   }
819   if ((pstr_input_config->aac_config.inv_quant != 0) &&
820       (pstr_input_config->aac_config.inv_quant != 1) &&
821       (pstr_input_config->aac_config.inv_quant != 2)) {
822     return (IA_EXHEAACE_CONFIG_FATAL_QUALITY_LEVEL);
823   }
824   if ((pstr_input_config->write_program_config_element != 0) &&
825       (pstr_input_config->write_program_config_element != 1)) {
826     return (IA_EXHEAACE_CONFIG_FATAL_WRITE_PCE);
827   }
828   if ((pstr_input_config->aac_config.f_no_stereo_preprocessing != 0) &&
829       (pstr_input_config->aac_config.f_no_stereo_preprocessing != 1)) {
830     return (IA_EXHEAACE_CONFIG_FATAL_USE_STEREO_PRE_PROC);
831   }
832   if ((pstr_input_config->aac_config.use_tns != 0) &&
833       (pstr_input_config->aac_config.use_tns != 1)) {
834     return (IA_EXHEAACE_CONFIG_FATAL_USE_TNS);
835   }
836   if ((pstr_input_config->aac_config.full_bandwidth != 0) &&
837       (pstr_input_config->aac_config.full_bandwidth != 1)) {
838     return (IA_EXHEAACE_CONFIG_FATAL_USE_FULL_BANDWIDTH);
839   }
840 
841   for (ele_idx = 0; ele_idx < MAXIMUM_BS_ELE; ele_idx++) {
842     pstr_api_struct->config[ele_idx].aac_classic = 1;
843     pstr_api_struct->config[ele_idx].firstframe = 1;
844     pstr_api_struct->config[ele_idx].aot = pstr_input_config->aot;
845     pstr_api_struct->config[ele_idx].adts_flag = pstr_input_config->i_use_adts;
846     pstr_api_struct->config[ele_idx].sample_rate = pstr_input_config->i_samp_freq;
847     pstr_api_struct->config[ele_idx].native_sample_rate = pstr_input_config->i_native_samp_freq;
848 
849     pstr_api_struct->config[ele_idx].i_channels = pstr_input_config->i_channels;
850     pstr_api_struct->config[ele_idx].i_native_channels = pstr_input_config->i_channels;
851     pstr_api_struct->config[ele_idx].i_channels_mode = pstr_input_config->i_channels;
852     pstr_api_struct->config[ele_idx].aac_config.bit_rate = pstr_input_config->i_bitrate;
853     pstr_api_struct->config[ele_idx].esbr_flag = pstr_input_config->esbr_flag;
854     pstr_api_struct->config[ele_idx].use_mps = pstr_input_config->i_use_mps;
855     pstr_api_struct->config[ele_idx].mps_tree_config = pstr_input_config->i_mps_tree_config;
856     pstr_api_struct->config[ele_idx].i_num_coupling_chan = pstr_input_config->i_num_coupling_chan;
857     pstr_api_struct->config[ele_idx].ui_pcm_wd_sz = pstr_input_config->ui_pcm_wd_sz;
858     pstr_api_struct->config[ele_idx].write_program_config_element =
859         pstr_input_config->write_program_config_element;
860     pstr_api_struct->config[ele_idx].frame_length = pstr_input_config->frame_length;
861     pstr_api_struct->config[ele_idx].aac_config.num_stereo_preprocessing =
862         pstr_input_config->aac_config.f_no_stereo_preprocessing;
863 
864     pstr_api_struct->config[ele_idx].aac_config.use_tns = pstr_input_config->aac_config.use_tns;
865     if (pstr_input_config->aot == AOT_AAC_LD || pstr_input_config->aot == AOT_AAC_ELD) {
866       pstr_api_struct->config[ele_idx].aac_config.inv_quant =
867           pstr_input_config->aac_config.inv_quant;
868       if (pstr_input_config->frame_length == FRAME_LEN_512) {
869         pstr_api_struct->config[ele_idx].aac_config.flag_framelength_small = 0;
870       } else if (pstr_input_config->frame_length == FRAME_LEN_480) {
871         pstr_api_struct->config[ele_idx].aac_config.flag_framelength_small = 1;
872       }
873     } else if (pstr_input_config->aot == AOT_AAC_LC || pstr_input_config->aot == AOT_SBR ||
874                pstr_input_config->aot == AOT_PS) {
875       pstr_api_struct->config[ele_idx].aac_config.inv_quant = 0;
876       if (pstr_input_config->frame_length == FRAME_LEN_1024) {
877         pstr_api_struct->config[ele_idx].aac_config.flag_framelength_small = 0;
878       } else if (pstr_input_config->frame_length == FRAME_LEN_960) {
879         pstr_api_struct->config[ele_idx].aac_config.flag_framelength_small = 1;
880       }
881     }
882     if ((AOT_SBR == pstr_input_config->aot) || (AOT_PS == pstr_input_config->aot) ||
883         (AOT_AAC_ELD == pstr_input_config->aot)) {
884       pstr_api_struct->config[ele_idx].aac_classic = 0;
885     }
886     if (pstr_api_struct->config[ele_idx].sample_rate < 32000) {
887       if (pstr_api_struct->config[ele_idx].aac_classic == 0) {
888         pstr_api_struct->config[ele_idx].aac_classic = 1;
889       }
890       if (pstr_input_config->aot == AOT_SBR || pstr_input_config->aot == AOT_PS) {
891         pstr_input_config->aot = AOT_AAC_LC;
892       }
893       if (pstr_input_config->aot == AOT_AAC_ELD) {
894         pstr_input_config->aot = AOT_AAC_LD;
895       }
896     }
897     pstr_api_struct->config[ele_idx].eldsbr_found =
898         !(pstr_api_struct->config[ele_idx].aac_classic);
899   }
900   if (pstr_input_config->aot == AOT_USAC) {
901     if (pstr_input_config->i_channels > 2) {
902       return IA_EXHEAACE_CONFIG_FATAL_NUM_CHANNELS;
903     }
904     if ((pstr_input_config->i_samp_freq < 6000) || (pstr_input_config->i_samp_freq > 96000)) {
905       return (IA_EXHEAACE_CONFIG_FATAL_SAMP_FREQ);
906     }
907     pstr_api_struct->usac_en = 1;
908 
909     pstr_usac_config->codec_mode = pstr_input_config->codec_mode;
910     pstr_usac_config->channels = pstr_input_config->i_channels;
911 
912     pstr_usac_config->core_sample_rate = pstr_input_config->i_samp_freq;
913     pstr_usac_config->sample_rate = pstr_input_config->i_samp_freq;
914     pstr_usac_config->native_sample_rate = pstr_input_config->i_native_samp_freq;
915 
916     pstr_usac_config->ui_pcm_wd_sz = pstr_input_config->ui_pcm_wd_sz;
917     pstr_usac_config->ccfl_idx = pstr_input_config->ccfl_idx;
918     pstr_usac_config->bit_rate = pstr_input_config->i_bitrate;
919     pstr_usac_config->basic_bitrate = pstr_input_config->i_bitrate;
920     pstr_usac_config->tns_select = pstr_input_config->aac_config.use_tns;
921     pstr_usac_config->cmplx_pred_flag = pstr_input_config->cplx_pred;
922     pstr_usac_config->flag_noiseFilling = pstr_input_config->aac_config.noise_filling;
923     pstr_usac_config->sbr_pvc_active = pstr_input_config->pvc_active;
924     pstr_usac_config->sbr_harmonic = pstr_input_config->harmonic_sbr;
925     pstr_usac_config->hq_esbr = pstr_input_config->hq_esbr;
926     pstr_usac_config->sbr_inter_tes_active = pstr_input_config->inter_tes_active;
927     pstr_api_struct->config[0].chmode_nchannels = pstr_api_struct->config[0].i_channels;
928 
929     switch (pstr_input_config->ccfl_idx) {
930       case NO_SBR_CCFL_768:
931         pstr_usac_config->ccfl = LEN_SUPERFRAME_768;
932         pstr_usac_config->in_frame_length = LEN_SUPERFRAME_768;
933         pstr_usac_config->sbr_enable = 0;
934         pstr_usac_config->drc_frame_size = LEN_SUPERFRAME_768;
935         break;
936       case NO_SBR_CCFL_1024:
937         pstr_usac_config->ccfl = LEN_SUPERFRAME;
938         pstr_usac_config->in_frame_length = LEN_SUPERFRAME;
939         pstr_usac_config->sbr_enable = 0;
940         pstr_usac_config->drc_frame_size = LEN_SUPERFRAME;
941         break;
942       case SBR_8_3:
943         pstr_usac_config->ccfl = LEN_SUPERFRAME_768;
944         pstr_usac_config->in_frame_length = (LEN_SUPERFRAME_768 * 8) / 3;
945         pstr_usac_config->sbr_enable = 1;
946         pstr_usac_config->drc_frame_size = (LEN_SUPERFRAME_768 * 8) / 3;
947         break;
948       case SBR_2_1:
949         pstr_usac_config->ccfl = LEN_SUPERFRAME;
950         pstr_usac_config->in_frame_length = (LEN_SUPERFRAME * 2);
951         pstr_usac_config->sbr_enable = 1;
952         pstr_usac_config->drc_frame_size = (LEN_SUPERFRAME * 2);
953         break;
954       case SBR_4_1:
955         pstr_usac_config->ccfl = LEN_SUPERFRAME;
956         pstr_usac_config->in_frame_length = (LEN_SUPERFRAME * 4);
957         pstr_usac_config->sbr_enable = 1;
958         pstr_usac_config->drc_frame_size = (LEN_SUPERFRAME * 4);
959         break;
960       default:
961         pstr_usac_config->ccfl = LEN_SUPERFRAME;
962         pstr_usac_config->in_frame_length = LEN_SUPERFRAME;
963         pstr_usac_config->sbr_enable = 0;
964         pstr_usac_config->drc_frame_size = LEN_SUPERFRAME;
965         break;
966     }
967     pstr_usac_config->random_access_interval = pstr_input_config->random_access_interval;
968     if (pstr_usac_config->random_access_interval > 0) {
969       pstr_usac_config->random_access_interval =
970           (WORD32)((((WORD64)pstr_usac_config->random_access_interval *
971                      pstr_input_config->i_native_samp_freq) +
972                     (pstr_usac_config->ccfl * 1000 - 1)) /
973                    (pstr_usac_config->ccfl * 1000));
974     }
975 
976     if (pstr_usac_config->random_access_interval) {
977       pstr_usac_config->preroll_flag = 1;
978     }
979     if (pstr_usac_config->sbr_enable == 1) {
980       pstr_usac_config->num_preroll_frames++;
981       if (pstr_usac_config->sbr_harmonic == 1) {
982         pstr_usac_config->num_preroll_frames++;
983       }
984     }
985     pstr_usac_config->stream_id = pstr_input_config->stream_id;
986     if (pstr_input_config->ccfl_idx < NO_SBR_CCFL_768 || pstr_input_config->ccfl_idx > SBR_4_1) {
987       pstr_api_struct->config[0].ccfl_idx = NO_SBR_CCFL_1024;  // default value
988     } else {
989       pstr_api_struct->config[0].ccfl_idx = pstr_input_config->ccfl_idx;
990     }
991     if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) {
992       pstr_api_struct->spectral_band_replication_tabs.ptr_sos_upsamp_tab =
993           (ixheaace_resampler_sos_table *)&iixheaace_resamp_1_to_3_filt_params;
994 
995       pstr_api_struct->spectral_band_replication_tabs.ptr_sos_downsamp_tab =
996           (ixheaace_resampler_sos_table *)&iixheaace_resamp_8_to_1_filt_params;
997     } else if (pstr_api_struct->config[0].ccfl_idx == SBR_2_1) {
998       pstr_api_struct->spectral_band_replication_tabs.ptr_resamp_tab =
999           (ixheaace_resampler_table *)&ixheaace_resamp_2_to_1_iir_filt_params;
1000     } else if (pstr_api_struct->config[0].ccfl_idx == SBR_4_1) {
1001       pstr_api_struct->spectral_band_replication_tabs.ptr_resamp_tab =
1002           (ixheaace_resampler_table *)&ixheaace_resamp_4_to_1_iir_filt_params;
1003     }
1004     pstr_usac_config->use_drc_element = pstr_input_config->use_drc_element;
1005     {
1006       ia_drc_input_config *pstr_drc_cfg = (ia_drc_input_config *)pstr_input_config->pv_drc_cfg;
1007       pstr_drc_cfg->str_uni_drc_config.str_channel_layout.base_ch_count =
1008           pstr_input_config->i_channels;
1009       pstr_drc_cfg->str_enc_params.sample_rate = pstr_input_config->i_samp_freq;
1010       pstr_drc_cfg->str_enc_params.domain = TIME_DOMAIN;
1011       pstr_drc_cfg->str_uni_drc_config.sample_rate = pstr_drc_cfg->str_enc_params.sample_rate;
1012       for (WORD32 i = 0; i < pstr_drc_cfg->str_uni_drc_config.drc_coefficients_uni_drc_count;
1013            i++) {
1014         for (WORD32 j = 0;
1015              j < pstr_drc_cfg->str_uni_drc_config.str_drc_coefficients_uni_drc[i].gain_set_count;
1016              j++) {
1017           pstr_drc_cfg->str_uni_drc_config.str_drc_coefficients_uni_drc[i]
1018               .str_gain_set_params[j]
1019               .delta_tmin =
1020               impd_drc_get_delta_t_min(pstr_drc_cfg->str_uni_drc_config.sample_rate);
1021         }
1022       }
1023       for (WORD32 i = 0; i < pstr_drc_cfg->str_uni_drc_config.str_uni_drc_config_ext
1024         .drc_coefficients_uni_drc_v1_count; i++) {
1025         for (WORD32 j = 0;
1026           j < pstr_drc_cfg->str_uni_drc_config.str_uni_drc_config_ext
1027           .str_drc_coefficients_uni_drc_v1[i].gain_set_count; j++) {
1028           pstr_drc_cfg->str_uni_drc_config.str_uni_drc_config_ext
1029             .str_drc_coefficients_uni_drc_v1[i]
1030             .str_gain_set_params[j]
1031             .delta_tmin =
1032             impd_drc_get_delta_t_min(pstr_drc_cfg->str_uni_drc_config.sample_rate);
1033         }
1034       }
1035 
1036       pstr_usac_config->str_drc_cfg = *pstr_drc_cfg;
1037       pstr_usac_config->str_drc_cfg.str_enc_params.frame_size = pstr_usac_config->drc_frame_size;
1038       pstr_usac_config->str_drc_cfg.str_uni_drc_config.str_drc_coefficients_uni_drc
1039           ->drc_frame_size = pstr_usac_config->drc_frame_size;
1040       pstr_input_config->drc_frame_size = pstr_usac_config->drc_frame_size;
1041     }
1042   } else {
1043     if ((pstr_input_config->i_channels > MAX_NUM_CORE_CODER_CHANNELS)) {
1044       return (IA_EXHEAACE_CONFIG_FATAL_NUM_CHANNELS);
1045     }
1046     if (!((pstr_input_config->i_native_samp_freq == 7350) ||
1047           (pstr_input_config->i_native_samp_freq == 8000) ||
1048           (pstr_input_config->i_native_samp_freq == 11025) ||
1049           (pstr_input_config->i_native_samp_freq == 12000) ||
1050           (pstr_input_config->i_native_samp_freq == 16000) ||
1051           (pstr_input_config->i_native_samp_freq == 22050) ||
1052           (pstr_input_config->i_native_samp_freq == 24000) ||
1053           (pstr_input_config->i_native_samp_freq == 32000) ||
1054           (pstr_input_config->i_native_samp_freq == 44100) ||
1055           (pstr_input_config->i_native_samp_freq == 48000) ||
1056           (pstr_input_config->i_native_samp_freq == 64000) ||
1057           (pstr_input_config->i_native_samp_freq == 88200) ||
1058           (pstr_input_config->i_native_samp_freq == 96000))) {
1059       return (IA_EXHEAACE_CONFIG_FATAL_SAMP_FREQ);
1060     }
1061 
1062     if ((pstr_input_config->aot == AOT_AAC_ELD) && (pstr_input_config->i_use_mps == 1) &&
1063         (pstr_input_config->i_channels > 2)) {
1064       pstr_api_struct->config[0].num_bs_elements = 1;
1065       pstr_api_struct->config[0].i_channels = pstr_input_config->i_channels;
1066       pstr_api_struct->config[0].i_native_channels = pstr_input_config->i_channels;
1067       pstr_api_struct->config[0].chmode_nchannels = pstr_input_config->i_channels;
1068       pstr_api_struct->config[0].element_type = ID_SCE;
1069       if (pstr_api_struct->config[0].mps_tree_config == TREE_525) {
1070         pstr_api_struct->config[0].element_type = ID_CPE;
1071       }
1072       pstr_api_struct->config[0].element_slot = 0;
1073       pstr_api_struct->config[0].element_instance_tag = 0;
1074       pstr_api_struct->config[0].aac_config.bit_rate = pstr_input_config->i_bitrate;
1075       pstr_api_struct->config[0].use_parametric_stereo = 0;
1076     }
1077     if (pstr_input_config->i_channels_mask == 0) {
1078       ixheaace_set_default_channel_mask(&pstr_input_config->i_channels_mask,
1079                                         pstr_input_config->i_channels);
1080     }
1081     if (pstr_api_struct->config[0].aac_config.dual_mono != 1) {
1082       if (pstr_input_config->aot != AOT_AAC_ELD || (pstr_input_config->i_use_mps != 1)) {
1083         WORD32 num_bs_elements, chan_config[MAXIMUM_BS_ELE], element_type[MAXIMUM_BS_ELE],
1084             element_slot[MAXIMUM_BS_ELE], element_instance_tag[MAXIMUM_BS_ELE],
1085             bitrate[MAXIMUM_BS_ELE];
1086         if ((pstr_input_config->i_channels_mask > 0x3FFFF)) {
1087           return (IA_EXHEAACE_CONFIG_FATAL_CHANNELS_MASK);
1088         }
1089         if (ixheaace_validate_channel_mask(pstr_input_config->i_channels_mask,
1090                                            pstr_input_config->i_channels)) {
1091           return IA_EXHEAACE_CONFIG_FATAL_CHANNELS_MASK;
1092         }
1093         for (ele_idx = 0; ele_idx < MAXIMUM_BS_ELE; ele_idx++) {
1094           pstr_api_struct->config[ele_idx].i_channels_mask = pstr_input_config->i_channels_mask;
1095         }
1096         ia_enhaacplus_enc_find_channel_config(
1097             &num_bs_elements, chan_config, element_type, element_slot, element_instance_tag,
1098             pstr_api_struct->config[0].i_num_coupling_chan, pstr_input_config->i_channels_mask);
1099         for (ele_idx = 0; ele_idx < num_bs_elements; ele_idx++) {
1100           pstr_api_struct->config[ele_idx].i_channels = chan_config[ele_idx];
1101           pstr_api_struct->config[ele_idx].i_native_channels = chan_config[ele_idx];
1102           pstr_api_struct->config[ele_idx].chmode_nchannels = chan_config[ele_idx];
1103           pstr_api_struct->config[ele_idx].element_type = element_type[ele_idx];
1104           pstr_api_struct->config[ele_idx].element_slot = element_slot[ele_idx];
1105           pstr_api_struct->config[ele_idx].num_bs_elements = num_bs_elements;
1106           pstr_api_struct->config[ele_idx].element_instance_tag = element_instance_tag[ele_idx];
1107         }
1108 
1109         if (pstr_api_struct->config[0].num_bs_elements > 1) {
1110           ia_enhaacplus_enc_allocate_bitrate_between_channels(pstr_api_struct, bitrate,
1111                                                               pstr_input_config->i_bitrate);
1112 
1113           for (ele_idx = 0; ele_idx < pstr_api_struct->config[0].num_bs_elements; ele_idx++) {
1114             pstr_api_struct->config[ele_idx].aac_config.bit_rate = bitrate[ele_idx];
1115           }
1116 
1117           for (ele_idx = 0; ele_idx < MAXIMUM_BS_ELE; ele_idx++) {
1118             pstr_api_struct->config[ele_idx].use_parametric_stereo = 0;
1119           }
1120         }
1121       }
1122     } else {
1123       WORD32 num_bs_elements;
1124       WORD32 bitrate[MAXIMUM_BS_ELE];
1125 
1126       num_bs_elements = 2;
1127 
1128       pstr_api_struct->config[0].i_channels = 1;
1129       pstr_api_struct->config[0].chmode_nchannels = 1;
1130       pstr_api_struct->config[0].element_type = ID_SCE;
1131       pstr_api_struct->config[0].element_slot = 0;
1132       pstr_api_struct->config[0].num_bs_elements = num_bs_elements;
1133       pstr_api_struct->config[0].element_instance_tag = 0;
1134 
1135       pstr_api_struct->config[1].i_channels = 1;
1136       pstr_api_struct->config[1].chmode_nchannels = 1;
1137       pstr_api_struct->config[1].element_type = ID_SCE;
1138       pstr_api_struct->config[1].element_slot = 1;
1139       pstr_api_struct->config[1].num_bs_elements = num_bs_elements;
1140       pstr_api_struct->config[1].element_instance_tag = 1;
1141 
1142       if (pstr_api_struct->config[0].num_bs_elements > 1) {
1143         ia_enhaacplus_enc_allocate_bitrate_between_channels(
1144             pstr_api_struct, bitrate, pstr_api_struct->config[0].aac_config.bit_rate);
1145 
1146         for (ele_idx = 0; ele_idx < pstr_api_struct->config[0].num_bs_elements; ele_idx++) {
1147           pstr_api_struct->config[ele_idx].aac_config.bit_rate = bitrate[ele_idx];
1148         }
1149 
1150         for (ele_idx = 0; ele_idx < MAXIMUM_BS_ELE; ele_idx++) {
1151           pstr_api_struct->config[ele_idx].use_parametric_stereo = 0;
1152         }
1153       }
1154     }
1155 
1156     if (pstr_input_config->aot == AOT_PS && pstr_input_config->i_channels == 2) {
1157       pstr_api_struct->config[0].use_parametric_stereo = 1;
1158       pstr_api_struct->config[0].chmode_nchannels = 2;
1159     } else {
1160       for (ele_idx = 0; ele_idx < pstr_api_struct->config[0].num_bs_elements; ele_idx++) {
1161         pstr_api_struct->config[ele_idx].chmode_nchannels =
1162             pstr_api_struct->config[ele_idx].i_channels;
1163       }
1164     }
1165 
1166     if (pstr_input_config->aot == AOT_AAC_LD || pstr_input_config->aot == AOT_AAC_ELD) {
1167       WORD32 max_channel_bits = (pstr_api_struct->config[0].aac_config.flag_framelength_small
1168                                      ? MAXIMUM_CHANNEL_BITS_480
1169                                      : MAXIMUM_CHANNEL_BITS_512);
1170       if ((pstr_input_config->aac_config.bitreservoir_size > max_channel_bits / 8) ||
1171           (pstr_input_config->aac_config.bitreservoir_size < -1)) {
1172         pstr_input_config->aac_config.bitreservoir_size =
1173             BITRESERVOIR_SIZE_CONFIG_PARAM_DEFAULT_VALUE_LD;
1174       }
1175       pstr_api_struct->config[0].aac_config.bitreservoir_size =
1176           pstr_input_config->aac_config.bitreservoir_size;
1177     }
1178     if (pstr_input_config->aot == AOT_AAC_LC || pstr_input_config->aot == AOT_SBR ||
1179         pstr_input_config->aot == AOT_PS) {
1180       WORD32 max_channel_bits = (pstr_api_struct->config[0].aac_config.flag_framelength_small
1181                                      ? MAXIMUM_CHANNEL_BITS_960
1182                                      : MAXIMUM_CHANNEL_BITS_1024);
1183 
1184       if ((pstr_input_config->aac_config.bitreservoir_size > max_channel_bits / 8) ||
1185           (pstr_input_config->aac_config.bitreservoir_size < -1)) {
1186         pstr_input_config->aac_config.bitreservoir_size =
1187             BITRESERVOIR_SIZE_CONFIG_PARAM_DEFAULT_VALUE_LC;
1188       }
1189       pstr_api_struct->config[0].aac_config.bitreservoir_size =
1190           pstr_input_config->aac_config.bitreservoir_size;
1191     }
1192     pstr_api_struct->config[0].aac_config.full_bandwidth =
1193         pstr_input_config->aac_config.full_bandwidth;
1194   }
1195 
1196   return IA_NO_ERROR;
1197 }
1198 
ixheaace_fill_mem_tabs(ixheaace_api_struct * pstr_api_struct,WORD32 aot)1199 static VOID ixheaace_fill_mem_tabs(ixheaace_api_struct *pstr_api_struct, WORD32 aot) {
1200   WORD32 ele_idx;
1201   WORD32 num_channel;
1202   WORD32 frame_length = LEN_SUPERFRAME;
1203   ixheaace_mem_info_struct *pstr_mem_info;
1204   frame_length = pstr_api_struct->config[0].frame_length;
1205   WORD32 offset_size = 0;
1206   if (pstr_api_struct->usac_en) {
1207     WORD32 fac_downsample = 1;
1208     if (pstr_api_struct->config[0].ccfl_idx > NO_SBR_CCFL_1024) {
1209       fac_downsample = pstr_api_struct->config[0].ccfl_idx >> 1;
1210     } else {
1211       fac_downsample = 1;
1212     }
1213     /* persistant */
1214     {
1215       pstr_mem_info = &pstr_api_struct->pstr_mem_info[IA_ENHAACPLUSENC_PERSIST_IDX];
1216       {
1217         pstr_mem_info->ui_size =
1218             IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_state_struct), BYTE_ALIGN_8) +
1219             iusace_calc_pers_buf_sizes(pstr_api_struct);
1220         if (pstr_api_struct->config[0].usac_config.sbr_enable) {
1221           pstr_mem_info->ui_size += ixheaace_sbr_enc_pers_size(
1222               2, 0, pstr_api_struct->config[0].usac_config.sbr_harmonic);
1223         }
1224         offset_size = 2 *
1225                       ia_enhaacplus_enc_sizeof_delay_buffer(
1226                           0, AOT_USAC, pstr_api_struct->config[0].ccfl_idx,
1227                           sizeof(pstr_api_struct->pstr_state->inp_delay[0]),
1228                           pstr_api_struct->config[0].use_mps) *
1229                       pstr_api_struct->config[0].num_bs_elements;
1230         pstr_mem_info->ui_size += IXHEAAC_GET_SIZE_ALIGNED(offset_size, BYTE_ALIGN_8);
1231 
1232         if (pstr_api_struct->config[0].use_mps) {
1233           offset_size =
1234               (MAX_INPUT_SAMPLES) * sizeof(pstr_api_struct->pstr_state->time_signal_mps[0]);
1235           pstr_mem_info->ui_size += IXHEAAC_GET_SIZE_ALIGNED(offset_size, BYTE_ALIGN_8);
1236 
1237           offset_size =
1238               (MAX_MPS_BS_PAYLOAD_SIZE) * sizeof(pstr_api_struct->pstr_state->mps_bs[0]);
1239           pstr_mem_info->ui_size += IXHEAAC_GET_SIZE_ALIGNED(offset_size, BYTE_ALIGN_8);
1240 
1241           pstr_mem_info->ui_size +=
1242               IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_mps_212_memory_struct), BYTE_ALIGN_8);
1243         }
1244         if (1 == pstr_api_struct->config[0].usac_config.sbr_enable) {
1245           offset_size =
1246               (MAX_FRAME_LEN * (1 << fac_downsample) + MAX_DS_8_1_FILTER_DELAY + INPUT_DELAY) *
1247               MAX_CHANNELS * sizeof(pstr_mem_info->ui_size);
1248           pstr_mem_info->ui_size += IXHEAAC_GET_SIZE_ALIGNED(offset_size, BYTE_ALIGN_8);
1249         }
1250         if ((2 != pstr_api_struct->config[0].usac_config.channels) &&
1251             (1 == pstr_api_struct->config[0].usac_config.sbr_enable)) {
1252           offset_size = (MAX_INPUT_SAMPLES) * sizeof(pstr_api_struct->pstr_state->time_signal[0]);
1253           pstr_mem_info->ui_size += IXHEAAC_GET_SIZE_ALIGNED(offset_size, BYTE_ALIGN_8);
1254         }
1255       }
1256 
1257       pstr_mem_info->ui_alignment = BYTE_ALIGN_8;
1258       pstr_mem_info->ui_type = IA_MEMTYPE_PERSIST;
1259       pstr_mem_info->ui_placement[0] = 0;
1260       pstr_mem_info->ui_placement[1] = 0;
1261       pstr_mem_info->ui_priority = IA_MEMPRIORITY_ANYWHERE;
1262       pstr_mem_info->ui_placed[0] = 0;
1263       pstr_mem_info->ui_placed[1] = 0;
1264     }
1265 
1266     /* scratch */
1267     {
1268       pstr_mem_info = &pstr_api_struct->pstr_mem_info[IA_ENHAACPLUSENC_SCRATCH_IDX];
1269       UWORD32 usac_scr_size = iusace_scratch_size();
1270       if (pstr_api_struct->config[0].usac_config.sbr_enable) {
1271         UWORD32 sbr_scr_size = ixheaace_sbr_enc_scr_size() + ixheaace_resampler_scr_size();
1272         pstr_mem_info->ui_size = max(usac_scr_size, sbr_scr_size);
1273       } else {
1274         pstr_mem_info->ui_size = usac_scr_size;
1275       }
1276 
1277       pstr_mem_info->ui_alignment = BYTE_ALIGN_8;
1278       pstr_mem_info->ui_type = IA_MEMTYPE_SCRATCH;
1279       pstr_mem_info->ui_placement[0] = 0;
1280       pstr_mem_info->ui_placement[1] = 0;
1281       pstr_mem_info->ui_priority = IA_MEMPRIORITY_ANYWHERE;
1282       pstr_mem_info->ui_placed[0] = 0;
1283       pstr_mem_info->ui_placed[1] = 0;
1284     }
1285 
1286     /* input */
1287     {
1288       pstr_mem_info = &pstr_api_struct->pstr_mem_info[IA_ENHAACPLUSENC_INPUT_IDX];
1289       WORD32 pcm_wd_sz;
1290       num_channel = pstr_api_struct->config[0].i_channels;
1291       pcm_wd_sz = pstr_api_struct->config[0].usac_config.ui_pcm_wd_sz;
1292       pstr_mem_info->ui_size = frame_length * num_channel * (pcm_wd_sz >> 3);
1293       if (1 == pstr_api_struct->config[0].usac_config.sbr_enable) {
1294         switch (pstr_api_struct->config[0].ccfl_idx) {
1295           case SBR_8_3:  // 8:3
1296             pstr_mem_info->ui_size *= 8;
1297             pstr_mem_info->ui_size /= 3;
1298             break;
1299 
1300           case SBR_2_1:  // 2:1
1301             pstr_mem_info->ui_size *= 2;
1302             break;
1303 
1304           case SBR_4_1:  // 4:1
1305             pstr_mem_info->ui_size *= 4;
1306             break;
1307         }
1308       }
1309 
1310       pstr_mem_info->ui_alignment =
1311           BYTE_ALIGN_8; /* As input is used as scratch memory internally */
1312       pstr_mem_info->ui_type = IA_MEMTYPE_INPUT;
1313       pstr_mem_info->ui_placement[0] = 0;
1314       pstr_mem_info->ui_placement[1] = 0;
1315       pstr_mem_info->ui_priority = IA_MEMPRIORITY_ANYWHERE;
1316       pstr_mem_info->ui_placed[0] = 0;
1317       pstr_mem_info->ui_placed[1] = 0;
1318     }
1319 
1320     /* output */
1321     {
1322       pstr_mem_info = &pstr_api_struct->pstr_mem_info[IA_ENHAACPLUSENC_OUTPUT_IDX];
1323       pstr_mem_info->ui_size =
1324           ((MAX_PREROLL_FRAMES + 1) * (MAX_CHANNEL_BITS / BYTE_NUMBIT) * num_channel) +
1325           MAX_PREROLL_CONFIG_SIZE;
1326       pstr_mem_info->ui_alignment = BYTE_ALIGN_8;
1327       pstr_mem_info->ui_type = IA_MEMTYPE_OUTPUT;
1328       pstr_mem_info->ui_placement[0] = 0;
1329       pstr_mem_info->ui_placement[1] = 0;
1330       pstr_mem_info->ui_priority = IA_MEMPRIORITY_ANYWHERE;
1331       pstr_mem_info->ui_placed[0] = 0;
1332       pstr_mem_info->ui_placed[1] = 0;
1333     }
1334   } else {
1335     /* persistant */
1336     {
1337       pstr_mem_info = &pstr_api_struct->pstr_mem_info[IA_ENHAACPLUSENC_PERSIST_IDX];
1338       {
1339         if (pstr_api_struct->config[0].num_bs_elements == 1) {
1340           num_channel = pstr_api_struct->config[0].aac_classic
1341                             ? pstr_api_struct->config[0].chmode_nchannels
1342                             : (pstr_api_struct->config[0].use_parametric_stereo
1343                                    ? 1
1344                                    : pstr_api_struct->config[0].chmode_nchannels);
1345           pstr_mem_info->ui_size =
1346               IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_state_struct), BYTE_ALIGN_8) +
1347               ia_enhaacplus_enc_aac_enc_pers_size(num_channel, aot);
1348           if (pstr_api_struct->config[0].aot != AOT_AAC_LC &&
1349               pstr_api_struct->config[0].aot != AOT_AAC_LD) {
1350             pstr_mem_info->ui_size += ixheaace_sbr_enc_pers_size(
1351                 num_channel, pstr_api_struct->config[0].use_parametric_stereo, 0);
1352           }
1353           offset_size = ia_enhaacplus_enc_sizeof_delay_buffer(
1354                             pstr_api_struct->config[0].aac_config.flag_framelength_small, aot, 3,
1355                             sizeof(pstr_api_struct->pstr_state->inp_delay[0]),
1356                             pstr_api_struct->config[0].use_mps) *
1357                         pstr_api_struct->config[0].num_bs_elements;
1358           pstr_mem_info->ui_size += IXHEAAC_GET_SIZE_ALIGNED(offset_size, BYTE_ALIGN_8);
1359         }
1360         if (pstr_api_struct->config[0].num_bs_elements > 1) {
1361           offset_size = IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_state_struct), BYTE_ALIGN_8) +
1362                         ia_enhaacplus_enc_sizeof_delay_buffer(
1363                             pstr_api_struct->config[0].aac_config.flag_framelength_small, aot, 3,
1364                             sizeof(pstr_api_struct->pstr_state->inp_delay[0]),
1365                             pstr_api_struct->config[0].use_mps) *
1366                             pstr_api_struct->config[0].num_bs_elements;
1367           pstr_mem_info->ui_size += IXHEAAC_GET_SIZE_ALIGNED(offset_size, BYTE_ALIGN_8);
1368           for (ele_idx = 0; ele_idx < pstr_api_struct->config[0].num_bs_elements; ele_idx++) {
1369             num_channel = pstr_api_struct->config[ele_idx].i_channels;
1370             if (pstr_api_struct->config[ele_idx].element_type != ID_LFE)
1371               pstr_mem_info->ui_size += ixheaace_sbr_enc_pers_size(num_channel, 0, 0);
1372             pstr_mem_info->ui_size += ia_enhaacplus_enc_aac_enc_pers_size(num_channel, aot) + 32;
1373           }
1374         }
1375 
1376         if (pstr_api_struct->config[0].use_mps) {
1377           if (pstr_api_struct->config[0].aac_config.flag_framelength_small) {
1378             offset_size =
1379                 (MAX_INPUT_SAMPLES + (INPUT_DELAY_ELDV2_480 * IXHEAACE_MAX_CH_IN_BS_ELE)) *
1380                 sizeof(pstr_api_struct->pstr_state->time_signal_mps[0]);
1381           } else {
1382             offset_size =
1383                 (MAX_INPUT_SAMPLES + (INPUT_DELAY_ELDV2_512 * IXHEAACE_MAX_CH_IN_BS_ELE)) *
1384                 sizeof(pstr_api_struct->pstr_state->time_signal_mps[0]);
1385           }
1386           pstr_mem_info->ui_size += IXHEAAC_GET_SIZE_ALIGNED(offset_size, BYTE_ALIGN_8);
1387           if (pstr_api_struct->config[0].mps_tree_config == TREE_212) {
1388             pstr_mem_info->ui_size +=
1389                 IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_mps_212_memory_struct), BYTE_ALIGN_8);
1390           } else {
1391             pstr_mem_info->ui_size +=
1392                 IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_mps_515_memory_struct), BYTE_ALIGN_8);
1393           }
1394           pstr_mem_info->ui_size += IXHEAAC_GET_SIZE_ALIGNED(
1395               (MAX_MPS_BS_PAYLOAD_SIZE) * sizeof(pstr_api_struct->pstr_state->mps_bs[0]),
1396               BYTE_ALIGN_8);
1397         }
1398 
1399         offset_size = IXHEAACE_MAX_PAYLOAD_SIZE * pstr_api_struct->config[0].num_bs_elements;
1400         pstr_mem_info->ui_size += IXHEAAC_GET_SIZE_ALIGNED(offset_size, BYTE_ALIGN_8);
1401         offset_size = (MAX_FRAME_LEN * 2 + MAX_DS_2_1_FILTER_DELAY + INPUT_DELAY) *
1402                       MAX_INPUT_CHAN * sizeof(pstr_mem_info->ui_size);
1403         pstr_mem_info->ui_size += IXHEAAC_GET_SIZE_ALIGNED(offset_size, BYTE_ALIGN_8);
1404       }
1405 
1406       pstr_mem_info->ui_alignment = BYTE_ALIGN_8;
1407       pstr_mem_info->ui_type = IA_MEMTYPE_PERSIST;
1408       pstr_mem_info->ui_placement[0] = 0;
1409       pstr_mem_info->ui_placement[1] = 0;
1410       pstr_mem_info->ui_priority = IA_MEMPRIORITY_ANYWHERE;
1411       pstr_mem_info->ui_placed[0] = 0;
1412       pstr_mem_info->ui_placed[1] = 0;
1413     }
1414 
1415     /* scratch */
1416     {
1417       pstr_mem_info = &pstr_api_struct->pstr_mem_info[IA_ENHAACPLUSENC_SCRATCH_IDX];
1418       {
1419         pstr_mem_info->ui_size = ia_enhaacplus_enc_aac_enc_scr_size();
1420         UWORD32 sbr_scr_size = ixheaace_sbr_enc_scr_size() + ixheaace_resampler_scr_size();
1421         UWORD32 mps_scr_size = 0;
1422         if (pstr_api_struct->config[0].use_mps) {
1423           if (pstr_api_struct->config[0].mps_tree_config != TREE_212) {
1424             mps_scr_size = ixheaace_mps_515_scratch_size();
1425           }
1426         }
1427         pstr_mem_info->ui_size += MAX(sbr_scr_size, mps_scr_size);
1428       }
1429       pstr_mem_info->ui_alignment = BYTE_ALIGN_8;
1430       pstr_mem_info->ui_type = IA_MEMTYPE_SCRATCH;
1431       pstr_mem_info->ui_placement[0] = 0;
1432       pstr_mem_info->ui_placement[1] = 0;
1433       pstr_mem_info->ui_priority = IA_MEMPRIORITY_ANYWHERE;
1434       pstr_mem_info->ui_placed[0] = 0;
1435       pstr_mem_info->ui_placed[1] = 0;
1436     }
1437 
1438     /* input */
1439     {
1440       pstr_mem_info = &pstr_api_struct->pstr_mem_info[IA_ENHAACPLUSENC_INPUT_IDX];
1441 
1442       WORD32 pcm_wd_sz;
1443       pcm_wd_sz = pstr_api_struct->config[0].ui_pcm_wd_sz;
1444       num_channel = 0;
1445       for (ele_idx = 0; ele_idx < pstr_api_struct->config[0].num_bs_elements; ele_idx++) {
1446         num_channel += pstr_api_struct->config[ele_idx].i_channels;
1447       }
1448       {
1449         if (pstr_api_struct->config[0].aac_classic) {
1450           pstr_mem_info->ui_size = (frame_length * (pcm_wd_sz >> 3)) * num_channel;
1451         } else {
1452           pstr_mem_info->ui_size = (frame_length * (pcm_wd_sz >> 3)) * 2 * num_channel;
1453         }
1454       }
1455       pstr_mem_info->ui_alignment =
1456           BYTE_ALIGN_8; /* As input is used as scratch memory internally */
1457       pstr_mem_info->ui_type = IA_MEMTYPE_INPUT;
1458       pstr_mem_info->ui_placement[0] = 0;
1459       pstr_mem_info->ui_placement[1] = 0;
1460       pstr_mem_info->ui_priority = IA_MEMPRIORITY_ANYWHERE;
1461       pstr_mem_info->ui_placed[0] = 0;
1462       pstr_mem_info->ui_placed[1] = 0;
1463     }
1464 
1465     /* output */
1466     {
1467       pstr_mem_info = &pstr_api_struct->pstr_mem_info[IA_ENHAACPLUSENC_OUTPUT_IDX];
1468       if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
1469         pstr_mem_info->ui_size = (6 * frame_length / 8) * num_channel;
1470         pstr_mem_info->ui_size += (7) * IXHEAACE_MAX_CH_IN_BS_ELE * MAXIMUM_BS_ELE;
1471       } else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) {
1472         pstr_mem_info->ui_size = (6 * frame_length / 8) * num_channel;
1473       }
1474       pstr_mem_info->ui_alignment = BYTE_ALIGN_8;
1475       pstr_mem_info->ui_type = IA_MEMTYPE_OUTPUT;
1476       pstr_mem_info->ui_placement[0] = 0;
1477       pstr_mem_info->ui_placement[1] = 0;
1478       pstr_mem_info->ui_priority = IA_MEMPRIORITY_ANYWHERE;
1479       pstr_mem_info->ui_placed[0] = 0;
1480       pstr_mem_info->ui_placed[1] = 0;
1481     }
1482   }
1483 
1484   return;
1485 }
1486 
get_drc_config_size(ixheaace_api_struct * pstr_api_struct,ixheaace_input_config * ptr_in_cfg)1487 static WORD32 get_drc_config_size(ixheaace_api_struct *pstr_api_struct,
1488                                   ixheaace_input_config *ptr_in_cfg) {
1489   WORD32 bit_count = 0;
1490   WORD32 total_byte_cnt = 0;
1491 
1492   ia_drc_enc_state *pstr_drc_state =
1493       &pstr_api_struct->pstr_state->str_usac_enc_data.str_drc_state;
1494   ia_drc_input_config *pstr_in_drc_cfg = (ia_drc_input_config *)ptr_in_cfg->pv_drc_cfg;
1495 
1496   memset(pstr_drc_state, 0, sizeof(*pstr_drc_state));
1497 
1498   pstr_drc_state->str_enc_params = pstr_in_drc_cfg->str_enc_params;
1499   pstr_drc_state->str_uni_drc_config = pstr_in_drc_cfg->str_uni_drc_config;
1500   pstr_drc_state->str_gain_enc.str_loudness_info_set = pstr_in_drc_cfg->str_enc_loudness_info_set;
1501   pstr_drc_state->str_enc_gain_extension = pstr_in_drc_cfg->str_enc_gain_extension;
1502   pstr_drc_state->str_gain_enc.str_uni_drc_config = pstr_in_drc_cfg->str_uni_drc_config;
1503   pstr_drc_state->drc_scratch_mem =
1504       pstr_api_struct->pstr_state->str_usac_enc_data.str_scratch.ptr_scratch_buf;
1505   pstr_drc_state->str_gain_enc.base_ch_count = ptr_in_cfg->i_channels;
1506 
1507   //uniDrc payload size
1508   impd_drc_write_uni_drc_config(pstr_drc_state, &bit_count, 0);
1509   total_byte_cnt += ((bit_count + 7) >> 3);
1510   bit_count = 0;
1511 
1512   // LoudnessInfo payload size
1513   impd_drc_write_loudness_info_set(pstr_drc_state, NULL, &bit_count, 0);
1514   total_byte_cnt += ((bit_count + 7) >> 3);
1515 
1516   return total_byte_cnt;
1517 }
1518 
ixheaace_alloc_and_assign_mem(ixheaace_api_struct * pstr_api_struct,ixheaace_output_config * ptr_out_cfg,ixheaace_input_config * ptr_in_cfg)1519 static IA_ERRORCODE ixheaace_alloc_and_assign_mem(ixheaace_api_struct *pstr_api_struct,
1520                                                   ixheaace_output_config *ptr_out_cfg,
1521                                                   ixheaace_input_config *ptr_in_cfg) {
1522   IA_ERRORCODE err_code = IA_NO_ERROR;
1523   UWORD32 i_idx;
1524   pVOID pv_value;
1525   for (i_idx = 0; i_idx < 4; i_idx++) {
1526     if (i_idx == IA_ENHAACPLUSENC_OUTPUT_IDX &&
1527         pstr_api_struct->config[0].usac_config.use_drc_element) {
1528       WORD32 drc_config_size_expected =
1529           get_drc_config_size(pstr_api_struct, ptr_in_cfg);
1530       if (drc_config_size_expected > MAX_DRC_CONFIG_SIZE_EXPECTED) {
1531         return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
1532       }
1533       pstr_api_struct->pstr_mem_info[i_idx].ui_size += drc_config_size_expected;
1534     }
1535     ptr_out_cfg->mem_info_table[i_idx].ui_size = pstr_api_struct->pstr_mem_info[i_idx].ui_size;
1536     ptr_out_cfg->mem_info_table[i_idx].ui_alignment =
1537         pstr_api_struct->pstr_mem_info[i_idx].ui_alignment;
1538     ptr_out_cfg->mem_info_table[i_idx].ui_type = pstr_api_struct->pstr_mem_info[i_idx].ui_type;
1539 
1540     ptr_out_cfg->arr_alloc_memory[ptr_out_cfg->malloc_count] =
1541         ptr_out_cfg->malloc_xheaace(ptr_out_cfg->mem_info_table[i_idx].ui_size +
1542                                         ptr_out_cfg->mem_info_table[i_idx].ui_alignment,
1543                                     ptr_out_cfg->mem_info_table[i_idx].ui_alignment);
1544 
1545     if (NULL == ptr_out_cfg->arr_alloc_memory[ptr_out_cfg->malloc_count]) {
1546       return IA_EXHEAACE_API_FATAL_MEM_ALLOC;
1547     }
1548     memset(ptr_out_cfg->arr_alloc_memory[ptr_out_cfg->malloc_count], 0,
1549            ptr_out_cfg->mem_info_table[i_idx].ui_size);
1550     if ((i_idx == IA_ENHAACPLUSENC_PERSIST_IDX) || (i_idx == IA_ENHAACPLUSENC_SCRATCH_IDX)) {
1551       ptr_out_cfg->ui_rem =
1552           (SIZE_T)((SIZE_T)ptr_out_cfg->arr_alloc_memory[ptr_out_cfg->malloc_count] %
1553                    ptr_out_cfg->mem_info_table[i_idx].ui_alignment);
1554 
1555       pv_value = ptr_out_cfg->mem_info_table[i_idx].mem_ptr =
1556           (pVOID)((WORD8 *)ptr_out_cfg->arr_alloc_memory[ptr_out_cfg->malloc_count] +
1557                   ptr_out_cfg->mem_info_table[i_idx].ui_alignment - ptr_out_cfg->ui_rem);
1558     } else {
1559       pv_value = ptr_out_cfg->mem_info_table[i_idx].mem_ptr =
1560           ptr_out_cfg->arr_alloc_memory[ptr_out_cfg->malloc_count];
1561     }
1562 
1563     pstr_api_struct->pp_mem[i_idx] = ptr_out_cfg->mem_info_table[i_idx].mem_ptr;
1564     memset(pstr_api_struct->pp_mem[i_idx], 0, pstr_api_struct->pstr_mem_info[i_idx].ui_size);
1565 
1566     pstr_api_struct->pp_mem[i_idx] = pv_value;
1567 
1568     if (i_idx == IA_ENHAACPLUSENC_PERSIST_IDX) {
1569       WORD32 offset_size = IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_state_struct), BYTE_ALIGN_8);
1570       WORD8 *p_offset = NULL;
1571 
1572       /* Set persistent memory pointer in api obj */
1573       pstr_api_struct->pstr_state = (ixheaace_state_struct *)pv_value;
1574       WORD32 i, inp_delay_size;
1575       WORD8 *p_temp;
1576       if (pstr_api_struct->usac_en) {
1577         memset(pstr_api_struct->pstr_state, 0, sizeof(*(pstr_api_struct->pstr_state)));
1578         ia_usac_encoder_config_struct *pstr_usac_config = &pstr_api_struct->config[0].usac_config;
1579         ixheaace_state_struct *pstr_state = pstr_api_struct->pstr_state;
1580         ia_usac_data_struct *pstr_usac_enc_data = &(pstr_state->str_usac_enc_data);
1581 
1582         pstr_state->ptr_in_buf = (FLOAT32 **)((WORD8 *)pstr_state + offset_size);
1583 
1584         offset_size = pstr_usac_config->channels * sizeof(FLOAT32 *);
1585         p_offset = (WORD8 *)pstr_state->ptr_in_buf +
1586                    IXHEAAC_GET_SIZE_ALIGNED(offset_size, BYTE_ALIGN_8);
1587 
1588         // Input delay
1589         pstr_state->inp_delay = (FLOAT32 *)(p_offset);
1590         inp_delay_size =
1591             2 *
1592             ia_enhaacplus_enc_sizeof_delay_buffer(
1593                 0, AOT_USAC, pstr_api_struct->config[0].ccfl_idx,
1594                 sizeof(pstr_state->inp_delay[0]), pstr_api_struct->config[0].use_mps) *
1595             pstr_api_struct->config[0].num_bs_elements;
1596         memset(pstr_state->inp_delay, 0, inp_delay_size);
1597         p_offset += IXHEAAC_GET_SIZE_ALIGNED(inp_delay_size, BYTE_ALIGN_8);
1598         if (1 == pstr_usac_config->sbr_enable) {
1599           if (2 != pstr_usac_config->channels) {
1600             pstr_api_struct->pstr_state->time_signal = (FLOAT32 *)(p_offset);
1601 
1602             memset(pstr_api_struct->pstr_state->time_signal, 0,
1603                    (MAX_INPUT_SAMPLES) * sizeof(pstr_api_struct->pstr_state->time_signal[0]));
1604             offset_size =
1605                 (MAX_INPUT_SAMPLES) * sizeof(pstr_api_struct->pstr_state->time_signal[0]);
1606             p_offset += IXHEAAC_GET_SIZE_ALIGNED(offset_size, BYTE_ALIGN_8);
1607           }
1608 
1609           pstr_api_struct->pstr_state->spectral_band_replication_enc_pers_mem[0] =
1610               (struct ixheaace_str_sbr_enc *)p_offset;
1611           p_offset = p_offset + ixheaace_sbr_enc_pers_size(pstr_usac_config->channels, 0,
1612                                                            pstr_usac_config->sbr_harmonic);
1613         }
1614         if (1 == pstr_api_struct->config[0].use_mps) {
1615           pstr_api_struct->pstr_state->time_signal_mps = (FLOAT32 *)(p_offset);
1616 
1617           memset(pstr_api_struct->pstr_state->time_signal_mps, 0,
1618                  (MAX_INPUT_SAMPLES) * sizeof(pstr_api_struct->pstr_state->time_signal_mps[0]));
1619           offset_size =
1620               (MAX_INPUT_SAMPLES) * sizeof(pstr_api_struct->pstr_state->time_signal_mps[0]);
1621           p_offset += IXHEAAC_GET_SIZE_ALIGNED(offset_size, BYTE_ALIGN_8);
1622           pstr_api_struct->pstr_state->mps_bs = (UWORD8 *)(p_offset);
1623 
1624           memset(pstr_api_struct->pstr_state->mps_bs, 0,
1625                  (MAX_MPS_BS_PAYLOAD_SIZE) * sizeof(pstr_api_struct->pstr_state->mps_bs[0]));
1626 
1627           offset_size =
1628               (MAX_MPS_BS_PAYLOAD_SIZE) * sizeof(pstr_api_struct->pstr_state->mps_bs[0]);
1629           p_offset += IXHEAAC_GET_SIZE_ALIGNED(offset_size, BYTE_ALIGN_8);
1630 
1631           pstr_api_struct->pstr_state->mps_pers_mem = (ixheaace_mps_212_memory_struct *)p_offset;
1632           p_offset +=
1633               IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_mps_212_memory_struct), BYTE_ALIGN_8);
1634         } else {
1635           pstr_api_struct->pstr_state->mps_bs = NULL;
1636         }
1637         if (1 == pstr_usac_config->use_drc_element) {
1638           pstr_state->pp_drc_in_buf = (FLOAT32 **)((WORD8 *)p_offset);
1639           offset_size = pstr_usac_config->channels * sizeof(pstr_state->pp_drc_in_buf[0]);
1640           p_offset += IXHEAAC_GET_SIZE_ALIGNED(offset_size, BYTE_ALIGN_8);
1641           p_temp = p_offset;
1642 
1643           for (i = 0; i < pstr_usac_config->channels; i++) {
1644             pstr_state->pp_drc_in_buf[i] = (FLOAT32 *)(p_offset);
1645             p_offset += IXHEAAC_GET_SIZE_ALIGNED(
1646                 (pstr_usac_config->drc_frame_size * sizeof(pstr_state->pp_drc_in_buf[0][0]) * 2),
1647                 BYTE_ALIGN_8);
1648           }
1649           memset(p_temp, 0, (p_offset - p_temp));
1650         }
1651         p_temp = p_offset;
1652 
1653         for (i = 0; i < pstr_usac_config->channels; i++) {
1654           pstr_state->ptr_in_buf[i] = (FLOAT32 *)(p_offset);
1655           p_offset += IXHEAAC_GET_SIZE_ALIGNED((pstr_usac_config->ccfl * sizeof(FLOAT32) * 2),
1656                                                 BYTE_ALIGN_8);
1657         }
1658         memset(p_temp, 0, (p_offset - p_temp));
1659 
1660         p_temp = p_offset;
1661         for (i = 0; i < pstr_usac_config->channels; i++) {
1662           pstr_usac_enc_data->ptr_time_data[i] = (FLOAT64 *)(p_offset);
1663           p_offset += IXHEAAC_GET_SIZE_ALIGNED((2 * (pstr_usac_config->ccfl) * sizeof(FLOAT64)),
1664                                                 BYTE_ALIGN_8);
1665         }
1666 
1667         for (i = 0; i < pstr_usac_config->channels; i++) {
1668           pstr_usac_enc_data->ptr_look_ahead_time_data[i] = (FLOAT64 *)(p_offset);
1669           p_offset +=
1670               IXHEAAC_GET_SIZE_ALIGNED((pstr_usac_config->ccfl * sizeof(FLOAT64)), BYTE_ALIGN_8);
1671         }
1672 
1673         for (i = 0; i < pstr_usac_config->channels; i++) {
1674           pstr_usac_enc_data->spectral_line_vector[i] = (FLOAT64 *)(p_offset);
1675           p_offset += IXHEAAC_GET_SIZE_ALIGNED((2 * pstr_usac_config->ccfl * sizeof(FLOAT64)),
1676                                                 BYTE_ALIGN_8);
1677         }
1678 
1679         for (i = 0; i < pstr_usac_config->channels; i++) {
1680           pstr_usac_enc_data->ptr_2frame_time_data[i] = (FLOAT64 *)(p_offset);
1681           p_offset += IXHEAAC_GET_SIZE_ALIGNED((3 * pstr_usac_config->ccfl * sizeof(FLOAT64)),
1682                                                 BYTE_ALIGN_8);
1683         }
1684         memset(p_temp, 0, p_offset - p_temp);
1685 
1686         if (pstr_usac_config->tns_select != 0) {
1687           p_temp = p_offset;
1688           for (i = 0; i < pstr_usac_config->channels; i++) {
1689             pstr_usac_enc_data->pstr_tns_info[i] = (ia_tns_info *)(p_offset);
1690             p_offset += IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_tns_info), BYTE_ALIGN_8);
1691           }
1692           memset(p_temp, 0, p_offset - p_temp);
1693         }
1694 
1695         p_temp = p_offset;
1696         for (i = 0; i < pstr_usac_config->channels; i++) {
1697           pstr_usac_enc_data->td_encoder[i] = (ia_usac_td_encoder_struct *)(p_offset);
1698           p_offset += IXHEAAC_GET_SIZE_ALIGNED(sizeof(ia_usac_td_encoder_struct), BYTE_ALIGN_8);
1699         }
1700         memset(p_temp, 0, p_offset - p_temp);
1701       } else {
1702         WORD32 num_aac_chan;
1703         ixheaace_state_struct *pstr_state = pstr_api_struct->pstr_state;
1704         memset(pstr_api_struct->pstr_state, 0, sizeof(*(pstr_api_struct->pstr_state)));
1705 
1706         pstr_api_struct->pstr_state->inp_delay = (FLOAT32 *)((WORD8 *)pstr_state + offset_size);
1707         offset_size = ia_enhaacplus_enc_sizeof_delay_buffer(
1708                           pstr_api_struct->config[0].aac_config.flag_framelength_small,
1709                           pstr_api_struct->config[0].aot, 3,
1710                           sizeof(pstr_api_struct->pstr_state->inp_delay[0]),
1711                           pstr_api_struct->config[0].use_mps) *
1712                       pstr_api_struct->config[0].num_bs_elements;
1713         p_offset = (WORD8 *)pstr_api_struct->pstr_state->inp_delay +
1714                    IXHEAAC_GET_SIZE_ALIGNED(offset_size, BYTE_ALIGN_8);
1715 
1716         if (pstr_api_struct->config[0].use_mps) {
1717           pstr_api_struct->pstr_state->time_signal_mps = (FLOAT32 *)(p_offset);
1718 
1719           memset(pstr_api_struct->pstr_state->time_signal_mps, 0,
1720                  (MAX_INPUT_SAMPLES + (INPUT_DELAY_ELDV2_512 * IXHEAACE_MAX_CH_IN_BS_ELE)) *
1721                      sizeof(pstr_api_struct->pstr_state->time_signal_mps[0]));
1722           offset_size =
1723               (MAX_INPUT_SAMPLES + (INPUT_DELAY_ELDV2_512 * IXHEAACE_MAX_CH_IN_BS_ELE)) *
1724               sizeof(pstr_api_struct->pstr_state->time_signal_mps[0]);
1725           p_offset += IXHEAAC_GET_SIZE_ALIGNED(offset_size, BYTE_ALIGN_8);
1726 
1727           pstr_api_struct->pstr_state->mps_bs = (UWORD8 *)(p_offset);
1728           memset(pstr_api_struct->pstr_state->mps_bs, 0,
1729                  (MAX_MPS_BS_PAYLOAD_SIZE) * sizeof(pstr_api_struct->pstr_state->mps_bs[0]));
1730           offset_size =
1731               (MAX_MPS_BS_PAYLOAD_SIZE) * sizeof(pstr_api_struct->pstr_state->mps_bs[0]);
1732           p_offset += IXHEAAC_GET_SIZE_ALIGNED(offset_size, BYTE_ALIGN_8);
1733 
1734           if (pstr_api_struct->config[0].mps_tree_config == TREE_212) {
1735             pstr_api_struct->pstr_state->mps_pers_mem =
1736                 (ixheaace_mps_212_memory_struct *)p_offset;
1737             p_offset +=
1738                 IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_mps_212_memory_struct), BYTE_ALIGN_8);
1739           } else {
1740             pstr_api_struct->pstr_state->mps_515_pers_mem =
1741                 (ixheaace_mps_515_memory_struct *)p_offset;
1742             p_offset +=
1743                 IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_mps_515_memory_struct), BYTE_ALIGN_8);
1744           }
1745         } else {
1746           pstr_api_struct->pstr_state->mps_bs = NULL;
1747         }
1748 
1749         for (WORD32 ele_idx = 0; ele_idx < pstr_api_struct->config[0].num_bs_elements;
1750              ele_idx++) {
1751           num_aac_chan = pstr_api_struct->config[ele_idx].aac_classic
1752                              ? pstr_api_struct->config[ele_idx].chmode_nchannels
1753                              : (pstr_api_struct->config[ele_idx].use_parametric_stereo
1754                                     ? 1
1755                                     : pstr_api_struct->config[ele_idx].chmode_nchannels);
1756 
1757           /* Set aac enc persistent memory pointer in api obj */
1758           pstr_api_struct->pstr_state->aac_enc_pers_mem[ele_idx] =
1759               (iexheaac_encoder_str *)p_offset;
1760           p_offset = p_offset + ia_enhaacplus_enc_aac_enc_pers_size(
1761                                     num_aac_chan, pstr_api_struct->config[ele_idx].aot);
1762 
1763           if (pstr_api_struct->config[ele_idx].aot != AOT_AAC_LC &&
1764               pstr_api_struct->config[ele_idx].aot != AOT_AAC_LD) {
1765             if (pstr_api_struct->config[ele_idx].element_type != ID_LFE) {
1766               /* Set spectral_band_replication_ enc persistent memory pointer in api obj */
1767               pstr_api_struct->pstr_state->spectral_band_replication_enc_pers_mem[ele_idx] =
1768                   (struct ixheaace_str_sbr_enc *)p_offset;
1769 
1770               p_offset =
1771                   p_offset +
1772                   ixheaace_sbr_enc_pers_size(
1773                       num_aac_chan, pstr_api_struct->config[ele_idx].use_parametric_stereo, 0);
1774             }
1775           }
1776         }
1777       }
1778     }
1779 
1780     if ((i_idx == IA_MEMTYPE_SCRATCH) && pstr_api_struct->usac_en) {
1781       pstr_api_struct->pstr_state->str_usac_enc_data.str_scratch.ptr_scratch_buf =
1782           (UWORD8 *)pstr_api_struct->pp_mem[IA_MEMTYPE_SCRATCH];
1783       memset(pstr_api_struct->pp_mem[IA_MEMTYPE_SCRATCH], 0,
1784              pstr_api_struct->pstr_mem_info[i_idx].ui_size);
1785     }
1786     if (i_idx == IA_ENHAACPLUSENC_INPUT_IDX) {
1787       ptr_out_cfg->ui_inp_buf_size = ptr_out_cfg->mem_info_table[i_idx].ui_size;
1788     }
1789     ptr_out_cfg->malloc_count++;
1790   }
1791   return err_code;
1792 }
1793 
ixheaace_write_audio_preroll_data(ixheaace_api_struct * pstr_api_struct,ia_bit_buf_struct * it_bit_buff)1794 static VOID ixheaace_write_audio_preroll_data(ixheaace_api_struct *pstr_api_struct,
1795                                               ia_bit_buf_struct *it_bit_buff) {
1796   ixheaace_config_struct *pstr_config = &pstr_api_struct->config[0];
1797   ixheaace_state_struct *pstr_enc_state = pstr_api_struct->pstr_state;
1798   ia_usac_data_struct *pstr_usac_data = &pstr_enc_state->str_usac_enc_data;
1799   ia_usac_encoder_config_struct *pstr_usac_config = &pstr_config->usac_config;
1800   WORD32 i, j, padding_bits;
1801 
1802   if (pstr_usac_config->is_ipf) {
1803     if (pstr_usac_config->iframes_interval == pstr_usac_config->num_preroll_frames) {
1804       WORD32 config_len = 0, num_bits = 0, au_len = 0, config_bits = 0;
1805       WORD32 bytes_to_write;
1806       UWORD8 *ptr_out = (UWORD8 *)pstr_api_struct->pp_mem[IA_MEMTYPE_OUTPUT];
1807       WORD32 max_output_size =
1808           ((MAX_CHANNEL_BITS / BYTE_NUMBIT) * pstr_usac_config->channels) * MAX_PREROLL_FRAMES +
1809           MAX_PREROLL_CONFIG_SIZE;
1810       UWORD8 *out_data = ptr_out + max_output_size;
1811       UWORD8 residual_bits = 0, residual_data = 0;
1812       memmove(ptr_out + max_output_size, ptr_out, pstr_enc_state->i_out_bytes);
1813       pstr_usac_config->is_ipf = 0;
1814 
1815       config_bits = ixheaace_get_usac_config_bytes(NULL, &pstr_enc_state->audio_specific_config,
1816                                                    pstr_config->ccfl_idx);
1817       config_len = (config_bits + 7) >> 3;
1818       num_bits = iusace_write_escape_value(NULL, config_len, 4, 4, 8);
1819       num_bits += (config_len * 8);  // config data bits
1820       num_bits++;                    // apply-crossfade
1821       num_bits++;                    // apr-reserved
1822       // bits for number of preroll frames
1823       num_bits += iusace_write_escape_value(NULL, pstr_usac_config->num_preroll_frames, 2, 4, 0);
1824       // bits for au_len
1825       for (i = 0; i < pstr_usac_config->num_preroll_frames; i++) {
1826         num_bits += iusace_write_escape_value(NULL, pstr_usac_data->prev_out_bytes[i], 16, 16, 0);
1827         au_len += pstr_usac_data->prev_out_bytes[i];
1828       }
1829       iusace_reset_bit_buffer(it_bit_buff);
1830       // total bytes to write
1831       bytes_to_write = (num_bits + 7) >> 3;
1832       // usacIndependencyFlag
1833       iusace_write_bits_buf(it_bit_buff, pstr_usac_data->usac_independency_flag, 1);
1834       iusace_write_bits_buf(it_bit_buff, 1, 1);  // usacExtElementPresent
1835       iusace_write_bits_buf(it_bit_buff, 0, 1);  // usacExtElementUseDefaultLength
1836 
1837       if (au_len + bytes_to_write >= MAXIMUM_VALUE_8BIT) {
1838         iusace_write_escape_value(it_bit_buff, au_len + bytes_to_write + 2, 8, 16, 0);
1839       } else {
1840         iusace_write_bits_buf(it_bit_buff, au_len + bytes_to_write, 8);
1841       }
1842 
1843       iusace_write_escape_value(it_bit_buff, config_len, 4, 4, 8);  // configLen
1844       // Config
1845       ixheaace_get_usac_config_bytes(it_bit_buff, &pstr_enc_state->audio_specific_config,
1846                                      pstr_config->ccfl_idx);
1847 
1848       if (config_bits % 8) {
1849         iusace_write_bits_buf(it_bit_buff, 0, (UWORD8)((config_len << 3) - config_bits));
1850       }
1851 
1852       iusace_write_bits_buf(it_bit_buff, 0, 1);  // applyCrossfade
1853       iusace_write_bits_buf(it_bit_buff, 0, 1);  // apr_reserved
1854       // numPreRollFrames
1855       iusace_write_escape_value(it_bit_buff, pstr_usac_config->num_preroll_frames, 2, 4, 0);
1856       for (i = 0; i < pstr_usac_config->num_preroll_frames; i++) {
1857         au_len = pstr_usac_data->prev_out_bytes[i];
1858 
1859         if (pstr_usac_config->iframes_interval != 0) {
1860           out_data = pstr_usac_data->prev_out_data[i];
1861         }
1862 
1863         // auLen
1864         iusace_write_escape_value(it_bit_buff, au_len, 16, 16, 0);
1865 
1866         // AccessUnit
1867         for (j = 0; j < au_len; j++) {
1868           iusace_write_bits_buf(it_bit_buff, *out_data, 8);
1869           out_data++;
1870         }
1871       }
1872 
1873       if (num_bits % 8) {
1874         iusace_write_bits_buf(it_bit_buff, 0, (UWORD8)((bytes_to_write << 3) - num_bits));
1875       }
1876       // current frame
1877       au_len = pstr_enc_state->i_out_bits >> 3;
1878       residual_bits = (UWORD8)(pstr_enc_state->i_out_bits - (au_len << 3));
1879       out_data = ptr_out + max_output_size;
1880       for (j = 0; j < au_len; j++) {
1881         iusace_write_bits_buf(it_bit_buff, *out_data, 8);
1882         out_data++;
1883       }
1884       residual_data = *out_data >> (8 - residual_bits);
1885       iusace_write_bits_buf(it_bit_buff, residual_data, residual_bits);
1886 
1887       padding_bits = 8 - (it_bit_buff->cnt_bits & 7);
1888       if (padding_bits > 0 && padding_bits < 8) {
1889         ptr_out[it_bit_buff->cnt_bits >> 3] =
1890             (WORD8)((UWORD32)ptr_out[it_bit_buff->cnt_bits >> 3]) & (0xFF << padding_bits);
1891       }
1892       pstr_enc_state->i_out_bytes = (it_bit_buff->cnt_bits + 7) >> 3;
1893       pstr_usac_config->preroll_idx++;
1894 
1895       if (!pstr_usac_config->is_first_frame) {
1896         pstr_usac_config->preroll_idx = pstr_usac_config->num_preroll_frames + 1;
1897       }
1898       if (pstr_usac_config->is_first_frame) {
1899         pstr_usac_config->is_first_frame = 0;
1900       }
1901     } else {
1902       if (pstr_usac_config->preroll_idx < pstr_usac_config->num_preroll_frames) {
1903         WORD32 *ptr_prev_out_bytes = pstr_usac_data->prev_out_bytes;
1904         WORD32 pr_idx = pstr_usac_config->preroll_idx;
1905         UWORD8 *ptr_out = (UWORD8 *)pstr_api_struct->pp_mem[IA_MEMTYPE_OUTPUT];
1906         ptr_prev_out_bytes[pr_idx] = pstr_enc_state->i_out_bytes;
1907         memcpy(pstr_usac_data->prev_out_data[pr_idx++], ptr_out, pstr_enc_state->i_out_bytes);
1908         pstr_usac_config->preroll_idx = pr_idx;
1909         pstr_enc_state->i_out_bytes = 0;
1910       }
1911     }
1912   } else {
1913     for (j = 0; j < pstr_usac_config->num_preroll_frames - 1; j++) {
1914       pstr_usac_data->prev_out_bytes[j] = pstr_usac_data->prev_out_bytes[j + 1];
1915     }
1916     if (pstr_usac_config->num_preroll_frames) {
1917       pstr_usac_data->prev_out_bytes[pstr_usac_config->num_preroll_frames - 1] =
1918           pstr_enc_state->i_out_bytes;
1919     }
1920     pstr_usac_config->preroll_idx = pstr_usac_config->num_preroll_frames + 1;
1921   }
1922   return;
1923 }
1924 
ia_usac_enc_init(ixheaace_api_struct * pstr_api_struct,WORD32 ccfl_idx)1925 static IA_ERRORCODE ia_usac_enc_init(ixheaace_api_struct *pstr_api_struct, WORD32 ccfl_idx) {
1926   IA_ERRORCODE error = IA_NO_ERROR;
1927   WORD32 i = 0;
1928   ixheaace_config_struct *pstr_config = &pstr_api_struct->config[0];
1929   ixheaace_state_struct *pstr_enc_state = pstr_api_struct->pstr_state;
1930   ia_usac_data_struct *pstr_enc_data = &pstr_enc_state->str_usac_enc_data;
1931   ia_usac_encoder_config_struct *pstr_usac_config = &pstr_config->usac_config;
1932 
1933   pstr_usac_config->bit_rate = pstr_api_struct->config[0].aac_config.bit_rate;
1934 
1935   if ((pstr_usac_config->codec_mode == USAC_SWITCHED) ||
1936       (pstr_usac_config->codec_mode == USAC_ONLY_FD)) {
1937     pstr_usac_config->aac_allow_scalefacs = 1;
1938     if (pstr_usac_config->aac_scale_facs == 0) pstr_usac_config->aac_allow_scalefacs = 0;
1939   }
1940 
1941   if (pstr_usac_config->codec_mode == USAC_ONLY_TD) {
1942     for (i = 0; i < pstr_config->i_channels; i++) {
1943       pstr_enc_data->core_mode_prev[i] = CORE_MODE_FD;
1944       pstr_enc_data->core_mode[i] = CORE_MODE_TD;
1945     }
1946   } else {
1947     for (i = 0; i < pstr_config->i_channels; i++) {
1948       pstr_enc_data->core_mode_prev[i] = CORE_MODE_FD;
1949       pstr_enc_data->core_mode[i] = CORE_MODE_FD;
1950     }
1951   }
1952 
1953   if (1 == pstr_usac_config->use_drc_element) {
1954     pstr_enc_data->str_scratch.drc_scratch = pstr_enc_data->str_scratch.ptr_scratch_buf;
1955   }
1956   if (pstr_usac_config->sbr_enable) {
1957     WORD8 *sbr_scr_ptr = (WORD8 *)pstr_enc_data->str_scratch.ptr_scratch_buf;
1958     ixheaace_audio_specific_config_struct *pstr_asc = &pstr_enc_state->audio_specific_config;
1959     ixheaace_str_sbr_cfg spectral_band_replication_config;
1960     // SBR defaults
1961     iaace_config *pstr_sbr_config = &(pstr_api_struct->config[0].aac_config);
1962     WORD32 sbr_ratio = 0;
1963     WORD32 samples = pstr_usac_config->ccfl;
1964     // Set scratch buffers for SBR and resampler
1965     pstr_api_struct->pstr_state->temp_buff_sbr =
1966         (WORD8 *)pstr_enc_data->str_scratch.ptr_scratch_buf;
1967     pstr_api_struct->pstr_state->ptr_temp_buff_resamp =
1968         (WORD8 *)pstr_enc_data->str_scratch.ptr_scratch_buf + ixheaace_sbr_enc_scr_size();
1969 
1970     ixheaace_initialize_sbr_defaults(&spectral_band_replication_config);
1971     // Set SBR codec as USAC
1972     spectral_band_replication_config.sbr_codec = USAC_SBR;
1973     spectral_band_replication_config.sbr_pvc_active = pstr_usac_config->sbr_pvc_active;
1974     spectral_band_replication_config.sbr_harmonic = pstr_usac_config->sbr_harmonic;
1975     spectral_band_replication_config.hq_esbr = pstr_usac_config->hq_esbr;
1976     pstr_usac_config->core_sample_rate = pstr_usac_config->sample_rate / 2;
1977     switch (pstr_usac_config->ccfl_idx) {
1978       case SBR_4_1:
1979         spectral_band_replication_config.sbr_ratio_idx = USAC_SBR_RATIO_INDEX_4_1;
1980         spectral_band_replication_config.sbr_pvc_rate = USAC_SBR_DOWNSAMPLE_RATIO_4_1;
1981         pstr_usac_config->core_sample_rate = pstr_usac_config->sample_rate / 4;
1982         sbr_ratio = 4;
1983         samples *= 4;
1984         break;
1985       case SBR_8_3:
1986         spectral_band_replication_config.sbr_ratio_idx = USAC_SBR_RATIO_INDEX_8_3;
1987         spectral_band_replication_config.sbr_pvc_rate = USAC_SBR_DOWNSAMPLE_RATIO_2_1;
1988         sbr_ratio = 2;
1989         samples *= 8;
1990         samples /= 3;
1991         break;
1992       case SBR_2_1:
1993         spectral_band_replication_config.sbr_ratio_idx = USAC_SBR_RATIO_INDEX_2_1;
1994         spectral_band_replication_config.sbr_pvc_rate = USAC_SBR_DOWNSAMPLE_RATIO_2_1;
1995         sbr_ratio = 2;
1996         samples *= 2;
1997         break;
1998       default:
1999         spectral_band_replication_config.sbr_ratio_idx = USAC_SBR_RATIO_NO_SBR;
2000         spectral_band_replication_config.sbr_pvc_rate = 2;
2001         sbr_ratio = 2;
2002         break;
2003     }
2004     if (pstr_api_struct->pstr_state->mps_enable) {
2005       ixheaace_mps_212_memory_struct *pstr_mps_memory;
2006       pstr_mps_memory = pstr_api_struct->pstr_state->mps_pers_mem;
2007       ixheaace_mps_212_open(&pstr_api_struct->pstr_mps_212_enc, pstr_mps_memory);
2008       pstr_asc->str_aac_config.num_sac_cfg_bits = 0;
2009 
2010       error = ixheaace_mps_212_initialise(
2011           pstr_api_struct->pstr_mps_212_enc, AOT_USAC, pstr_usac_config->sample_rate,
2012           &pstr_sbr_config->bit_rate, sbr_ratio, (WORD32)samples, samples, 515 * sbr_ratio,
2013           (WORD8 *)pstr_api_struct->pstr_state->ptr_temp_buff_resamp);
2014       if (error) {
2015         return error;
2016       }
2017 
2018       pstr_asc->str_aac_config.num_sac_cfg_bits = ixheaace_mps_212_get_spatial_specific_config(
2019           pstr_api_struct->pstr_mps_212_enc, (WORD8 *)pstr_asc->str_aac_config.sac_cfg_data,
2020           sizeof(pstr_asc->str_aac_config.sac_cfg_data), AOT_USAC);
2021     }
2022     ixheaace_adjust_sbr_settings(
2023         &spectral_band_replication_config, pstr_sbr_config->bit_rate,
2024         (pstr_api_struct->pstr_state->mps_enable != 1) ? pstr_config->i_channels : 1,
2025         pstr_usac_config->core_sample_rate, AACENC_TRANS_FAC, 24000,
2026         pstr_api_struct->spectral_band_replication_tabs.ptr_qmf_tab,
2027         pstr_api_struct->pstr_state->aot);
2028 
2029     error = ixheaace_env_open(
2030         &pstr_api_struct->pstr_state->spectral_band_replication_enc_pers_mem[0],
2031         &spectral_band_replication_config, &pstr_sbr_config->band_width, sbr_scr_ptr,
2032         &(pstr_api_struct->spectral_band_replication_tabs), &pstr_asc->str_aac_config.sbr_config);
2033     if (error) {
2034       return error;
2035     }
2036 
2037     if (pstr_api_struct->config[0].ccfl_idx >= 2) {
2038       pstr_api_struct->pstr_state->downsample[0] = 1;
2039     } else {
2040       pstr_api_struct->pstr_state->downsample[0] = 0;
2041     }
2042 
2043     if (pstr_api_struct->pstr_state->downsample[0]) {
2044       IA_ERRORCODE resamp_error = IA_NO_ERROR;
2045       WORD32 resamp_ratio = 0, upsamp_fac = 0, downsamp_fac = 0;
2046       WORD32 ele_idx = 0, ch_idx = 0;
2047 
2048       if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) {
2049         upsamp_fac = 3;
2050         downsamp_fac = 8;
2051         pstr_usac_config->sample_rate /= 2;
2052       } else if (pstr_api_struct->config[0].ccfl_idx == SBR_2_1) {
2053         resamp_ratio = 2;
2054         pstr_usac_config->sample_rate /= 2;
2055       } else if (pstr_api_struct->config[0].ccfl_idx == SBR_4_1) {
2056         resamp_ratio = 4;
2057         pstr_usac_config->sample_rate /= 4;
2058       }
2059 
2060       if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) {
2061         if (upsamp_fac != 3 || downsamp_fac != 8) {
2062           return IA_EXHEAACE_CONFIG_FATAL_USAC_RESAMPLER_RATIO;
2063         }
2064       } else {
2065         if (resamp_ratio != 2 && resamp_ratio != 4) {
2066           return IA_EXHEAACE_CONFIG_FATAL_USAC_RESAMPLER_RATIO;
2067         }
2068       }
2069       if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) {  // Upsampler initialization
2070         resamp_error = ia_enhaacplus_enc_init_iir_sos_resampler(
2071             &(pstr_api_struct->pstr_state->up_sampler[ele_idx][ch_idx]), upsamp_fac,
2072             pstr_api_struct->spectral_band_replication_tabs.ptr_sos_upsamp_tab);
2073         if (resamp_error) {
2074           return resamp_error;
2075         }
2076         if (pstr_api_struct->config[0].i_channels > 1) {
2077           resamp_error = ia_enhaacplus_enc_init_iir_sos_resampler(
2078               &(pstr_api_struct->pstr_state->up_sampler[ele_idx][ch_idx + 1]), upsamp_fac,
2079               pstr_api_struct->spectral_band_replication_tabs.ptr_sos_upsamp_tab);
2080           if (resamp_error) {
2081             return resamp_error;
2082           }
2083         }
2084         if (pstr_usac_config->sbr_harmonic) {
2085           resamp_error = ia_enhaacplus_enc_init_iir_sos_resampler(
2086               &(pstr_api_struct->pstr_state->hbe_up_sampler[ele_idx][ch_idx]), upsamp_fac,
2087               pstr_api_struct->spectral_band_replication_tabs.ptr_sos_upsamp_tab);
2088           if (resamp_error) {
2089             return resamp_error;
2090           }
2091           if (pstr_api_struct->config[0].i_channels > 1) {
2092             resamp_error = ia_enhaacplus_enc_init_iir_sos_resampler(
2093                 &(pstr_api_struct->pstr_state->hbe_up_sampler[ele_idx][ch_idx + 1]), upsamp_fac,
2094                 pstr_api_struct->spectral_band_replication_tabs.ptr_sos_upsamp_tab);
2095             if (resamp_error) {
2096               return resamp_error;
2097             }
2098           }
2099         }
2100         // Downsampler initialization
2101         resamp_error = ia_enhaacplus_enc_init_iir_sos_resampler(
2102             &(pstr_api_struct->pstr_state->down_samp_sos[ele_idx][ch_idx]), downsamp_fac,
2103             pstr_api_struct->spectral_band_replication_tabs.ptr_sos_downsamp_tab);
2104         if (resamp_error) {
2105           return resamp_error;
2106         }
2107         if (pstr_api_struct->config[0].i_channels > 1) {
2108           resamp_error = ia_enhaacplus_enc_init_iir_sos_resampler(
2109               &(pstr_api_struct->pstr_state->down_samp_sos[ele_idx][ch_idx + 1]), downsamp_fac,
2110               pstr_api_struct->spectral_band_replication_tabs.ptr_sos_downsamp_tab);
2111           if (resamp_error) {
2112             return resamp_error;
2113           }
2114         }
2115         if (pstr_usac_config->sbr_harmonic) {
2116           resamp_error = ia_enhaacplus_enc_init_iir_sos_resampler(
2117               &(pstr_api_struct->pstr_state->hbe_down_samp_sos[ele_idx][ch_idx]), downsamp_fac,
2118               pstr_api_struct->spectral_band_replication_tabs.ptr_sos_downsamp_tab);
2119           if (resamp_error) {
2120             return resamp_error;
2121           }
2122           if (pstr_api_struct->config[0].i_channels > 1) {
2123             resamp_error = ia_enhaacplus_enc_init_iir_sos_resampler(
2124                 &(pstr_api_struct->pstr_state->hbe_down_samp_sos[ele_idx][ch_idx + 1]),
2125                 downsamp_fac,
2126                 pstr_api_struct->spectral_band_replication_tabs.ptr_sos_downsamp_tab);
2127             if (resamp_error) {
2128               return resamp_error;
2129             }
2130           }
2131         }
2132       } else if (pstr_api_struct->config[0].ccfl_idx == SBR_2_1 ||
2133                  pstr_api_struct->config[0].ccfl_idx == SBR_4_1) {
2134         resamp_error = ia_enhaacplus_enc_init_iir_resampler(
2135             &(pstr_api_struct->pstr_state->down_sampler[ele_idx][ch_idx]), resamp_ratio,
2136             pstr_api_struct->spectral_band_replication_tabs.ptr_resamp_tab);
2137         if (resamp_error) {
2138           return resamp_error;
2139         }
2140         if (pstr_api_struct->config[0].i_channels > 1) {
2141           resamp_error = ia_enhaacplus_enc_init_iir_resampler(
2142               &(pstr_api_struct->pstr_state->down_sampler[ele_idx][ch_idx + 1]), resamp_ratio,
2143               pstr_api_struct->spectral_band_replication_tabs.ptr_resamp_tab);
2144           if (resamp_error) {
2145             return resamp_error;
2146           }
2147         }
2148         if (pstr_usac_config->sbr_harmonic) {
2149           resamp_error = ia_enhaacplus_enc_init_iir_resampler(
2150               &(pstr_api_struct->pstr_state->hbe_down_sampler[ele_idx][ch_idx]), resamp_ratio,
2151               pstr_api_struct->spectral_band_replication_tabs.ptr_resamp_tab);
2152           if (resamp_error) {
2153             return resamp_error;
2154           }
2155           if (pstr_api_struct->config[0].i_channels > 1) {
2156             resamp_error = ia_enhaacplus_enc_init_iir_resampler(
2157                 &(pstr_api_struct->pstr_state->hbe_down_sampler[ele_idx][ch_idx + 1]),
2158                 resamp_ratio, pstr_api_struct->spectral_band_replication_tabs.ptr_resamp_tab);
2159             if (resamp_error) {
2160               return resamp_error;
2161             }
2162           }
2163         }
2164       }
2165     }
2166   }
2167 
2168   error = iusace_enc_init(pstr_usac_config, &pstr_api_struct->pstr_state->audio_specific_config,
2169                           &pstr_api_struct->pstr_state->str_usac_enc_data);
2170   if (error & IA_FATAL_ERROR) {
2171     return error;
2172   }
2173   pstr_api_struct->pstr_state->str_usac_enc_data.frame_count = 0;
2174   pstr_usac_config->is_ipf = 1;
2175   pstr_enc_data->stereo_config_index = (pstr_enc_state->mps_enable == 1) ? 2 : 0;
2176   ia_bit_buf_struct *pstr_ia_asc_bit_buf;
2177   pstr_ia_asc_bit_buf = iusace_create_bit_buffer(
2178       &(pstr_api_struct->pstr_state->str_bit_buf), pstr_api_struct->pp_mem[IA_MEMTYPE_OUTPUT],
2179       pstr_api_struct->pstr_mem_info[IA_MEMTYPE_OUTPUT].ui_size, 1);
2180   if (pstr_usac_config->sbr_enable) {
2181     for (UWORD32 idx = 0; idx < pstr_usac_config->num_elements; idx++) {
2182       switch (pstr_enc_state->audio_specific_config.str_usac_config.usac_element_type[idx]) {
2183         case ID_USAC_SCE:
2184         case ID_USAC_CPE:
2185           pstr_enc_state->audio_specific_config.str_usac_config.str_usac_element_config[idx]
2186               .stereo_config_index = pstr_enc_data->stereo_config_index;
2187           pstr_enc_state->audio_specific_config.str_usac_config.str_usac_element_config[idx]
2188               .str_usac_sbr_config.bs_inter_tes = pstr_usac_config->sbr_inter_tes_active;
2189           pstr_enc_state->audio_specific_config.str_usac_config.str_usac_element_config[idx]
2190               .str_usac_sbr_config.bs_pvc = pstr_usac_config->sbr_pvc_active;
2191           pstr_enc_state->audio_specific_config.str_usac_config.str_usac_element_config[idx]
2192               .str_usac_sbr_config.dflt_header_extra1 = 0;
2193           pstr_enc_state->audio_specific_config.str_usac_config.str_usac_element_config[idx]
2194               .str_usac_sbr_config.dflt_header_extra2 = 0;
2195           pstr_enc_state->audio_specific_config.str_usac_config.str_usac_element_config[idx]
2196               .str_usac_sbr_config.dflt_start_freq = 0;
2197           pstr_enc_state->audio_specific_config.str_usac_config.str_usac_element_config[idx]
2198               .str_usac_sbr_config.dflt_stop_freq = 4;
2199           pstr_enc_state->audio_specific_config.str_usac_config.str_usac_element_config[idx]
2200               .str_usac_sbr_config.harmonic_sbr = pstr_usac_config->sbr_harmonic;
2201           break;
2202         default:
2203           continue;
2204       }
2205     }
2206   }
2207 
2208   ixheaace_get_audiospecific_config_bytes(pstr_ia_asc_bit_buf,
2209                                           &pstr_api_struct->pstr_state->audio_specific_config,
2210                                           AOT_USAC, ccfl_idx);
2211   pstr_api_struct->pstr_state->i_out_bytes = (pstr_ia_asc_bit_buf->cnt_bits + 7) >> 3;
2212 
2213   return IA_NO_ERROR;
2214 }
2215 
ia_enhaacplus_enc_init(ixheaace_api_struct * pstr_api_struct,WORD32 ele_idx)2216 static IA_ERRORCODE ia_enhaacplus_enc_init(ixheaace_api_struct *pstr_api_struct, WORD32 ele_idx) {
2217   IA_ERRORCODE error = IA_NO_ERROR;
2218   WORD32 anc_flag = 0;
2219   WORD32 anc_rate = -1;
2220   WORD32 anc_mode = 0;
2221   WORD32 core_ch;
2222   WORD32 asc_channels;
2223   WORD8 *ptr_resampler_scratch;
2224   iaace_scratch *pstr_aac_scratch;
2225   WORD8 *ptr_spectral_band_replication_scratch;
2226   UWORD32 core_sample_rate;
2227   ixheaace_state_struct *pstr_enc_state = pstr_api_struct->pstr_state;
2228   ixheaace_audio_specific_config_struct *pstr_asc = &pstr_enc_state->audio_specific_config;
2229 
2230   iaace_config *pstr_aac_config = &(pstr_api_struct->config[ele_idx].aac_config);
2231 
2232   ixheaace_config_ancillary *pstr_ancillary = &(pstr_api_struct->config[ele_idx].pstr_ancillary);
2233   pstr_aac_scratch = (iaace_scratch *)pstr_api_struct->pp_mem[IA_ENHAACPLUSENC_SCRATCH_IDX];
2234   ptr_spectral_band_replication_scratch =
2235       ((pWORD8)pstr_aac_scratch) + ia_enhaacplus_enc_aac_enc_scr_size();
2236   ptr_resampler_scratch = ((pWORD8)pstr_aac_scratch) + ia_enhaacplus_enc_aac_enc_scr_size() +
2237                           ixheaace_sbr_enc_scr_size();
2238 
2239   /* fill pstr_ancillary data */
2240   pstr_ancillary->anc_flag = anc_flag;
2241   pstr_ancillary->anc_mode = anc_mode;
2242   pstr_ancillary->anc_rate = anc_rate;
2243   pstr_api_struct->pstr_state->temp_buff_aac =
2244       (void *)pstr_api_struct->pp_mem[IA_ENHAACPLUSENC_SCRATCH_IDX];
2245   pstr_api_struct->pstr_state->temp_buff_sbr =
2246       (void *)((WORD8 *)pstr_api_struct->pp_mem[IA_ENHAACPLUSENC_SCRATCH_IDX] +
2247                ia_enhaacplus_enc_aac_enc_scr_size());
2248 
2249   if (pstr_api_struct->config[ele_idx].use_mps &&
2250       pstr_api_struct->config[ele_idx].mps_tree_config != TREE_212) {
2251     pstr_api_struct->pstr_state->mps_scratch =
2252         (FLOAT32 *)((WORD8 *)pstr_api_struct->pp_mem[IA_ENHAACPLUSENC_SCRATCH_IDX] +
2253                     ia_enhaacplus_enc_aac_enc_scr_size());
2254 
2255     pstr_api_struct->pstr_state->ptr_temp_buff_resamp =
2256         (void *)((WORD8 *)pstr_api_struct->pp_mem[IA_ENHAACPLUSENC_SCRATCH_IDX] +
2257                  ia_enhaacplus_enc_aac_enc_scr_size() + ixheaace_sbr_enc_scr_size());
2258   } else {
2259     pstr_api_struct->pstr_state->ptr_temp_buff_resamp =
2260         (void *)((WORD8 *)pstr_api_struct->pp_mem[IA_ENHAACPLUSENC_SCRATCH_IDX] +
2261                  ia_enhaacplus_enc_aac_enc_scr_size() + ixheaace_sbr_enc_scr_size());
2262   }
2263 
2264   if (pstr_api_struct->config[ele_idx].chmode_nchannels == 2) {
2265     /* When the chmode option is not used,
2266       the number of channels depends on the input file */
2267     pstr_api_struct->config[ele_idx].chmode_nchannels =
2268         pstr_api_struct->config[ele_idx].i_channels;
2269   }
2270 
2271   switch (pstr_api_struct->pstr_state->aot) {
2272     case AOT_AAC_LC:
2273     case AOT_SBR:
2274     case AOT_PS:
2275       pstr_api_struct->pstr_state->buffer_offset = INPUT_DELAY_LC;
2276       break;
2277 
2278     case AOT_AAC_LD:
2279       if (pstr_aac_config->flag_framelength_small == 1) {
2280         pstr_api_struct->pstr_state->buffer_offset = INPUT_DELAY_LD_480;
2281       } else {
2282         pstr_api_struct->pstr_state->buffer_offset = INPUT_DELAY_LD_512;
2283       }
2284       break;
2285 
2286     case AOT_AAC_ELD:
2287       if (pstr_aac_config->flag_framelength_small == 1) {
2288         pstr_api_struct->pstr_state->buffer_offset = INPUT_DELAY_ELD_480;
2289       } else {
2290         pstr_api_struct->pstr_state->buffer_offset = INPUT_DELAY_ELD_512;
2291       }
2292       break;
2293   }
2294   pstr_api_struct->pstr_state->downsample[ele_idx] = 0;
2295   pstr_api_struct->config->frame_count = 0;
2296   core_ch = pstr_api_struct->config[ele_idx].chmode_nchannels;
2297   pstr_aac_config->sample_rate = pstr_api_struct->config[ele_idx].sample_rate;
2298   pstr_aac_config->core_sample_rate = pstr_api_struct->config[ele_idx].sample_rate;
2299   pstr_aac_config->native_sample_rate = pstr_api_struct->config[ele_idx].native_sample_rate;
2300   pstr_aac_config->num_in_channels = pstr_api_struct->config[ele_idx].i_channels;
2301   pstr_aac_config->num_out_channels = pstr_api_struct->config[ele_idx].chmode_nchannels;
2302   if (pstr_api_struct->config[ele_idx].aac_classic == 0) {
2303     pstr_aac_config->core_sample_rate = pstr_aac_config->core_sample_rate / 2;
2304   }
2305   if (pstr_api_struct->pstr_state->mps_enable) {
2306     switch (pstr_api_struct->pstr_state->mps_tree_config) {
2307       case TREE_212:
2308       case TREE_5151:
2309       case TREE_5152:
2310         pstr_aac_config->num_out_channels = 1;
2311         core_ch = 1;
2312         break;
2313 
2314       case TREE_525:
2315         pstr_aac_config->num_out_channels = 2;
2316         core_ch = 2;
2317         break;
2318     }
2319   }
2320 
2321   if (pstr_api_struct->config[ele_idx].use_parametric_stereo) {
2322     pstr_api_struct->config[ele_idx].chmode_nchannels = 2;
2323     pstr_aac_config->num_out_channels = 1;
2324     core_ch = 1;
2325     pstr_api_struct->config[ele_idx].element_type = ID_SCE;
2326   }
2327   if ((pstr_api_struct->config[ele_idx].i_channels == 2) &&
2328       (pstr_api_struct->config[ele_idx].chmode == 0)) {
2329     pstr_api_struct->config[ele_idx].chmode_nchannels = 1;
2330     pstr_aac_config->num_out_channels = 1;
2331   }
2332   if ((pstr_api_struct->config[ele_idx].use_parametric_stereo) &&
2333       (pstr_api_struct->config[ele_idx].aac_classic)) {
2334     return (IA_EXHEAACE_CONFIG_FATAL_AAC_CLASSIC_WITH_PS);
2335   }
2336 
2337   if (!(pstr_api_struct->config[ele_idx].adts_flag) &&
2338       (pstr_api_struct->config[0].aac_config.calc_crc)) {
2339     // set here default for crc as 0
2340     pstr_api_struct->config[0].aac_config.calc_crc = 0;
2341     return (IA_EXHEAACE_CONFIG_NONFATAL_INVALID_CONFIG);
2342   }
2343 
2344   if ((pstr_api_struct->config[0].chmode == 3) &&
2345       (pstr_api_struct->config[0].aac_config.calc_crc == 1)) {
2346     // dual mono case so crc if enabled must be disabled
2347     pstr_api_struct->config[0].aac_config.calc_crc = 0;
2348     return (IA_EXHEAACE_CONFIG_NONFATAL_INVALID_CONFIG);
2349   }
2350 
2351   pstr_aac_config->bit_rate = ixheaac_min32(360000 * core_ch, pstr_aac_config->bit_rate);
2352   pstr_aac_config->bit_rate = ixheaac_max32(8000 * core_ch, pstr_aac_config->bit_rate);
2353   switch (pstr_api_struct->pstr_state->aot) {
2354     case AOT_AAC_LC:
2355     case AOT_SBR:
2356     case AOT_PS:
2357       pstr_aac_config->bit_rate = ia_enhaacplus_aac_limitbitrate(
2358           pstr_aac_config->core_sample_rate,
2359           (pstr_aac_config->flag_framelength_small ? FRAME_LEN_960 : FRAME_LEN_1024), core_ch,
2360           pstr_aac_config->bit_rate);
2361       break;
2362 
2363     case AOT_AAC_LD:
2364     case AOT_AAC_ELD:
2365       pstr_aac_config->bit_rate = ia_enhaacplus_aac_limitbitrate(
2366           pstr_aac_config->core_sample_rate,
2367           (pstr_aac_config->flag_framelength_small ? FRAME_LEN_480 : FRAME_LEN_512), core_ch,
2368           pstr_aac_config->bit_rate);
2369       break;
2370   }
2371   if (pstr_api_struct->config[ele_idx].eldsbr_found == 1) {
2372     WORD32 num_iter = 0;
2373     WORD32 initial_bitrate, adjusted_bitrate;
2374     adjusted_bitrate = pstr_aac_config->bit_rate;
2375 
2376     /* Find total bitrate which provides valid configuration for each SBR element. */
2377     do {
2378       WORD32 e;
2379       WORD32 q_format;
2380       initial_bitrate = adjusted_bitrate;
2381 
2382       for (e = 0; e < pstr_api_struct->config[ele_idx].num_bs_elements; e++) {
2383         WORD32 sbr_element_bitate_in, sbr_bitrate_out;
2384 
2385         sbr_element_bitate_in = pstr_aac_config->bit_rate;
2386         sbr_bitrate_out = ixheaace_sbr_limit_bitrate(
2387             sbr_element_bitate_in, core_ch, pstr_aac_config->core_sample_rate,
2388             pstr_api_struct->spectral_band_replication_tabs.ptr_qmf_tab,
2389             pstr_api_struct->pstr_state->aot);
2390 
2391         if (sbr_bitrate_out == 0) {
2392           pstr_aac_config->bit_rate = 0;
2393         }
2394 
2395         /* If bitrates don't match, distribution and limiting needs to be determined again.
2396         Abort element loop and restart with adapted bitrate. */
2397         if (sbr_element_bitate_in != sbr_bitrate_out) {
2398           if (sbr_element_bitate_in < sbr_bitrate_out) {
2399             adjusted_bitrate = ixheaac_max32(
2400                 initial_bitrate,
2401                 (WORD32)ixheaac_div32((WORD32)(sbr_bitrate_out + 8), MAX_32, &q_format));
2402             adjusted_bitrate = adjusted_bitrate >> (q_format - 31);
2403             break;
2404           }
2405 
2406           if (sbr_element_bitate_in > sbr_bitrate_out) {
2407             adjusted_bitrate = ixheaac_min32(
2408                 initial_bitrate,
2409                 (WORD32)ixheaac_div32((WORD32)(sbr_bitrate_out - 8), MAX_32, &q_format));
2410             break;
2411           }
2412 
2413         } /* sbr_element_bitate_in != sbr_bitrate_out */
2414 
2415       } /* elements */
2416 
2417       num_iter++; /* restrict iteration to worst case of num elements */
2418 
2419     } while ((initial_bitrate != adjusted_bitrate) &&
2420              (num_iter <= pstr_api_struct->config[ele_idx].num_bs_elements));
2421 
2422     /* Unequal bitrates mean that no reasonable bitrate configuration found. */
2423     pstr_aac_config->bit_rate = (initial_bitrate == adjusted_bitrate) ? adjusted_bitrate : 0;
2424   }
2425 
2426   pstr_asc->str_aac_config.frame_length_flag = pstr_aac_config->flag_framelength_small;
2427   pstr_asc->sampling_frequency = pstr_api_struct->config[0].native_sample_rate;
2428   asc_channels = pstr_api_struct->config[ele_idx].i_channels_mode;
2429   pstr_asc->channel_configuration =
2430       (pstr_api_struct->pstr_state->mps_enable ? core_ch : asc_channels);
2431   pstr_asc->channel_configuration =
2432       pstr_api_struct->config[ele_idx].use_parametric_stereo
2433           ? 1
2434           : (pstr_api_struct->pstr_state->mps_enable
2435                  ? core_ch
2436                  : pstr_api_struct->config[ele_idx].i_channels_mode);
2437 
2438   if (!(pstr_api_struct->config[ele_idx].aac_classic) &&
2439       ixheaace_is_sbr_setting_available(
2440           pstr_aac_config->bit_rate,
2441           (pstr_api_struct->pstr_state->mps_enable
2442                ? 1
2443                : pstr_api_struct->config[ele_idx].chmode_nchannels),
2444           pstr_aac_config->sample_rate, &core_sample_rate,
2445           pstr_api_struct->spectral_band_replication_tabs.ptr_qmf_tab,
2446           pstr_api_struct->pstr_state->aot)) {
2447     ixheaace_str_sbr_cfg spectral_band_replication_config;
2448     ixheaace_initialize_sbr_defaults(&spectral_band_replication_config);
2449 
2450     spectral_band_replication_config.use_ps =
2451         pstr_api_struct->config[ele_idx].use_parametric_stereo;
2452     spectral_band_replication_config.crc_sbr = 0;
2453     spectral_band_replication_config.parametric_coding = 1;
2454     spectral_band_replication_config.is_esbr = pstr_api_struct->config[0].esbr_flag;
2455     if (pstr_api_struct->pstr_state->aot == AOT_AAC_ELD) {
2456       spectral_band_replication_config.is_ld_sbr = 1;
2457       spectral_band_replication_config.sbr_codec = ELD_SBR;
2458       spectral_band_replication_config.frame_flag_480 = pstr_aac_config->flag_framelength_small;
2459     } else if (pstr_api_struct->pstr_state->aot == AOT_SBR ||
2460                pstr_api_struct->pstr_state->aot == AOT_PS) {
2461       spectral_band_replication_config.frame_flag_960 = pstr_aac_config->flag_framelength_small;
2462       spectral_band_replication_config.sbr_codec = HEAAC_SBR;
2463     }
2464 
2465     if (pstr_api_struct->config[ele_idx].aac_classic == 0) {
2466       pstr_api_struct->pstr_state->downsample[ele_idx] = 1;
2467     }
2468 
2469     if (pstr_api_struct->pstr_state->mps_enable) {
2470       if (pstr_api_struct->pstr_state->mps_tree_config == TREE_212) {
2471         WORD32 delay =
2472             ((pstr_aac_config->flag_framelength_small ? FRAME_LEN_480 / 2 : FRAME_LEN_512 / 2) *
2473                  2 +
2474              4);
2475         ixheaace_mps_212_memory_struct *pstr_mps_memory;
2476         pstr_mps_memory = pstr_api_struct->pstr_state->mps_pers_mem;
2477         ixheaace_mps_212_open(&pstr_api_struct->pstr_mps_212_enc, pstr_mps_memory);
2478 
2479         pstr_asc->str_aac_config.num_sac_cfg_bits = 0;
2480 
2481         error = ixheaace_mps_212_initialise(
2482             pstr_api_struct->pstr_mps_212_enc, AOT_AAC_ELD, pstr_aac_config->sample_rate,
2483             &pstr_aac_config->bit_rate,
2484             pstr_api_struct->config[ele_idx].eldsbr_found ? 2 /*hAacConfig->sbrRatio*/ : 0,
2485             (pstr_aac_config->flag_framelength_small ? FRAME_LEN_480 * 2 : FRAME_LEN_512 * 2),
2486             /* for dual rate sbr this value is already multiplied by 2 */
2487             (pstr_aac_config->flag_framelength_small
2488                  ? FRAME_LEN_480 * 2
2489                  : FRAME_LEN_512 * 2) /* samples read per ch*/,
2490             delay, (WORD8 *)pstr_api_struct->pstr_state->ptr_temp_buff_resamp);
2491         if (error) {
2492           return error;
2493         }
2494 
2495         pstr_asc->str_aac_config.num_sac_cfg_bits = ixheaace_mps_212_get_spatial_specific_config(
2496             pstr_api_struct->pstr_mps_212_enc, (WORD8 *)pstr_asc->str_aac_config.sac_cfg_data,
2497             sizeof(pstr_asc->str_aac_config.sac_cfg_data), AOT_AAC_ELD);
2498         pstr_asc->str_aac_config.eld_ext_type[0] = IAAC_ELDEXT_LDSAC;
2499         pstr_asc->str_aac_config.eld_ext_len[0] =
2500             (pstr_asc->str_aac_config.num_sac_cfg_bits + 7) >> 3;
2501       } else {
2502         WORD32 tree_config;
2503         WORD32 bits_written;
2504         ixheaace_bit_buf bit_buf;
2505         ixheaace_bit_buf_handle ptr_bit_buf;
2506         ixheaace_mps_515_memory_struct *pstr_mps_memory;
2507         if (pstr_api_struct->pstr_state->mps_tree_config == TREE_525) {
2508           tree_config = 525;
2509         } else if (pstr_api_struct->pstr_state->mps_tree_config == TREE_5152) {
2510           tree_config = 5152;
2511         } else {
2512           tree_config = 5151;
2513         }
2514         pstr_mps_memory = pstr_api_struct->pstr_state->mps_515_pers_mem;
2515         ptr_bit_buf = ia_enhaacplus_enc_create_bitbuffer(
2516             &bit_buf, (UWORD8 *)pstr_asc->str_aac_config.sac_cfg_data,
2517             sizeof(pstr_asc->str_aac_config.sac_cfg_data));
2518 
2519         error = ixheaace_mps_515_open(
2520             &pstr_api_struct->pstr_mps_515_enc, pstr_aac_config->sample_rate, tree_config,
2521             ptr_bit_buf, &bits_written, pstr_mps_memory, pstr_aac_config->flag_framelength_small);
2522         pstr_asc->str_aac_config.num_sac_cfg_bits = bits_written;
2523         pstr_asc->str_aac_config.eld_ext_type[0] = IAAC_ELDEXT_LDSAC;
2524         pstr_asc->str_aac_config.eld_ext_len[0] = (bits_written + 7) >> 3;
2525         if (error) {
2526           return error;
2527         }
2528       }
2529     }
2530 
2531     ixheaace_adjust_sbr_settings(&spectral_band_replication_config, pstr_aac_config->bit_rate,
2532                                  pstr_aac_config->num_out_channels, core_sample_rate,
2533                                  AACENC_TRANS_FAC, 24000,
2534                                  pstr_api_struct->spectral_band_replication_tabs.ptr_qmf_tab,
2535                                  pstr_api_struct->pstr_state->aot);
2536 
2537     if (pstr_api_struct->config[ele_idx].element_type != ID_LFE) {
2538       /* open SBR PART, set core bandwidth */
2539       error = ixheaace_env_open(
2540           &pstr_api_struct->pstr_state->spectral_band_replication_enc_pers_mem[ele_idx],
2541           &spectral_band_replication_config, &pstr_aac_config->band_width,
2542           ptr_spectral_band_replication_scratch,
2543           &(pstr_api_struct->spectral_band_replication_tabs),
2544           &pstr_asc->str_aac_config.sbr_config);
2545       pstr_asc->str_aac_config.ld_sbr_present_flag =
2546           pstr_api_struct->config[ele_idx].eldsbr_found;
2547       if (error) {
2548         return error;
2549       }
2550       pstr_asc->str_aac_config.ld_sbr_sample_rate =
2551           (spectral_band_replication_config.codec_settings.sample_freq !=
2552            pstr_aac_config->sample_rate)
2553               ? 1
2554               : 0;
2555       pstr_asc->str_aac_config.ld_sbr_crc_flag = spectral_band_replication_config.crc_sbr;
2556     }
2557 
2558     if (!pstr_api_struct->config[ele_idx].use_parametric_stereo) {
2559       IA_ERRORCODE resamp_error = IA_NO_ERROR;
2560       WORD32 ch_idx = 0;
2561 
2562       resamp_error = ia_enhaacplus_enc_init_iir_resampler(
2563           &(pstr_api_struct->pstr_state->down_sampler[ele_idx][ch_idx]), 2,
2564           pstr_api_struct->spectral_band_replication_tabs.ptr_resamp_tab);
2565       if (resamp_error) {
2566         return resamp_error;
2567       }
2568       if (pstr_api_struct->config[ele_idx].i_channels > 1) {
2569         resamp_error = ia_enhaacplus_enc_init_iir_resampler(
2570             &(pstr_api_struct->pstr_state->down_sampler[ele_idx][ch_idx + 1]), 2,
2571             pstr_api_struct->spectral_band_replication_tabs.ptr_resamp_tab);
2572         if (resamp_error) {
2573           return resamp_error;
2574         }
2575       }
2576     }
2577   } else {
2578     if (!(pstr_api_struct->config[ele_idx].aac_classic &&
2579           !(pstr_api_struct->config[ele_idx].eldsbr_found))) {
2580       if (pstr_api_struct->config[ele_idx].aac_classic == 0) {
2581         error = IA_EXHEAACE_INIT_FATAL_AACPLUS_NOT_AVAIL;
2582       } else {
2583         error = IA_EXHEAACE_INIT_FATAL_BITRATE_NOT_SUPPORTED;
2584       }
2585       return error;
2586     }
2587     pstr_api_struct->pstr_state->buffer_offset = 0;
2588     pstr_api_struct->config[ele_idx].aac_classic = 1;
2589   }
2590   {
2591     WORD32 *shared_buf1, *shared_buf2;
2592     WORD32 *shared_buf3;
2593     WORD8 *shared_buf4;
2594     switch (pstr_api_struct->pstr_state->aot) {
2595       case AOT_AAC_LC:
2596       case AOT_SBR:
2597       case AOT_PS:
2598         ia_enhaacplus_enc_get_shared_bufs(
2599             ptr_spectral_band_replication_scratch, &shared_buf1, &shared_buf2, &shared_buf3,
2600             &shared_buf4,
2601             (pstr_aac_config->flag_framelength_small == 1) ? FRAME_LEN_960 : FRAME_LEN_1024);
2602         break;
2603 
2604       case AOT_AAC_LD:
2605       case AOT_AAC_ELD:
2606         ia_enhaacplus_enc_get_shared_bufs(
2607             ptr_spectral_band_replication_scratch, &shared_buf1, &shared_buf2, &shared_buf3,
2608             &shared_buf4,
2609             (pstr_aac_config->flag_framelength_small == 1) ? FRAME_LEN_480 : FRAME_LEN_512);
2610         break;
2611     }
2612 
2613     ia_enhaacplus_enc_set_shared_bufs(pstr_aac_scratch, &shared_buf1, &shared_buf2, &shared_buf3,
2614                                       &ptr_resampler_scratch);
2615 
2616     error = ia_enhaacplus_enc_aac_enc_open(
2617         &(pstr_api_struct->pstr_state->aac_enc_pers_mem[ele_idx]),
2618         *pstr_aac_config /*, *pstr_ancillary*/, pstr_aac_scratch,
2619         &(pstr_api_struct->pstr_aac_tabs), pstr_api_struct->config[ele_idx].element_type,
2620         pstr_api_struct->config[ele_idx].element_instance_tag, pstr_api_struct->pstr_state->aot);
2621     if (error != IA_NO_ERROR) {
2622       return error;
2623     }
2624     if (error) {
2625       if (pstr_api_struct->pstr_mps_212_enc && pstr_api_struct->pstr_state->mps_enable) {
2626         ixheaace_mps_212_close(&(pstr_api_struct->pstr_mps_212_enc));
2627       }
2628       if (pstr_api_struct->pstr_mps_515_enc && pstr_api_struct->pstr_state->mps_enable) {
2629         ixheaace_mps_515_close(pstr_api_struct->pstr_mps_212_enc);
2630       }
2631 
2632       return (IA_EXHEAACE_INIT_FATAL_AAC_INIT_FAILED);
2633     }
2634   }
2635 
2636   return error;
2637 }
2638 
ia_enhaacplus_enc_execute(ixheaace_api_struct * pstr_api_struct,WORD32 ele_idx)2639 static IA_ERRORCODE ia_enhaacplus_enc_execute(ixheaace_api_struct *pstr_api_struct,
2640                                               WORD32 ele_idx) {
2641   IA_ERRORCODE error = IA_NO_ERROR;
2642   WORD32 downsample;
2643   WORD32 aot;
2644   WORD32 idx;
2645   WORD32 header_bytes = 0;
2646   WORD32 num_samples_read;
2647   WORD32 env_read_offset = 0;
2648   WORD32 write_off_set = 0;
2649   WORD32 aacenc_blocksize;
2650   WORD32 ch, out_samples;
2651   WORD32 total_channels = 0, ele, slot;
2652   WORD32 time_in_stride;
2653   WORD32 num_bs_elements;
2654   FLAG flag_last_element;
2655   WORD32 i_num_coup_channels;
2656   WORD32 i_channels_mask;
2657   ixheaace_pstr_sbr_enc pstr_sbr_encoder = NULL;
2658   iexheaac_encoder_str **pstr_aac_enc;
2659   iaace_config *pstr_aac_config;
2660   pWORD16 pw_inp_buf = NULL;
2661   pUWORD8 pub_out_buf = NULL;
2662   FLOAT32 *ptr_input_buffer = NULL;
2663   FLOAT32 *ptr_input_buffer_mps = NULL;
2664   FLOAT32 *shared_buf1_ring, *shared_buf2_ring;
2665   WORD32 out_stride = IXHEAACE_MAX_CH_IN_BS_ELE;
2666   WORD32 *pstr_aac_scratch = (pWORD32)pstr_api_struct->pp_mem[IA_ENHAACPLUSENC_SCRATCH_IDX];
2667   WORD8 *ptr_spectral_band_replication_scratch =
2668       ((pWORD8)pstr_aac_scratch) + ia_enhaacplus_enc_aac_enc_scr_size();
2669   WORD32 *total_fill_bits = &(pstr_api_struct->pstr_state->total_fill_bits);
2670   WORD32 *write_program_config_element =
2671       &(pstr_api_struct->config[0].write_program_config_element);
2672 
2673   aot = pstr_api_struct->pstr_state->aot;
2674   num_bs_elements = pstr_api_struct->config[0].num_bs_elements;
2675   flag_last_element = (ele_idx == (num_bs_elements - 1));
2676   i_num_coup_channels = pstr_api_struct->config[0].i_num_coupling_chan;
2677   i_channels_mask = pstr_api_struct->config[0].i_channels_mask;
2678   aacenc_blocksize = pstr_api_struct->config[0].frame_length;
2679   downsample = pstr_api_struct->pstr_state->downsample[ele_idx];
2680   num_samples_read =
2681       aacenc_blocksize * pstr_api_struct->config[ele_idx].i_native_channels * (1 << downsample);
2682   for (ele = 0; ele < num_bs_elements; ele++) {
2683     total_channels += pstr_api_struct->config[ele].i_native_channels;
2684   }
2685   pstr_aac_config = &(pstr_api_struct->config[ele_idx].aac_config);
2686   if ((pstr_api_struct->config[ele_idx].aac_classic == 0) &&
2687       pstr_api_struct->config[ele_idx].use_parametric_stereo) {
2688     time_in_stride = 1;
2689   } else if ((pstr_api_struct->config[ele_idx].aac_classic == 1) &&
2690              (pstr_api_struct->config[ele_idx].num_bs_elements == 1)) {
2691     time_in_stride = pstr_aac_config->num_out_channels;
2692   } else {
2693     time_in_stride = IXHEAACE_MAX_CH_IN_BS_ELE;
2694   }
2695   pstr_aac_enc = pstr_api_struct->pstr_state->aac_enc_pers_mem;
2696 
2697   pw_inp_buf = (pWORD16)pstr_api_struct->pp_mem[IA_ENHAACPLUSENC_INPUT_IDX];
2698   if (ele_idx == 0) {
2699     pstr_api_struct->pstr_state->i_out_bytes = 0;
2700     pub_out_buf = ((pUWORD8)pstr_api_struct->pp_mem[IA_ENHAACPLUSENC_OUTPUT_IDX]);
2701     *total_fill_bits = 0;
2702   }
2703 
2704   if (pstr_api_struct->config->adts_flag) {
2705     pub_out_buf = (pUWORD8)(pub_out_buf + 7);
2706   }
2707 
2708   for (ch = 0; ch < IXHEAACE_MAX_CH_IN_BS_ELE; ch++)
2709     pstr_api_struct->pstr_state->num_anc_data_bytes[ele_idx][ch] = 0;
2710 
2711   if (aot == AOT_SBR || aot == AOT_PS) {
2712     write_off_set = INPUT_DELAY_LC * IXHEAACE_MAX_CH_IN_BS_ELE;
2713   } else if (aot == AOT_AAC_ELD && pstr_api_struct->pstr_state->mps_enable != 1) {
2714     if (pstr_api_struct->config[0].aac_config.flag_framelength_small)
2715       write_off_set = INPUT_DELAY_ELD_480 * IXHEAACE_MAX_CH_IN_BS_ELE;
2716     else
2717       write_off_set = INPUT_DELAY_ELD_512 * IXHEAACE_MAX_CH_IN_BS_ELE;
2718   } else if (aot == AOT_AAC_ELD && pstr_api_struct->pstr_state->mps_enable == 1 &&
2719              pstr_api_struct->pstr_state->mps_tree_config == TREE_212) {
2720     if (pstr_api_struct->config[0].aac_config.flag_framelength_small)
2721       write_off_set = INPUT_DELAY_ELDV2_480 * IXHEAACE_MAX_CH_IN_BS_ELE;
2722     else
2723       write_off_set = INPUT_DELAY_ELDV2_512 * IXHEAACE_MAX_CH_IN_BS_ELE;
2724   } else if (aot == AOT_AAC_ELD && pstr_api_struct->pstr_state->mps_enable == 1 &&
2725              pstr_api_struct->pstr_state->mps_tree_config != TREE_212) {
2726     write_off_set = INPUT_DELAY_ELD_512_MPS * IXHEAACE_MAX_CH_IN_BS_ELE;
2727   }
2728   if (pstr_api_struct->config[ele_idx].aac_classic == 1) {
2729     write_off_set = 0;
2730   }
2731   if (aot == AOT_AAC_ELD && pstr_api_struct->pstr_state->mps_enable == 1) {
2732     if (pstr_api_struct->pstr_state->mps_tree_config == TREE_212) {
2733       env_read_offset = INPUT_DELAY_ELD_512_MPS;
2734     } else {
2735       env_read_offset = write_off_set;
2736     }
2737   }
2738   if (pstr_api_struct->pstr_state->downsample[ele_idx]) {
2739     if (!pstr_api_struct->config[ele_idx].use_parametric_stereo) {
2740       if (aot == AOT_AAC_ELD && pstr_api_struct->pstr_state->mps_enable != 1) {
2741         write_off_set +=
2742             4 * IXHEAACE_MAX_CH_IN_BS_ELE;  // Downsampler delay = 4 samples per channel @input SR
2743       } else {
2744         write_off_set += (pstr_api_struct->pstr_state->down_sampler[ele_idx][0].delay) *
2745                          IXHEAACE_MAX_CH_IN_BS_ELE;
2746       }
2747     }
2748     if (pstr_api_struct->config[ele_idx].use_parametric_stereo) {
2749       env_read_offset = (MAXIMUM_DS_2_1_FILTER_DELAY + INPUT_DELAY) * IXHEAACE_MAX_CH_IN_BS_ELE;
2750       write_off_set = env_read_offset;
2751     }
2752   }
2753 
2754   if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
2755     ptr_input_buffer = pstr_api_struct->pstr_state->inp_delay +
2756                        (aacenc_blocksize * 2 + MAXIMUM_DS_2_1_FILTER_DELAY + INPUT_DELAY_LC) *
2757                            IXHEAACE_MAX_CH_IN_BS_ELE * ele_idx;
2758   } else if (aot == AOT_AAC_LD) {
2759     if (pstr_api_struct->config[0].aac_config.flag_framelength_small) {
2760       ptr_input_buffer = pstr_api_struct->pstr_state->inp_delay +
2761                          (FRAME_LEN_480 * 2 + MAXIMUM_DS_2_1_FILTER_DELAY + INPUT_DELAY_LD_480) *
2762                              IXHEAACE_MAX_CH_IN_BS_ELE * ele_idx;
2763     } else {
2764       ptr_input_buffer = pstr_api_struct->pstr_state->inp_delay +
2765                          (FRAME_LEN_512 * 2 + MAXIMUM_DS_2_1_FILTER_DELAY + INPUT_DELAY_LD_512) *
2766                              IXHEAACE_MAX_CH_IN_BS_ELE * ele_idx;
2767     }
2768   } else if (aot == AOT_AAC_ELD) {
2769     if (pstr_api_struct->config[0].aac_config.flag_framelength_small) {
2770       if (pstr_api_struct->pstr_state->mps_enable == 1) {
2771         ptr_input_buffer =
2772             pstr_api_struct->pstr_state->inp_delay +
2773             (FRAME_LEN_480 * 2 + MAXIMUM_DS_2_1_FILTER_DELAY + INPUT_DELAY_ELDV2_480) *
2774                 IXHEAACE_MAX_CH_IN_BS_ELE * ele_idx;
2775       } else {
2776         ptr_input_buffer =
2777             pstr_api_struct->pstr_state->inp_delay +
2778             (FRAME_LEN_480 * 2 + MAXIMUM_DS_2_1_FILTER_DELAY + INPUT_DELAY_ELD_480) *
2779                 IXHEAACE_MAX_CH_IN_BS_ELE * ele_idx;
2780       }
2781     } else {
2782       if (pstr_api_struct->pstr_state->mps_enable == 1) {
2783         ptr_input_buffer =
2784             pstr_api_struct->pstr_state->inp_delay +
2785             (FRAME_LEN_512 * 2 + MAXIMUM_DS_2_1_FILTER_DELAY + INPUT_DELAY_ELDV2_512) *
2786                 IXHEAACE_MAX_CH_IN_BS_ELE * ele_idx;
2787       } else {
2788         ptr_input_buffer =
2789             pstr_api_struct->pstr_state->inp_delay +
2790             (FRAME_LEN_512 * 2 + MAXIMUM_DS_2_1_FILTER_DELAY + INPUT_DELAY_ELD_512) *
2791                 IXHEAACE_MAX_CH_IN_BS_ELE * ele_idx;
2792       }
2793     }
2794   } else {
2795     return IA_EXHEAACE_EXE_FATAL_UNSUPPORTED_AOT;
2796   }
2797 
2798   if (aot != AOT_AAC_LD && aot != AOT_AAC_LC) {
2799     pstr_sbr_encoder =
2800         pstr_api_struct->pstr_state->spectral_band_replication_enc_pers_mem[ele_idx];
2801     if (pstr_api_struct->config[ele_idx].element_type != ID_LFE) {
2802       ixheaace_sbr_set_scratch_ptr(pstr_sbr_encoder, ptr_spectral_band_replication_scratch);
2803     }
2804   }
2805 
2806   {
2807     ixheaace_mps_enc_ext_payload mps_extension_payload;
2808     UWORD8 *mps_bs = pstr_api_struct->pstr_state->mps_bs;
2809     memset(&mps_extension_payload, 0, sizeof(ixheaace_mps_enc_ext_payload));
2810     mps_extension_payload.p_data = mps_bs;
2811 
2812     if ((pstr_api_struct->config[ele_idx].num_bs_elements == 1) &&
2813         (pstr_api_struct->config[ele_idx].i_channels <= 2)) {
2814       if (pstr_api_struct->config[ele_idx].aac_classic != 1) {
2815         if ((pstr_api_struct->config[ele_idx].i_channels == 2 &&
2816              pstr_api_struct->config[ele_idx].chmode_nchannels == 2) &&
2817             (!((pstr_api_struct->pstr_mps_212_enc != NULL) &&
2818                pstr_api_struct->pstr_state->mps_enable))) {
2819           for (idx = 0; idx < (num_samples_read); idx++) {
2820             ptr_input_buffer[write_off_set + idx] = (FLOAT32)pw_inp_buf[idx];
2821           }
2822         } else if (pstr_api_struct->config[ele_idx].i_channels == 1) {
2823           for (idx = 0; idx < num_samples_read; idx++) {
2824             ptr_input_buffer[write_off_set + (IXHEAACE_MAX_CH_IN_BS_ELE * idx)] =
2825                 (FLOAT32)pw_inp_buf[idx];
2826           }
2827         } else if ((pstr_api_struct->pstr_mps_212_enc != NULL) &&
2828                    pstr_api_struct->pstr_state->mps_enable) {
2829           ptr_input_buffer_mps = pstr_api_struct->pstr_state->time_signal_mps;
2830           for (idx = 0; idx < (num_samples_read / 2); idx++) {
2831             ptr_input_buffer_mps[idx] = (FLOAT32)pw_inp_buf[2 * idx];
2832             ptr_input_buffer_mps[(num_samples_read / 2) + idx] =
2833                 (FLOAT32)pw_inp_buf[(2 * idx) + 1];
2834           }
2835         }
2836       } else {
2837         for (idx = 0; idx < (num_samples_read + write_off_set); idx++) {
2838           ptr_input_buffer[idx] = (FLOAT32)pw_inp_buf[idx];
2839         }
2840       }
2841     } else {
2842       if (pstr_api_struct->config[ele_idx].i_channels == 2) {
2843         slot = pstr_api_struct->config[ele_idx].element_slot;
2844         for (idx = 0; idx < num_samples_read / 2; idx++) {
2845           ptr_input_buffer[2 * idx + write_off_set] =
2846               (FLOAT32)pw_inp_buf[total_channels * idx + slot];
2847           ptr_input_buffer[2 * idx + write_off_set + 1] =
2848               (FLOAT32)pw_inp_buf[total_channels * idx + slot + 1];
2849         }
2850       }
2851 
2852       if (pstr_api_struct->config[ele_idx].i_channels == 1) {
2853         slot = pstr_api_struct->config[ele_idx].element_slot;
2854         for (idx = 0; idx < num_samples_read; idx++) {
2855           ptr_input_buffer[write_off_set + (IXHEAACE_MAX_CH_IN_BS_ELE * idx)] =
2856               (FLOAT32)pw_inp_buf[total_channels * idx + slot];
2857         }
2858       }
2859 
2860       if (pstr_api_struct->config[ele_idx].i_channels == 6) {
2861         ptr_input_buffer_mps = pstr_api_struct->pstr_state->time_signal_mps;
2862         for (idx = 0; idx < num_samples_read; idx++) {
2863           ptr_input_buffer_mps[idx] = (FLOAT32)pw_inp_buf[idx];
2864         }
2865       }
2866     }
2867 
2868     if ((pstr_api_struct->pstr_mps_212_enc != NULL) && pstr_api_struct->pstr_state->mps_enable) {
2869       ptr_input_buffer_mps = pstr_api_struct->pstr_state->time_signal_mps;
2870       error = ixheaace_mps_212_process(pstr_api_struct->pstr_mps_212_enc, ptr_input_buffer_mps,
2871                                        num_samples_read, &mps_extension_payload);
2872       if (error) {
2873         return error;
2874       }
2875       num_samples_read /= 2;
2876       for (idx = 0; idx < num_samples_read; idx++) {
2877         ptr_input_buffer[2 * idx + write_off_set] = (FLOAT32)ptr_input_buffer_mps[idx];
2878       }
2879       env_read_offset = write_off_set;
2880     }
2881     if ((pstr_api_struct->pstr_mps_515_enc != NULL) && pstr_api_struct->pstr_state->mps_enable) {
2882       ixheaace_bit_buf bit_buf;
2883       ixheaace_bit_buf_handle ptr_bit_buf = NULL;
2884       FLOAT32 *ptr_downmix_buffer_mps = pstr_api_struct->pstr_state->mps_scratch;
2885       VOID *ptr_scratch_515_mps = (VOID *)(pstr_api_struct->pstr_state->mps_scratch +
2886                                            (MAX_INPUT_CHANNELS * MAX_BUFFER_SIZE) +
2887                                            (MAX_OUTPUT_CHANNELS * MAX_BUFFER_SIZE));
2888       ptr_bit_buf = ia_enhaacplus_enc_create_bitbuffer(&bit_buf, mps_bs, MAX_MPS_BS_PAYLOAD_SIZE);
2889 
2890       error =
2891           ixheaace_mps_515_apply(pstr_api_struct->pstr_mps_515_enc, &ptr_input_buffer_mps[0],
2892                                  &ptr_downmix_buffer_mps[0], ptr_bit_buf, ptr_scratch_515_mps);
2893       if (error) {
2894         return error;
2895       }
2896       mps_extension_payload.data_size = ptr_bit_buf->cnt_bits;
2897       mps_extension_payload.data_type = IXHEAACE_MPS_EXT_LDSAC_DATA;
2898       mps_extension_payload.associated_ch_element = -1;
2899 
2900       if (pstr_api_struct->pstr_state->mps_tree_config == TREE_5151 ||
2901           pstr_api_struct->pstr_state->mps_tree_config == TREE_5152) {
2902         num_samples_read /= 6;
2903         for (idx = 0; idx < num_samples_read; idx++) {
2904           ptr_input_buffer[2 * idx + write_off_set] = (FLOAT32)ptr_downmix_buffer_mps[idx];
2905         }
2906       } else {
2907         num_samples_read /= 3;
2908         for (idx = 0; idx < num_samples_read; idx++) {
2909           ptr_input_buffer[idx + write_off_set] = (FLOAT32)ptr_downmix_buffer_mps[idx];
2910         }
2911       }
2912       env_read_offset = write_off_set;
2913     }
2914 
2915     if (pstr_api_struct->pstr_state->downsample[ele_idx]) {
2916       ixheaace_resampler_scratch *pstr_scratch_resampler =
2917           (ixheaace_resampler_scratch *)pstr_api_struct->pstr_state->ptr_temp_buff_resamp;
2918 
2919       if (pstr_api_struct->config[ele_idx].element_type != ID_LFE) {
2920         error = ixheaace_env_encode_frame(
2921             pstr_sbr_encoder, ptr_input_buffer + env_read_offset, ptr_input_buffer,
2922             IXHEAACE_MAX_CH_IN_BS_ELE,
2923             &(pstr_api_struct->pstr_state->num_anc_data_bytes[ele_idx][0]),
2924             pstr_api_struct->pstr_state->anc_data_bytes[ele_idx],
2925             &(pstr_api_struct->spectral_band_replication_tabs), &(pstr_api_struct->common_tabs),
2926             &(mps_extension_payload.p_data[0]), mps_extension_payload.data_size,
2927             pstr_api_struct->config[0].aac_config.flag_framelength_small, NULL);
2928 
2929         if (error != IA_NO_ERROR) {
2930           return error;
2931         }
2932       }
2933 
2934       if (!pstr_api_struct->config[ele_idx].use_parametric_stereo) {
2935         for (ch = 0; ch < pstr_aac_config->num_out_channels; ch++) {
2936           ia_enhaacplus_enc_get_scratch_bufs(pstr_api_struct->pstr_state->temp_buff_sbr,
2937                                              &shared_buf1_ring, &shared_buf2_ring);
2938           {
2939             ia_enhaacplus_enc_iir_downsampler(
2940                 &(pstr_api_struct->pstr_state->down_sampler[ele_idx][ch]),
2941                 ptr_input_buffer + write_off_set + ch,
2942                 num_samples_read / pstr_aac_config->num_out_channels, IXHEAACE_MAX_CH_IN_BS_ELE,
2943                 ptr_input_buffer + ch, &out_samples, out_stride, shared_buf1_ring,
2944                 shared_buf2_ring, pstr_scratch_resampler);
2945           }
2946         }
2947       }
2948     }
2949 
2950     error = ia_enhaacplus_enc_aac_core_encode(
2951         pstr_aac_enc, ptr_input_buffer, time_in_stride,
2952         pstr_api_struct->pstr_state->anc_data_bytes[ele_idx],
2953         pstr_api_struct->pstr_state->num_anc_data_bytes[ele_idx], pub_out_buf,
2954         &(pstr_api_struct->pstr_state->i_out_bytes), &(pstr_api_struct->pstr_aac_tabs),
2955         pstr_api_struct->pstr_state->pstr_bit_stream_handle,
2956         &(pstr_api_struct->pstr_state->bit_stream), flag_last_element,
2957         write_program_config_element, i_num_coup_channels, i_channels_mask, ele_idx,
2958         total_fill_bits, total_channels, aot, pstr_api_struct->config->adts_flag,
2959         num_bs_elements, &pstr_api_struct->pstr_state->is_quant_spec_zero,
2960         &pstr_api_struct->pstr_state->is_gain_limited);
2961     if (error != IA_NO_ERROR) {
2962       return error;
2963     }
2964     if (pstr_sbr_encoder && !(pstr_api_struct->config[ele_idx].use_parametric_stereo)) {
2965       if (pstr_sbr_encoder && (ptr_input_buffer != NULL)) {
2966         memmove(ptr_input_buffer,
2967                 ptr_input_buffer + aacenc_blocksize * 2 * IXHEAACE_MAX_CH_IN_BS_ELE,
2968                 write_off_set * sizeof(ptr_input_buffer[0]));
2969       }
2970     }
2971   }
2972   {}
2973   /*ADTS Header Write*/
2974   if (pstr_api_struct->config->adts_flag) {
2975     pub_out_buf = ((pUWORD8)pstr_api_struct->pp_mem[IA_ENHAACPLUSENC_OUTPUT_IDX]);
2976     {
2977       WORD32 num_channels = 0;
2978 
2979       for (ele = 0; ele < pstr_api_struct->config[0].num_bs_elements; ele++) {
2980         num_channels += pstr_api_struct->config[ele].i_channels;
2981       }
2982       {
2983         header_bytes = ia_enhaacplus_enc_write_ADTS_header(
2984             pub_out_buf, pstr_api_struct->pstr_state->i_out_bytes,
2985             pstr_api_struct->config->aac_config.core_sample_rate,
2986             (pstr_api_struct->config[0].num_bs_elements > 1)
2987                 ? num_channels
2988                 : pstr_api_struct->config[0].aac_config.num_out_channels);
2989       }
2990     }
2991 
2992     pstr_api_struct->pstr_state->i_out_bytes += header_bytes;
2993   }
2994 
2995   return IA_NO_ERROR;
2996 }
iusace_process(ixheaace_api_struct * pstr_api_struct)2997 static IA_ERRORCODE iusace_process(ixheaace_api_struct *pstr_api_struct) {
2998   IA_ERRORCODE error = IA_NO_ERROR;
2999   WORD32 idx;
3000   WORD32 write_off_set = 0;
3001   WORD32 core_coder_frame_length;
3002   WORD32 usac_independency_flg;
3003   UWORD32 padding_bits = 0;
3004   WORD32 core_sample;
3005   WORD32 drc_sample;
3006   WORD32 i4_inp_data;
3007   WORD32 ptr_inp_buf_offset = 0;
3008   WORD32 num_ch;
3009   WORD16 *ps_inp_buf = NULL;
3010   WORD8 *pi1_inp_buf = NULL;
3011   WORD8 *ps_out_buf = NULL;
3012   WORD32 *pi4_inp_buf = NULL;
3013   FLOAT32 *ptr_input_buffer = NULL;
3014   FLOAT32 *ptr_inp_buf[MAX_TIME_CHANNELS];
3015   FLOAT32 *ptr_drc_inp_buf[MAX_TIME_CHANNELS];
3016   ixheaace_state_struct *pstr_state = pstr_api_struct->pstr_state;
3017   ia_bit_buf_struct *pstr_it_bit_buff = &pstr_state->str_bit_buf;
3018   ia_usac_encoder_config_struct *pstr_config = &pstr_api_struct->config[0].usac_config;
3019   ia_usac_data_struct *pstr_usac_data = &pstr_api_struct->pstr_state->str_usac_enc_data;
3020   iusace_scratch_mem *pstr_scratch = &pstr_usac_data->str_scratch;
3021   ia_classification_struct *pstr_sig_class_data =
3022       &pstr_state->str_usac_enc_data.str_sig_class_data;
3023   core_sample = (pstr_config->ccfl * pstr_config->channels);
3024   drc_sample = pstr_config->drc_frame_size * pstr_config->channels;
3025   core_coder_frame_length = pstr_config->ccfl;
3026   num_ch = pstr_config->channels;
3027   usac_independency_flg = pstr_usac_data->usac_independency_flag;
3028   ps_inp_buf = (WORD16 *)pstr_api_struct->pp_mem[IA_MEMTYPE_INPUT];
3029   pi1_inp_buf = (WORD8 *)pstr_api_struct->pp_mem[IA_MEMTYPE_INPUT];
3030   ps_out_buf = (WORD8 *)pstr_api_struct->pp_mem[IA_MEMTYPE_OUTPUT];
3031 
3032   if (pstr_config->use_drc_element) {
3033     for (idx = 0; idx < core_sample; idx++) {
3034       pstr_api_struct->pstr_state->pp_drc_in_buf[idx % num_ch][idx / num_ch] =
3035           pstr_api_struct->pstr_state
3036               ->pp_drc_in_buf[idx % num_ch][idx / num_ch + pstr_config->drc_frame_size];
3037     }
3038     ptr_inp_buf_offset = pstr_config->drc_frame_size;
3039     for (idx = 0; idx < num_ch; idx++) {
3040       ptr_drc_inp_buf[idx] = pstr_api_struct->pstr_state->pp_drc_in_buf[idx];
3041     }
3042   }
3043 
3044   ixheaace_pstr_sbr_enc pstr_sbr_encoder =
3045       pstr_api_struct->pstr_state->spectral_band_replication_enc_pers_mem[0];
3046   if (pstr_config->sbr_enable) {
3047     ixheaace_mps_enc_ext_payload mps_extension_payload;
3048     UWORD8 *mps_bs = pstr_api_struct->pstr_state->mps_bs;
3049     FLOAT32 *time_signal_mps = pstr_api_struct->pstr_state->time_signal_mps;
3050     WORD32 sbr_pvc_mode = 0;
3051     WORD32 sbr_patching_mode = 1;
3052     WORD32 ccfl_size;
3053     WORD32 num_samples_read;
3054     WORD32 out_samples, ch;
3055     WORD32 resamp_ratio =
3056         ia_enhaacplus_enc_compute_resampling_ratio(pstr_api_struct->config[0].ccfl_idx);
3057     switch (pstr_config->codec_mode) {
3058       case USAC_SWITCHED:
3059         if (pstr_usac_data->str_sig_class_data.coding_mode == 2) {
3060           sbr_pvc_mode = 0;
3061         } else {
3062           sbr_pvc_mode = 2;
3063         }
3064         sbr_patching_mode = 1;
3065         break;
3066       case USAC_ONLY_FD:
3067         sbr_pvc_mode = 0;
3068         sbr_patching_mode = 0;
3069         break;
3070       case USAC_ONLY_TD:
3071         sbr_pvc_mode = 2;
3072         sbr_patching_mode = 1;
3073         break;
3074     }
3075 
3076     write_off_set = INPUT_DELAY_LC * IXHEAACE_MAX_CH_IN_BS_ELE;
3077     if (pstr_api_struct->pstr_state->downsample[0]) {
3078       if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) {
3079         write_off_set +=
3080             (pstr_api_struct->pstr_state->down_samp_sos[0][0].delay) * IXHEAACE_MAX_CH_IN_BS_ELE;
3081 
3082         write_off_set +=
3083             (pstr_api_struct->pstr_state->up_sampler[0][0].delay) * IXHEAACE_MAX_CH_IN_BS_ELE;
3084       } else if (pstr_api_struct->config[0].ccfl_idx == SBR_2_1 ||
3085                  pstr_api_struct->config[0].ccfl_idx == SBR_4_1) {
3086         write_off_set +=
3087             (pstr_api_struct->pstr_state->down_sampler[0][0].delay) * IXHEAACE_MAX_CH_IN_BS_ELE;
3088       }
3089     }
3090 
3091     ptr_input_buffer = pstr_api_struct->pstr_state->inp_delay;
3092     ccfl_size = pstr_api_struct->config[0].usac_config.ccfl;
3093     num_samples_read = ccfl_size * pstr_api_struct->config[0].i_channels;
3094     switch (pstr_api_struct->config[0].ccfl_idx) {
3095       case SBR_8_3:
3096         num_samples_read *= 8;
3097         num_samples_read /= 3;
3098         break;
3099 
3100       case SBR_2_1:
3101         num_samples_read *= 2;
3102         break;
3103 
3104       case SBR_4_1:
3105         num_samples_read *= 4;
3106         break;
3107     }
3108 
3109     mps_extension_payload.p_data = mps_bs;
3110     memset(&mps_extension_payload, 0, sizeof(ixheaace_mps_enc_ext_payload));
3111 
3112     if ((pstr_api_struct->pstr_mps_212_enc != NULL) && pstr_api_struct->pstr_state->mps_enable) {
3113       for (idx = 0; idx < num_samples_read / 2; idx++) {
3114         time_signal_mps[idx] = (FLOAT32)ps_inp_buf[2 * idx];
3115         time_signal_mps[num_samples_read / 2 + idx] = (FLOAT32)ps_inp_buf[2 * idx + 1];
3116       }
3117       ixheaace_mps_pstr_struct pstr_mps_enc =
3118           (ixheaace_mps_pstr_struct)pstr_api_struct->pstr_mps_212_enc;
3119       pstr_mps_enc->ptr_sac_encoder->independency_flag = usac_independency_flg;
3120 
3121       error = ixheaace_mps_212_process(pstr_api_struct->pstr_mps_212_enc, time_signal_mps,
3122                                        num_samples_read, &mps_extension_payload);
3123       if (error) {
3124         return error;
3125       }
3126       if (pstr_api_struct->pstr_state->mps_enable == 1) {
3127         for (idx = 0; idx < num_samples_read / 2; idx++) {
3128           ptr_input_buffer[write_off_set + 2 * idx] = time_signal_mps[idx];
3129           ptr_input_buffer[write_off_set + 2 * idx + 1] =
3130               time_signal_mps[num_samples_read / 2 + idx];
3131         }
3132       }
3133     } else if (pstr_api_struct->config[0].i_channels == 2 &&
3134                pstr_api_struct->config[0].chmode_nchannels == 2) {
3135       for (idx = 0; idx < (num_samples_read); idx++) {
3136         ptr_input_buffer[write_off_set + idx] = (FLOAT32)ps_inp_buf[idx];
3137       }
3138     } else if (pstr_api_struct->config[0].i_channels == 1) {
3139       for (idx = 0; idx < num_samples_read; idx++) {
3140         ptr_input_buffer[write_off_set + (IXHEAACE_MAX_CH_IN_BS_ELE * idx)] =
3141             (FLOAT32)ps_inp_buf[idx];
3142       }
3143     }
3144 
3145     if (num_ch == 2) {
3146       if (1 == pstr_config->use_drc_element) {
3147         if (16 == pstr_config->ui_pcm_wd_sz) {
3148           for (idx = 0; idx < drc_sample; idx++) {
3149             ptr_drc_inp_buf[idx % num_ch][idx / num_ch + ptr_inp_buf_offset] =
3150                 ptr_input_buffer[idx];
3151           }
3152         } else if (24 == pstr_config->ui_pcm_wd_sz) {
3153           for (idx = 0; idx < drc_sample; idx++) {
3154             i4_inp_data = ((WORD32)(*pi1_inp_buf)) & 0xFF;
3155             pi1_inp_buf++;
3156             i4_inp_data += ((WORD32)(*pi1_inp_buf) << 8) & 0xFFFF;
3157             pi1_inp_buf++;
3158             i4_inp_data += ((WORD32)(*pi1_inp_buf) << 16) & 0xFFFFFF;
3159             pi1_inp_buf++;
3160             i4_inp_data = i4_inp_data - (i4_inp_data >> 23 << 24);
3161             ptr_drc_inp_buf[idx % num_ch][idx / num_ch + ptr_inp_buf_offset] =
3162                 (FLOAT32)i4_inp_data / DIV_FAC_24_BIT_PCM;
3163           }
3164         } else if (32 == pstr_config->ui_pcm_wd_sz) {
3165           pi4_inp_buf = (WORD32 *)pi1_inp_buf;
3166           for (idx = 0; idx < drc_sample; idx++) {
3167             i4_inp_data = *pi4_inp_buf++;
3168             ptr_drc_inp_buf[idx % num_ch][idx / num_ch + ptr_inp_buf_offset] =
3169                 (FLOAT32)i4_inp_data / DIV_FAC_32_BIT_PCM;
3170           }
3171         }
3172       }
3173 
3174       // update Header and bit-stream parameters
3175       if (0 == pstr_config->sbr_pvc_active) {
3176         sbr_pvc_mode = 0;
3177       }
3178 
3179       ixheaace_set_usac_sbr_params(
3180           pstr_sbr_encoder, usac_independency_flg, 0, pstr_config->sbr_pvc_active, sbr_pvc_mode,
3181           pstr_config->sbr_inter_tes_active, pstr_config->sbr_harmonic, sbr_patching_mode);
3182 
3183       // Downsample SBR input buffer for Harmonic SBR
3184       if (pstr_config->sbr_harmonic) {
3185         FLOAT32 *in_buffer_temp;
3186         ixheaace_get_input_scratch_buf(pstr_api_struct->pstr_state->ptr_temp_buff_resamp,
3187                                        &in_buffer_temp);
3188         FLOAT32 *outbuf = ixheaace_get_hbe_resample_buffer(pstr_sbr_encoder);
3189         if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) {
3190           WORD32 input_tot = num_samples_read / pstr_api_struct->config[0].i_channels;
3191           ixheaace_upsampling_inp_buf_generation(ptr_input_buffer, in_buffer_temp, input_tot,
3192                                                  UPSAMPLE_FAC, 0);
3193         }
3194 
3195         // Resampler
3196         for (ch = 0; ch < num_ch; ch++) {
3197           FLOAT32 *shared_buf1_ring, *shared_buf2_ring;
3198           ixheaace_resampler_scratch *pstr_scratch_resampler =
3199               (ixheaace_resampler_scratch *)(ixheaace_resampler_scratch *)
3200                   pstr_api_struct->pstr_state->ptr_temp_buff_resamp;
3201 
3202           ia_enhaacplus_enc_get_scratch_bufs(pstr_api_struct->pstr_state->temp_buff_sbr,
3203                                              &shared_buf1_ring, &shared_buf2_ring);
3204 
3205           if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) {
3206             // Upsampling by factor 3 - SOS implementation
3207             ia_enhaacplus_enc_iir_sos_upsampler(
3208                 &(pstr_api_struct->pstr_state->hbe_up_sampler[0][ch]), in_buffer_temp + ch,
3209                 num_samples_read / pstr_api_struct->config[0].i_channels,
3210                 IXHEAACE_MAX_CH_IN_BS_ELE, in_buffer_temp + ch, &out_samples, shared_buf1_ring,
3211                 shared_buf2_ring, pstr_scratch_resampler);
3212 
3213             // Downsampling by factor 8
3214             ia_enhaacplus_enc_iir_sos_downsampler(
3215                 &(pstr_api_struct->pstr_state->hbe_down_samp_sos[0][ch]), in_buffer_temp + ch,
3216                 out_samples, IXHEAACE_MAX_CH_IN_BS_ELE, outbuf + ch, &out_samples,
3217                 shared_buf1_ring, shared_buf2_ring, pstr_scratch_resampler);
3218           } else {
3219             WORD32 out_stride = IXHEAACE_MAX_CH_IN_BS_ELE * resamp_ratio;
3220 
3221             ia_enhaacplus_enc_iir_downsampler(
3222                 &(pstr_api_struct->pstr_state->hbe_down_sampler[0][ch]), ptr_input_buffer + ch,
3223                 num_samples_read / pstr_api_struct->config[0].i_channels,
3224                 IXHEAACE_MAX_CH_IN_BS_ELE, outbuf + ch, &out_samples, out_stride,
3225                 shared_buf1_ring, shared_buf2_ring, pstr_scratch_resampler);
3226           }
3227         }
3228       }
3229 
3230       // SBR Encode
3231       error = ixheaace_env_encode_frame(
3232           pstr_sbr_encoder, ptr_input_buffer, ptr_input_buffer,
3233           pstr_api_struct->config[0].i_channels,
3234           &(pstr_api_struct->pstr_state->num_anc_data_bytes[0][0]),
3235           pstr_api_struct->pstr_state->anc_data_bytes[0],
3236           &(pstr_api_struct->spectral_band_replication_tabs), &(pstr_api_struct->common_tabs),
3237           &(mps_extension_payload.p_data[0]), mps_extension_payload.data_size, 0,
3238           &pstr_api_struct->pstr_state->str_usac_enc_data.num_sbr_bits);
3239       if (error != IA_NO_ERROR) {
3240         return error;
3241       }
3242     } else {
3243       if (0 == pstr_config->sbr_pvc_active) {
3244         sbr_pvc_mode = 0;
3245       }
3246 
3247       ixheaace_set_usac_sbr_params(
3248           pstr_sbr_encoder, usac_independency_flg, 0, pstr_config->sbr_pvc_active, sbr_pvc_mode,
3249           pstr_config->sbr_inter_tes_active, pstr_config->sbr_harmonic, sbr_patching_mode);
3250       if (pstr_config->sbr_harmonic) {
3251         FLOAT32 *in_buffer_temp;
3252         ixheaace_get_input_scratch_buf(pstr_api_struct->pstr_state->ptr_temp_buff_resamp,
3253                                        &in_buffer_temp);
3254         FLOAT32 *outbuf = ixheaace_get_hbe_resample_buffer(pstr_sbr_encoder);
3255         if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) {
3256           WORD32 input_tot = num_samples_read / pstr_api_struct->config[0].i_channels;
3257           ixheaace_upsampling_inp_buf_generation(ptr_input_buffer, in_buffer_temp, input_tot,
3258                                                  UPSAMPLE_FAC, 0);
3259         }
3260 
3261         // Resampler
3262         for (ch = 0; ch < num_ch; ch++) {
3263           FLOAT32 *shared_buf1_ring, *shared_buf2_ring;
3264           ixheaace_resampler_scratch *pstr_scratch_resampler =
3265               (ixheaace_resampler_scratch *)(ixheaace_resampler_scratch *)
3266                   pstr_api_struct->pstr_state->ptr_temp_buff_resamp;
3267 
3268           ia_enhaacplus_enc_get_scratch_bufs(pstr_api_struct->pstr_state->temp_buff_sbr,
3269                                              &shared_buf1_ring, &shared_buf2_ring);
3270 
3271           if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) {
3272             // Upsampling by factor 3 - SOS implementation
3273             ia_enhaacplus_enc_iir_sos_upsampler(
3274                 &(pstr_api_struct->pstr_state->hbe_up_sampler[0][ch]), in_buffer_temp + ch,
3275                 num_samples_read / pstr_api_struct->config[0].i_channels,
3276                 IXHEAACE_MAX_CH_IN_BS_ELE, in_buffer_temp + ch, &out_samples, shared_buf1_ring,
3277                 shared_buf2_ring, pstr_scratch_resampler);
3278 
3279             // Downsampling by factor 8
3280             ia_enhaacplus_enc_iir_sos_downsampler(
3281                 &(pstr_api_struct->pstr_state->hbe_down_samp_sos[0][ch]), in_buffer_temp + ch,
3282                 out_samples, IXHEAACE_MAX_CH_IN_BS_ELE, outbuf + ch, &out_samples,
3283                 shared_buf1_ring, shared_buf2_ring, pstr_scratch_resampler);
3284           } else {
3285             WORD32 out_stride = IXHEAACE_MAX_CH_IN_BS_ELE * resamp_ratio;
3286 
3287             ia_enhaacplus_enc_iir_downsampler(
3288                 &(pstr_api_struct->pstr_state->hbe_down_sampler[0][ch]),
3289                 ptr_input_buffer /*input_buffer_fix + write_off_set*/ + ch,
3290                 num_samples_read / pstr_api_struct->config[0].i_channels,
3291                 IXHEAACE_MAX_CH_IN_BS_ELE, outbuf + ch, &out_samples, out_stride,
3292                 shared_buf1_ring, shared_buf2_ring, pstr_scratch_resampler);
3293           }
3294         }
3295       }
3296 
3297       FLOAT32 *time_signal = pstr_api_struct->pstr_state->time_signal;
3298       for (idx = 0; idx < num_samples_read; idx++) {
3299         time_signal[idx] = (FLOAT32)ptr_input_buffer[2 * idx];
3300       }
3301 
3302       if (1 == pstr_config->use_drc_element) {
3303         if (16 == pstr_config->ui_pcm_wd_sz) {
3304           for (idx = 0; idx < drc_sample; idx++) {
3305             ptr_drc_inp_buf[idx % num_ch][idx / num_ch + ptr_inp_buf_offset] = time_signal[idx];
3306           }
3307         } else if (24 == pstr_config->ui_pcm_wd_sz) {
3308           for (idx = 0; idx < drc_sample; idx++) {
3309             i4_inp_data = ((WORD32)(*pi1_inp_buf)) & 0xFF;
3310             pi1_inp_buf++;
3311             i4_inp_data += ((WORD32)(*pi1_inp_buf) << 8) & 0xFFFF;
3312             pi1_inp_buf++;
3313             i4_inp_data += ((WORD32)(*pi1_inp_buf) << 16) & 0xFFFFFF;
3314             pi1_inp_buf++;
3315             i4_inp_data = i4_inp_data - (i4_inp_data >> 23 << 24);
3316             ptr_drc_inp_buf[idx % num_ch][idx / num_ch + ptr_inp_buf_offset] =
3317                 (FLOAT32)i4_inp_data / DIV_FAC_24_BIT_PCM;
3318           }
3319         } else if (32 == pstr_config->ui_pcm_wd_sz) {
3320           pi4_inp_buf = (WORD32 *)pi1_inp_buf;
3321           for (idx = 0; idx < drc_sample; idx++) {
3322             i4_inp_data = *pi4_inp_buf++;
3323             ptr_drc_inp_buf[idx % num_ch][idx / num_ch + ptr_inp_buf_offset] =
3324                 (FLOAT32)i4_inp_data / DIV_FAC_32_BIT_PCM;
3325           }
3326         }
3327       }
3328 
3329       // SBR Encode
3330       error = ixheaace_env_encode_frame(
3331           pstr_sbr_encoder, time_signal, time_signal, pstr_api_struct->config[0].i_channels,
3332           &(pstr_api_struct->pstr_state->num_anc_data_bytes[0][0]),
3333           pstr_api_struct->pstr_state->anc_data_bytes[0],
3334           &(pstr_api_struct->spectral_band_replication_tabs), &(pstr_api_struct->common_tabs),
3335           &(mps_extension_payload.p_data[0]), mps_extension_payload.data_size, 0,
3336           &pstr_api_struct->pstr_state->str_usac_enc_data.num_sbr_bits);
3337       if (error != IA_NO_ERROR) {
3338         return error;
3339       }
3340     }
3341 
3342     /* Resampling for USAC core */
3343     {
3344       FLOAT32 *in_buffer_temp;
3345       ixheaace_get_input_scratch_buf(pstr_api_struct->pstr_state->ptr_temp_buff_resamp,
3346                                      &in_buffer_temp);
3347       if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) {
3348         WORD32 input_tot = num_samples_read / pstr_api_struct->config[0].i_channels;
3349         ixheaace_upsampling_inp_buf_generation(ptr_input_buffer, in_buffer_temp, input_tot,
3350                                                UPSAMPLE_FAC, write_off_set);
3351       }
3352 
3353       for (ch = 0; ch < num_ch; ch++) {
3354         FLOAT32 *shared_buf1_ring, *shared_buf2_ring;
3355         ixheaace_resampler_scratch *pstr_scratch_resampler =
3356             (ixheaace_resampler_scratch *)pstr_api_struct->pstr_state->ptr_temp_buff_resamp;
3357 
3358         ia_enhaacplus_enc_get_scratch_bufs(pstr_api_struct->pstr_state->temp_buff_sbr,
3359                                            &shared_buf1_ring, &shared_buf2_ring);
3360 
3361         if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) {
3362           // Upsampling by factor 3 - SOS implementation
3363           ia_enhaacplus_enc_iir_sos_upsampler(
3364               &(pstr_api_struct->pstr_state->up_sampler[0][ch]), in_buffer_temp + ch,
3365               num_samples_read / pstr_api_struct->config[0].i_channels, IXHEAACE_MAX_CH_IN_BS_ELE,
3366               in_buffer_temp + ch, &out_samples, shared_buf1_ring, shared_buf2_ring,
3367               pstr_scratch_resampler);
3368 
3369           // Downsampling by factor 8
3370           ia_enhaacplus_enc_iir_sos_downsampler(
3371               &(pstr_api_struct->pstr_state->down_samp_sos[0][ch]), in_buffer_temp + ch,
3372               out_samples, IXHEAACE_MAX_CH_IN_BS_ELE, ptr_input_buffer + ch, &out_samples,
3373               shared_buf1_ring, shared_buf2_ring, pstr_scratch_resampler);
3374         } else {
3375           WORD32 out_stride = IXHEAACE_MAX_CH_IN_BS_ELE * resamp_ratio;
3376 
3377           ia_enhaacplus_enc_iir_downsampler(
3378               &(pstr_api_struct->pstr_state->down_sampler[0][ch]),
3379               ptr_input_buffer + write_off_set + ch,
3380               num_samples_read / pstr_api_struct->config[0].i_channels, IXHEAACE_MAX_CH_IN_BS_ELE,
3381               ptr_input_buffer + ch, &out_samples, out_stride, shared_buf1_ring, shared_buf2_ring,
3382               pstr_scratch_resampler);
3383         }
3384       }
3385     }
3386 
3387     if (num_ch != 0) {
3388       for (idx = 0; idx < num_ch; idx++) {
3389         ptr_inp_buf[idx] = pstr_api_struct->pstr_state->ptr_in_buf[idx];
3390       }
3391 
3392       if (16 == pstr_config->ui_pcm_wd_sz) {
3393         if (num_ch == 1) {
3394           for (idx = 0; idx < core_sample; idx++) {
3395             ptr_inp_buf[idx % num_ch][idx / num_ch] = ptr_input_buffer[2 * idx];
3396           }
3397         } else {
3398           for (idx = 0; idx < core_sample; idx++) {
3399             ptr_inp_buf[idx % num_ch][idx / num_ch] = ptr_input_buffer[idx];
3400           }
3401         }
3402       } else if (24 == pstr_config->ui_pcm_wd_sz) {
3403         for (idx = 0; idx < core_sample; idx++) {
3404           i4_inp_data = ((WORD32)(*pi1_inp_buf)) & 0xFF;
3405           pi1_inp_buf++;
3406           i4_inp_data += ((WORD32)(*pi1_inp_buf) << 8) & 0xFFFF;
3407           pi1_inp_buf++;
3408           i4_inp_data += ((WORD32)(*pi1_inp_buf) << 16) & 0xFFFFFF;
3409           pi1_inp_buf++;
3410           i4_inp_data = i4_inp_data - (i4_inp_data >> 23 << 24);
3411           ptr_inp_buf[idx % num_ch][idx / num_ch] = (FLOAT32)i4_inp_data / DIV_FAC_24_BIT_PCM;
3412         }
3413       } else if (32 == pstr_config->ui_pcm_wd_sz) {
3414         pi4_inp_buf = (WORD32 *)pi1_inp_buf;
3415         for (idx = 0; idx < core_sample; idx++) {
3416           i4_inp_data = *pi4_inp_buf++;
3417           ptr_inp_buf[idx % num_ch][idx / num_ch] = (FLOAT32)i4_inp_data / DIV_FAC_32_BIT_PCM;
3418         }
3419       }
3420     }
3421   } else {
3422     if (num_ch != 0) {
3423       for (idx = 0; idx < num_ch; idx++) {
3424         ptr_inp_buf[idx] = pstr_api_struct->pstr_state->ptr_in_buf[idx];
3425       }
3426 
3427       if (16 == pstr_config->ui_pcm_wd_sz) {
3428         for (idx = 0; idx < core_sample; idx++) {
3429           ptr_inp_buf[idx % num_ch][idx / num_ch] = ps_inp_buf[idx];
3430         }
3431       } else if (24 == pstr_config->ui_pcm_wd_sz) {
3432         for (idx = 0; idx < core_sample; idx++) {
3433           i4_inp_data = ((WORD32)(*pi1_inp_buf)) & 0xFF;
3434           pi1_inp_buf++;
3435           i4_inp_data += ((WORD32)(*pi1_inp_buf) << 8) & 0xFFFF;
3436           pi1_inp_buf++;
3437           i4_inp_data += ((WORD32)(*pi1_inp_buf) << 16) & 0xFFFFFF;
3438           pi1_inp_buf++;
3439           i4_inp_data = i4_inp_data - (i4_inp_data >> 23 << 24);
3440           ptr_inp_buf[idx % num_ch][idx / num_ch] = (FLOAT32)i4_inp_data / DIV_FAC_24_BIT_PCM;
3441         }
3442       } else if (32 == pstr_config->ui_pcm_wd_sz) {
3443         pi4_inp_buf = (WORD32 *)pi1_inp_buf;
3444         for (idx = 0; idx < core_sample; idx++) {
3445           i4_inp_data = *pi4_inp_buf++;
3446           ptr_inp_buf[idx % num_ch][idx / num_ch] = (FLOAT32)i4_inp_data / DIV_FAC_32_BIT_PCM;
3447         }
3448       }
3449       if (1 == pstr_config->use_drc_element) {
3450         if (16 == pstr_config->ui_pcm_wd_sz) {
3451           for (idx = 0; idx < drc_sample; idx++) {
3452             ptr_drc_inp_buf[idx % num_ch][idx / num_ch + ptr_inp_buf_offset] = ps_inp_buf[idx];
3453           }
3454         } else if (24 == pstr_config->ui_pcm_wd_sz) {
3455           for (idx = 0; idx < drc_sample; idx++) {
3456             i4_inp_data = ((WORD32)(*pi1_inp_buf)) & 0xFF;
3457             pi1_inp_buf++;
3458             i4_inp_data += ((WORD32)(*pi1_inp_buf) << 8) & 0xFFFF;
3459             pi1_inp_buf++;
3460             i4_inp_data += ((WORD32)(*pi1_inp_buf) << 16) & 0xFFFFFF;
3461             pi1_inp_buf++;
3462             i4_inp_data = i4_inp_data - (i4_inp_data >> 23 << 24);
3463             ptr_drc_inp_buf[idx % num_ch][idx / num_ch + ptr_inp_buf_offset] =
3464                 (FLOAT32)i4_inp_data / DIV_FAC_24_BIT_PCM;
3465           }
3466         } else if (32 == pstr_config->ui_pcm_wd_sz) {
3467           pi4_inp_buf = (WORD32 *)pi1_inp_buf;
3468           for (idx = 0; idx < drc_sample; idx++) {
3469             i4_inp_data = *pi4_inp_buf++;
3470             ptr_drc_inp_buf[idx % num_ch][idx / num_ch + ptr_inp_buf_offset] =
3471                 (FLOAT32)i4_inp_data / DIV_FAC_32_BIT_PCM;
3472           }
3473         }
3474       }
3475     }
3476   }
3477 
3478   if (pstr_sig_class_data->is_switch_mode) {
3479     for (idx = 0; idx < core_coder_frame_length; idx++) {
3480       pstr_sig_class_data->input_samples[pstr_sig_class_data->n_buffer_samples + idx] =
3481           pstr_api_struct->pstr_state->ptr_in_buf[0][idx];
3482     }
3483     pstr_sig_class_data->n_buffer_samples += core_coder_frame_length;
3484     iusace_classification(pstr_sig_class_data, pstr_scratch, core_coder_frame_length);
3485   }
3486 
3487   pstr_it_bit_buff =
3488       iusace_create_bit_buffer(pstr_it_bit_buff, pstr_api_struct->pp_mem[IA_MEMTYPE_OUTPUT],
3489                                pstr_api_struct->pstr_mem_info[IA_MEMTYPE_OUTPUT].ui_size, 1);
3490   if (pstr_it_bit_buff == NULL) {
3491     return IA_EXHEAACE_INIT_FATAL_USAC_BITBUFFER_INIT_FAILED;
3492   }
3493   error =
3494       ixheaace_usac_encode(pstr_api_struct->pstr_state->ptr_in_buf, pstr_config,
3495                            &pstr_api_struct->pstr_state->str_usac_enc_data,
3496                            &pstr_api_struct->pstr_state->audio_specific_config, pstr_it_bit_buff,
3497                            pstr_sbr_encoder, pstr_api_struct->pstr_state->pp_drc_in_buf,
3498                            &pstr_api_struct->pstr_state->is_quant_spec_zero,
3499                            &pstr_api_struct->pstr_state->is_gain_limited);
3500   if (error) return error;
3501 
3502   padding_bits = 8 - (pstr_it_bit_buff->cnt_bits & 7);
3503   if (padding_bits > 0 && padding_bits < 8) {
3504     ps_out_buf[pstr_it_bit_buff->cnt_bits >> 3] =
3505         (WORD8)((UWORD32)ps_out_buf[pstr_it_bit_buff->cnt_bits >> 3]) & (0xFF << padding_bits);
3506   }
3507   pstr_api_struct->pstr_state->i_out_bytes =
3508       (padding_bits > 0 && padding_bits < 8) ? (pstr_it_bit_buff->cnt_bits + padding_bits) >> 3
3509                                              : pstr_it_bit_buff->cnt_bits >> 3;
3510   pstr_api_struct->pstr_state->i_out_bits = pstr_it_bit_buff->cnt_bits;
3511   ixheaace_write_audio_preroll_data(pstr_api_struct, pstr_it_bit_buff);
3512   pstr_state->str_usac_enc_data.frame_count++;
3513   pstr_usac_data->usac_independency_flag_count =
3514       (pstr_usac_data->usac_independency_flag_count + 1) %
3515       pstr_usac_data->usac_independency_flag_interval;
3516 
3517   if (pstr_config->sbr_enable) {
3518     WORD32 num_samples = pstr_api_struct->config[0].usac_config.ccfl * IXHEAACE_MAX_CH_IN_BS_ELE;
3519     switch (pstr_api_struct->config[0].ccfl_idx) {
3520       case SBR_8_3:
3521         num_samples *= 8;
3522         num_samples /= 3;
3523         break;
3524 
3525       case SBR_2_1:
3526         num_samples *= 2;
3527         break;
3528 
3529       case SBR_4_1:
3530         num_samples *= 4;
3531         break;
3532     }
3533 
3534     if (ptr_input_buffer != NULL) {
3535       memmove(ptr_input_buffer, ptr_input_buffer + num_samples,
3536               write_off_set * sizeof(ptr_input_buffer[0]));
3537     }
3538   }
3539 
3540   return IA_NO_ERROR;
3541 }
ixheaace_get_lib_id_strings(pVOID pv_output)3542 IA_ERRORCODE ixheaace_get_lib_id_strings(pVOID pv_output) {
3543   IA_ERRORCODE err_code = IA_NO_ERROR;
3544   ixheaace_version *pstr_output_config = (ixheaace_version *)pv_output;
3545   pstr_output_config->p_lib_name = (WORD8 *)LIB_NAME;
3546   pstr_output_config->p_version_num = (WORD8 *)ITTIAM_VER;
3547 
3548   return err_code;
3549 }
3550 
ixheaace_config_drc_parameters(ixheaace_api_struct * pstr_api_struct,ixheaace_input_config * pstr_input_config)3551 static void ixheaace_config_drc_parameters(ixheaace_api_struct *pstr_api_struct,
3552                                            ixheaace_input_config *pstr_input_config) {
3553   ia_drc_input_config *pstr_drc_cfg;
3554   pstr_drc_cfg = (ia_drc_input_config *)pstr_input_config->pv_drc_cfg;
3555 
3556   ia_drc_internal_config *pstr_internal_drc_cfg =
3557       &pstr_api_struct->config[0].usac_config.str_internal_drc_cfg;
3558 
3559   ia_drc_loudness_info_set_struct *pstr_enc_loudness_info_set =
3560       &pstr_drc_cfg->str_enc_loudness_info_set;
3561   ia_drc_loudness_info_set_struct *pstr_enc_internal_loudness_info_set =
3562       &pstr_internal_drc_cfg->str_enc_loudness_info_set;
3563 
3564   WORD32 n;
3565 
3566   pstr_enc_loudness_info_set->loudness_info_count =
3567       MIN(pstr_enc_internal_loudness_info_set->loudness_info_count, MAX_LOUDNESS_INFO_COUNT);
3568 
3569   for (n = 0; n < pstr_enc_loudness_info_set->loudness_info_count; n++) {
3570     memcpy(&pstr_enc_loudness_info_set->str_loudness_info[n],
3571            &pstr_enc_internal_loudness_info_set->str_loudness_info[n],
3572            sizeof(ia_drc_loudness_info_struct));
3573   }
3574 
3575   pstr_enc_loudness_info_set->loudness_info_album_count = MIN(
3576       pstr_enc_internal_loudness_info_set->loudness_info_album_count, MAX_LOUDNESS_INFO_COUNT);
3577   for (n = 0; n < pstr_enc_loudness_info_set->loudness_info_album_count; n++) {
3578     memcpy(&pstr_enc_loudness_info_set->str_loudness_info_album[n],
3579            &pstr_enc_internal_loudness_info_set->str_loudness_info_album[n],
3580            sizeof(ia_drc_loudness_info_struct));
3581   }
3582 }
3583 
ixheaace_get_measured_loudness_info(ixheaace_api_struct * pstr_api_struct,ixheaace_input_config * pstr_input_config)3584 static void ixheaace_get_measured_loudness_info(ixheaace_api_struct *pstr_api_struct,
3585                                                 ixheaace_input_config *pstr_input_config) {
3586   ia_drc_input_config *pstr_internal_drc_cfg;
3587   if (!pstr_input_config->use_measured_loudness) {
3588     pstr_internal_drc_cfg =
3589         (ia_drc_input_config *)&pstr_api_struct->config[0].usac_config.str_internal_drc_cfg;
3590   } else {
3591     pstr_internal_drc_cfg = &pstr_api_struct->config[0].usac_config.str_drc_cfg;
3592   }
3593   memset(pstr_internal_drc_cfg, 0, sizeof(ia_drc_input_config));
3594   ia_drc_uni_drc_config_struct *pstr_uni_drc_config = &pstr_internal_drc_cfg->str_uni_drc_config;
3595   ia_drc_loudness_info_set_struct *pstr_enc_loudness_info_set =
3596       &pstr_internal_drc_cfg->str_enc_loudness_info_set;
3597   {
3598     WORD32 n, m;
3599     pstr_uni_drc_config->sample_rate_present = 1;
3600     pstr_uni_drc_config->loudness_info_set_present = 1;
3601     pstr_enc_loudness_info_set->loudness_info_count = 1;
3602     pstr_enc_loudness_info_set->loudness_info_count =
3603         MIN(pstr_enc_loudness_info_set->loudness_info_count, MAX_LOUDNESS_INFO_COUNT);
3604     for (n = 0; n < pstr_enc_loudness_info_set->loudness_info_count; n++) {
3605       pstr_enc_loudness_info_set->str_loudness_info[n].drc_set_id = 0;
3606       pstr_enc_loudness_info_set->str_loudness_info[n].downmix_id = 0;
3607       pstr_enc_loudness_info_set->str_loudness_info[n].sample_peak_level_present = 1;
3608       pstr_enc_loudness_info_set->str_loudness_info[n].sample_peak_level =
3609           pstr_input_config->sample_peak_level;
3610       pstr_enc_loudness_info_set->str_loudness_info[n].true_peak_level_present = 0;
3611       pstr_enc_loudness_info_set->str_loudness_info[n].measurement_count = 1;
3612       pstr_enc_loudness_info_set->str_loudness_info[n].measurement_count =
3613           MIN(pstr_enc_loudness_info_set->str_loudness_info[n].measurement_count,
3614               MAX_MEASUREMENT_COUNT);
3615 
3616       for (m = 0; m < pstr_enc_loudness_info_set->str_loudness_info[n].measurement_count; m++) {
3617         pstr_enc_loudness_info_set->str_loudness_info[n]
3618             .str_loudness_measure[m]
3619             .method_definition = pstr_input_config->method_def;
3620         pstr_enc_loudness_info_set->str_loudness_info[n].str_loudness_measure[m].method_value =
3621             (FLOAT32)pstr_input_config->measured_loudness;
3622         pstr_enc_loudness_info_set->str_loudness_info[n]
3623             .str_loudness_measure[m]
3624             .measurement_system = pstr_input_config->measurement_system;
3625         pstr_enc_loudness_info_set->str_loudness_info[n].str_loudness_measure[m].reliability = 3;
3626       }
3627     }
3628   }
3629 }
3630 
ixheaace_allocate(pVOID pv_input,pVOID pv_output)3631 IA_ERRORCODE ixheaace_allocate(pVOID pv_input, pVOID pv_output) {
3632   IA_ERRORCODE err_code = IA_NO_ERROR;
3633   WORD32 ui_api_size;
3634   pVOID pv_value;
3635   ixheaace_input_config *pstr_input_config = (ixheaace_input_config *)pv_input;
3636   ixheaace_output_config *pstr_output_config = (ixheaace_output_config *)pv_output;
3637   ixheaace_api_struct *pstr_api_struct;
3638   if (1 == pstr_input_config->usac_en) {
3639     pstr_input_config->aot = AOT_USAC;
3640   }
3641   if (pstr_input_config->aot != AOT_AAC_ELD && pstr_input_config->aot != AOT_AAC_LC &&
3642       pstr_input_config->aot != AOT_AAC_LD && pstr_input_config->aot != AOT_SBR &&
3643       pstr_input_config->aot != AOT_PS && pstr_input_config->aot != AOT_USAC) {
3644     return IA_EXHEAACE_API_FATAL_UNSUPPORTED_AOT;
3645   }
3646   ui_api_size = sizeof(ixheaace_api_struct);
3647   pstr_output_config->arr_alloc_memory[pstr_output_config->malloc_count] =
3648       pstr_output_config->malloc_xheaace(ui_api_size + EIGHT_BYTE_SIZE, DEFAULT_MEM_ALIGN_8);
3649   if (NULL == pstr_output_config->arr_alloc_memory[pstr_output_config->malloc_count]) {
3650     return IA_EXHEAACE_API_FATAL_MEM_ALLOC;
3651   }
3652   memset(pstr_output_config->arr_alloc_memory[pstr_output_config->malloc_count], 0, ui_api_size);
3653 
3654   pstr_output_config->ui_rem =
3655       (SIZE_T)((SIZE_T)pstr_output_config->arr_alloc_memory[pstr_output_config->malloc_count] %
3656                BYTE_ALIGN_8);
3657 
3658   pstr_output_config->pv_ia_process_api_obj =
3659       (pVOID)((WORD8 *)pstr_output_config->arr_alloc_memory[pstr_output_config->malloc_count] +
3660               BYTE_ALIGN_8 - pstr_output_config->ui_rem);
3661   pstr_output_config->malloc_count++;
3662 
3663   pstr_api_struct = (ixheaace_api_struct *)pstr_output_config->pv_ia_process_api_obj;
3664   memset(pstr_api_struct, 0, sizeof(*pstr_api_struct));
3665 
3666   if (pstr_input_config->aot == AOT_USAC) {
3667     if (pstr_input_config->use_drc_element == 0) {
3668       pstr_input_config->use_measured_loudness = 1;
3669     } else {
3670       pstr_input_config->use_measured_loudness = 0;
3671     }
3672     ixheaace_get_measured_loudness_info(pstr_api_struct, pstr_input_config);
3673 
3674     if (!pstr_input_config->use_measured_loudness)
3675       ixheaace_config_drc_parameters(pstr_api_struct, pstr_input_config);
3676 
3677     if (pstr_input_config->use_measured_loudness) {
3678       memcpy(pstr_input_config->pv_drc_cfg, &pstr_api_struct->config[0].usac_config.str_drc_cfg,
3679              sizeof(ia_drc_input_config));
3680     }
3681   }
3682 
3683   ixheaace_set_default_config(pstr_api_struct, pstr_input_config);
3684 
3685   err_code = ixheaace_set_config_params(pstr_api_struct, pstr_input_config);
3686   if (err_code) {
3687     return err_code;
3688   }
3689 
3690   pstr_output_config->ui_proc_mem_tabs_size =
3691       (sizeof(ixheaace_mem_info_struct) + sizeof(pVOID *)) * 4;
3692   pstr_output_config->arr_alloc_memory[pstr_output_config->malloc_count] =
3693       pstr_output_config->malloc_xheaace(
3694           pstr_output_config->ui_proc_mem_tabs_size + EIGHT_BYTE_SIZE, DEFAULT_MEM_ALIGN_8);
3695   if (NULL == pstr_output_config->arr_alloc_memory[pstr_output_config->malloc_count]) {
3696     return IA_EXHEAACE_API_FATAL_MEM_ALLOC;
3697   }
3698   memset(pstr_output_config->arr_alloc_memory[pstr_output_config->malloc_count], 0,
3699          pstr_output_config->ui_proc_mem_tabs_size);
3700 
3701   pstr_output_config->ui_rem =
3702       (SIZE_T)((SIZE_T)pstr_output_config->arr_alloc_memory[pstr_output_config->malloc_count] %
3703                BYTE_ALIGN_8);
3704 
3705   pv_value =
3706       (pVOID)((WORD8 *)pstr_output_config->arr_alloc_memory[pstr_output_config->malloc_count] +
3707               BYTE_ALIGN_8 - pstr_output_config->ui_rem);
3708   if (pv_value == NULL) {
3709     return IA_EXHEAACE_API_FATAL_MEM_ALLOC;
3710   }
3711   memset(pv_value, 0, (sizeof(ixheaace_mem_info_struct) + sizeof(pVOID *)) * 4);
3712 
3713   pstr_api_struct->pstr_mem_info = (ixheaace_mem_info_struct *)pv_value;
3714   pstr_api_struct->pp_mem = (pVOID *)((WORD8 *)pv_value + sizeof(ixheaace_mem_info_struct) * 4);
3715 
3716   pstr_output_config->malloc_count++;
3717 
3718   if (pstr_input_config->aot == AOT_USAC) {
3719     if (pstr_input_config->use_measured_loudness) {
3720       pstr_api_struct->config[0].usac_config.use_measured_loudness = 1;
3721     }
3722   }
3723 
3724   ixheaace_fill_mem_tabs(pstr_api_struct, pstr_input_config->aot);
3725 
3726   err_code =
3727       ixheaace_alloc_and_assign_mem(pstr_api_struct, pstr_output_config, pstr_input_config);
3728   if (err_code) {
3729     return err_code;
3730   }
3731   return err_code;
3732 }
3733 
ixheaace_init(pVOID pstr_obj_ixheaace,pVOID pv_input,pVOID pv_output)3734 IA_ERRORCODE ixheaace_init(pVOID pstr_obj_ixheaace, pVOID pv_input, pVOID pv_output) {
3735   IA_ERRORCODE error = IA_NO_ERROR;
3736   WORD32 frame_length;
3737   WORD32 channels, ele_idx;
3738   ixheaace_api_struct *pstr_api_struct = (ixheaace_api_struct *)pstr_obj_ixheaace;
3739   ixheaace_input_config *pstr_input_config = (ixheaace_input_config *)pv_input;
3740   ixheaace_output_config *pstr_output_config = (ixheaace_output_config *)pv_output;
3741   WORD32 total_bitrate_used = 0;
3742   frame_length = pstr_input_config->frame_length;
3743   channels = 0;
3744   for (ele_idx = 0; ele_idx < pstr_api_struct->config[0].num_bs_elements; ele_idx++) {
3745     channels += pstr_api_struct->config[ele_idx].i_channels;
3746   }
3747   pstr_api_struct->pstr_state->aot = pstr_input_config->aot;
3748 
3749   if ((pstr_api_struct->config[0].use_mps == 1) &&
3750       (0 == pstr_api_struct->config->aac_classic ||
3751        pstr_api_struct->pstr_state->aot == AOT_USAC)) {
3752     pstr_api_struct->pstr_state->mps_enable = pstr_api_struct->config[0].use_mps;
3753     pstr_api_struct->pstr_state->mps_tree_config = pstr_api_struct->config[0].mps_tree_config;
3754   }
3755   if (pstr_api_struct->config[0].num_bs_elements == 1) {
3756     pstr_api_struct->config[ele_idx].write_program_config_element = 0;
3757   }
3758 
3759   if (pstr_api_struct->pstr_state->aot != AOT_USAC) {
3760     for (ele_idx = 0; ele_idx < pstr_api_struct->config[0].num_bs_elements; ele_idx++) {
3761       /* Set config pointer in api obj */
3762       pstr_api_struct->pstr_state->pstr_config[ele_idx] = &pstr_api_struct->config[ele_idx];
3763 
3764       error = ia_enhaacplus_enc_init(pstr_api_struct, ele_idx);
3765       if (error) {
3766         return error;
3767       }
3768 
3769       pstr_api_struct->pstr_state->ui_init_done = 1;
3770       total_bitrate_used += pstr_api_struct->config[ele_idx].aac_config.bit_rate;
3771     }
3772     if (pstr_input_config->i_bitrate != total_bitrate_used) {
3773       pstr_input_config->i_bitrate = total_bitrate_used;
3774     }
3775     if (pstr_api_struct->config[0].aac_config.bitreservoir_size != -1) {
3776       WORD32 avg_bytes_per_frame_per_ch = pstr_api_struct->config[0].aac_config.bitreservoir_size;
3777       if (pstr_api_struct->config[0].aac_config.flag_framelength_small) {
3778         if (pstr_api_struct->config[0].aot == AOT_AAC_LC ||
3779             pstr_api_struct->config[0].aot == AOT_PS ||
3780             pstr_api_struct->config[0].aot == AOT_SBR) {
3781           avg_bytes_per_frame_per_ch = (pstr_api_struct->config[0].aac_config.bit_rate) *
3782                                        FRAME_LEN_960 /
3783                                        (pstr_api_struct->config[0].aac_config.core_sample_rate *
3784                                         pstr_api_struct->config[0].i_channels * 8);
3785         }
3786         if (pstr_input_config->aot == AOT_AAC_LD || pstr_input_config->aot == AOT_AAC_ELD) {
3787           avg_bytes_per_frame_per_ch = (pstr_api_struct->config[0].aac_config.bit_rate) *
3788                                        FRAME_LEN_480 /
3789                                        (pstr_api_struct->config[0].aac_config.core_sample_rate *
3790                                         pstr_api_struct->config[0].i_channels * 8);
3791         }
3792       } else {
3793         if (pstr_api_struct->config[0].aot == AOT_AAC_LC ||
3794             pstr_api_struct->config[0].aot == AOT_PS ||
3795             pstr_api_struct->config[0].aot == AOT_SBR) {
3796           avg_bytes_per_frame_per_ch = (pstr_api_struct->config[0].aac_config.bit_rate) *
3797                                        FRAME_LEN_1024 /
3798                                        (pstr_api_struct->config[0].aac_config.core_sample_rate *
3799                                         pstr_api_struct->config[0].i_channels * 8);
3800         }
3801         if (pstr_input_config->aot == AOT_AAC_LD || pstr_input_config->aot == AOT_AAC_ELD) {
3802           avg_bytes_per_frame_per_ch = (pstr_api_struct->config[0].aac_config.bit_rate) *
3803                                        FRAME_LEN_512 /
3804                                        (pstr_api_struct->config[0].aac_config.core_sample_rate *
3805                                         pstr_api_struct->config[0].i_channels * 8);
3806         }
3807       }
3808 
3809       if (pstr_api_struct->config[0].aac_config.bitreservoir_size < avg_bytes_per_frame_per_ch) {
3810         return IA_EXHEAACE_CONFIG_NONFATAL_BITRES_SIZE_TOO_SMALL;
3811       }
3812     }
3813     if (pstr_input_config->i_use_es) {
3814       // Write GA header
3815       ia_bit_buf_struct *pstr_ia_asc_bit_buf;
3816       pstr_ia_asc_bit_buf = iusace_create_bit_buffer(
3817           &(pstr_api_struct->pstr_state->str_bit_buf), pstr_api_struct->pp_mem[IA_MEMTYPE_OUTPUT],
3818           pstr_api_struct->pstr_mem_info[IA_MEMTYPE_OUTPUT].ui_size, 1);
3819 
3820       ixheaace_get_audiospecific_config_bytes(pstr_ia_asc_bit_buf,
3821                                               &pstr_api_struct->pstr_state->audio_specific_config,
3822                                               pstr_api_struct->pstr_state->aot,
3823                                               pstr_input_config->ccfl_idx);
3824 
3825       pstr_api_struct->pstr_state->i_out_bytes = (pstr_ia_asc_bit_buf->cnt_bits + 7) >> 3;
3826     }
3827     if (pstr_api_struct->config->aac_classic) {
3828       pstr_output_config->input_size =
3829           frame_length * channels * pstr_api_struct->config[0].ui_pcm_wd_sz / 8;
3830     } else {
3831       pstr_output_config->input_size =
3832           2 * frame_length * channels * pstr_api_struct->config[0].ui_pcm_wd_sz / 8;
3833     }
3834     pstr_output_config->samp_freq = pstr_api_struct->config[0].native_sample_rate;
3835     pstr_output_config->header_samp_freq = pstr_api_struct->config[0].aac_config.core_sample_rate;
3836     pstr_output_config->down_sampling_ratio =
3837         pstr_api_struct->config->aac_classic == 0 ? 2.0f : 1.0f;
3838     switch (pstr_api_struct->config->aot) {
3839       case AOT_AAC_LC:
3840         pstr_output_config->audio_profile = AUDIO_PROFILE_AAC_LC_L5;
3841         break;
3842       case AOT_SBR:
3843         pstr_output_config->audio_profile = AUDIO_PROFILE_HEAAC_L5;
3844         break;
3845       case AOT_PS:
3846         pstr_output_config->audio_profile = AUDIO_PROFILE_HEAAC_V2_L5;
3847         break;
3848       case AOT_AAC_LD:
3849         pstr_output_config->audio_profile = AUDIO_PROFILE_AAC_LD_L4;
3850         break;
3851       case AOT_AAC_ELD:
3852         if (pstr_api_struct->config[0].use_mps) {
3853           if (pstr_api_struct->config[0].mps_tree_config == TREE_212) {
3854             pstr_output_config->audio_profile = AUDIO_PROFILE_AAC_ELD_L2;
3855           } else {
3856             pstr_output_config->audio_profile = AUDIO_PROFILE_AAC_ELD_L4;
3857           }
3858         } else {
3859           pstr_output_config->audio_profile = AUDIO_PROFILE_AAC_ELD_L1;
3860         }
3861         break;
3862       default:
3863         pstr_output_config->audio_profile = AUDIO_PROFILE_NOT_SPECIFIED;
3864         break;
3865     }
3866   }
3867 
3868   else {
3869     pstr_api_struct->pstr_state->pstr_config[0] = &pstr_api_struct->config[0];
3870     error = ia_usac_enc_init(pstr_api_struct, pstr_input_config->ccfl_idx);
3871     if (error) {
3872       return error;
3873     }
3874 
3875     pstr_output_config->input_size =
3876         frame_length * channels * (pstr_api_struct->config[0].usac_config.ui_pcm_wd_sz >> 3);
3877 
3878     if (pstr_api_struct->config[0].usac_config.use_drc_element) {
3879       ia_drc_input_config *pstr_drc_cfg = (ia_drc_input_config *)(pstr_input_config->pv_drc_cfg);
3880       memcpy(pstr_drc_cfg, &pstr_api_struct->config[0].usac_config.str_drc_cfg,
3881              sizeof(ia_drc_input_config));
3882     }
3883 
3884     pstr_output_config->down_sampling_ratio = 1;
3885     if (pstr_api_struct->config[0].usac_config.sbr_enable == 1) {
3886       switch (pstr_api_struct->config[0].ccfl_idx) {
3887         case SBR_8_3:
3888           pstr_output_config->input_size *= 8;
3889           pstr_output_config->input_size /= 3;
3890           pstr_output_config->down_sampling_ratio = 8.0f / 3.0f;
3891           break;
3892 
3893         case SBR_2_1:
3894           pstr_output_config->input_size *= 2;
3895           pstr_output_config->down_sampling_ratio = 2;
3896           break;
3897 
3898         case SBR_4_1:
3899           pstr_output_config->input_size *= 4;
3900           pstr_output_config->down_sampling_ratio = 4;
3901           break;
3902       }
3903     }
3904     pstr_output_config->samp_freq = pstr_api_struct->config[0].usac_config.native_sample_rate;
3905     pstr_output_config->header_samp_freq =
3906         pstr_api_struct->config[0].usac_config.native_sample_rate;
3907     pstr_output_config->audio_profile = AUDIO_PROFILE_USAC_L2;
3908     if (pstr_input_config->use_drc_element !=
3909         pstr_api_struct->config[0].usac_config.use_drc_element) {
3910       error = IA_EXHEAACE_EXE_NONFATAL_USAC_INVALID_GAIN_POINTS;
3911     }
3912     pstr_input_config->use_drc_element = pstr_api_struct->config[0].usac_config.use_drc_element;
3913   }
3914 
3915   pstr_api_struct->pstr_state->ui_init_done = 1;
3916   pstr_output_config->i_out_bytes = pstr_api_struct->pstr_state->i_out_bytes;
3917 
3918   return error;
3919 }
3920 
ixheaace_create(pVOID pv_input,pVOID pv_output)3921 IA_ERRORCODE ixheaace_create(pVOID pv_input, pVOID pv_output) {
3922   IA_ERRORCODE err_code = IA_NO_ERROR;
3923   ixheaace_output_config *pstr_out_cfg = (ixheaace_output_config *)pv_output;
3924   err_code = ixheaace_allocate(pv_input, pv_output);
3925   if (!err_code) {
3926     err_code = ixheaace_init(pstr_out_cfg->pv_ia_process_api_obj, pv_input, pv_output);
3927   }
3928   if (err_code & IA_FATAL_ERROR) {
3929     IXHEAACE_MEM_FREE(pv_output);
3930   }
3931   return err_code;
3932 }
3933 
ixheaace_process(pVOID pstr_obj_ixheaace,pVOID pv_input,pVOID pv_output)3934 IA_ERRORCODE ixheaace_process(pVOID pstr_obj_ixheaace, pVOID pv_input, pVOID pv_output) {
3935   IA_ERRORCODE error = IA_NO_ERROR;
3936   WORD32 ele_idx;
3937   (VOID) pv_input;
3938   ixheaace_api_struct *pstr_api_struct = (ixheaace_api_struct *)pstr_obj_ixheaace;
3939   ixheaace_output_config *pstr_output_config = (ixheaace_output_config *)pv_output;
3940   pstr_api_struct->pstr_state->is_quant_spec_zero = 0;
3941   pstr_api_struct->pstr_state->is_gain_limited = 0;
3942   if (!pstr_api_struct->usac_en) {
3943     for (ele_idx = 0; ele_idx < pstr_api_struct->config[0].num_bs_elements; ele_idx++) {
3944       error = ia_enhaacplus_enc_execute(pstr_api_struct, ele_idx);
3945       if (error != IA_NO_ERROR) {
3946         return error;
3947       }
3948     }
3949     if ((error == IA_NO_ERROR) && (pstr_api_struct->pstr_state->is_quant_spec_zero)) {
3950       error = IA_EXHEAACE_EXE_NONFATAL_QUANTIZATION_SPECTRUM_ZERO;
3951     }
3952     if ((error == IA_NO_ERROR) && (pstr_api_struct->pstr_state->is_gain_limited)) {
3953       error = IA_EXHEAACE_EXE_NONFATAL_QUANTIZATION_INSUFFICIENT_BITRES;
3954     }
3955   } else {
3956     ia_usac_encoder_config_struct *usac_config = &pstr_api_struct->config[0].usac_config;
3957     if (usac_config->iframes_interval <= usac_config->num_preroll_frames) {
3958       pstr_api_struct->pstr_state->str_usac_enc_data.usac_independency_flag = 1;
3959       if (usac_config->iframes_interval == usac_config->num_preroll_frames &&
3960           usac_config->is_first_frame == 0) {
3961         usac_config->is_ipf = 1;
3962       }
3963     } else {
3964       pstr_api_struct->pstr_state->str_usac_enc_data.usac_independency_flag = 0;
3965     }
3966     if (pstr_api_struct->pstr_state->str_usac_enc_data.frame_count >
3967         usac_config->num_preroll_frames) {
3968       if (usac_config->iframes_interval <= usac_config->num_preroll_frames) {
3969         pstr_api_struct->pstr_state->str_usac_enc_data.usac_independency_flag = 1;
3970       } else {
3971         pstr_api_struct->pstr_state->str_usac_enc_data.usac_independency_flag = 0;
3972       }
3973     }
3974 
3975     {
3976       error = iusace_process(pstr_api_struct);
3977       if (error & IA_FATAL_ERROR) {
3978         pstr_output_config->i_out_bytes = 0;
3979         return error;
3980       }
3981       if ((error == IA_NO_ERROR) && (pstr_api_struct->pstr_state->is_quant_spec_zero)) {
3982         error = IA_EXHEAACE_EXE_NONFATAL_USAC_QUANTIZATION_SPECTRUM_ZERO;
3983       }
3984       if ((error == IA_NO_ERROR) && (pstr_api_struct->pstr_state->is_gain_limited)) {
3985         error = IA_EXHEAACE_EXE_NONFATAL_USAC_QUANTIZATION_INSUFFICIENT_BITRES;
3986       }
3987     }
3988 
3989     usac_config->iframes_interval++;
3990     if (usac_config->iframes_interval ==
3991         (usac_config->random_access_interval - usac_config->num_preroll_frames)) {
3992       usac_config->iframes_interval = 0;
3993     }
3994   }
3995   pstr_output_config->i_out_bytes = pstr_api_struct->pstr_state->i_out_bytes;
3996   return error;
3997 }
3998 
ixheaace_delete(pVOID pv_output)3999 IA_ERRORCODE ixheaace_delete(pVOID pv_output) {
4000   IXHEAACE_MEM_FREE(pv_output);
4001   return IA_NO_ERROR;
4002 }
4003