1406 lines
57 KiB
C
1406 lines
57 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 <math.h>
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "ixheaac_type_def.h"
|
|
#include "ixheaac_constants.h"
|
|
#include "ixheaace_aac_constants.h"
|
|
#include "ixheaac_basic_ops32.h"
|
|
#include "ixheaac_basic_ops16.h"
|
|
#include "ixheaac_basic_ops40.h"
|
|
|
|
#include "ixheaace_sbr_header.h"
|
|
#include "ixheaace_sbr_def.h"
|
|
#include "ixheaace_resampler.h"
|
|
#include "ixheaace_sbr_rom.h"
|
|
#include "ixheaace_common_rom.h"
|
|
#include "ixheaace_bitbuffer.h"
|
|
#include "ixheaace_sbr_hbe.h"
|
|
#include "ixheaace_sbr_qmf_enc.h"
|
|
#include "ixheaace_sbr_tran_det.h"
|
|
#include "ixheaace_sbr_frame_info_gen.h"
|
|
#include "ixheaace_sbr_env_est.h"
|
|
#include "ixheaace_sbr_code_envelope.h"
|
|
#include "ixheaace_sbr_main.h"
|
|
#include "ixheaace_sbr_missing_harmonics_det.h"
|
|
#include "ixheaace_sbr_inv_filtering_estimation.h"
|
|
#include "ixheaace_sbr_noise_floor_est.h"
|
|
|
|
#include "ixheaace_sbr_ton_corr.h"
|
|
#include "iusace_esbr_pvc.h"
|
|
#include "iusace_esbr_inter_tes.h"
|
|
#include "ixheaace_sbr.h"
|
|
#include "ixheaace_sbr_cmondata.h"
|
|
#include "iusace_esbr_pvc.h"
|
|
|
|
#include "ixheaace_sbr_hybrid.h"
|
|
#include "ixheaace_sbr_ps_enc.h"
|
|
#include "ixheaace_sbr_ps_bitenc.h"
|
|
#include "ixheaace_sbr_write_bitstream.h"
|
|
#include "ixheaac_error_standards.h"
|
|
#include "ixheaace_error_codes.h"
|
|
#include "ixheaace_common_utils.h"
|
|
|
|
static WORD32 ixheaace_get_esbr_ext_data_size(ixheaace_str_esbr_bs_data *pstr_esbr_bs_data) {
|
|
WORD32 num_bits = 1;
|
|
if (1 == pstr_esbr_bs_data->sbr_num_chan) {
|
|
num_bits += 1;
|
|
if (pstr_esbr_bs_data->sbr_patching_mode[0] == 0) {
|
|
num_bits += 2;
|
|
if (pstr_esbr_bs_data->sbr_pitchin_flags[0] == 1) {
|
|
num_bits += 7;
|
|
}
|
|
}
|
|
} else if (2 == pstr_esbr_bs_data->sbr_num_chan) {
|
|
if (pstr_esbr_bs_data->sbr_coupling) {
|
|
num_bits += 1;
|
|
if (pstr_esbr_bs_data->sbr_patching_mode[0] == 0) {
|
|
num_bits += 2;
|
|
if (pstr_esbr_bs_data->sbr_pitchin_flags[0] == 1) {
|
|
num_bits += 7;
|
|
}
|
|
}
|
|
} else {
|
|
num_bits += 1;
|
|
if (pstr_esbr_bs_data->sbr_patching_mode[0] == 0) {
|
|
num_bits += 2;
|
|
if (pstr_esbr_bs_data->sbr_pitchin_flags[0] == 1) {
|
|
num_bits += 7;
|
|
}
|
|
}
|
|
num_bits += 1;
|
|
if (pstr_esbr_bs_data->sbr_patching_mode[1] == 0) {
|
|
num_bits += 2;
|
|
if (pstr_esbr_bs_data->sbr_pitchin_flags[1] == 1) {
|
|
num_bits += 7;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
num_bits = 0;
|
|
}
|
|
if (num_bits != 0 && num_bits < 6) {
|
|
num_bits = 6;
|
|
}
|
|
return num_bits;
|
|
}
|
|
static WORD32 iusace_encode_pvc_envelope(ixheaace_bit_buf_handle pstr_bs_handle,
|
|
ixheaace_pvc_bs_info *pstr_pvc_bs_data,
|
|
WORD32 usac_indep_flag) {
|
|
WORD32 payload_cnt_bits = 0;
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_pvc_bs_data->div_mode,
|
|
IXHEAACE_ESBR_PVC_DIV_MODE_BITS);
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_pvc_bs_data->ns_mode,
|
|
IXHEAACE_ESBR_PVC_NS_MODE_BITS);
|
|
|
|
if (0 == pstr_pvc_bs_data->div_mode) {
|
|
if (1 == usac_indep_flag) {
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_pvc_bs_data->pvc_id_bs[0],
|
|
IXHEAACE_ESBR_PVC_ID_BITS);
|
|
} else {
|
|
if (1 == pstr_pvc_bs_data->grid_info[0]) {
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 0, IXHEAACE_ESBR_PVC_REUSE_BITS);
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_pvc_bs_data->pvc_id_bs[0],
|
|
IXHEAACE_ESBR_PVC_ID_BITS);
|
|
} else {
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 1, IXHEAACE_ESBR_PVC_REUSE_BITS);
|
|
}
|
|
}
|
|
} else if (pstr_pvc_bs_data->div_mode <= 3) {
|
|
/* Do nothing */
|
|
} else {
|
|
WORD32 gi, is_grid_info;
|
|
for (gi = 0; gi < pstr_pvc_bs_data->num_grid_info; gi++) {
|
|
if (gi == 0 && 1 == usac_indep_flag) {
|
|
is_grid_info = 1;
|
|
} else {
|
|
is_grid_info = pstr_pvc_bs_data->grid_info[gi];
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, is_grid_info, IXHEAACE_ESBR_PVC_GRID_INFO_BITS);
|
|
}
|
|
if (is_grid_info) {
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_pvc_bs_data->pvc_id_bs[gi],
|
|
IXHEAACE_ESBR_PVC_ID_BITS);
|
|
}
|
|
}
|
|
}
|
|
return payload_cnt_bits;
|
|
}
|
|
static WORD32 ia_enhaacplus_enc_ceil_ln2(WORD32 x) {
|
|
WORD32 tmp = -1;
|
|
|
|
while (ixheaac_shl32(1, ++tmp) < x)
|
|
;
|
|
|
|
return (tmp);
|
|
}
|
|
|
|
static WORD32 ixheaace_encode_sbr_grid(ixheaace_pstr_sbr_env_data pstr_sbr_env_info,
|
|
ixheaace_bit_buf_handle pstr_bs_handle,
|
|
ixheaace_sbr_codec_type sbr_codec) {
|
|
WORD32 payload_cnt_bits = 0;
|
|
WORD32 i, tmp_var;
|
|
|
|
if (ELD_SBR != sbr_codec) {
|
|
if (HEAAC_SBR == sbr_codec ||
|
|
(USAC_SBR == sbr_codec && pstr_sbr_env_info->sbr_pvc_mode == 0)) {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_info->pstr_sbr_bs_grid->frame_type, SBR_CLA_BITS);
|
|
|
|
switch (pstr_sbr_env_info->pstr_sbr_bs_grid->frame_type) {
|
|
case IXHEAACE_FIXFIX:
|
|
|
|
tmp_var = ia_enhaacplus_enc_ceil_ln2(pstr_sbr_env_info->pstr_sbr_bs_grid->bs_num_env);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, tmp_var, SBR_ENV_BITS);
|
|
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->freq_res_fix, SBR_RES_BITS);
|
|
break;
|
|
|
|
case IXHEAACE_FIXVAR:
|
|
case IXHEAACE_VARFIX:
|
|
|
|
if (pstr_sbr_env_info->pstr_sbr_bs_grid->frame_type == IXHEAACE_FIXVAR) {
|
|
tmp_var = pstr_sbr_env_info->pstr_sbr_bs_grid->bs_abs_bord - 16;
|
|
} else {
|
|
tmp_var = pstr_sbr_env_info->pstr_sbr_bs_grid->bs_abs_bord;
|
|
}
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, tmp_var, SBR_ABS_BITS);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_info->pstr_sbr_bs_grid->n, SBR_NUM_BITS);
|
|
|
|
for (i = 0; i < pstr_sbr_env_info->pstr_sbr_bs_grid->n; i++) {
|
|
tmp_var = (pstr_sbr_env_info->pstr_sbr_bs_grid->bs_rel_bord[i] - 2) >> 1;
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, tmp_var, SBR_REL_BITS);
|
|
}
|
|
|
|
tmp_var = ia_enhaacplus_enc_ceil_ln2(pstr_sbr_env_info->pstr_sbr_bs_grid->n + 2);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_info->pstr_sbr_bs_grid->p, (UWORD8)tmp_var);
|
|
|
|
for (i = 0; i < pstr_sbr_env_info->pstr_sbr_bs_grid->n + 1; i++) {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_info->pstr_sbr_bs_grid->v_f[i], SBR_RES_BITS);
|
|
}
|
|
break;
|
|
|
|
case IXHEAACE_VARVAR:
|
|
|
|
tmp_var = pstr_sbr_env_info->pstr_sbr_bs_grid->bs_abs_bord_0;
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, tmp_var, SBR_ABS_BITS);
|
|
tmp_var = pstr_sbr_env_info->pstr_sbr_bs_grid->bs_abs_bord_1 - 16;
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, tmp_var, SBR_ABS_BITS);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_info->pstr_sbr_bs_grid->bs_num_rel_0, SBR_NUM_BITS);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_info->pstr_sbr_bs_grid->bs_num_rel_1, SBR_NUM_BITS);
|
|
|
|
for (i = 0; i < pstr_sbr_env_info->pstr_sbr_bs_grid->bs_num_rel_0; i++) {
|
|
tmp_var = (pstr_sbr_env_info->pstr_sbr_bs_grid->bs_rel_bord_0[i] - 2) >> 1;
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, tmp_var, SBR_REL_BITS);
|
|
}
|
|
|
|
for (i = 0; i < pstr_sbr_env_info->pstr_sbr_bs_grid->bs_num_rel_1; i++) {
|
|
tmp_var = (pstr_sbr_env_info->pstr_sbr_bs_grid->bs_rel_bord_1[i] - 2) >> 1;
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, tmp_var, SBR_REL_BITS);
|
|
}
|
|
|
|
tmp_var =
|
|
ia_enhaacplus_enc_ceil_ln2(pstr_sbr_env_info->pstr_sbr_bs_grid->bs_num_rel_0 +
|
|
pstr_sbr_env_info->pstr_sbr_bs_grid->bs_num_rel_1 + 2);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_info->pstr_sbr_bs_grid->p, (UWORD8)tmp_var);
|
|
|
|
tmp_var = pstr_sbr_env_info->pstr_sbr_bs_grid->bs_num_rel_0 +
|
|
pstr_sbr_env_info->pstr_sbr_bs_grid->bs_num_rel_1 + 1;
|
|
|
|
for (i = 0; i < tmp_var; i++) {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_info->pstr_sbr_bs_grid->v_f_lr[i], SBR_RES_BITS);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else {
|
|
// If PVC mode is non-zero, bit stream parameters are updated here
|
|
if (pstr_sbr_env_info->no_of_envelopes > 1) {
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 8, SBR_PVC_NOISE_POSITION_BITS);
|
|
} else {
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 0, SBR_PVC_NOISE_POSITION_BITS);
|
|
}
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 0, SBR_PVC_VAR_LEN_HF_BITS);
|
|
}
|
|
} else {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_info->pstr_sbr_bs_grid->frame_type, LDSBR_CLA_BITS);
|
|
|
|
switch (pstr_sbr_env_info->pstr_sbr_bs_grid->frame_type) {
|
|
case IXHEAACE_FIXFIX:
|
|
tmp_var = ia_enhaacplus_enc_ceil_ln2(pstr_sbr_env_info->pstr_sbr_bs_grid->bs_num_env);
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, tmp_var, SBR_ENV_BITS);
|
|
if (pstr_sbr_env_info->pstr_sbr_bs_grid->bs_num_env == 1) {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_info->curr_sbr_amp_res, SI_SBR_AMP_RES_BITS);
|
|
}
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_info->pstr_sbr_bs_grid->v_f[0], SBR_RES_BITS);
|
|
break;
|
|
|
|
case IXHEAACE_LD_TRAN:
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_info->pstr_sbr_bs_grid->bs_transient_position,
|
|
IXHEAACE_SBR_TRAN_BITS);
|
|
for (i = 0; i < pstr_sbr_env_info->pstr_sbr_bs_grid->bs_num_env; i++) {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_info->pstr_sbr_bs_grid->v_f[i], SBR_RES_BITS);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return payload_cnt_bits;
|
|
}
|
|
|
|
static WORD32 ixheaace_encode_sbr_dtdf(ixheaace_pstr_sbr_env_data pstr_sbr_env_info,
|
|
ixheaace_bit_buf_handle pstr_bs_handle,
|
|
ixheaace_sbr_codec_type sbr_codec, WORD32 usac_indep_flag,
|
|
WORD32 sbr_pvc_mode) {
|
|
WORD32 i, payload_cnt_bits = 0, num_of_noise_env;
|
|
|
|
num_of_noise_env = (pstr_sbr_env_info->no_of_envelopes > 1) ? 2 : 1;
|
|
|
|
if (USAC_SBR != sbr_codec) {
|
|
for (i = 0; i < pstr_sbr_env_info->no_of_envelopes; ++i) {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->domain_vec[i], SBR_DIR_BITS);
|
|
}
|
|
}
|
|
|
|
else {
|
|
if (sbr_pvc_mode == 0) {
|
|
WORD32 start_env = 0;
|
|
if (1 == usac_indep_flag) {
|
|
start_env = 1;
|
|
}
|
|
for (i = start_env; i < pstr_sbr_env_info->no_of_envelopes; ++i) {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->domain_vec[i], SBR_DIR_BITS);
|
|
}
|
|
} else {
|
|
/* Do nothing */
|
|
}
|
|
}
|
|
if (USAC_SBR != sbr_codec) {
|
|
for (i = 0; i < num_of_noise_env; ++i) {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_info->domain_vec_noise[i], SBR_DIR_BITS);
|
|
}
|
|
} else {
|
|
WORD32 start_env = 0;
|
|
if (1 == usac_indep_flag) {
|
|
start_env = 1;
|
|
}
|
|
|
|
for (i = start_env; i < num_of_noise_env; ++i) {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_info->domain_vec_noise[i], SBR_DIR_BITS);
|
|
}
|
|
}
|
|
return payload_cnt_bits;
|
|
}
|
|
|
|
static WORD32 ixheaace_write_noise_lvl_data(ixheaace_pstr_sbr_env_data pstr_sbr_env_info,
|
|
ixheaace_bit_buf_handle pstr_bs_handle,
|
|
WORD32 coupling) {
|
|
WORD32 j, i, payload_cnt_bits = 0;
|
|
WORD32 n_noise_envelopes = ((pstr_sbr_env_info->no_of_envelopes > 1) ? 2 : 1);
|
|
|
|
for (i = 0; i < n_noise_envelopes; i++) {
|
|
switch (pstr_sbr_env_info->domain_vec_noise[i]) {
|
|
case FREQ:
|
|
|
|
if (coupling && pstr_sbr_env_info->balance) {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle,
|
|
pstr_sbr_env_info->noise_level[i * pstr_sbr_env_info->noise_band_count],
|
|
(UWORD8)pstr_sbr_env_info->si_sbr_start_noise_bits_balance);
|
|
} else {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle,
|
|
pstr_sbr_env_info->noise_level[i * pstr_sbr_env_info->noise_band_count],
|
|
(UWORD8)pstr_sbr_env_info->si_sbr_start_noise_bits);
|
|
}
|
|
|
|
for (j = 1 + i * pstr_sbr_env_info->noise_band_count;
|
|
j < (pstr_sbr_env_info->noise_band_count * (1 + i)); j++) {
|
|
if (coupling) {
|
|
if (pstr_sbr_env_info->balance) {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle,
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_noise_bal_freq_c[pstr_sbr_env_info->noise_level[j] +
|
|
CODE_BCK_SCF_LAV_BALANCE11],
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_noise_bal_freq_l[pstr_sbr_env_info->noise_level[j] +
|
|
CODE_BCK_SCF_LAV_BALANCE11]);
|
|
} else {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle,
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_noise_lvl_freq_c[pstr_sbr_env_info->noise_level[j] +
|
|
CODE_BCK_SCF_LAV11],
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_noise_lvl_freq_l[pstr_sbr_env_info->noise_level[j] +
|
|
CODE_BCK_SCF_LAV11]);
|
|
}
|
|
} else {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle,
|
|
pstr_sbr_env_info->ptr_huff_tab_noise_freq_c[pstr_sbr_env_info->noise_level[j] +
|
|
CODE_BCK_SCF_LAV11],
|
|
pstr_sbr_env_info->ptr_huff_tab_noise_freq_l[pstr_sbr_env_info->noise_level[j] +
|
|
CODE_BCK_SCF_LAV11]);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case TIME:
|
|
for (j = i * pstr_sbr_env_info->noise_band_count;
|
|
j < (pstr_sbr_env_info->noise_band_count * (1 + i)); j++) {
|
|
if (coupling) {
|
|
if (pstr_sbr_env_info->balance) {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle,
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_noise_bal_time_c[pstr_sbr_env_info->noise_level[j] +
|
|
CODE_BCK_SCF_LAV_BALANCE11],
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_noise_bal_time_l[pstr_sbr_env_info->noise_level[j] +
|
|
CODE_BCK_SCF_LAV_BALANCE11]);
|
|
} else {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle,
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_noise_lvl_time_c[pstr_sbr_env_info->noise_level[j] +
|
|
CODE_BCK_SCF_LAV11],
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_noise_lvl_time_l[pstr_sbr_env_info->noise_level[j] +
|
|
CODE_BCK_SCF_LAV11]);
|
|
}
|
|
} else {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle,
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_noise_lvl_time_c[pstr_sbr_env_info->noise_level[j] +
|
|
CODE_BCK_SCF_LAV11],
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_noise_lvl_time_l[pstr_sbr_env_info->noise_level[j] +
|
|
CODE_BCK_SCF_LAV11]);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return payload_cnt_bits;
|
|
}
|
|
|
|
static IA_ERRORCODE ixheaace_write_env_data(ixheaace_pstr_sbr_env_data pstr_sbr_env_info,
|
|
ixheaace_bit_buf_handle pstr_bs_handle,
|
|
WORD32 coupling, ixheaace_sbr_codec_type sbr_codec,
|
|
WORD32 *ptr_payload_cnt_bits) {
|
|
WORD32 j, i, delta;
|
|
|
|
*ptr_payload_cnt_bits = 0;
|
|
|
|
for (j = 0; j < pstr_sbr_env_info->no_of_envelopes; j++) {
|
|
if (pstr_sbr_env_info->domain_vec[j] == FREQ) {
|
|
if (coupling && pstr_sbr_env_info->balance) {
|
|
*ptr_payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->ienvelope[j][0],
|
|
(UWORD8)pstr_sbr_env_info->si_sbr_start_env_bits_balance);
|
|
} else {
|
|
*ptr_payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->ienvelope[j][0],
|
|
(UWORD8)pstr_sbr_env_info->si_sbr_start_env_bits);
|
|
}
|
|
}
|
|
|
|
for (i = 1 - pstr_sbr_env_info->domain_vec[j]; i < pstr_sbr_env_info->no_scf_bands[j]; i++) {
|
|
delta = pstr_sbr_env_info->ienvelope[j][i];
|
|
|
|
if (coupling && pstr_sbr_env_info->balance) {
|
|
if (abs(delta) > pstr_sbr_env_info->code_book_scf_lav_balance) {
|
|
return IA_EXHEAACE_EXE_FATAL_SBR_INVALID_CODEBOOK;
|
|
}
|
|
} else {
|
|
if (abs(delta) > pstr_sbr_env_info->code_book_scf_lav) {
|
|
return IA_EXHEAACE_EXE_FATAL_SBR_INVALID_CODEBOOK;
|
|
}
|
|
}
|
|
|
|
if (coupling) {
|
|
if (pstr_sbr_env_info->balance) {
|
|
if (pstr_sbr_env_info->domain_vec[j]) {
|
|
*ptr_payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle,
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_bal_time_c[delta +
|
|
pstr_sbr_env_info->code_book_scf_lav_balance],
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_bal_time_l[delta +
|
|
pstr_sbr_env_info->code_book_scf_lav_balance]);
|
|
} else {
|
|
*ptr_payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle,
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_bal_freq_c[delta +
|
|
pstr_sbr_env_info->code_book_scf_lav_balance],
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_bal_freq_l[delta +
|
|
pstr_sbr_env_info->code_book_scf_lav_balance]);
|
|
}
|
|
} else {
|
|
if (pstr_sbr_env_info->domain_vec[j]) {
|
|
*ptr_payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle,
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_lvl_time_c[delta + pstr_sbr_env_info->code_book_scf_lav],
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_lvl_time_l[delta + pstr_sbr_env_info->code_book_scf_lav]);
|
|
} else {
|
|
*ptr_payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle,
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_lvl_freq_c[delta + pstr_sbr_env_info->code_book_scf_lav],
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_lvl_freq_l[delta + pstr_sbr_env_info->code_book_scf_lav]);
|
|
}
|
|
}
|
|
} else {
|
|
if (pstr_sbr_env_info->domain_vec[j]) {
|
|
*ptr_payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle,
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_time_c[delta + pstr_sbr_env_info->code_book_scf_lav],
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_time_l[delta + pstr_sbr_env_info->code_book_scf_lav]);
|
|
} else {
|
|
*ptr_payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle,
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_freq_c[delta + pstr_sbr_env_info->code_book_scf_lav],
|
|
pstr_sbr_env_info
|
|
->ptr_huff_tab_freq_l[delta + pstr_sbr_env_info->code_book_scf_lav]);
|
|
}
|
|
}
|
|
}
|
|
if (USAC_SBR == sbr_codec) {
|
|
if (1 == pstr_sbr_env_info->sbr_inter_tes) {
|
|
*ptr_payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->ptr_sbr_inter_tes_shape[j],
|
|
IXHEAACE_SBR_TES_SHAPE_BITS);
|
|
if (1 == pstr_sbr_env_info->ptr_sbr_inter_tes_shape[j]) {
|
|
*ptr_payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_info->ptr_sbr_inter_tes_shape_mode[j],
|
|
IXHEAACE_SBR_TES_SHAPE_MODE_BITS);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return IA_NO_ERROR;
|
|
}
|
|
|
|
static WORD32 ixheaace_write_synthetic_coding_data(ixheaace_pstr_sbr_env_data pstr_sbr_env_info,
|
|
ixheaace_bit_buf_handle pstr_bs_handle,
|
|
ixheaace_sbr_codec_type sbr_codec,
|
|
WORD32 sbr_pvc_mode)
|
|
|
|
{
|
|
WORD32 i;
|
|
WORD32 payload_cnt_bits = 0;
|
|
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->add_harmonic_flag, 1);
|
|
|
|
if (pstr_sbr_env_info->add_harmonic_flag) {
|
|
for (i = 0; i < pstr_sbr_env_info->no_harmonics; i++) {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->add_harmonic[i], 1);
|
|
}
|
|
if (USAC_SBR == sbr_codec && 0 != sbr_pvc_mode) {
|
|
if (pstr_sbr_env_info->sbr_sinusoidal_pos_flag) {
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 1, 1);
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 31, 5);
|
|
} else {
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 0, 1);
|
|
}
|
|
}
|
|
}
|
|
return payload_cnt_bits;
|
|
}
|
|
|
|
static IA_ERRORCODE ixheaace_encode_sbr_single_channel_element(
|
|
ixheaace_pstr_sbr_env_data pstr_sbr_env_info, ixheaace_bit_buf_handle pstr_bs_handle,
|
|
ixheaace_sbr_codec_type sbr_codec, WORD32 *ptr_num_bits)
|
|
|
|
{
|
|
WORD32 payload_cnt_bits = 0;
|
|
IA_ERRORCODE err_code = IA_NO_ERROR;
|
|
|
|
if (sbr_codec != USAC_SBR) {
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 0, 1);
|
|
} else {
|
|
if (pstr_sbr_env_info->harmonic_sbr) {
|
|
// USAC Harmonic SBR data
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->sbr_patching_mode, 1);
|
|
if (0 == pstr_sbr_env_info->sbr_patching_mode) {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->sbr_oversampling_flag, 1);
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->sbr_pitchin_bins_flag, 1);
|
|
if (0 != pstr_sbr_env_info->sbr_pitchin_bins_flag) {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->sbr_pitchin_bins, 7);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
payload_cnt_bits += ixheaace_encode_sbr_grid(pstr_sbr_env_info, pstr_bs_handle, sbr_codec);
|
|
if (sbr_codec == USAC_SBR) {
|
|
payload_cnt_bits += ixheaace_encode_sbr_dtdf(pstr_sbr_env_info, pstr_bs_handle, sbr_codec,
|
|
pstr_sbr_env_info->usac_indep_flag,
|
|
pstr_sbr_env_info->sbr_pvc_mode);
|
|
} else {
|
|
payload_cnt_bits +=
|
|
ixheaace_encode_sbr_dtdf(pstr_sbr_env_info, pstr_bs_handle, sbr_codec, 0, 0);
|
|
}
|
|
|
|
{
|
|
WORD32 i;
|
|
for (i = 0; i < pstr_sbr_env_info->noise_band_count; i++) {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_info->sbr_invf_mode_vec[i], SI_SBR_INVF_MODE_BITS);
|
|
}
|
|
}
|
|
if (sbr_codec != USAC_SBR) {
|
|
WORD32 env_data_len;
|
|
err_code =
|
|
ixheaace_write_env_data(pstr_sbr_env_info, pstr_bs_handle, 0, sbr_codec, &env_data_len);
|
|
if (err_code) {
|
|
*ptr_num_bits = payload_cnt_bits;
|
|
return err_code;
|
|
}
|
|
payload_cnt_bits += env_data_len;
|
|
} else {
|
|
if (0 == pstr_sbr_env_info->sbr_pvc_mode) {
|
|
WORD32 env_data_len;
|
|
err_code =
|
|
ixheaace_write_env_data(pstr_sbr_env_info, pstr_bs_handle, 0, sbr_codec, &env_data_len);
|
|
if (err_code) {
|
|
*ptr_num_bits = payload_cnt_bits;
|
|
return err_code;
|
|
}
|
|
payload_cnt_bits += env_data_len;
|
|
} else {
|
|
// PVC envelope goes here
|
|
payload_cnt_bits += iusace_encode_pvc_envelope(pstr_bs_handle, &pstr_sbr_env_info->pvc_info,
|
|
pstr_sbr_env_info->usac_indep_flag);
|
|
}
|
|
}
|
|
payload_cnt_bits += ixheaace_write_noise_lvl_data(pstr_sbr_env_info, pstr_bs_handle, 0);
|
|
|
|
if (USAC_SBR == sbr_codec) {
|
|
payload_cnt_bits += ixheaace_write_synthetic_coding_data(
|
|
pstr_sbr_env_info, pstr_bs_handle, sbr_codec, pstr_sbr_env_info->sbr_pvc_mode);
|
|
} else {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_synthetic_coding_data(pstr_sbr_env_info, pstr_bs_handle, sbr_codec, 0);
|
|
}
|
|
|
|
*ptr_num_bits = payload_cnt_bits;
|
|
return err_code;
|
|
}
|
|
|
|
static IA_ERRORCODE ixheaace_encode_sbr_channel_pair_element(
|
|
ixheaace_pstr_sbr_env_data pstr_sbr_env_data_left,
|
|
ixheaace_pstr_sbr_env_data pstr_sbr_env_data_right, ixheaace_bit_buf_handle pstr_bs_handle,
|
|
WORD32 coupling, ixheaace_sbr_codec_type sbr_codec, WORD32 *ptr_num_bits) {
|
|
IA_ERRORCODE err_code = IA_NO_ERROR;
|
|
WORD32 payload_cnt_bits = 0;
|
|
WORD32 env_data_len;
|
|
WORD32 i = 0;
|
|
|
|
if (USAC_SBR != sbr_codec) {
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 0, 1); /* no reserved bits */
|
|
}
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, coupling, SI_SBR_COUPLING_BITS);
|
|
|
|
if (coupling) {
|
|
if (sbr_codec == USAC_SBR && pstr_sbr_env_data_left->harmonic_sbr) {
|
|
// USAC Harmonic SBR data
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_left->sbr_patching_mode, 1);
|
|
if (0 == pstr_sbr_env_data_left->sbr_patching_mode) {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_left->sbr_oversampling_flag, 1);
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_left->sbr_pitchin_bins_flag, 1);
|
|
if (0 != pstr_sbr_env_data_left->sbr_pitchin_bins_flag) {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_left->sbr_pitchin_bins, 7);
|
|
}
|
|
}
|
|
}
|
|
payload_cnt_bits +=
|
|
ixheaace_encode_sbr_grid(pstr_sbr_env_data_left, pstr_bs_handle, sbr_codec);
|
|
|
|
payload_cnt_bits +=
|
|
ixheaace_encode_sbr_dtdf(pstr_sbr_env_data_left, pstr_bs_handle, sbr_codec,
|
|
pstr_sbr_env_data_left->usac_indep_flag, 0);
|
|
|
|
payload_cnt_bits +=
|
|
ixheaace_encode_sbr_dtdf(pstr_sbr_env_data_right, pstr_bs_handle, sbr_codec,
|
|
pstr_sbr_env_data_left->usac_indep_flag, 0);
|
|
|
|
for (i = 0; i < pstr_sbr_env_data_left->noise_band_count; i++) {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_data_left->sbr_invf_mode_vec[i], SI_SBR_INVF_MODE_BITS);
|
|
}
|
|
|
|
err_code = ixheaace_write_env_data(pstr_sbr_env_data_left, pstr_bs_handle, 1, sbr_codec,
|
|
&env_data_len);
|
|
if (err_code) {
|
|
*ptr_num_bits = payload_cnt_bits;
|
|
return err_code;
|
|
}
|
|
|
|
payload_cnt_bits += env_data_len;
|
|
|
|
payload_cnt_bits += ixheaace_write_noise_lvl_data(pstr_sbr_env_data_left, pstr_bs_handle, 1);
|
|
|
|
err_code = ixheaace_write_env_data(pstr_sbr_env_data_right, pstr_bs_handle, 1, sbr_codec,
|
|
&env_data_len);
|
|
if (err_code) {
|
|
*ptr_num_bits = payload_cnt_bits;
|
|
return err_code;
|
|
}
|
|
payload_cnt_bits += env_data_len;
|
|
|
|
payload_cnt_bits += ixheaace_write_noise_lvl_data(pstr_sbr_env_data_right, pstr_bs_handle, 1);
|
|
|
|
payload_cnt_bits += ixheaace_write_synthetic_coding_data(pstr_sbr_env_data_left,
|
|
pstr_bs_handle, sbr_codec, 0);
|
|
|
|
payload_cnt_bits += ixheaace_write_synthetic_coding_data(pstr_sbr_env_data_right,
|
|
pstr_bs_handle, sbr_codec, 0);
|
|
} else {
|
|
if (sbr_codec == USAC_SBR && pstr_sbr_env_data_left->harmonic_sbr) {
|
|
// USAC Harmonic SBR data
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_left->sbr_patching_mode, 1);
|
|
if (0 == pstr_sbr_env_data_left->sbr_patching_mode) {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_left->sbr_oversampling_flag, 1);
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_left->sbr_pitchin_bins_flag, 1);
|
|
if (0 != pstr_sbr_env_data_left->sbr_pitchin_bins_flag) {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_left->sbr_pitchin_bins, 7);
|
|
}
|
|
}
|
|
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_right->sbr_patching_mode, 1);
|
|
if (0 == pstr_sbr_env_data_right->sbr_patching_mode) {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_data_right->sbr_oversampling_flag, 1);
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_data_right->sbr_pitchin_bins_flag, 1);
|
|
if (0 != pstr_sbr_env_data_right->sbr_pitchin_bins_flag) {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_right->sbr_pitchin_bins, 7);
|
|
}
|
|
}
|
|
}
|
|
payload_cnt_bits +=
|
|
ixheaace_encode_sbr_grid(pstr_sbr_env_data_left, pstr_bs_handle, sbr_codec);
|
|
|
|
payload_cnt_bits +=
|
|
ixheaace_encode_sbr_grid(pstr_sbr_env_data_right, pstr_bs_handle, sbr_codec);
|
|
|
|
payload_cnt_bits +=
|
|
ixheaace_encode_sbr_dtdf(pstr_sbr_env_data_left, pstr_bs_handle, sbr_codec,
|
|
pstr_sbr_env_data_left->usac_indep_flag, 0);
|
|
|
|
payload_cnt_bits +=
|
|
ixheaace_encode_sbr_dtdf(pstr_sbr_env_data_right, pstr_bs_handle, sbr_codec,
|
|
pstr_sbr_env_data_left->usac_indep_flag, 0);
|
|
|
|
for (i = 0; i < pstr_sbr_env_data_left->noise_band_count; i++) {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_data_left->sbr_invf_mode_vec[i], SI_SBR_INVF_MODE_BITS);
|
|
}
|
|
|
|
for (i = 0; i < pstr_sbr_env_data_right->noise_band_count; i++) {
|
|
payload_cnt_bits += ixheaace_write_bits(
|
|
pstr_bs_handle, pstr_sbr_env_data_right->sbr_invf_mode_vec[i], SI_SBR_INVF_MODE_BITS);
|
|
}
|
|
|
|
err_code = ixheaace_write_env_data(pstr_sbr_env_data_left, pstr_bs_handle, 0, sbr_codec,
|
|
&env_data_len);
|
|
if (err_code) {
|
|
*ptr_num_bits = payload_cnt_bits;
|
|
return err_code;
|
|
}
|
|
payload_cnt_bits += env_data_len;
|
|
|
|
err_code = ixheaace_write_env_data(pstr_sbr_env_data_right, pstr_bs_handle, 0, sbr_codec,
|
|
&env_data_len);
|
|
if (err_code) {
|
|
*ptr_num_bits = payload_cnt_bits;
|
|
return err_code;
|
|
}
|
|
payload_cnt_bits += env_data_len;
|
|
|
|
payload_cnt_bits += ixheaace_write_noise_lvl_data(pstr_sbr_env_data_left, pstr_bs_handle, 0);
|
|
|
|
payload_cnt_bits += ixheaace_write_noise_lvl_data(pstr_sbr_env_data_right, pstr_bs_handle, 0);
|
|
|
|
payload_cnt_bits += ixheaace_write_synthetic_coding_data(pstr_sbr_env_data_left,
|
|
pstr_bs_handle, sbr_codec, 0);
|
|
|
|
payload_cnt_bits += ixheaace_write_synthetic_coding_data(pstr_sbr_env_data_right,
|
|
pstr_bs_handle, sbr_codec, 0);
|
|
}
|
|
|
|
*ptr_num_bits = payload_cnt_bits;
|
|
return err_code;
|
|
}
|
|
|
|
static WORD32 iexhaace_esbr_write_bs(ixheaace_str_esbr_bs_data *pstr_esbr_bs_data,
|
|
ixheaace_bit_buf_handle pstr_bs_handle) {
|
|
WORD32 num_bits = 0;
|
|
num_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, EXTENSION_ID_ESBR_CODING, SI_SBR_EXTENSION_ID_BITS);
|
|
num_bits += ixheaace_write_bits(pstr_bs_handle, pstr_esbr_bs_data->sbr_preprocessing, 1);
|
|
if (1 == pstr_esbr_bs_data->sbr_num_chan) {
|
|
num_bits += ixheaace_write_bits(pstr_bs_handle, pstr_esbr_bs_data->sbr_patching_mode[0], 1);
|
|
if (pstr_esbr_bs_data->sbr_patching_mode[0] == 0) {
|
|
num_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_esbr_bs_data->sbr_oversampling_flag[0], 1);
|
|
num_bits += ixheaace_write_bits(pstr_bs_handle, pstr_esbr_bs_data->sbr_pitchin_flags[0], 1);
|
|
if (pstr_esbr_bs_data->sbr_pitchin_flags[0] == 1) {
|
|
num_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_esbr_bs_data->sbr_pitchin_bins[0], 7);
|
|
}
|
|
}
|
|
} else if (2 == pstr_esbr_bs_data->sbr_num_chan) {
|
|
if (pstr_esbr_bs_data->sbr_coupling) {
|
|
num_bits += ixheaace_write_bits(pstr_bs_handle, pstr_esbr_bs_data->sbr_patching_mode[0], 1);
|
|
if (pstr_esbr_bs_data->sbr_patching_mode[0] == 0) {
|
|
num_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_esbr_bs_data->sbr_oversampling_flag[0], 1);
|
|
num_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_esbr_bs_data->sbr_pitchin_flags[0], 1);
|
|
if (pstr_esbr_bs_data->sbr_pitchin_flags[0] == 1) {
|
|
num_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_esbr_bs_data->sbr_pitchin_bins[0], 7);
|
|
}
|
|
}
|
|
} else {
|
|
num_bits += ixheaace_write_bits(pstr_bs_handle, pstr_esbr_bs_data->sbr_patching_mode[0], 1);
|
|
if (pstr_esbr_bs_data->sbr_patching_mode[0] == 0) {
|
|
num_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_esbr_bs_data->sbr_oversampling_flag[0], 1);
|
|
num_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_esbr_bs_data->sbr_pitchin_flags[0], 1);
|
|
if (pstr_esbr_bs_data->sbr_pitchin_flags[0] == 1) {
|
|
num_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_esbr_bs_data->sbr_pitchin_bins[0], 7);
|
|
} else {
|
|
pstr_esbr_bs_data->sbr_patching_mode[0] = pstr_esbr_bs_data->sbr_patching_mode[0];
|
|
}
|
|
}
|
|
num_bits += ixheaace_write_bits(pstr_bs_handle, pstr_esbr_bs_data->sbr_patching_mode[1], 1);
|
|
if (pstr_esbr_bs_data->sbr_patching_mode[1] == 0) {
|
|
num_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_esbr_bs_data->sbr_oversampling_flag[1], 1);
|
|
num_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_esbr_bs_data->sbr_pitchin_flags[1], 1);
|
|
if (pstr_esbr_bs_data->sbr_pitchin_flags[1] == 1) {
|
|
num_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_esbr_bs_data->sbr_pitchin_bins[0], 7);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (num_bits < 8) {
|
|
num_bits += ixheaace_write_bits(pstr_bs_handle, 0, (UWORD8)(8 - num_bits));
|
|
}
|
|
|
|
return num_bits;
|
|
}
|
|
|
|
static WORD32 ixheaace_get_sbr_extended_data_size(struct ixheaace_ps_enc *pstr_ps_handle,
|
|
WORD32 is_hdr_active,
|
|
ixheaace_str_sbr_tabs *pstr_sbr_tab,
|
|
WORD32 is_esbr,
|
|
ixheaace_str_esbr_bs_data *pstr_esbr_data) {
|
|
WORD32 ext_data_bits = 0;
|
|
|
|
if (pstr_ps_handle) {
|
|
ext_data_bits +=
|
|
ixheaace_enc_write_ps_data(pstr_ps_handle, is_hdr_active, pstr_sbr_tab->ptr_ps_tab);
|
|
}
|
|
if (is_esbr) {
|
|
ext_data_bits += ixheaace_get_esbr_ext_data_size(pstr_esbr_data);
|
|
}
|
|
|
|
if (ext_data_bits != 0) {
|
|
ext_data_bits += SI_SBR_EXTENSION_ID_BITS;
|
|
}
|
|
|
|
return (ext_data_bits + 7) >> 3;
|
|
}
|
|
|
|
static VOID ixheaace_encode_extended_data(struct ixheaace_ps_enc *pstr_ps_handle,
|
|
WORD32 is_hdr_active,
|
|
ixheaace_bit_buf_handle pstr_bs_prev,
|
|
WORD32 *ptr_sbr_hdr_bits,
|
|
ixheaace_bit_buf_handle pstr_bs_handle,
|
|
WORD32 *ptr_payload_bits,
|
|
ixheaace_str_sbr_tabs *pstr_sbr_tab, WORD32 is_esbr,
|
|
ixheaace_str_esbr_bs_data *pstr_esbr_data) {
|
|
WORD32 ext_data_size;
|
|
WORD32 payload_bits_in = *ptr_payload_bits;
|
|
WORD32 payload_cnt_bits = 0;
|
|
|
|
ext_data_size = ixheaace_get_sbr_extended_data_size(pstr_ps_handle, is_hdr_active, pstr_sbr_tab,
|
|
is_esbr, pstr_esbr_data);
|
|
|
|
if (ext_data_size != 0) {
|
|
if (pstr_ps_handle && ixheaace_append_ps_bitstream(pstr_ps_handle, NULL_PTR, 0)) {
|
|
ixheaace_bit_buf bitbuf_tmp;
|
|
UWORD8 tmp[IXHEAACE_MAX_PAYLOAD_SIZE];
|
|
WORD32 max_ext_size = (1 << SI_SBR_EXTENSION_SIZE_BITS) - 1;
|
|
WORD32 num_bits;
|
|
|
|
num_bits = ia_enhaacplus_enc_get_bits_available(&pstr_ps_handle->ps_bit_buf);
|
|
num_bits += SI_SBR_EXTENSION_ID_BITS;
|
|
if (is_esbr) {
|
|
num_bits += ixheaace_get_esbr_ext_data_size(pstr_esbr_data);
|
|
num_bits += SI_SBR_EXTENSION_ID_BITS;
|
|
}
|
|
ext_data_size = (num_bits + 7) >> 3;
|
|
if (ia_enhaacplus_enc_get_bits_available(pstr_bs_prev) == 0) {
|
|
pstr_ps_handle->hdr_bits_prev_frame = *ptr_sbr_hdr_bits;
|
|
ia_enhaacplus_enc_copy_bitbuf(pstr_bs_handle, pstr_bs_prev);
|
|
} else {
|
|
WORD32 tmp_bits;
|
|
ia_enhaacplus_enc_create_bitbuffer(&bitbuf_tmp, tmp, sizeof(tmp));
|
|
tmp_bits = *ptr_sbr_hdr_bits;
|
|
*ptr_sbr_hdr_bits = pstr_ps_handle->hdr_bits_prev_frame;
|
|
pstr_ps_handle->hdr_bits_prev_frame = tmp_bits;
|
|
ixheaace_copy_bitbuf_to_and_fro(pstr_bs_prev, pstr_bs_handle);
|
|
}
|
|
ixheaace_write_bits(pstr_bs_handle, 1, SI_SBR_EXTENDED_DATA_BITS);
|
|
|
|
if (ext_data_size < max_ext_size) {
|
|
ixheaace_write_bits(pstr_bs_handle, ext_data_size, SI_SBR_EXTENSION_SIZE_BITS);
|
|
} else {
|
|
ixheaace_write_bits(pstr_bs_handle, max_ext_size, SI_SBR_EXTENSION_SIZE_BITS);
|
|
ixheaace_write_bits(pstr_bs_handle, ext_data_size - max_ext_size,
|
|
SI_SBR_EXTENSION_ESC_COUNT_BITS);
|
|
}
|
|
WORD32 start_bits = pstr_bs_handle->cnt_bits;
|
|
*ptr_payload_bits =
|
|
ixheaace_append_ps_bitstream(pstr_ps_handle, pstr_bs_handle, ptr_sbr_hdr_bits);
|
|
|
|
if (is_esbr) {
|
|
*ptr_payload_bits += iexhaace_esbr_write_bs(pstr_esbr_data, pstr_bs_handle);
|
|
}
|
|
|
|
WORD32 fill_bits = (ext_data_size << 3) - (pstr_bs_handle->cnt_bits - start_bits);
|
|
ixheaace_write_bits(pstr_bs_handle, 0, (UWORD8)fill_bits);
|
|
*ptr_payload_bits = *ptr_payload_bits + fill_bits;
|
|
} else {
|
|
if (is_esbr) {
|
|
WORD32 max_ext_size = (1 << SI_SBR_EXTENSION_SIZE_BITS) - 1;
|
|
WORD32 num_bits;
|
|
num_bits = ixheaace_get_esbr_ext_data_size(pstr_esbr_data);
|
|
ext_data_size = (num_bits + SI_SBR_EXTENSION_ID_BITS + 7) >> 3;
|
|
ixheaace_write_bits(pstr_bs_handle, 1, SI_SBR_EXTENDED_DATA_BITS);
|
|
if (ext_data_size < max_ext_size) {
|
|
ixheaace_write_bits(pstr_bs_handle, ext_data_size, SI_SBR_EXTENSION_SIZE_BITS);
|
|
} else {
|
|
ixheaace_write_bits(pstr_bs_handle, max_ext_size, SI_SBR_EXTENSION_SIZE_BITS);
|
|
ixheaace_write_bits(pstr_bs_handle, ext_data_size - max_ext_size,
|
|
SI_SBR_EXTENSION_ESC_COUNT_BITS);
|
|
}
|
|
WORD32 start_bits = pstr_bs_handle->cnt_bits;
|
|
*ptr_payload_bits += iexhaace_esbr_write_bs(pstr_esbr_data, pstr_bs_handle);
|
|
UWORD8 fill_bits =
|
|
(UWORD8)((ext_data_size << 3) - (pstr_bs_handle->cnt_bits - start_bits));
|
|
ixheaace_write_bits(pstr_bs_handle, 0, fill_bits);
|
|
*ptr_payload_bits = *ptr_payload_bits + fill_bits;
|
|
} else {
|
|
WORD32 max_ext_size = (1 << SI_SBR_EXTENSION_SIZE_BITS) - 1;
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 1, SI_SBR_EXTENDED_DATA_BITS);
|
|
|
|
if (ext_data_size < max_ext_size) {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, ext_data_size, SI_SBR_EXTENSION_SIZE_BITS);
|
|
} else {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, max_ext_size, SI_SBR_EXTENSION_SIZE_BITS);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, ext_data_size - max_ext_size,
|
|
SI_SBR_EXTENSION_ESC_COUNT_BITS);
|
|
}
|
|
|
|
*ptr_payload_bits = payload_cnt_bits + payload_bits_in;
|
|
}
|
|
}
|
|
} else {
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 0, SI_SBR_EXTENDED_DATA_BITS);
|
|
|
|
*ptr_payload_bits = payload_cnt_bits + payload_bits_in;
|
|
}
|
|
}
|
|
|
|
static IA_ERRORCODE ixheaace_encode_sbr_data(
|
|
ixheaace_pstr_sbr_env_data pstr_sbr_env_data_left,
|
|
ixheaace_pstr_sbr_env_data pstr_sbr_env_data_right, ixheaace_pstr_common_data pstr_cmon_data,
|
|
ixheaace_sbr_element_type sbr_ele_type, struct ixheaace_ps_enc *pstr_ps_handle,
|
|
WORD32 is_hdr_active, WORD32 coupling, ixheaace_str_sbr_tabs *pstr_sbr_tab,
|
|
ixheaace_sbr_codec_type sbr_codec, WORD32 is_esbr, ixheaace_str_esbr_bs_data *pstr_esbr_data,
|
|
WORD32 *ptr_num_bits) {
|
|
WORD32 payload_cnt_bits = 0;
|
|
IA_ERRORCODE err_code = IA_NO_ERROR;
|
|
|
|
switch (sbr_ele_type) {
|
|
case IXHEAACE_SBR_ID_SCE:
|
|
|
|
err_code = ixheaace_encode_sbr_single_channel_element(
|
|
pstr_sbr_env_data_left, &pstr_cmon_data->str_sbr_bit_buf, sbr_codec, &payload_cnt_bits);
|
|
if (err_code) {
|
|
return err_code;
|
|
}
|
|
if (USAC_SBR != sbr_codec) {
|
|
ixheaace_encode_extended_data(
|
|
pstr_ps_handle, is_hdr_active, &pstr_cmon_data->str_sbr_bit_buf_prev,
|
|
&pstr_cmon_data->sbr_hdr_bits, &pstr_cmon_data->str_sbr_bit_buf, &payload_cnt_bits,
|
|
pstr_sbr_tab, is_esbr, pstr_esbr_data);
|
|
}
|
|
break;
|
|
case IXHEAACE_SBR_ID_CPE:
|
|
|
|
err_code = ixheaace_encode_sbr_channel_pair_element(
|
|
pstr_sbr_env_data_left, pstr_sbr_env_data_right, &pstr_cmon_data->str_sbr_bit_buf,
|
|
coupling, sbr_codec, &payload_cnt_bits);
|
|
if (err_code) {
|
|
return err_code;
|
|
}
|
|
if (USAC_SBR != sbr_codec) {
|
|
ixheaace_encode_extended_data(NULL_PTR, 0, NULL_PTR, 0, &pstr_cmon_data->str_sbr_bit_buf,
|
|
&payload_cnt_bits, pstr_sbr_tab, is_esbr, pstr_esbr_data);
|
|
}
|
|
break;
|
|
}
|
|
|
|
pstr_cmon_data->sbr_data_bits = payload_cnt_bits;
|
|
*ptr_num_bits = payload_cnt_bits;
|
|
|
|
pstr_cmon_data->prev_bit_buf_read_offset =
|
|
(WORD32)(pstr_cmon_data->str_sbr_bit_buf_prev.ptr_read_next -
|
|
pstr_cmon_data->str_sbr_bit_buf_prev.ptr_bit_buf_base);
|
|
pstr_cmon_data->prev_bit_buf_write_offset =
|
|
(WORD32)(pstr_cmon_data->str_sbr_bit_buf_prev.ptr_write_next -
|
|
pstr_cmon_data->str_sbr_bit_buf_prev.ptr_bit_buf_base);
|
|
|
|
return err_code;
|
|
}
|
|
|
|
static WORD32 ixheaace_encode_sbr_header_data(ixheaace_pstr_sbr_hdr_data pstr_sbr_hdr,
|
|
ixheaace_bit_buf_handle pstr_bs_handle)
|
|
|
|
{
|
|
WORD32 payload_cnt_bits = 0;
|
|
|
|
if (pstr_sbr_hdr != NULL_PTR) {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_amp_res, SI_SBR_AMP_RES_BITS);
|
|
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_start_freq, SI_SBR_START_FREQ_BITS);
|
|
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_stop_freq, SI_SBR_STOP_FREQ_BITS);
|
|
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_xover_band, SI_SBR_XOVER_BAND_BITS);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 0, SI_SBR_RESERVED_BITS);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->header_extra_1,
|
|
SI_SBR_HEADER_EXTRA_1_BITS);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->header_extra_2,
|
|
SI_SBR_HEADER_EXTRA_2_BITS);
|
|
|
|
if (pstr_sbr_hdr->header_extra_1) {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->freq_scale, SI_SBR_FREQ_SCALE_BITS);
|
|
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->alter_scale, SI_SBR_ALTER_SCALE_BITS);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_noise_bands,
|
|
SI_SBR_NOISE_BANDS_BITS);
|
|
}
|
|
|
|
if (pstr_sbr_hdr->header_extra_2) {
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_limiter_bands,
|
|
SI_SBR_LIMITER_BANDS_BITS);
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_limiter_gains,
|
|
SI_SBR_LIMITER_GAINS_BITS);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_interpol_freq,
|
|
SI_SBR_INTERPOL_FREQ_BITS);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_smoothing_length,
|
|
SI_SBR_SMOOTHING_LENGTH_BITS);
|
|
}
|
|
}
|
|
|
|
return payload_cnt_bits;
|
|
}
|
|
|
|
static WORD32 ia_enhaacplus_enc_encode_sbr_header(ixheaace_pstr_sbr_hdr_data pstr_sbr_hdr,
|
|
ixheaace_pstr_sbr_bitstream_data pstr_sbr_bs,
|
|
ixheaace_pstr_common_data pstr_cmon_data) {
|
|
WORD32 payload_cnt_bits = 0;
|
|
|
|
if (pstr_sbr_bs->crc_active) {
|
|
pstr_cmon_data->sbr_crc_len = 1;
|
|
} else {
|
|
pstr_cmon_data->sbr_crc_len = 0;
|
|
}
|
|
|
|
if (pstr_sbr_bs->header_active) {
|
|
payload_cnt_bits += ixheaace_write_bits(&pstr_cmon_data->str_sbr_bit_buf, 1, 1);
|
|
|
|
payload_cnt_bits +=
|
|
ixheaace_encode_sbr_header_data(pstr_sbr_hdr, &pstr_cmon_data->str_sbr_bit_buf);
|
|
} else {
|
|
payload_cnt_bits += ixheaace_write_bits(&pstr_cmon_data->str_sbr_bit_buf, 0, 1);
|
|
}
|
|
|
|
pstr_cmon_data->sbr_hdr_bits = payload_cnt_bits;
|
|
|
|
return payload_cnt_bits;
|
|
}
|
|
static WORD32 iusace_encode_sbr_header_data(ixheaace_pstr_sbr_hdr_data pstr_sbr_hdr,
|
|
ixheaace_bit_buf_handle pstr_bs_handle) {
|
|
WORD32 payload_cnt_bits = 0;
|
|
|
|
if (pstr_sbr_hdr != NULL_PTR) {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_start_freq, SI_SBR_START_FREQ_BITS);
|
|
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_stop_freq, SI_SBR_STOP_FREQ_BITS);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->header_extra_1,
|
|
SI_SBR_HEADER_EXTRA_1_BITS);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->header_extra_2,
|
|
SI_SBR_HEADER_EXTRA_2_BITS);
|
|
|
|
if (pstr_sbr_hdr->header_extra_1) {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->freq_scale, SI_SBR_FREQ_SCALE_BITS);
|
|
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->alter_scale, SI_SBR_ALTER_SCALE_BITS);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_noise_bands,
|
|
SI_SBR_NOISE_BANDS_BITS);
|
|
}
|
|
|
|
if (pstr_sbr_hdr->header_extra_2) {
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_limiter_bands,
|
|
SI_SBR_LIMITER_BANDS_BITS);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_limiter_gains,
|
|
SI_SBR_LIMITER_GAINS_BITS);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_interpol_freq,
|
|
SI_SBR_INTERPOL_FREQ_BITS);
|
|
|
|
payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_smoothing_length,
|
|
SI_SBR_SMOOTHING_LENGTH_BITS);
|
|
}
|
|
}
|
|
|
|
return payload_cnt_bits;
|
|
}
|
|
|
|
static WORD32 ia_usac_enc_encode_sbr_header(ixheaace_pstr_sbr_hdr_data pstr_sbr_hdr,
|
|
ixheaace_pstr_sbr_bitstream_data pstr_sbr_bs,
|
|
ixheaace_pstr_common_data pstr_cmon_data) {
|
|
WORD32 payload_cnt_bits = 0;
|
|
WORD32 sbr_info_flag = 0;
|
|
WORD32 sbr_hdr_flag = 0;
|
|
if (pstr_sbr_bs->usac_indep_flag) {
|
|
sbr_hdr_flag = 1;
|
|
sbr_info_flag = 1;
|
|
} else {
|
|
if (pstr_sbr_bs->header_active) {
|
|
sbr_info_flag = 1;
|
|
payload_cnt_bits += ixheaace_write_bits(&pstr_cmon_data->str_sbr_bit_buf, 1, 1);
|
|
sbr_hdr_flag = 1;
|
|
payload_cnt_bits += ixheaace_write_bits(&pstr_cmon_data->str_sbr_bit_buf, 1, 1);
|
|
} else {
|
|
payload_cnt_bits += ixheaace_write_bits(&pstr_cmon_data->str_sbr_bit_buf, 0, 1);
|
|
}
|
|
}
|
|
|
|
if (1 == sbr_info_flag) {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(&pstr_cmon_data->str_sbr_bit_buf, pstr_sbr_hdr->sbr_amp_res, 1);
|
|
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(&pstr_cmon_data->str_sbr_bit_buf, pstr_sbr_hdr->sbr_xover_band, 4);
|
|
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(&pstr_cmon_data->str_sbr_bit_buf, pstr_sbr_hdr->sbr_pre_proc, 1);
|
|
if (pstr_sbr_hdr->sbr_pvc_active) {
|
|
payload_cnt_bits +=
|
|
ixheaace_write_bits(&pstr_cmon_data->str_sbr_bit_buf, pstr_sbr_hdr->sbr_pvc_mode, 2);
|
|
}
|
|
}
|
|
|
|
if (1 == sbr_hdr_flag) {
|
|
WORD32 sbr_def_hdr = 0;
|
|
// SBR default header
|
|
payload_cnt_bits += ixheaace_write_bits(&pstr_cmon_data->str_sbr_bit_buf, sbr_def_hdr, 1);
|
|
if (0 == sbr_def_hdr) {
|
|
payload_cnt_bits +=
|
|
iusace_encode_sbr_header_data(pstr_sbr_hdr, &pstr_cmon_data->str_sbr_bit_buf);
|
|
}
|
|
}
|
|
pstr_cmon_data->sbr_hdr_bits = payload_cnt_bits;
|
|
|
|
return payload_cnt_bits;
|
|
}
|
|
IA_ERRORCODE
|
|
ixheaace_write_env_single_channel_element(
|
|
ixheaace_pstr_sbr_hdr_data pstr_sbr_hdr, ixheaace_pstr_sbr_bitstream_data pstr_sbr_bs,
|
|
ixheaace_pstr_sbr_env_data pstr_sbr_env_info, struct ixheaace_ps_enc *pstr_ps_handle,
|
|
ixheaace_pstr_common_data pstr_cmon_data, ixheaace_str_sbr_tabs *pstr_sbr_tab,
|
|
ixheaace_sbr_codec_type sbr_codec, WORD32 is_esbr, ixheaace_str_esbr_bs_data *pstr_esbr_data,
|
|
WORD32 *ptr_num_bits) {
|
|
WORD32 payload_cnt_bits = 0;
|
|
WORD32 num_sbr_data_bits = 0;
|
|
IA_ERRORCODE err_code = IA_NO_ERROR;
|
|
|
|
pstr_cmon_data->sbr_hdr_bits = 0;
|
|
pstr_cmon_data->sbr_data_bits = 0;
|
|
pstr_cmon_data->sbr_crc_len = 0;
|
|
|
|
if (pstr_sbr_env_info != NULL_PTR) {
|
|
if (USAC_SBR == sbr_codec) {
|
|
payload_cnt_bits +=
|
|
ia_usac_enc_encode_sbr_header(pstr_sbr_hdr, pstr_sbr_bs, pstr_cmon_data);
|
|
} else {
|
|
/* write header */
|
|
payload_cnt_bits +=
|
|
ia_enhaacplus_enc_encode_sbr_header(pstr_sbr_hdr, pstr_sbr_bs, pstr_cmon_data);
|
|
}
|
|
/* write data */
|
|
err_code =
|
|
ixheaace_encode_sbr_data(pstr_sbr_env_info, NULL_PTR, pstr_cmon_data, IXHEAACE_SBR_ID_SCE,
|
|
pstr_ps_handle, pstr_sbr_bs->header_active, 0, pstr_sbr_tab,
|
|
sbr_codec, is_esbr, pstr_esbr_data, &num_sbr_data_bits);
|
|
if (err_code) {
|
|
return err_code;
|
|
}
|
|
payload_cnt_bits += num_sbr_data_bits;
|
|
}
|
|
|
|
*ptr_num_bits = payload_cnt_bits;
|
|
return err_code;
|
|
}
|
|
|
|
IA_ERRORCODE
|
|
ixheaace_write_env_channel_pair_element(
|
|
ixheaace_pstr_sbr_hdr_data pstr_sbr_hdr, ixheaace_pstr_sbr_bitstream_data pstr_sbr_bs,
|
|
ixheaace_pstr_sbr_env_data pstr_sbr_env_data_left,
|
|
ixheaace_pstr_sbr_env_data pstr_sbr_env_data_right, ixheaace_pstr_common_data pstr_cmon_data,
|
|
ixheaace_str_sbr_tabs *pstr_sbr_tab, ixheaace_sbr_codec_type sbr_codec, WORD32 is_esbr,
|
|
ixheaace_str_esbr_bs_data *pstr_esbr_data, WORD32 *ptr_num_bits)
|
|
|
|
{
|
|
WORD32 payload_cnt_bits = 0;
|
|
WORD32 num_sbr_data_bits = 0;
|
|
IA_ERRORCODE err_code = IA_NO_ERROR;
|
|
|
|
pstr_cmon_data->sbr_hdr_bits = 0;
|
|
pstr_cmon_data->sbr_data_bits = 0;
|
|
pstr_cmon_data->sbr_crc_len = 0;
|
|
|
|
/* write pure SBR data */
|
|
if ((pstr_sbr_env_data_left != NULL_PTR) && (pstr_sbr_env_data_right != NULL_PTR)) {
|
|
if (USAC_SBR == sbr_codec) {
|
|
payload_cnt_bits +=
|
|
ia_usac_enc_encode_sbr_header(pstr_sbr_hdr, pstr_sbr_bs, pstr_cmon_data);
|
|
} else {
|
|
/* write header */
|
|
payload_cnt_bits +=
|
|
ia_enhaacplus_enc_encode_sbr_header(pstr_sbr_hdr, pstr_sbr_bs, pstr_cmon_data);
|
|
}
|
|
|
|
/* write data */
|
|
err_code = ixheaace_encode_sbr_data(pstr_sbr_env_data_left, pstr_sbr_env_data_right,
|
|
pstr_cmon_data, IXHEAACE_SBR_ID_CPE, NULL_PTR, 0,
|
|
pstr_sbr_hdr->coupling, pstr_sbr_tab, sbr_codec, is_esbr,
|
|
pstr_esbr_data, &num_sbr_data_bits);
|
|
if (err_code) {
|
|
return err_code;
|
|
}
|
|
payload_cnt_bits += num_sbr_data_bits;
|
|
}
|
|
|
|
*ptr_num_bits = payload_cnt_bits;
|
|
return err_code;
|
|
}
|
|
|
|
IA_ERRORCODE
|
|
ixheaace_count_sbr_channel_pair_element(
|
|
ixheaace_pstr_sbr_hdr_data pstr_sbr_hdr, ixheaace_pstr_sbr_bitstream_data pstr_sbr_bs,
|
|
ixheaace_pstr_sbr_env_data pstr_sbr_env_data_left,
|
|
ixheaace_pstr_sbr_env_data pstr_sbr_env_data_right, ixheaace_pstr_common_data pstr_cmon_data,
|
|
ixheaace_str_sbr_tabs *pstr_sbr_tab, ixheaace_sbr_codec_type sbr_codec, WORD32 is_esbr,
|
|
ixheaace_str_esbr_bs_data *pstr_esbr_data, WORD32 *ptr_num_bits)
|
|
|
|
{
|
|
IA_ERRORCODE err_code = IA_NO_ERROR;
|
|
ixheaace_bit_buf bit_buf_tmp = pstr_cmon_data->str_sbr_bit_buf;
|
|
|
|
err_code = ixheaace_write_env_channel_pair_element(
|
|
pstr_sbr_hdr, pstr_sbr_bs, pstr_sbr_env_data_left, pstr_sbr_env_data_right, pstr_cmon_data,
|
|
pstr_sbr_tab, sbr_codec, is_esbr, pstr_esbr_data, ptr_num_bits);
|
|
|
|
pstr_cmon_data->str_sbr_bit_buf = bit_buf_tmp;
|
|
|
|
return err_code;
|
|
}
|
|
|
|
VOID ixheaace_map_low_res_energy_value(WORD32 curr_val, WORD32 *ptr_prev_data, WORD32 offset,
|
|
WORD32 index, ixheaace_freq_res res) {
|
|
if (res == FREQ_RES_LOW) {
|
|
if (offset >= 0) {
|
|
if (index < offset) {
|
|
ptr_prev_data[index] = curr_val;
|
|
} else {
|
|
ptr_prev_data[2 * index - offset] = curr_val;
|
|
ptr_prev_data[2 * index + 1 - offset] = curr_val;
|
|
}
|
|
} else {
|
|
offset = -offset;
|
|
|
|
if (index < offset) {
|
|
ptr_prev_data[3 * index] = curr_val;
|
|
ptr_prev_data[3 * index + 1] = curr_val;
|
|
ptr_prev_data[3 * index + 2] = curr_val;
|
|
} else {
|
|
ptr_prev_data[2 * index + offset] = curr_val;
|
|
ptr_prev_data[2 * index + 1 + offset] = curr_val;
|
|
}
|
|
}
|
|
} else {
|
|
ptr_prev_data[index] = curr_val;
|
|
}
|
|
}
|
|
|
|
IA_ERRORCODE
|
|
ixheaace_compute_bits(WORD32 delta, WORD32 code_book_scf_lav_lvl,
|
|
WORD32 code_book_scf_lav_balance, const UWORD8 *ptr_huff_tbl_lvl,
|
|
const UWORD8 *ptr_huff_tbl_bal, WORD32 coupling, WORD32 ch,
|
|
WORD32 *ptr_delta_bits) {
|
|
WORD32 index;
|
|
*ptr_delta_bits = 0;
|
|
|
|
if (coupling) {
|
|
if (ch == 1) {
|
|
index = (delta < 0) ? ixheaac_max32(delta, -code_book_scf_lav_balance)
|
|
: ixheaac_min32(delta, code_book_scf_lav_balance);
|
|
|
|
if (index != delta) {
|
|
raise(SIGTRAP);
|
|
return IA_EXHEAACE_EXE_FATAL_SBR_INVALID_BS;
|
|
}
|
|
|
|
*ptr_delta_bits = ptr_huff_tbl_bal[index + code_book_scf_lav_balance];
|
|
} else {
|
|
printf("cp2\n");
|
|
printf("lav: %d, del: %d\n", code_book_scf_lav_lvl, delta);
|
|
index = (delta < 0) ? ixheaac_max32(delta, -code_book_scf_lav_lvl)
|
|
: ixheaac_min32(delta, code_book_scf_lav_lvl);
|
|
|
|
if (index != delta) {
|
|
raise(SIGTRAP);
|
|
return IA_EXHEAACE_EXE_FATAL_SBR_INVALID_BS;
|
|
}
|
|
|
|
*ptr_delta_bits = ptr_huff_tbl_lvl[index + code_book_scf_lav_lvl];
|
|
}
|
|
} else {
|
|
printf("def2\n");
|
|
index = (delta < 0) ? ixheaac_max32(delta, -code_book_scf_lav_lvl)
|
|
: ixheaac_min32(delta, code_book_scf_lav_lvl);
|
|
|
|
*ptr_delta_bits = ptr_huff_tbl_lvl[index + code_book_scf_lav_lvl];
|
|
}
|
|
|
|
return IA_NO_ERROR;
|
|
}
|