blob: e3000a5af5e7f6bdc4c14e1cce1559f5829620ea [file] [log] [blame]
/******************************************************************************
*
* 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 "ixheaac_constants.h"
#include "ixheaac_basic_ops32.h"
#include "ixheaac_basic_ops40.h"
#include "ixheaac_basic_ops.h"
#include "ixheaacd_bitbuffer.h"
#include "ixheaac_basic_op.h"
#include "ixheaacd_mps_aac_struct.h"
#include "ixheaacd_mps_res_rom.h"
#include "ixheaacd_mps_res_block.h"
#include "ixheaacd_mps_res_huffman.h"
static PLATFORM_INLINE WORD32 ixheaacd_res_extract_symbol(WORD32 value, WORD32 l_shift,
WORD32 r_shift, WORD32 *pow_table_q17) {
WORD32 out;
out = (WORD16)((value << l_shift) >> r_shift);
if (out < 0) {
out = -out;
out = pow_table_q17[out];
out = -out;
} else
out = pow_table_q17[out];
return out;
}
static PLATFORM_INLINE WORD32 ixheaacd_res_extract_signed_symbol(WORD32 value, WORD32 l_shift,
WORD32 r_shift,
WORD32 *pow_table_q17,
WORD32 *temp_word,
WORD32 *pr_bit_pos) {
WORD32 out;
out = ixheaac_extu(value, l_shift, r_shift);
if (out) {
WORD32 bit_pos = *pr_bit_pos;
out = pow_table_q17[out];
if (*temp_word & 0x80000000) {
out = -out;
}
*temp_word = *temp_word << 1;
bit_pos++;
*pr_bit_pos = bit_pos;
}
return out;
}
VOID ixheaacd_res_inverse_quant_lb(WORD32 *x_invquant, WORD t_bands, WORD32 *pow_table_q17,
WORD8 *pulse_data) {
WORD32 j;
WORD32 temp;
WORD32 q_abs;
for (j = t_bands - 1; j >= 0; j--) {
q_abs = *pulse_data++;
temp = (pow_table_q17[q_abs]);
*x_invquant++ = -temp;
}
}
static PLATFORM_INLINE WORD ixheaacd_res_c_block_decode_huff_word1(
ia_bit_buf_struct *it_bit_buf, WORD32 *qp, WORD16 *offsets, WORD no_bands, WORD group_no,
const UWORD16 *h_ori, WORD32 *pow_table_q17, WORD32 maximum_bins_short) {
WORD32 sp1, sp2;
WORD32 flush_cw;
WORD32 i, value, norm_val, off;
WORD idx, grp_idx;
WORD32 out1, out2;
WORD32 err_code = 0;
WORD len_idx = 0;
UWORD8 *ptr_read_next = it_bit_buf->ptr_read_next;
WORD32 bit_pos = it_bit_buf->bit_pos;
WORD32 read_word = ixheaacd_res_aac_showbits_32(ptr_read_next);
ptr_read_next += 4;
do {
len_idx = offsets[1] - offsets[0];
grp_idx = group_no;
do {
qp = qp + offsets[0];
idx = len_idx;
do {
{
UWORD16 first_offset;
WORD16 sign_ret_val;
UWORD32 read_word1;
UWORD16 *h;
read_word1 = read_word << bit_pos;
h = (UWORD16 *)h_ori;
h += (read_word1) >> (27);
sign_ret_val = *h;
first_offset = 5;
while (sign_ret_val > 0) {
bit_pos += first_offset;
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bit_buf->ptr_bit_buf_end);
read_word1 = (read_word1) << (first_offset);
first_offset = (sign_ret_val >> 11);
h += sign_ret_val & (0x07FF);
h += (read_word1) >> (32 - first_offset);
sign_ret_val = *h;
}
bit_pos += ((sign_ret_val & 0x7fff) >> 11);
bit_pos = min(bit_pos, 31);
value = sign_ret_val & (0x07FF);
}
out1 = (value & 0x3E0) >> 5;
out2 = value & 0x1F;
flush_cw = read_word << bit_pos;
sp1 = out1;
sp2 = out2;
if (out1) {
if (flush_cw & 0x80000000) {
out1 = -out1;
}
bit_pos++;
flush_cw = (WORD32)flush_cw << 1;
}
if (out2) {
bit_pos++;
if (flush_cw & 0x80000000) {
out2 = -out2;
}
}
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bit_buf->ptr_bit_buf_end);
if (sp1 == 16) {
i = 4;
value = ixheaac_extu(read_word, bit_pos, 23);
value = value | 0xfffffe00;
norm_val = ixheaac_norm32(value);
i += (norm_val - 22);
bit_pos += (norm_val - 21);
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bit_buf->ptr_bit_buf_end);
off = ixheaac_extu(read_word, bit_pos, 32 - i);
bit_pos += i;
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bit_buf->ptr_bit_buf_end);
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bit_buf->ptr_bit_buf_end);
i = off + ((WORD32)1 << i);
if (i <= IQ_TABLE_SIZE_HALF)
i = pow_table_q17[i];
else {
err_code |= ixheaacd_res_inv_quant(&i, pow_table_q17);
}
if (out1 < 0) {
out1 = -i;
} else {
out1 = i;
}
*qp++ = out1;
} else {
if (out1 <= 0) {
out1 = -out1;
out1 = pow_table_q17[out1];
*qp++ = -out1;
} else {
out1 = pow_table_q17[out1];
*qp++ = out1;
}
}
if (sp2 == 16) {
i = 4;
value = ixheaac_extu(read_word, bit_pos, 23);
value = value | 0xfffffe00;
norm_val = ixheaac_norm32(value);
i += (norm_val - 22);
bit_pos += (norm_val - 21);
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bit_buf->ptr_bit_buf_end);
off = ixheaac_extu(read_word, bit_pos, 32 - i);
bit_pos += i;
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bit_buf->ptr_bit_buf_end);
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bit_buf->ptr_bit_buf_end);
i = off + ((WORD32)1 << i);
if (i <= IQ_TABLE_SIZE_HALF)
i = pow_table_q17[i];
else {
err_code |= ixheaacd_res_inv_quant(&i, pow_table_q17);
}
if (out2 < 0) {
out2 = -i;
} else {
out2 = i;
}
*qp++ = out2;
} else {
if (out2 <= 0) {
out2 = -out2;
out2 = pow_table_q17[out2];
*qp++ = -out2;
} else {
out2 = pow_table_q17[out2];
*qp++ = out2;
}
}
idx -= 2;
} while (idx != 0);
qp += (maximum_bins_short - offsets[1]);
grp_idx--;
} while (grp_idx != 0);
offsets++;
qp -= (maximum_bins_short * group_no);
no_bands--;
} while (no_bands >= 0);
it_bit_buf->bit_pos = bit_pos;
it_bit_buf->ptr_read_next = ptr_read_next - 4;
return err_code;
}
static PLATFORM_INLINE WORD ixheaacd_res_c_block_decode_huff_word1_lb(
ia_bit_buf_struct *it_bif_buf, WORD32 len, const UWORD16 *h_ori, WORD32 *x_invquant,
WORD32 *pow_table_q17, WORD8 *p_pul_arr) {
WORD32 sp1, sp2;
WORD32 flush_cw;
WORD32 i, value, norm_val, off;
WORD idx;
WORD32 out1, out2;
WORD32 err_code = 0;
UWORD8 *ptr_read_next = it_bif_buf->ptr_read_next;
WORD32 bit_pos = it_bif_buf->bit_pos;
WORD32 read_word = ixheaacd_res_aac_showbits_32(ptr_read_next);
ptr_read_next += 4;
for (idx = len; idx != 0; idx -= 2) {
{
UWORD16 first_offset;
WORD16 sign_ret_val;
UWORD32 read_word1;
UWORD16 *h;
read_word1 = read_word << bit_pos;
h = (UWORD16 *)h_ori;
h += (read_word1) >> (27);
sign_ret_val = *h;
first_offset = 5;
while (sign_ret_val > 0) {
bit_pos += first_offset;
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bif_buf->ptr_bit_buf_end);
read_word1 = (read_word1) << (first_offset);
first_offset = (sign_ret_val >> 11);
h += sign_ret_val & (0x07FF);
h += (read_word1) >> (32 - first_offset);
sign_ret_val = *h;
}
bit_pos += ((sign_ret_val & 0x7fff) >> 11);
bit_pos = min(bit_pos, 31);
value = sign_ret_val & (0x07FF);
}
flush_cw = read_word << bit_pos;
out1 = (value & 0x3E0) >> 5;
out2 = value & 0x1F;
sp1 = out1;
if (out1) {
if (flush_cw & 0x80000000) {
out1 = -out1;
}
bit_pos++;
flush_cw = (WORD32)flush_cw << 1;
}
sp2 = out2;
if (out2) {
bit_pos++;
if (flush_cw & 0x80000000) {
out2 = -out2;
}
}
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bif_buf->ptr_bit_buf_end);
if (sp1 == 16) {
i = 4;
value = ixheaac_extu(read_word, bit_pos, 23);
value = value | 0xfffffe00;
norm_val = ixheaac_norm32(value);
i += (norm_val - 22);
bit_pos += (norm_val - 21);
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bif_buf->ptr_bit_buf_end);
off = ixheaac_extu(read_word, bit_pos, 32 - i);
bit_pos += i;
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bif_buf->ptr_bit_buf_end);
value = *p_pul_arr++;
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bif_buf->ptr_bit_buf_end);
i = off + ((WORD32)1 << i);
i = add_d(i, value);
if (i <= IQ_TABLE_SIZE_HALF)
i = pow_table_q17[i];
else {
err_code |= ixheaacd_res_inv_quant(&i, pow_table_q17);
}
if (out1 < 0) {
i = -i;
}
*x_invquant++ = i;
} else {
WORD8 temp = *p_pul_arr++;
if (out1 <= 0) {
out1 = sub_d(temp, out1);
out1 = pow_table_q17[out1];
*x_invquant++ = -out1;
} else {
out1 = add_d(out1, temp);
out1 = pow_table_q17[out1];
*x_invquant++ = out1;
}
}
if (sp2 == 16) {
i = 4;
value = ixheaac_extu(read_word, bit_pos, 23);
value = value | 0xfffffe00;
norm_val = ixheaac_norm32(value);
i += (norm_val - 22);
bit_pos += (norm_val - 21);
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bif_buf->ptr_bit_buf_end);
off = ixheaac_extu(read_word, bit_pos, 32 - i);
bit_pos += i;
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bif_buf->ptr_bit_buf_end);
value = *p_pul_arr++;
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bif_buf->ptr_bit_buf_end);
i = off + ((WORD32)1 << i);
i = add_d(i, value);
if (i <= IQ_TABLE_SIZE_HALF)
i = pow_table_q17[i];
else {
err_code |= ixheaacd_res_inv_quant(&i, pow_table_q17);
}
if (out2 < 0) {
i = -i;
}
*x_invquant++ = i;
} else {
WORD8 temp = *p_pul_arr++;
if (out2 <= 0) {
out2 = sub_d(temp, out2);
out2 = pow_table_q17[out2];
*x_invquant++ = -out2;
} else {
out2 = add_d(out2, temp);
out2 = pow_table_q17[out2];
*x_invquant++ = out2;
}
}
}
it_bif_buf->ptr_read_next = ptr_read_next - 4;
it_bif_buf->bit_pos = bit_pos;
return err_code;
}
static PLATFORM_INLINE WORD ixheaacd_res_c_block_decode_huff_word2_4(
ia_bit_buf_struct *it_bit_buf, WORD32 *qp, WORD16 *offsets, WORD no_bands, WORD group_no,
const UWORD16 *h_ori, WORD32 *pow_table_q17, WORD32 sign, WORD32 maximum_bins_short) {
WORD32 value;
WORD idx, grp_idx;
WORD idx_len;
WORD32 *qp_org;
UWORD8 *ptr_read_next = it_bit_buf->ptr_read_next;
WORD32 bit_pos = it_bit_buf->bit_pos;
WORD32 read_word = ixheaacd_res_aac_showbits_32(ptr_read_next);
ptr_read_next += 4;
qp_org = qp;
do {
idx_len = offsets[1] - offsets[0];
grp_idx = group_no;
do {
qp = qp + offsets[0];
idx = idx_len;
do {
UWORD16 first_offset;
WORD16 sign_ret_val;
UWORD32 read_word1;
UWORD16 *h;
read_word1 = read_word << bit_pos;
h = (UWORD16 *)h_ori;
h += (read_word1) >> (27);
sign_ret_val = *h;
first_offset = 5;
while (sign_ret_val > 0) {
bit_pos += first_offset;
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bit_buf->ptr_bit_buf_end);
read_word1 = (read_word1) << (first_offset);
first_offset = (sign_ret_val >> 11);
h += sign_ret_val & (0x07FF);
h += (read_word1) >> (32 - first_offset);
sign_ret_val = *h;
}
bit_pos += ((sign_ret_val & 0x7fff) >> 11);
bit_pos = min(bit_pos, 31);
value = sign_ret_val & (0x07FF);
if (sign) {
WORD32 temp_word;
temp_word = read_word << bit_pos;
*qp++ = ixheaacd_res_extract_signed_symbol(value, 24, 30, pow_table_q17, &temp_word,
&bit_pos);
*qp++ = ixheaacd_res_extract_signed_symbol(value, 26, 30, pow_table_q17, &temp_word,
&bit_pos);
*qp++ = ixheaacd_res_extract_signed_symbol(value, 28, 30, pow_table_q17, &temp_word,
&bit_pos);
*qp++ = ixheaacd_res_extract_signed_symbol(value, 30, 30, pow_table_q17, &temp_word,
&bit_pos);
} else {
*qp++ = ixheaacd_res_extract_symbol(value, 24, 30, pow_table_q17);
*qp++ = ixheaacd_res_extract_symbol(value, 26, 30, pow_table_q17);
*qp++ = ixheaacd_res_extract_symbol(value, 28, 30, pow_table_q17);
*qp++ = ixheaacd_res_extract_symbol(value, 30, 30, pow_table_q17);
}
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bit_buf->ptr_bit_buf_end);
idx -= 4;
} while (idx != 0);
qp += (maximum_bins_short - offsets[1]);
grp_idx--;
} while (grp_idx != 0);
offsets++;
qp = qp_org;
no_bands--;
} while (no_bands >= 0);
it_bit_buf->ptr_read_next = ptr_read_next - 4;
it_bit_buf->bit_pos = bit_pos;
return 0;
}
static PLATFORM_INLINE WORD ixheaacd_res_c_block_decode_huff_word2_4_lb(
ia_bit_buf_struct *it_bit_buf, WORD32 len, const UWORD16 *h_ori, WORD32 *x_invquant,
WORD32 *pow_table_q17, WORD8 *p_pul_arr, WORD32 sign) {
WORD32 value;
WORD idx;
UWORD8 *ptr_read_next = it_bit_buf->ptr_read_next;
WORD32 bit_pos = it_bit_buf->bit_pos;
WORD32 read_word = ixheaacd_res_aac_showbits_32(ptr_read_next);
ptr_read_next += 4;
for (idx = len; idx != 0; idx -= 4) {
WORD32 res;
WORD32 ampres, ampres1;
WORD32 ampres2, ampres3;
UWORD16 first_offset;
WORD16 sign_ret_val;
UWORD32 read_word1;
UWORD16 *h;
read_word1 = read_word << bit_pos;
h = (UWORD16 *)h_ori;
h += (read_word1) >> (27);
sign_ret_val = *h;
first_offset = 5;
while (sign_ret_val > 0) {
bit_pos += first_offset;
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bit_buf->ptr_bit_buf_end);
read_word1 = (read_word1) << (first_offset);
first_offset = (sign_ret_val >> 11);
h += sign_ret_val & (0x07FF);
h += (read_word1) >> (32 - first_offset);
sign_ret_val = *h;
}
bit_pos += ((sign_ret_val & 0x7fff) >> 11);
bit_pos = min(bit_pos, 31);
value = sign_ret_val & (0x07FF);
if (sign) {
WORD32 out0, out1, out2, out3;
WORD32 ampout0, ampout1, ampout2, ampout3;
WORD32 temp_word;
temp_word = read_word << bit_pos;
out0 = (ixheaac_extu(value, 24, 30));
ampout0 = add_d(out0, *p_pul_arr++);
ampout0 = pow_table_q17[ampout0];
if (out0) {
if (temp_word & 0x80000000) {
ampout0 = -ampout0;
}
temp_word = temp_word << 1;
bit_pos++;
} else {
ampout0 = -ampout0;
}
out1 = (ixheaac_extu(value, 26, 30));
ampout1 = add_d(out1, *p_pul_arr++);
ampout1 = pow_table_q17[ampout1];
if (out1) {
if (temp_word & 0x80000000) {
ampout1 = -(ampout1);
}
temp_word = temp_word << 1;
bit_pos++;
} else {
ampout1 = -ampout1;
}
out2 = (ixheaac_extu(value, 28, 30));
ampout2 = add_d(out2, *p_pul_arr++);
ampout2 = pow_table_q17[ampout2];
if (out2) {
if (temp_word & 0x80000000) {
ampout2 = -(ampout2);
}
temp_word = temp_word << 1;
bit_pos++;
} else {
ampout2 = -ampout2;
}
*x_invquant++ = ampout0;
*x_invquant++ = ampout1;
*x_invquant++ = ampout2;
out3 = (ixheaac_extu(value, 30, 30));
ampout3 = add_d(out3, *p_pul_arr++);
ampout3 = pow_table_q17[ampout3];
if (out3) {
if (temp_word & 0x80000000) {
ampout3 = -(ampout3);
}
temp_word = temp_word << 1;
bit_pos++;
} else {
ampout3 = -ampout3;
}
*x_invquant++ = ampout3;
} else {
ampres = *p_pul_arr++;
res = (ixheaacd_res_exts(value, 24, 30));
if (res > 0) {
ampres = add_d(res, ampres);
ampres = pow_table_q17[ampres];
} else {
ampres = sub_d(ampres, res);
ampres = pow_table_q17[ampres];
ampres = -ampres;
}
res = (ixheaacd_res_exts(value, 26, 30));
ampres1 = *p_pul_arr++;
if (res > 0) {
ampres1 = add_d(res, ampres1);
ampres1 = pow_table_q17[ampres1];
} else {
ampres1 = sub_d(ampres1, res);
ampres1 = pow_table_q17[ampres1];
ampres1 = -ampres1;
}
res = (ixheaacd_res_exts(value, 28, 30));
ampres2 = *p_pul_arr++;
if (res > 0) {
ampres2 = add_d(res, ampres2);
ampres2 = pow_table_q17[ampres2];
} else {
ampres2 = sub_d(ampres2, res);
ampres2 = pow_table_q17[ampres2];
ampres2 = -ampres2;
}
res = (ixheaacd_res_exts(value, 30, 30));
ampres3 = *p_pul_arr++;
if (res > 0) {
ampres3 = add_d(res, ampres3);
ampres3 = pow_table_q17[ampres3];
} else {
ampres3 = sub_d(ampres3, res);
ampres3 = pow_table_q17[ampres3];
ampres3 = -ampres3;
}
*x_invquant++ = ampres;
*x_invquant++ = ampres1;
*x_invquant++ = ampres2;
*x_invquant++ = ampres3;
}
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bit_buf->ptr_bit_buf_end);
}
it_bit_buf->ptr_read_next = ptr_read_next - 4;
it_bit_buf->bit_pos = bit_pos;
return 0;
}
static PLATFORM_INLINE WORD ixheaacd_res_c_block_decode_huff_word2_2(
ia_bit_buf_struct *it_bif_buf, WORD32 *qp, WORD16 *offsets, WORD no_bands, WORD group_no,
const UWORD16 *h_ori, WORD32 *pow_table_q17, WORD32 sign, WORD32 maximum_bins_short)
{
WORD32 value;
WORD idx, grp_idx;
WORD len_idx;
WORD32 *qp_org = qp;
UWORD8 *ptr_read_next = it_bif_buf->ptr_read_next;
WORD32 bit_pos = it_bif_buf->bit_pos;
WORD32 read_word = ixheaacd_res_aac_showbits_32(ptr_read_next);
ptr_read_next += 4;
do {
len_idx = offsets[1] - offsets[0];
grp_idx = group_no;
do {
qp += offsets[0];
idx = len_idx;
do {
UWORD16 first_offset;
WORD16 sign_ret_val;
UWORD32 read_word1;
UWORD16 *h;
read_word1 = read_word << bit_pos;
h = (UWORD16 *)h_ori;
h += (read_word1) >> (27);
sign_ret_val = *h;
first_offset = 5;
while (sign_ret_val > 0) {
bit_pos += first_offset;
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bif_buf->ptr_bit_buf_end);
read_word1 = (read_word1) << (first_offset);
first_offset = (sign_ret_val >> 11);
h += sign_ret_val & (0x07FF);
h += (read_word1) >> (32 - first_offset);
sign_ret_val = *h;
}
bit_pos += ((sign_ret_val & 0x7fff) >> 11);
bit_pos = min(bit_pos, 31);
value = sign_ret_val & (0x07FF);
if (sign) {
WORD32 temp_word;
temp_word = read_word << bit_pos;
*qp++ = ixheaacd_res_extract_signed_symbol(value, 24, 28, pow_table_q17, &temp_word,
&bit_pos);
*qp++ = ixheaacd_res_extract_signed_symbol(value, 28, 28, pow_table_q17, &temp_word,
&bit_pos);
} else {
*qp++ = ixheaacd_res_extract_symbol(value, 24, 28, pow_table_q17);
*qp++ = ixheaacd_res_extract_symbol(value, 28, 28, pow_table_q17);
}
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bif_buf->ptr_bit_buf_end);
idx -= 2;
} while (idx != 0);
qp += (maximum_bins_short - offsets[1]);
grp_idx--;
} while (grp_idx != 0);
offsets++;
qp = qp_org;
no_bands--;
} while (no_bands >= 0);
it_bif_buf->ptr_read_next = ptr_read_next - 4;
it_bif_buf->bit_pos = bit_pos;
return 0;
}
static PLATFORM_INLINE WORD ixheaacd_res_c_block_decode_huff_word2_2_lb(
ia_bit_buf_struct *it_bit_buf, WORD32 len, const UWORD16 *h_ori, WORD32 *x_invquant,
WORD32 *pow_table_q17, WORD8 *p_pul_arr, WORD32 sign) {
WORD32 value, res, ampres;
WORD idx;
UWORD8 *ptr_read_next = it_bit_buf->ptr_read_next;
WORD32 bit_pos = it_bit_buf->bit_pos;
WORD32 read_word = ixheaacd_res_aac_showbits_32(ptr_read_next);
ptr_read_next += 4;
for (idx = len; idx != 0; idx -= 2) {
{
UWORD16 first_offset;
WORD16 sign_ret_val;
UWORD32 read_word1;
UWORD16 *h;
read_word1 = read_word << bit_pos;
h = (UWORD16 *)h_ori;
h += (read_word1) >> (27);
sign_ret_val = *h;
first_offset = 5;
while (sign_ret_val > 0) {
bit_pos += first_offset;
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bit_buf->ptr_bit_buf_end);
read_word1 = (read_word1) << (first_offset);
first_offset = (sign_ret_val >> 11);
h += sign_ret_val & (0x07FF);
h += (read_word1) >> (32 - first_offset);
sign_ret_val = *h;
}
bit_pos += ((sign_ret_val & 0x7fff) >> 11);
bit_pos = min(bit_pos, 31);
value = sign_ret_val & (0x07FF);
}
if (sign) {
WORD32 out0, out1, temp_word;
WORD32 ampout0, ampout1;
ampout0 = *p_pul_arr++;
ampout1 = *p_pul_arr++;
out0 = value & 0xf0;
ampout0 = add_d(ampout0, (UWORD32)out0 >> 4);
ampout0 = pow_table_q17[ampout0];
out1 = value & 0xf;
ampout1 = add_d(out1, ampout1);
ampout1 = pow_table_q17[ampout1];
temp_word = read_word << bit_pos;
if (out0) {
if (temp_word & 0x80000000) {
ampout0 = -(ampout0);
}
bit_pos++;
temp_word = temp_word << 1;
} else {
ampout0 = -(ampout0);
}
if (out1) {
if (temp_word & 0x80000000) {
ampout1 = -(ampout1);
}
bit_pos++;
} else {
ampout1 = -(ampout1);
}
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bit_buf->ptr_bit_buf_end);
*x_invquant++ = ampout0;
*x_invquant++ = ampout1;
} else {
res = ((value << 24) >> 28);
ampres = *p_pul_arr++;
if (res > 0) {
ampres = add_d(res, ampres);
*x_invquant++ = pow_table_q17[ampres];
} else {
ampres = sub_d(ampres, res);
ampres = pow_table_q17[ampres];
*x_invquant++ = -ampres;
}
res = ((value << 28) >> 28);
value = *p_pul_arr++;
if (res > 0) {
ampres = add_d(res, value);
*x_invquant++ = pow_table_q17[ampres];
} else {
ampres = sub_d(value, res);
ampres = pow_table_q17[ampres];
*x_invquant++ = -ampres;
}
}
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
it_bit_buf->ptr_bit_buf_end);
}
it_bit_buf->ptr_read_next = ptr_read_next - 4;
it_bit_buf->bit_pos = bit_pos;
return 0;
}
WORD ixheaacd_res_c_block_decode_huff_word_all(
ia_bit_buf_struct *it_bit_buf, WORD32 code_no, WORD32 *quantized_coef, WORD16 *band_offsets,
WORD start, WORD band, WORD group_no, ia_mps_dec_residual_aac_tables_struct *aac_tables_ptr,
WORD32 maximum_bins_short) {
WORD ret_val = 0;
WORD start_bit_pos = it_bit_buf->bit_pos;
UWORD8 *start_read_pos = it_bit_buf->ptr_read_next;
const UWORD16 *h_ori = (UWORD16 *)(aac_tables_ptr->code_book[code_no]);
WORD32 *pow_table = (WORD32 *)aac_tables_ptr->res_block_tables_ptr->pow_table_q17;
WORD32 no_bands = band - start - 1;
WORD16 *p_band_off = band_offsets + start;
if (code_no == 11) {
const UWORD16 *h_ori = aac_tables_ptr->res_huffmann_tables_ptr->huffman_codebook_11;
ret_val =
ixheaacd_res_c_block_decode_huff_word1(it_bit_buf, quantized_coef, p_band_off, no_bands,
group_no, h_ori, pow_table, maximum_bins_short);
} else if (code_no <= 4) {
WORD32 sign = 0;
if (code_no > 2) sign = 1;
ret_val = ixheaacd_res_c_block_decode_huff_word2_4(it_bit_buf, quantized_coef, p_band_off,
no_bands, group_no, h_ori, pow_table, sign,
maximum_bins_short);
}
else if (code_no <= 10) {
WORD32 sign = 0;
if (code_no > 6) sign = 1;
ret_val = ixheaacd_res_c_block_decode_huff_word2_2(it_bit_buf, quantized_coef, p_band_off,
no_bands, group_no, h_ori, pow_table, sign,
maximum_bins_short);
}
{
WORD bits_cons;
bits_cons = (WORD)(((it_bit_buf->ptr_read_next - start_read_pos) << 3) +
(it_bit_buf->bit_pos - start_bit_pos));
it_bit_buf->cnt_bits -= bits_cons;
}
return ret_val;
}
WORD ixheaacd_res_c_block_decode_huff_word_all_lb(
ia_bit_buf_struct *it_bit_buf, WORD32 code_no, WORD32 len,
ia_mps_dec_residual_aac_tables_struct *aac_tables_ptr, WORD32 *x_invquant, WORD8 *p_pul_arr) {
WORD ret_val = 0;
WORD start_bit_pos = it_bit_buf->bit_pos;
WORD32 *pow_table = (WORD32 *)aac_tables_ptr->res_block_tables_ptr->pow_table_q17;
UWORD8 *start_read_pos = it_bit_buf->ptr_read_next;
const UWORD16 *h_ori = (UWORD16 *)(aac_tables_ptr->code_book[code_no]);
if (code_no == 11) {
const UWORD16 *h_ori = aac_tables_ptr->res_huffmann_tables_ptr->huffman_codebook_11;
ret_val = ixheaacd_res_c_block_decode_huff_word1_lb(it_bit_buf, len, h_ori, x_invquant,
pow_table, p_pul_arr);
} else if (code_no <= 4) {
WORD32 sign = 0;
if (code_no > 2) sign = 1;
ret_val = ixheaacd_res_c_block_decode_huff_word2_4_lb(it_bit_buf, len, h_ori, x_invquant,
pow_table, p_pul_arr, sign);
} else if (code_no <= 10) {
WORD32 sign = 0;
if (code_no > 6) sign = 1;
ret_val = ixheaacd_res_c_block_decode_huff_word2_2_lb(it_bit_buf, len, h_ori, x_invquant,
pow_table, p_pul_arr, sign);
}
{
WORD bits_cons;
if (it_bit_buf->bit_pos <= 7) {
bits_cons = (WORD)(((it_bit_buf->ptr_read_next - start_read_pos) << 3) +
(it_bit_buf->bit_pos - start_bit_pos));
it_bit_buf->cnt_bits -= bits_cons;
} else {
it_bit_buf->ptr_read_next += (it_bit_buf->bit_pos) >> 3;
it_bit_buf->bit_pos = it_bit_buf->bit_pos & 0x7;
bits_cons = (WORD)(((it_bit_buf->ptr_read_next - start_read_pos) << 3) +
((it_bit_buf->bit_pos - start_bit_pos)));
it_bit_buf->cnt_bits -= bits_cons;
}
}
return ret_val;
}
static VOID ixheaacd_res_apply_one_scf(WORD32 scale_factor, WORD32 *x_invquant, WORD32 end,
WORD32 *scale_table_ptr) {
WORD32 j;
WORD32 temp_1;
WORD32 q_factor;
WORD32 buffer1;
WORD16 scale_short;
if (scale_factor < 24) {
for (j = end; j > 0; j--) {
*x_invquant++ = 0;
}
} else {
WORD32 shift;
q_factor = 37 - (scale_factor >> 2);
scale_short = scale_table_ptr[(scale_factor & 0x0003)];
shift = q_factor;
if (shift > 0) {
if (scale_short == (WORD16)0x8000) {
for (j = end; j > 0; j--) {
temp_1 = *x_invquant;
buffer1 = ixheaac_mult32x16in32_shl_sat(temp_1, scale_short);
buffer1 = ixheaac_shr32(buffer1, shift);
*x_invquant++ = buffer1;
}
} else {
for (j = end; j > 0; j--) {
temp_1 = *x_invquant;
buffer1 = ixheaac_mult32x16in32_shl(temp_1, scale_short);
buffer1 = ixheaac_shr32(buffer1, shift);
*x_invquant++ = buffer1;
}
}
} else {
shift = -shift;
if (shift > 0) {
if (scale_short == (WORD16)0x8000) {
for (j = end; j > 0; j--) {
temp_1 = *x_invquant;
temp_1 = ixheaac_shl32(temp_1, shift - 1);
buffer1 = ixheaac_mult32x16in32_shl_sat(temp_1, scale_short);
buffer1 = ixheaac_shl32(buffer1, 1);
*x_invquant++ = buffer1;
}
} else {
for (j = end; j > 0; j--) {
temp_1 = *x_invquant;
temp_1 = ixheaac_shl32(temp_1, shift - 1);
buffer1 = ixheaac_mult32x16in32_shl(temp_1, scale_short);
buffer1 = ixheaac_shl32(buffer1, 1);
*x_invquant++ = buffer1;
}
}
} else {
if (scale_short == (WORD16)0x8000) {
for (j = end; j > 0; j--) {
temp_1 = *x_invquant;
buffer1 = ixheaac_mult32x16in32_shl_sat(temp_1, scale_short);
*x_invquant++ = buffer1;
}
} else {
for (j = end; j > 0; j--) {
temp_1 = *x_invquant;
buffer1 = ixheaac_mult32x16in32_shl(temp_1, scale_short);
*x_invquant++ = buffer1;
}
}
}
}
}
}
VOID ixheaacd_res_apply_scfs(WORD32 *x_invquant, WORD16 *sc_factor, WORD t_bands, WORD8 *offset,
WORD32 *scale_table_ptr) {
WORD32 i;
WORD16 scale_factor;
for (i = t_bands - 1; i >= 0; i--) {
scale_factor = *sc_factor++;
ixheaacd_res_apply_one_scf(scale_factor, x_invquant, *offset, scale_table_ptr);
x_invquant += *offset;
offset++;
}
}