* Combined Workspace for Encoder and Decoder * Addressed review comments and some minor edits --------- Co-authored-by: Divya B M <100655@ittiam.com>
312 lines
9.1 KiB
C
312 lines
9.1 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 "ixheaac_type_def.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_main.h"
|
|
|
|
#include "ixheaace_sbr_hybrid.h"
|
|
#include "ixheaace_sbr_ps_enc.h"
|
|
#include "ixheaace_sbr_ps_bitenc.h"
|
|
#include "ixheaace_env_bit.h"
|
|
|
|
static WORD32 iexheaax_append_bitstream(ixheaace_bit_buf_handle hdl_bitbuf_write,
|
|
ixheaace_bit_buf_handle hdl_bitbuf_read,
|
|
UWORD8 num_bits) {
|
|
WORD32 idx;
|
|
UWORD32 value;
|
|
|
|
if (num_bits > 16) {
|
|
WORD32 cnt;
|
|
UWORD8 rem;
|
|
cnt = num_bits >> 4;
|
|
rem = num_bits % 16;
|
|
|
|
for (idx = 0; idx < cnt; idx++) {
|
|
value = ixheaace_readbits(hdl_bitbuf_read, 16);
|
|
ixheaace_write_bits(hdl_bitbuf_write, value, 16);
|
|
}
|
|
if (rem) {
|
|
value = ixheaace_readbits(hdl_bitbuf_read, rem);
|
|
ixheaace_write_bits(hdl_bitbuf_write, value, rem);
|
|
}
|
|
} else {
|
|
value = ixheaace_readbits(hdl_bitbuf_read, num_bits);
|
|
ixheaace_write_bits(hdl_bitbuf_write, value, num_bits);
|
|
}
|
|
|
|
return num_bits;
|
|
}
|
|
|
|
WORD32
|
|
ixheaace_enc_write_ps_data(ixheaace_pstr_ps_enc pstr_ps_handle, WORD32 b_header_active,
|
|
ixheaace_str_ps_tab *ps_tables) {
|
|
WORD32 tmp_var, gr;
|
|
const WORD32 *aa_huff_book_iid_c;
|
|
const WORD16 *aa_huff_book_icc_c;
|
|
const WORD8 *aa_huff_book_iid_l;
|
|
const WORD8 *aa_huff_book_icc_l;
|
|
WORD32 *aa_delta_iid;
|
|
WORD32 *aa_delta_icc;
|
|
|
|
WORD8 index, last_index;
|
|
WORD32 no_bits_f = 0;
|
|
WORD32 no_bits_t = 0;
|
|
|
|
WORD32 aa_delta_iid_t[NUMBER_OF_IID_BINS] = {0};
|
|
WORD32 aa_delta_icc_t[NUMBER_OF_ICC_BINS] = {0};
|
|
|
|
WORD32 aa_delta_iid_f[NUMBER_OF_IID_BINS] = {0};
|
|
WORD32 aa_delta_icc_f[NUMBER_OF_ICC_BINS] = {0};
|
|
|
|
WORD32 ab_dt_flag_iid;
|
|
WORD32 ab_dt_flag_icc;
|
|
|
|
WORD32 b_send_header;
|
|
|
|
UWORD32 b_zero_iid = 1;
|
|
UWORD32 b_zero_icc = 1;
|
|
UWORD32 b_keep_params = 1;
|
|
|
|
ixheaace_bit_buf_handle bb = &pstr_ps_handle->ps_bit_buf;
|
|
|
|
tmp_var = ia_enhaacplus_enc_get_bits_available(bb);
|
|
|
|
/* bit buffer shall be empty */
|
|
if (tmp_var != 0) {
|
|
return -1;
|
|
}
|
|
|
|
if (b_header_active) {
|
|
b_keep_params = 0;
|
|
}
|
|
|
|
last_index = 0;
|
|
|
|
for (gr = 0; gr < pstr_ps_handle->iid_icc_bins; gr++) {
|
|
WORD IID_flag;
|
|
FLOAT32 pan_value = pstr_ps_handle->aaa_IID_data_buf[gr][SYSTEMLOOKAHEAD];
|
|
IID_flag = 0;
|
|
if ((pan_value >= -ps_tables->pan_class[0]) && (pan_value <= ps_tables->pan_class[0])) {
|
|
IID_flag = 1;
|
|
}
|
|
|
|
if (IID_flag) {
|
|
index = 0;
|
|
} else {
|
|
if (pan_value < 0) {
|
|
for (index = NO_IID_STEPS - 1; pan_value > -ps_tables->pan_class[index]; index--) {
|
|
}
|
|
index = -index - 1;
|
|
} else {
|
|
for (index = NO_IID_STEPS - 1; pan_value < ps_tables->pan_class[index]; index--) {
|
|
}
|
|
index++;
|
|
}
|
|
|
|
b_zero_iid = 0;
|
|
}
|
|
|
|
if (gr == 0) {
|
|
aa_delta_iid_f[gr] = index;
|
|
no_bits_t = 0;
|
|
|
|
no_bits_f = ps_tables->a_book_ps_iid_freq_length[index + CODE_BCK_LAV_IID];
|
|
} else {
|
|
aa_delta_iid_f[gr] = index - last_index;
|
|
|
|
no_bits_f += ps_tables->a_book_ps_iid_freq_length[aa_delta_iid_f[gr] + CODE_BCK_LAV_IID];
|
|
}
|
|
|
|
last_index = index;
|
|
|
|
aa_delta_iid_t[gr] = index - pstr_ps_handle->a_last_iid_index[gr];
|
|
|
|
pstr_ps_handle->a_last_iid_index[gr] = index;
|
|
|
|
no_bits_t += ps_tables->a_book_ps_iid_time_length[aa_delta_iid_t[gr] + CODE_BCK_LAV_IID];
|
|
|
|
if (aa_delta_iid_t[gr] != 0) {
|
|
b_keep_params = 0;
|
|
}
|
|
}
|
|
|
|
if (no_bits_t < no_bits_f && !b_header_active) {
|
|
ab_dt_flag_iid = 1;
|
|
aa_delta_iid = aa_delta_iid_t;
|
|
aa_huff_book_iid_c = ps_tables->a_book_ps_iid_time_code;
|
|
aa_huff_book_iid_l = ps_tables->a_book_ps_iid_time_length;
|
|
} else {
|
|
ab_dt_flag_iid = 0;
|
|
aa_delta_iid = aa_delta_iid_f;
|
|
aa_huff_book_iid_c = ps_tables->a_book_ps_iid_freq_code;
|
|
aa_huff_book_iid_l = ps_tables->a_book_ps_iid_freq_length;
|
|
}
|
|
|
|
last_index = 0;
|
|
|
|
for (gr = 0; gr < pstr_ps_handle->iid_icc_bins; gr++) {
|
|
WORD ICC_flag;
|
|
FLOAT32 sa_value = pstr_ps_handle->aaa_ICC_data_buf[gr][SYSTEMLOOKAHEAD];
|
|
ICC_flag = 0;
|
|
if (sa_value <= ps_tables->sa_class[0]) {
|
|
ICC_flag = 1;
|
|
}
|
|
if (ICC_flag) {
|
|
index = 0;
|
|
} else {
|
|
for (index = NO_ICC_STEPS - 2; sa_value < ps_tables->sa_class[index]; index--) {
|
|
}
|
|
index++;
|
|
|
|
b_zero_icc = 0;
|
|
}
|
|
|
|
if (gr == 0) {
|
|
aa_delta_icc_f[gr] = index;
|
|
|
|
no_bits_f = ps_tables->a_book_ps_icc_freq_length[index + CODE_BCK_LAV_ICC];
|
|
|
|
no_bits_t = 0;
|
|
} else {
|
|
aa_delta_icc_f[gr] = index - last_index;
|
|
|
|
no_bits_f += ps_tables->a_book_ps_icc_freq_length[aa_delta_icc_f[gr] + CODE_BCK_LAV_ICC];
|
|
}
|
|
|
|
last_index = index;
|
|
|
|
aa_delta_icc_t[gr] = index - pstr_ps_handle->a_last_icc_index[gr];
|
|
|
|
pstr_ps_handle->a_last_icc_index[gr] = index;
|
|
|
|
no_bits_t += ps_tables->a_book_ps_icc_time_length[aa_delta_icc_t[gr] + CODE_BCK_LAV_ICC];
|
|
|
|
if (aa_delta_icc_t[gr] != 0) {
|
|
b_keep_params = 0;
|
|
}
|
|
}
|
|
|
|
if (no_bits_t < no_bits_f && !b_header_active) {
|
|
ab_dt_flag_icc = 1;
|
|
aa_delta_icc = aa_delta_icc_t;
|
|
aa_huff_book_icc_c = ps_tables->a_book_ps_icc_time_code;
|
|
aa_huff_book_icc_l = ps_tables->a_book_ps_icc_time_length;
|
|
} else {
|
|
ab_dt_flag_icc = 0;
|
|
aa_delta_icc = aa_delta_icc_f;
|
|
aa_huff_book_icc_c = ps_tables->a_book_ps_icc_freq_code;
|
|
aa_huff_book_icc_l = ps_tables->a_book_ps_icc_freq_length;
|
|
}
|
|
|
|
{
|
|
static WORD32 initheader = 0;
|
|
|
|
if (!initheader || b_header_active) {
|
|
initheader = 1;
|
|
pstr_ps_handle->b_enable_header = 1;
|
|
} else {
|
|
pstr_ps_handle->b_enable_header = 0;
|
|
}
|
|
}
|
|
|
|
b_send_header = pstr_ps_handle->b_enable_header ||
|
|
pstr_ps_handle->b_prev_zero_iid != b_zero_iid ||
|
|
pstr_ps_handle->b_prev_zero_icc != b_zero_icc;
|
|
|
|
ixheaace_write_bits(bb, b_send_header, 1);
|
|
|
|
if (b_send_header) {
|
|
ixheaace_write_bits(bb, !b_zero_iid, 1);
|
|
|
|
if (!b_zero_iid) {
|
|
ixheaace_write_bits(bb, (pstr_ps_handle->b_hi_freq_res_iid_icc) ? 1 : 0, 3);
|
|
}
|
|
|
|
ixheaace_write_bits(bb, !b_zero_icc, 1);
|
|
|
|
if (!b_zero_icc) {
|
|
ixheaace_write_bits(bb, (pstr_ps_handle->b_hi_freq_res_iid_icc) ? 1 : 0, 3);
|
|
}
|
|
|
|
ixheaace_write_bits(bb, 0, 1);
|
|
}
|
|
|
|
ixheaace_write_bits(bb, 0, 1);
|
|
|
|
ixheaace_write_bits(bb, 1 - b_keep_params, 2);
|
|
|
|
if (!b_keep_params) {
|
|
if (!b_zero_iid) {
|
|
ixheaace_write_bits(bb, ab_dt_flag_iid, 1);
|
|
|
|
for (gr = 0; gr < pstr_ps_handle->iid_icc_bins; gr++) {
|
|
ixheaace_write_bits(bb, aa_huff_book_iid_c[aa_delta_iid[gr] + CODE_BCK_LAV_IID],
|
|
aa_huff_book_iid_l[aa_delta_iid[gr] + CODE_BCK_LAV_IID]);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!b_keep_params) {
|
|
if (!b_zero_icc) {
|
|
ixheaace_write_bits(bb, ab_dt_flag_icc, 1);
|
|
|
|
for (gr = 0; gr < pstr_ps_handle->iid_icc_bins; gr++) {
|
|
ixheaace_write_bits(bb, aa_huff_book_icc_c[aa_delta_icc[gr] + CODE_BCK_LAV_ICC],
|
|
aa_huff_book_icc_l[aa_delta_icc[gr] + CODE_BCK_LAV_ICC]);
|
|
}
|
|
}
|
|
}
|
|
|
|
pstr_ps_handle->b_prev_zero_iid = b_zero_iid;
|
|
pstr_ps_handle->b_prev_zero_icc = b_zero_icc;
|
|
|
|
return ia_enhaacplus_enc_get_bits_available(bb);
|
|
}
|
|
|
|
WORD32
|
|
ixheaace_append_ps_bitstream(ixheaace_pstr_ps_enc pstr_ps_handle, ixheaace_bit_buf_handle hdl_bs,
|
|
WORD32 *sbr_hdr_bits) {
|
|
if (!pstr_ps_handle) {
|
|
return 0;
|
|
}
|
|
if (!hdl_bs) {
|
|
return ia_enhaacplus_enc_get_bits_available(&pstr_ps_handle->ps_bit_buf);
|
|
} else {
|
|
UWORD8 num_bits = (UWORD8)ia_enhaacplus_enc_get_bits_available(&pstr_ps_handle->ps_bit_buf);
|
|
|
|
ixheaace_write_bits(hdl_bs, EXTENSION_ID_PS_CODING, SI_SBR_EXTENSION_ID_BITS);
|
|
iexheaax_append_bitstream(hdl_bs, &pstr_ps_handle->ps_bit_buf, num_bits);
|
|
|
|
pstr_ps_handle->bit_buf_read_offset = (WORD32)(pstr_ps_handle->ps_bit_buf.ptr_read_next -
|
|
pstr_ps_handle->ps_bit_buf.ptr_bit_buf_base);
|
|
pstr_ps_handle->bit_buf_write_offset = (WORD32)(pstr_ps_handle->ps_bit_buf.ptr_write_next -
|
|
pstr_ps_handle->ps_bit_buf.ptr_bit_buf_base);
|
|
|
|
return ia_enhaacplus_enc_get_bits_available(hdl_bs) - (*sbr_hdr_bits) -
|
|
SI_FILL_EXTENTION_BITS;
|
|
}
|
|
}
|