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