libxaac/encoder/ixheaace_qc_util.c
2023-10-12 19:24:54 +05:30

518 lines
18 KiB
C

/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <string.h>
#include "ixheaac_type_def.h"
#include "ixheaac_constants.h"
#include "impd_drc_common_enc.h"
#include "impd_drc_uni_drc.h"
#include "impd_drc_tables.h"
#include "impd_drc_api.h"
#include "ixheaace_api.h"
#include "ixheaace_aac_constants.h"
#include "ixheaace_error_codes.h"
#include "ixheaac_error_standards.h"
#include <stdlib.h>
#include "ixheaace_psy_const.h"
#include "ixheaace_tns.h"
#include "ixheaace_tns_params.h"
#include "ixheaace_rom.h"
#include "ixheaace_common_rom.h"
#include "ixheaace_quant.h"
#include "ixheaace_block_switch.h"
#include "ixheaace_bitbuffer.h"
#include "ixheaac_basic_ops32.h"
#include "ixheaac_basic_ops16.h"
#include "ixheaac_basic_ops40.h"
#include "ixheaac_basic_ops.h"
#include "ixheaace_psy_const.h"
#include "ixheaace_tns.h"
#include "ixheaace_psy_data.h"
#include "ixheaace_interface.h"
#include "ixheaace_adjust_threshold_data.h"
#include "ixheaace_dynamic_bits.h"
#include "ixheaace_qc_data.h"
#include "ixheaace_adjust_threshold.h"
#include "ixheaace_sf_estimation.h"
#include "ixheaace_static_bits.h"
#include "ixheaace_bits_count.h"
#include "ixheaace_channel_map.h"
#include "ixheaace_write_bitstream.h"
#include "ixheaace_psy_configuration.h"
#include "ixheaace_psy_mod.h"
#include "ixheaace_tns_params.h"
#include "ixheaace_stereo_preproc.h"
#include "ixheaace_enc_main.h"
#include "ixheaace_qc_util.h"
#include "ixheaace_common_utils.h"
static WORD32 ia_enhaacplus_enc_calc_frame_len(WORD32 bit_rate, WORD32 sample_rate,
FRAME_LEN_RESULT_MODE mode,
WORD32 long_frame_len) {
WORD32 result;
result = ((long_frame_len) >> 3) * (bit_rate);
switch (mode) {
case FRAME_LEN_BYTES_MODULO:
result %= sample_rate;
break;
case FRAME_LEN_BYTES_INT:
result /= sample_rate;
break;
default:
break;
}
return result;
}
static WORD32 ia_enhaacplus_enc_frame_padding(WORD32 bit_rate, WORD32 sample_rate,
WORD32 *ptr_padding_rest, WORD32 frame_len_long) {
WORD32 padding_on;
WORD32 difference;
padding_on = 0;
difference = ia_enhaacplus_enc_calc_frame_len(bit_rate, sample_rate, FRAME_LEN_BYTES_MODULO,
frame_len_long);
*ptr_padding_rest -= difference;
if (*ptr_padding_rest <= 0) {
padding_on = 1;
*ptr_padding_rest += sample_rate;
}
return padding_on;
}
IA_ERRORCODE ia_enhaacplus_enc_qc_out_new(ixheaace_qc_out *pstr_qc_out, WORD32 num_channels,
WORD32 *ptr_shared_buffer1, WORD32 *ptr_shared_buffer3,
WORD32 long_frame_len)
{
WORD32 i;
for (i = 0; i < num_channels; i++) {
pstr_qc_out->qc_channel[i]->quant_spec = &((WORD16 *)ptr_shared_buffer1)[i * long_frame_len];
memset(pstr_qc_out->qc_channel[i]->quant_spec, 0,
sizeof(*pstr_qc_out->qc_channel[i]->quant_spec) * long_frame_len);
pstr_qc_out->qc_channel[i]->max_val_in_sfb =
&((UWORD16 *)&ptr_shared_buffer3[(long_frame_len + long_frame_len / 2) +
IXHEAACE_MAX_CH_IN_BS_ELE *
MAXIMUM_GROUPED_SCALE_FACTOR_BAND /
2])[i * MAXIMUM_GROUPED_SCALE_FACTOR_BAND];
memset(
pstr_qc_out->qc_channel[i]->max_val_in_sfb, 0,
sizeof(*pstr_qc_out->qc_channel[i]->max_val_in_sfb) * MAXIMUM_GROUPED_SCALE_FACTOR_BAND);
pstr_qc_out->qc_channel[i]->scalefactor = &((WORD16 *)&ptr_shared_buffer3[(
long_frame_len + long_frame_len / 2)])[i * MAXIMUM_GROUPED_SCALE_FACTOR_BAND];
memset(pstr_qc_out->qc_channel[i]->scalefactor, 0,
sizeof(*pstr_qc_out->qc_channel[i]->scalefactor) * MAXIMUM_GROUPED_SCALE_FACTOR_BAND);
}
if (pstr_qc_out == NULL) {
return IA_EXHEAACE_INIT_FATAL_AAC_INIT_FAILED;
}
return IA_NO_ERROR;
}
IA_ERRORCODE ia_enhaacplus_enc_qc_new(ixheaace_qc_state *pstr_qc_state,
WORD32 *ptr_shared_buffer_2, WORD32 long_frame_len
) {
memset(pstr_qc_state, 0, sizeof(ixheaace_qc_state));
pstr_qc_state->qc_scr.shared_buffer_2 =
(ptr_shared_buffer_2 + long_frame_len * IXHEAACE_MAX_CH_IN_BS_ELE + 16);
return IA_NO_ERROR;
}
IA_ERRORCODE ia_enhaacplus_enc_qc_init(ixheaace_qc_state *pstr_qc_state, WORD32 aot,
ixheaace_qc_init *pstr_init, FLAG flag_framelength_small) {
IA_ERRORCODE error = IA_NO_ERROR;
pstr_qc_state->num_channels = pstr_init->pstr_element_info->n_channels_in_el;
pstr_qc_state->max_bits_tot = pstr_init->max_bits;
switch (aot) {
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
pstr_qc_state->bit_res_tot = pstr_init->bit_res - pstr_init->average_bits;
break;
case AOT_AAC_LD:
case AOT_AAC_ELD:
if (pstr_init->bit_res) {
pstr_qc_state->bit_res_tot = pstr_init->bit_res - pstr_init->average_bits;
} else {
pstr_qc_state->bit_res_tot = 0;
}
break;
}
pstr_qc_state->average_bits_tot = pstr_init->average_bits;
pstr_qc_state->max_bit_fac = pstr_init->max_bit_fac;
pstr_qc_state->padding.padding_rest = pstr_init->padding.padding_rest;
pstr_qc_state->quality_level = pstr_init->inv_quant;
if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
pstr_qc_state->glob_stat_bits = 3; /* for ID_END */
}
error = ia_enhaacplus_enc_init_element_bits(
&pstr_qc_state->element_bits, *pstr_init->pstr_element_info, pstr_init->bitrate,
pstr_init->average_bits, aot, pstr_qc_state->glob_stat_bits, pstr_init->bit_res,
flag_framelength_small);
if (error != IA_NO_ERROR) {
return error;
}
iaace_adj_thr_init(&pstr_qc_state->str_adj_thr, pstr_init->mean_pe,
pstr_qc_state->element_bits.ch_bitrate, aot);
ia_enhaacplus_enc_bitcount_init((WORD32 *)pstr_qc_state->side_info_tab_long,
(WORD32 *)pstr_qc_state->side_info_tab_short);
return IA_NO_ERROR;
}
VOID ia_enhaacplus_enc_update_bit_reservoir(ixheaace_qc_state *pstr_qc_kernel,
ixheaace_qc_out *pstr_qc_out)
{
ixheaace_element_bits *pstr_el_bits;
pstr_qc_kernel->bit_res_tot = 0;
pstr_el_bits = &pstr_qc_kernel->element_bits;
if (pstr_el_bits->average_bits > 0) {
/* constant bitrate */
pstr_el_bits->bit_res_level +=
pstr_el_bits->average_bits -
(pstr_qc_out->qc_element.static_bits_used + pstr_qc_out->qc_element.dyn_bits_used +
pstr_qc_out->qc_element.anc_bits_used + pstr_qc_out->qc_element.fill_bits);
pstr_qc_kernel->bit_res_tot += pstr_el_bits->bit_res_level;
} else {
/* variable bitrate */
pstr_el_bits->bit_res_level = pstr_el_bits->max_bits;
pstr_qc_kernel->bit_res_tot = pstr_qc_kernel->max_bits_tot;
}
}
IA_ERRORCODE ia_enhaacplus_enc_finalize_bit_consumption(ixheaace_qc_state *pstr_qc_kernel,
ixheaace_qc_out *pstr_qc_out,
WORD32 flag_last_element, WORD32 cnt_bits,
WORD32 *tot_fill_bits,
iexheaac_encoder_str **pstr_aac_enc,
WORD32 num_bs_elements, WORD32 aot) {
WORD32 n_full_fill_elem, diff_bits;
WORD32 total_fill_bits = 0;
const WORD32 max_fill_elem_bits = 7 + 270 * 8;
WORD32 tfb_flag = 0;
WORD32 tfb_flag1 = 0;
WORD32 tfb_flag2 = 0;
pstr_qc_out->tot_static_bits_used = (flag_last_element ? pstr_qc_kernel->glob_stat_bits : 0);
pstr_qc_out->tot_dyn_bits_used = 0;
pstr_qc_out->tot_anc_bits_used = 0;
pstr_qc_out->total_fill_bits = 0;
pstr_qc_out->tot_static_bits_used += pstr_qc_out->qc_element.static_bits_used;
pstr_qc_out->tot_dyn_bits_used += pstr_qc_out->qc_element.dyn_bits_used;
pstr_qc_out->tot_anc_bits_used += pstr_qc_out->qc_element.anc_bits_used;
pstr_qc_out->total_fill_bits += pstr_qc_out->qc_element.fill_bits;
/* Accumulate total fill bits */
*tot_fill_bits += pstr_qc_out->qc_element.fill_bits;
if (flag_last_element) {
WORD32 i, j, temp_resv;
WORD32 bit_resv_spc[(MAXIMUM_BS_ELE << 1) + 1];
WORD32 bit_resv_spc_sort[(MAXIMUM_BS_ELE << 1) + 1] = {0, 1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16};
total_fill_bits = *tot_fill_bits;
/* Distribute fill bits among all channel elements for next frame */
if (total_fill_bits > 0) {
/* Generate array of vacancies in bit reservoirs */
for (i = 0, temp_resv = 0; i < num_bs_elements; i++, temp_resv++) {
bit_resv_spc[temp_resv] = (pstr_aac_enc[i]->qc_kernel.element_bits.max_bit_res_bits -
pstr_aac_enc[i]->qc_kernel.element_bits.bit_res_level);
/* CPE gets double the weight of SCE, so split CPE reservoir into two */
if (pstr_aac_enc[i]->qc_kernel.num_channels == 2) {
bit_resv_spc[temp_resv + 1] = bit_resv_spc[temp_resv] >> 1;
bit_resv_spc[temp_resv] -= bit_resv_spc[temp_resv + 1];
temp_resv++;
}
}
/* Sort bit_resv_spc[] in descending order of levels and
store the order in bit_resv_spc_sort[] */
for (i = (temp_resv - 1); i > 0; i--) {
for (j = 0; j < i; j++) {
if (bit_resv_spc[bit_resv_spc_sort[j]] < bit_resv_spc[bit_resv_spc_sort[j + 1]]) {
WORD32 tmp_var = bit_resv_spc_sort[j];
bit_resv_spc_sort[j] = bit_resv_spc_sort[j + 1];
bit_resv_spc_sort[j + 1] = tmp_var;
}
}
}
/* One dummy full reservoir at the end to help in bit distribution */
bit_resv_spc[temp_resv] = 0;
bit_resv_spc_sort[temp_resv] = temp_resv;
/* Distribute fill bits among reservoirs in the order of bit_resv_spc_sort[]:
- Bring up [0] to the level of [1]
- Next bring up [0] and [1] to the level of [2]...and so on */
for (i = 1; ((i < (temp_resv + 1)) && (total_fill_bits > 0)); i++) {
if (((bit_resv_spc[bit_resv_spc_sort[0]] - bit_resv_spc[bit_resv_spc_sort[i]]) * i) <=
total_fill_bits) {
total_fill_bits -=
((bit_resv_spc[bit_resv_spc_sort[0]] - bit_resv_spc[bit_resv_spc_sort[i]]) * i);
for (j = 0; j < i; j++) {
bit_resv_spc[bit_resv_spc_sort[j]] = bit_resv_spc[bit_resv_spc_sort[i]];
}
} else {
WORD32 div_bs_ele;
div_bs_ele = (WORD32)(total_fill_bits / i);
total_fill_bits -= (div_bs_ele * i);
for (j = 0; j < i; j++) {
bit_resv_spc[bit_resv_spc_sort[j]] -= div_bs_ele;
}
for (j = 0; ((j < i) && (total_fill_bits > 0)); j++) {
bit_resv_spc[bit_resv_spc_sort[j]]--;
total_fill_bits--;
}
}
}
/* Supply additional bits added for coding next frame */
for (i = 0, temp_resv = 0; i < num_bs_elements; i++, temp_resv++) {
WORD32 add_bits;
add_bits = (pstr_aac_enc[i]->qc_kernel.element_bits.max_bit_res_bits -
pstr_aac_enc[i]->qc_kernel.element_bits.bit_res_level) -
bit_resv_spc[temp_resv];
/* Because CPE reservoir has been split into two */
if (pstr_aac_enc[i]->qc_kernel.num_channels == 2) {
temp_resv++;
add_bits -= bit_resv_spc[temp_resv];
}
/* These will be in addition to the avg. bitrate for the next frame */
pstr_aac_enc[i]->qc_kernel.element_bits.carry_bits = add_bits;
}
/* Update remaining fill bits */
*tot_fill_bits = total_fill_bits;
}
n_full_fill_elem = (total_fill_bits - 1) / max_fill_elem_bits;
if (n_full_fill_elem) {
total_fill_bits -= n_full_fill_elem * max_fill_elem_bits;
}
if (total_fill_bits > 0) {
/* minimum Fillelement contains 7 (TAG + byte cnt) bits */
total_fill_bits = MAX(7, total_fill_bits);
/* fill element size equals n*8 + 7 */
total_fill_bits += ((8 - (total_fill_bits - 7) % 8) % 8);
switch (total_fill_bits) {
case 7:
tfb_flag2 = 1;
break;
case 15:
tfb_flag1 = 1;
break;
default:
tfb_flag = 1;
break;
}
}
total_fill_bits += n_full_fill_elem * max_fill_elem_bits;
pstr_qc_out->align_bits =
7 - (cnt_bits + pstr_qc_out->tot_dyn_bits_used + pstr_qc_out->tot_static_bits_used +
pstr_qc_out->tot_anc_bits_used + +total_fill_bits - 1) %
8;
if (((pstr_qc_out->align_bits + total_fill_bits - *tot_fill_bits) == 8) &&
(total_fill_bits > 8)) {
total_fill_bits -= 8;
}
diff_bits = (pstr_qc_out->align_bits + total_fill_bits) - *tot_fill_bits;
if (diff_bits) {
if (diff_bits < 0) {
return IA_EXHEAACE_EXE_FATAL_INVALID_BIT_CONSUMPTION;
} else {
{
if (cnt_bits + pstr_qc_out->tot_static_bits_used + pstr_qc_out->tot_dyn_bits_used +
pstr_qc_out->tot_anc_bits_used + total_fill_bits >
12288) {
if ((diff_bits > 8) && (total_fill_bits > 8)) {
if (tfb_flag || tfb_flag1) {
total_fill_bits -= 8;
}
if (tfb_flag2) {
total_fill_bits -= 7;
}
}
} else {
if (pstr_qc_kernel->element_bits.bit_res_level - diff_bits > 0) {
pstr_qc_kernel->element_bits.bit_res_level -= diff_bits;
pstr_qc_kernel->bit_res_tot = pstr_qc_kernel->element_bits.bit_res_level;
} else {
if ((diff_bits > 8) && (total_fill_bits > 8) && (tfb_flag)) {
total_fill_bits -= 8;
} else if ((diff_bits > 8) && (total_fill_bits > 8) && (tfb_flag1)) {
total_fill_bits -= 8;
} else if ((diff_bits > 8) && (total_fill_bits > 8) && (tfb_flag2)) {
total_fill_bits -= 7;
}
}
}
}
}
}
switch (aot) {
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
*tot_fill_bits = total_fill_bits;
break;
case AOT_AAC_LD:
case AOT_AAC_ELD:
pstr_qc_out->total_fill_bits = total_fill_bits;
*tot_fill_bits = 0;
break;
}
} // if flag_last_element
else {
pstr_qc_out->align_bits = 0;
}
if ((pstr_qc_out->tot_dyn_bits_used + pstr_qc_out->tot_static_bits_used +
pstr_qc_out->tot_anc_bits_used + pstr_qc_out->total_fill_bits + pstr_qc_out->align_bits) >
pstr_qc_kernel->max_bits_tot) {
}
return IA_NO_ERROR;
}
VOID ia_enhaacplus_enc_adjust_bitrate(ixheaace_qc_state *pstr_qc_state, WORD32 bit_rate,
WORD32 sample_rate, WORD32 flag_last_element,
WORD32 frame_len_long)
{
WORD32 padding_on;
WORD32 frame_len;
WORD32 code_bits;
WORD32 code_bits_last;
padding_on = ia_enhaacplus_enc_frame_padding(
bit_rate, sample_rate, &pstr_qc_state->padding.padding_rest, frame_len_long);
frame_len = padding_on + ia_enhaacplus_enc_calc_frame_len(bit_rate, sample_rate,
FRAME_LEN_BYTES_INT, frame_len_long);
frame_len <<= 3;
if (flag_last_element) {
code_bits_last = pstr_qc_state->average_bits_tot - pstr_qc_state->glob_stat_bits;
code_bits = frame_len - pstr_qc_state->glob_stat_bits;
} else {
code_bits_last = pstr_qc_state->average_bits_tot;
code_bits = frame_len;
}
/* calculate bits for every channel element */
if (code_bits != code_bits_last) {
WORD32 total_bits = 0;
pstr_qc_state->element_bits.average_bits =
(WORD32)(pstr_qc_state->element_bits.relative_bits * code_bits);
total_bits += pstr_qc_state->element_bits.average_bits;
pstr_qc_state->element_bits.average_bits += code_bits - total_bits;
}
pstr_qc_state->average_bits_tot = frame_len;
/* Bits carried over from previous frame due to distribution of fill bits */
pstr_qc_state->element_bits.average_bits += pstr_qc_state->element_bits.carry_bits;
pstr_qc_state->average_bits_tot += pstr_qc_state->element_bits.carry_bits;
/* Flush for current frame */
pstr_qc_state->element_bits.carry_bits = 0;
}
WORD32 ia_enhaacplus_aac_limitbitrate(WORD32 core_sampling_rate, WORD32 frame_length,
WORD32 num_channels, WORD32 bit_rate) {
WORD32 prev_bit_rate, shift = 0, iter = 0;
WORD32 max_ch_bits = MAXIMUM_CHANNEL_BITS_1024;
while ((frame_length & ~((1 << (shift + 1)) - 1)) == frame_length &&
(core_sampling_rate & ~((1 << (shift + 1)) - 1)) == core_sampling_rate) {
shift++;
}
max_ch_bits = MAXIMUM_CHANNEL_BITS_1024 * frame_length / MAX_FRAME_LEN;
do {
prev_bit_rate = bit_rate;
bit_rate = MAX(bit_rate, ((((40 * num_channels) + TRANSPORT_BITS) * (core_sampling_rate)) /
frame_length));
bit_rate = MIN(bit_rate, ((num_channels * max_ch_bits) * (core_sampling_rate >> shift)) /
(frame_length >> shift));
} while (prev_bit_rate != bit_rate && iter++ < 3);
return bit_rate;
}