- The bit-writing logic had to be skipped when no bits were to be written. Updated the existing check for the same. - This change also resolves an issue identified by oss-fuzz. Bug: ossFuzz: 69103 Test: poc in bug
537 lines
16 KiB
C
537 lines
16 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 "ixheaace_adjust_threshold_data.h"
|
|
#include "iusace_bitbuffer.h"
|
|
|
|
/* DRC */
|
|
#include "impd_drc_common_enc.h"
|
|
#include "impd_drc_uni_drc.h"
|
|
#include "impd_drc_tables.h"
|
|
#include "impd_drc_api.h"
|
|
#include "impd_drc_uni_drc_eq.h"
|
|
#include "impd_drc_uni_drc_filter_bank.h"
|
|
#include "impd_drc_gain_enc.h"
|
|
#include "impd_drc_struct_def.h"
|
|
|
|
#include "iusace_cnst.h"
|
|
#include "iusace_tns_usac.h"
|
|
#include "iusace_psy_mod.h"
|
|
#include "iusace_config.h"
|
|
#include "iusace_arith_enc.h"
|
|
#include "iusace_block_switch_const.h"
|
|
#include "iusace_block_switch_struct_def.h"
|
|
#include "iusace_fd_qc_util.h"
|
|
#include "iusace_fd_quant.h"
|
|
#include "iusace_ms.h"
|
|
#include "iusace_signal_classifier.h"
|
|
#include "ixheaace_sbr_header.h"
|
|
#include "ixheaace_config.h"
|
|
#include "ixheaace_asc_write.h"
|
|
#include "iusace_main.h"
|
|
#include "iusace_write_bitstream.h"
|
|
#include "iusace_func_prototypes.h"
|
|
#include "iusace_avq_enc.h"
|
|
#include "iusace_lpd_rom.h"
|
|
|
|
static WORD32 iusace_unary_code(WORD32 idx, WORD16 *ptr_bit_buf) {
|
|
WORD32 num_bits;
|
|
|
|
num_bits = 1;
|
|
|
|
idx -= 1;
|
|
while (idx-- > 0) {
|
|
*ptr_bit_buf++ = 1;
|
|
num_bits++;
|
|
}
|
|
|
|
*ptr_bit_buf = 0;
|
|
|
|
return (num_bits);
|
|
}
|
|
|
|
static VOID iusace_get_nk_mode(WORD32 mode_lpc, ia_bit_buf_struct *pstr_it_bit_buff,
|
|
WORD32 *nk_mode, WORD32 lpc_set) {
|
|
switch (lpc_set) {
|
|
case 4:
|
|
break;
|
|
case 0:
|
|
case 2:
|
|
*nk_mode = 3;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, mode_lpc, 1);
|
|
break;
|
|
case 1:
|
|
*nk_mode = mode_lpc;
|
|
if (mode_lpc == 2) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
|
|
} else if (mode_lpc == 1) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
|
|
} else if (mode_lpc == 0) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
|
|
}
|
|
break;
|
|
case 3:
|
|
if (mode_lpc == 0) {
|
|
*nk_mode = 0;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
|
|
} else if (mode_lpc == 1) {
|
|
*nk_mode = 1;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
|
|
} else if (mode_lpc == 2) {
|
|
*nk_mode = 2;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
|
|
} else {
|
|
*nk_mode = 2;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
|
|
}
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
static VOID iusace_write_qn_data(WORD32 *qn, ia_bit_buf_struct *pstr_it_bit_buff, WORD32 nk_mode,
|
|
WORD32 num_frames) {
|
|
WORD32 k, i;
|
|
switch (nk_mode) {
|
|
case 1:
|
|
for (k = 0; k < 2; k++) {
|
|
for (i = 0; i < qn[k] - 1; i++) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
|
|
}
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
|
|
}
|
|
break;
|
|
case 0:
|
|
case 2:
|
|
case 3:
|
|
for (k = 0; k < 2; k++) {
|
|
WORD32 qn1 = qn[k] - 2;
|
|
if (qn1 < 0 || qn1 > 3) {
|
|
qn1 = 3;
|
|
}
|
|
iusace_write_bits_buf(pstr_it_bit_buff, qn1, 2);
|
|
}
|
|
if ((nk_mode == 2) && num_frames != 2) {
|
|
for (k = 0; k < 2; k++) {
|
|
if (qn[k] > 4) {
|
|
for (i = 0; i < qn[k] - 4; i++) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
|
|
}
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
|
|
}
|
|
if (qn[k] == 0) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
|
|
}
|
|
}
|
|
} else {
|
|
for (k = 0; k < 2; k++) {
|
|
if (qn[k] == 5) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
|
|
} else if (qn[k] == 6) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
|
|
} else if (qn[k] == 0) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
|
|
} else {
|
|
WORD32 qn_ext = qn[k] - 4;
|
|
if (qn_ext > 0) {
|
|
for (i = 0; i < qn_ext; i++) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
|
|
}
|
|
iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
static VOID iusace_write_cb_indices(WORD32 *qn, WORD32 *ptr_params, WORD32 *idx,
|
|
ia_bit_buf_struct *pstr_it_bit_buff, WORD32 nk_mode,
|
|
WORD32 num_frames) {
|
|
WORD32 k;
|
|
WORD32 j = *idx;
|
|
|
|
iusace_write_qn_data(qn, pstr_it_bit_buff, nk_mode, num_frames);
|
|
|
|
for (k = 0; k < 2; k++) {
|
|
if (qn[k] > 0) {
|
|
WORD32 n, nk, i;
|
|
if (qn[k] > 4) {
|
|
nk = (qn[k] - 3) >> 1;
|
|
n = qn[k] - nk * 2;
|
|
} else {
|
|
nk = 0;
|
|
n = qn[k];
|
|
}
|
|
|
|
iusace_write_bits_buf(pstr_it_bit_buff, ptr_params[j++], (UWORD8)(4 * n));
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, ptr_params[j++], (UWORD8)nk);
|
|
}
|
|
}
|
|
}
|
|
|
|
*idx = j;
|
|
|
|
return;
|
|
}
|
|
|
|
static VOID iusace_write_lpc_data(ia_bit_buf_struct *pstr_it_bit_buff, WORD32 *param_lpc,
|
|
WORD32 first_lpd_flag, WORD32 *mod, WORD32 num_frames) {
|
|
WORD32 nk_mode = 0;
|
|
WORD32 j = 0, k;
|
|
WORD32 mode_lpc = 0;
|
|
WORD32 qn[2] = {0};
|
|
|
|
iusace_get_nk_mode(mode_lpc, pstr_it_bit_buff, &nk_mode, 4);
|
|
|
|
iusace_write_bits_buf(pstr_it_bit_buff, param_lpc[j++], 8);
|
|
|
|
for (k = 0; k < 2; k++) {
|
|
qn[k] = param_lpc[j++];
|
|
}
|
|
|
|
iusace_write_cb_indices(qn, param_lpc, &j, pstr_it_bit_buff, nk_mode, num_frames);
|
|
|
|
if (first_lpd_flag) {
|
|
mode_lpc = param_lpc[j++];
|
|
iusace_get_nk_mode(mode_lpc, pstr_it_bit_buff, &nk_mode, 0);
|
|
|
|
if (mode_lpc == 0) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, param_lpc[j++], 8);
|
|
}
|
|
|
|
for (k = 0; k < 2; k++) {
|
|
qn[k] = param_lpc[j++];
|
|
}
|
|
|
|
iusace_write_cb_indices(qn, param_lpc, &j, pstr_it_bit_buff, nk_mode, num_frames);
|
|
}
|
|
|
|
mode_lpc = param_lpc[j++];
|
|
|
|
if (num_frames == 4 && mod[0] < 3) {
|
|
iusace_get_nk_mode(mode_lpc, pstr_it_bit_buff, &nk_mode, 2);
|
|
|
|
if (mode_lpc == 0) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, param_lpc[j++], 8);
|
|
}
|
|
|
|
for (k = 0; k < 2; k++) {
|
|
qn[k] = param_lpc[j++];
|
|
}
|
|
|
|
iusace_write_cb_indices(qn, param_lpc, &j, pstr_it_bit_buff, nk_mode, num_frames);
|
|
}
|
|
mode_lpc = param_lpc[j++];
|
|
if (mod[0] < 2) {
|
|
iusace_get_nk_mode(mode_lpc, pstr_it_bit_buff, &nk_mode, 1);
|
|
|
|
if (mode_lpc != 1) {
|
|
if (mode_lpc == 0) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, param_lpc[j++], 8);
|
|
}
|
|
|
|
for (k = 0; k < 2; k++) {
|
|
qn[k] = param_lpc[j++];
|
|
}
|
|
|
|
iusace_write_cb_indices(qn, param_lpc, &j, pstr_it_bit_buff, nk_mode, num_frames);
|
|
}
|
|
} else if (mode_lpc != 1) {
|
|
if (mode_lpc == 0) {
|
|
j++;
|
|
}
|
|
for (k = 0; k < 2; k++) {
|
|
qn[k] = param_lpc[j++];
|
|
}
|
|
j += ((qn[0] > 0) ? 9 : 0) + ((qn[1] > 0) ? 9 : 0);
|
|
}
|
|
|
|
mode_lpc = param_lpc[j++];
|
|
if (num_frames != 2 && mod[2] < 2) {
|
|
iusace_get_nk_mode(mode_lpc, pstr_it_bit_buff, &nk_mode, 3);
|
|
if (mode_lpc == 0) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, param_lpc[j++], 8);
|
|
}
|
|
|
|
for (k = 0; k < 2; k++) {
|
|
qn[k] = param_lpc[j++];
|
|
}
|
|
iusace_write_cb_indices(qn, param_lpc, &j, pstr_it_bit_buff, nk_mode, num_frames);
|
|
}
|
|
return;
|
|
}
|
|
|
|
VOID iusace_encode_fac_params(WORD32 *mod, WORD32 *n_param_tcx, ia_usac_data_struct *usac_data,
|
|
WORD32 const usac_independency_flag,
|
|
ia_bit_buf_struct *pstr_it_bit_buff, WORD32 ch_idx) {
|
|
WORD32 *total_nbbits = &usac_data->total_nbbits[ch_idx];
|
|
ia_usac_td_encoder_struct *pstr_td = usac_data->td_encoder[ch_idx];
|
|
WORD32 codec_mode = pstr_td->acelp_core_mode;
|
|
WORD16 *bit_buf = usac_data->td_serial_out[ch_idx];
|
|
WORD32 is_bass_post_filter = 1;
|
|
WORD32 first_lpd_flag = (usac_data->core_mode_prev[ch_idx] == CORE_MODE_FD);
|
|
WORD32 *param_lpc = usac_data->param_buf + (NUM_FRAMES * MAX_NUM_TCX_PRM_PER_DIV);
|
|
WORD32 *param = usac_data->param_buf;
|
|
WORD32 j, k, n, sfr, lpd_mode, num_bits, sq_bits, *prm;
|
|
WORD16 first_tcx_flag = 1;
|
|
WORD32 nbits_fac, nb_bits_lpc;
|
|
WORD32 core_mode_last = (first_lpd_flag) ? 0 : 1;
|
|
WORD32 fac_data_present;
|
|
WORD32 num_frames = NUM_FRAMES;
|
|
WORD16 *ptr_bit_buf = bit_buf;
|
|
|
|
pstr_td->num_bits_per_supfrm = 0;
|
|
*total_nbbits = 0;
|
|
|
|
iusace_write_bits_buf(pstr_it_bit_buff, pstr_td->acelp_core_mode, 3);
|
|
|
|
if (mod[0] == 3) {
|
|
lpd_mode = 25;
|
|
} else if ((mod[0] == 2) && (mod[2] == 2)) {
|
|
lpd_mode = 24;
|
|
} else {
|
|
if (mod[0] == 2) {
|
|
lpd_mode = 16 + mod[2] + 2 * mod[3];
|
|
} else if (mod[2] == 2) {
|
|
lpd_mode = 20 + mod[0] + 2 * mod[1];
|
|
} else {
|
|
lpd_mode = mod[0] + 2 * mod[1] + 4 * mod[2] + 8 * mod[3];
|
|
}
|
|
}
|
|
iusace_write_bits_buf(pstr_it_bit_buff, lpd_mode, 5);
|
|
pstr_td->num_bits_per_supfrm = 5;
|
|
*total_nbbits += 5;
|
|
|
|
iusace_write_bits_buf(pstr_it_bit_buff, is_bass_post_filter, 1);
|
|
*total_nbbits += 1;
|
|
|
|
iusace_write_bits_buf(pstr_it_bit_buff, core_mode_last, 1);
|
|
*total_nbbits += 1;
|
|
|
|
if (((mod[0] == 0) && (mod[-1] != 0)) || ((mod[0] > 0) && (mod[-1] == 0))) {
|
|
fac_data_present = 1;
|
|
} else {
|
|
fac_data_present = 0;
|
|
}
|
|
|
|
iusace_write_bits_buf(pstr_it_bit_buff, fac_data_present, 1);
|
|
*total_nbbits += 1;
|
|
|
|
num_bits = (iusace_acelp_core_numbits_1024[codec_mode] / 4) - 2;
|
|
|
|
k = 0;
|
|
while (k < num_frames) {
|
|
lpd_mode = mod[k];
|
|
prm = param + (k * MAX_NUM_TCX_PRM_PER_DIV);
|
|
j = 0;
|
|
|
|
if (((mod[k - 1] == 0) && (mod[k] > 0)) || ((mod[k - 1] > 0) && (mod[k] == 0))) {
|
|
nbits_fac = iusace_fd_encode_fac(&prm[j], ptr_bit_buf, (pstr_td->len_subfrm) / 2);
|
|
j += (pstr_td->len_subfrm) / 2;
|
|
*total_nbbits += nbits_fac;
|
|
for (WORD32 i = 0; i < nbits_fac; i++) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, ptr_bit_buf[i], 1);
|
|
}
|
|
}
|
|
|
|
if (lpd_mode == 0) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j++], 2);
|
|
|
|
for (sfr = 0; sfr < (pstr_td->num_subfrm); sfr++) {
|
|
n = 6;
|
|
if ((sfr == 0) || (((pstr_td->len_subfrm) == 256) && (sfr == 2))) n = 9;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], (UWORD8)n);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 1);
|
|
j++;
|
|
if (codec_mode == ACELP_CORE_MODE_9k6) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 5);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 5);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 5);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 5);
|
|
j++;
|
|
} else if (codec_mode == ACELP_CORE_MODE_11k2) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 5);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 5);
|
|
j++;
|
|
} else if (codec_mode == ACELP_CORE_MODE_12k8) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9);
|
|
j++;
|
|
} else if (codec_mode == ACELP_CORE_MODE_14k4) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 13);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 13);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9);
|
|
j++;
|
|
} else if (codec_mode == ACELP_CORE_MODE_16k) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 13);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 13);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 13);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 13);
|
|
j++;
|
|
} else if (codec_mode == ACELP_CORE_MODE_18k4) {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 2);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 2);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 2);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 2);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 14);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 14);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 14);
|
|
j++;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 14);
|
|
j++;
|
|
}
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 7);
|
|
j++;
|
|
}
|
|
*total_nbbits += (num_bits - NBITS_LPC);
|
|
pstr_td->num_bits_per_supfrm += (num_bits - NBITS_LPC);
|
|
k++;
|
|
} else {
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j++], 3);
|
|
*total_nbbits += 3;
|
|
pstr_td->num_bits_per_supfrm += 3;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, prm[j++], 7);
|
|
*total_nbbits += 7;
|
|
pstr_td->num_bits_per_supfrm += 7;
|
|
|
|
if (first_tcx_flag) {
|
|
first_tcx_flag = 0;
|
|
if (usac_independency_flag) {
|
|
pstr_td->arith_reset_flag = 1;
|
|
memset(pstr_td->c_pres, 0, 516 * sizeof(WORD32));
|
|
memset(pstr_td->c_prev, 0, 516 * sizeof(WORD32));
|
|
} else {
|
|
if (pstr_td->arith_reset_flag) {
|
|
memset(pstr_td->c_pres, 0, 516 * sizeof(WORD32));
|
|
memset(pstr_td->c_prev, 0, 516 * sizeof(WORD32));
|
|
}
|
|
iusace_write_bits_buf(pstr_it_bit_buff, pstr_td->arith_reset_flag, 1);
|
|
*total_nbbits += 1;
|
|
pstr_td->num_bits_per_supfrm += 1;
|
|
}
|
|
}
|
|
|
|
sq_bits = iusace_tcx_coding(pstr_it_bit_buff, n_param_tcx[k], pstr_td->len_frame, prm + j,
|
|
pstr_td->c_pres, pstr_td->c_prev);
|
|
|
|
*total_nbbits += sq_bits;
|
|
pstr_td->num_bits_per_supfrm += sq_bits;
|
|
|
|
k += (1 << (lpd_mode - 1));
|
|
}
|
|
}
|
|
|
|
nb_bits_lpc = pstr_it_bit_buff->cnt_bits;
|
|
|
|
iusace_write_lpc_data(pstr_it_bit_buff, param_lpc, first_lpd_flag, mod, num_frames);
|
|
|
|
nb_bits_lpc = pstr_it_bit_buff->cnt_bits - nb_bits_lpc;
|
|
*total_nbbits += nb_bits_lpc;
|
|
pstr_td->num_bits_per_supfrm += nb_bits_lpc;
|
|
|
|
if ((core_mode_last == 0) && (fac_data_present == 1)) {
|
|
WORD32 short_fac_flag = (mod[-1] == -2) ? 1 : 0;
|
|
iusace_write_bits_buf(pstr_it_bit_buff, short_fac_flag, 1);
|
|
*total_nbbits += 1;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
WORD32 iusace_fd_encode_fac(WORD32 *prm, WORD16 *ptr_bit_buf, WORD32 fac_length) {
|
|
WORD32 i, j, n, nb, qn, kv[8], nk, fac_bits;
|
|
WORD32 I;
|
|
|
|
fac_bits = 0;
|
|
|
|
for (i = 0; i < fac_length; i += 8) {
|
|
iusace_apply_voronoi_ext(&prm[i], &qn, &I, kv);
|
|
|
|
nb = iusace_unary_code(qn, ptr_bit_buf);
|
|
ptr_bit_buf += nb;
|
|
|
|
fac_bits += nb;
|
|
|
|
nk = 0;
|
|
n = qn;
|
|
if (qn > 4) {
|
|
nk = (qn - 3) >> 1;
|
|
n = qn - nk * 2;
|
|
}
|
|
|
|
if (qn != 0) {
|
|
iusace_write_bits2buf(I, 4 * n, ptr_bit_buf);
|
|
ptr_bit_buf += 4 * n;
|
|
}
|
|
if (qn > 4) {
|
|
for (j = 0; j < 8; j++) {
|
|
iusace_write_bits2buf(kv[j], nk, ptr_bit_buf);
|
|
ptr_bit_buf += nk;
|
|
}
|
|
}
|
|
fac_bits += 4 * qn;
|
|
}
|
|
|
|
return fac_bits;
|
|
}
|