You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
305 lines
10 KiB
305 lines
10 KiB
/******************************************************************************
|
|
* *
|
|
* Copyright (C) 2018 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 "ixheaacd_sbr_common.h"
|
|
#include "ixheaacd_type_def.h"
|
|
#include "ixheaacd_constants.h"
|
|
#include "ixheaacd_basic_ops32.h"
|
|
#include "ixheaacd_basic_ops16.h"
|
|
#include "ixheaacd_basic_ops40.h"
|
|
#include "ixheaacd_basic_ops.h"
|
|
|
|
#include "ixheaacd_defines.h"
|
|
#include "ixheaacd_aac_rom.h"
|
|
#include "ixheaacd_aac_imdct.h"
|
|
#include "ixheaacd_bitbuffer.h"
|
|
#include "ixheaacd_basic_op.h"
|
|
#include "ixheaacd_intrinsics.h"
|
|
|
|
#include "ixheaacd_pulsedata.h"
|
|
|
|
#include "ixheaacd_pns.h"
|
|
#include "ixheaacd_common_rom.h"
|
|
#include "ixheaacd_drc_data_struct.h"
|
|
|
|
#include "ixheaacd_lt_predict.h"
|
|
|
|
#include "ixheaacd_channelinfo.h"
|
|
#include "ixheaacd_cnst.h"
|
|
#include "ixheaacd_drc_dec.h"
|
|
|
|
#include "ixheaacd_block.h"
|
|
#include "ixheaacd_channel.h"
|
|
|
|
#include "ixheaacd_pulsedata.h"
|
|
#include "ixheaacd_pns.h"
|
|
#include "ixheaacd_sbrdecoder.h"
|
|
#include "ixheaacd_error_codes.h"
|
|
#include "ixheaacd_audioobjtypes.h"
|
|
#include "ixheaacd_latmdemux.h"
|
|
#include "ixheaacd_aacdec.h"
|
|
|
|
#define LONG_BLOCK_SECT_LEN 5
|
|
#define SHORT_BLOCK_SECT_LEN 3
|
|
|
|
IA_ERRORCODE ixheaacd_read_section_data(
|
|
ia_bit_buf_struct *it_bit_buff,
|
|
ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info,
|
|
WORD32 aac_spect_data_resil_flag, WORD32 aac_sect_data_resil_flag,
|
|
ia_aac_dec_tables_struct *ptr_aac_tables) {
|
|
WORD sfb;
|
|
WORD sect_cb;
|
|
WORD sect_len;
|
|
WORD sect_len_incr;
|
|
WORD sect_esc_val;
|
|
ia_ics_info_struct *ptr_ics_info = &ptr_aac_dec_channel_info->str_ics_info;
|
|
WORD max_sfb = ptr_ics_info->max_sfb;
|
|
WORD num_win_group;
|
|
|
|
WORD8 *ptr_code_book = ptr_aac_dec_channel_info->ptr_code_book;
|
|
WORD8 *ptr_code_book_temp = ptr_code_book;
|
|
WORD32 sect_bitlen = LONG_BLOCK_SECT_LEN;
|
|
int num_lines_sec_idx = 0, top;
|
|
short *ptr_num_sect_lines =
|
|
ptr_aac_dec_channel_info->num_line_in_sec4_hcr_arr;
|
|
UWORD8 *ptr_hcr_code_book = ptr_aac_dec_channel_info->cb4_hcr_arr;
|
|
const short *band_offsets = (WORD16 *)ixheaacd_getscalefactorbandoffsets(
|
|
&(ptr_aac_dec_channel_info->str_ics_info), ptr_aac_tables);
|
|
ptr_aac_dec_channel_info->number_sect = 0;
|
|
|
|
if (ptr_aac_dec_channel_info->str_ics_info.window_sequence ==
|
|
EIGHT_SHORT_SEQUENCE) {
|
|
sect_bitlen = SHORT_BLOCK_SECT_LEN;
|
|
}
|
|
|
|
sect_esc_val = (1 << sect_bitlen) - 1;
|
|
|
|
for (num_win_group = 0; num_win_group < ptr_ics_info->num_window_groups;
|
|
num_win_group++) {
|
|
sfb = 0;
|
|
|
|
while (sfb < max_sfb) {
|
|
sect_len = 0;
|
|
if (aac_sect_data_resil_flag) {
|
|
sect_cb = ixheaacd_read_bits_buf(it_bit_buff, 5);
|
|
} else {
|
|
sect_cb = ixheaacd_read_bits_buf(it_bit_buff, 4);
|
|
}
|
|
|
|
if ((aac_sect_data_resil_flag == 0) ||
|
|
((sect_cb < 11) || ((sect_cb > 11) && (sect_cb < 16)))) {
|
|
sect_len_incr = ixheaacd_read_bits_buf(it_bit_buff, sect_bitlen);
|
|
while (sect_len_incr == sect_esc_val) {
|
|
sect_len = (sect_len + sect_esc_val);
|
|
sect_len_incr = ixheaacd_read_bits_buf(it_bit_buff, sect_bitlen);
|
|
}
|
|
} else
|
|
sect_len_incr = 1;
|
|
|
|
sect_len = (sect_len + sect_len_incr);
|
|
|
|
if (aac_spect_data_resil_flag) {
|
|
top = (sfb + sect_len);
|
|
if ((num_lines_sec_idx >= MAX_SFB_HCR) ||
|
|
(top >= MAX_SCALE_FACTOR_BANDS_LONG)) {
|
|
return -1;
|
|
}
|
|
ptr_num_sect_lines[num_lines_sec_idx] =
|
|
band_offsets[top] - band_offsets[sfb];
|
|
num_lines_sec_idx++;
|
|
if (sect_cb == (ESC_HCB + 1)) {
|
|
return IA_ENHAACPLUS_DEC_EXE_NONFATAL_INVALID_CODE_BOOK;
|
|
} else {
|
|
*ptr_hcr_code_book++ = sect_cb;
|
|
}
|
|
ptr_aac_dec_channel_info->number_sect++;
|
|
}
|
|
|
|
sfb = (sfb + sect_len);
|
|
if (sfb > max_sfb) {
|
|
return (WORD16)(
|
|
(WORD32)IA_ENHAACPLUS_DEC_EXE_NONFATAL_EXCEEDS_SFB_TRANSMITTED);
|
|
}
|
|
if (sect_cb == (ESC_HCB + 1)) {
|
|
return (WORD16)(
|
|
(WORD32)IA_ENHAACPLUS_DEC_EXE_NONFATAL_INVALID_CODE_BOOK);
|
|
}
|
|
|
|
while (sect_len--) {
|
|
*ptr_code_book_temp++ = sect_cb;
|
|
}
|
|
}
|
|
ptr_code_book += MAX_SCALE_FACTOR_BANDS_SHORT;
|
|
ptr_code_book_temp = ptr_code_book;
|
|
}
|
|
|
|
return AAC_DEC_OK;
|
|
}
|
|
|
|
VOID ixheaacd_read_scale_factor_data(
|
|
ia_bit_buf_struct *it_bit_buff,
|
|
ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info,
|
|
ia_aac_dec_tables_struct *ptr_aac_tables, WORD32 object_type) {
|
|
WORD sfb;
|
|
WORD16 position = 0;
|
|
WORD num_win_group;
|
|
WORD16 factor = ptr_aac_dec_channel_info->global_gain;
|
|
WORD8 *ptr_code_book, *ptr_code_book_short;
|
|
WORD16 *ptr_scale_fact, *ptr_scale_fact_short;
|
|
WORD16 norm_value;
|
|
WORD16 index, length;
|
|
const UWORD16 *hcod_sf =
|
|
ptr_aac_tables->pstr_huffmann_tables->huffman_code_book_scl;
|
|
const UWORD32 *table_idx =
|
|
ptr_aac_tables->pstr_huffmann_tables->huffman_code_book_scl_index;
|
|
|
|
WORD start_bit_pos = it_bit_buff->bit_pos;
|
|
UWORD8 *start_read_pos = it_bit_buff->ptr_read_next;
|
|
UWORD8 *ptr_read_next = it_bit_buff->ptr_read_next;
|
|
WORD32 bit_pos = 7 - it_bit_buff->bit_pos;
|
|
WORD32 read_word;
|
|
WORD32 increment;
|
|
read_word = ixheaacd_aac_showbits_32(ptr_read_next, it_bit_buff->cnt_bits,
|
|
&increment);
|
|
ptr_read_next += increment;
|
|
|
|
ptr_code_book = ptr_aac_dec_channel_info->ptr_code_book;
|
|
|
|
ptr_scale_fact = ptr_aac_dec_channel_info->ptr_scale_factor;
|
|
|
|
for (num_win_group = 0;
|
|
num_win_group < ptr_aac_dec_channel_info->str_ics_info.num_window_groups;
|
|
num_win_group++) {
|
|
ptr_code_book_short =
|
|
&ptr_code_book[num_win_group * MAX_SCALE_FACTOR_BANDS_SHORT];
|
|
ptr_scale_fact_short =
|
|
&ptr_scale_fact[num_win_group * MAX_SCALE_FACTOR_BANDS_SHORT];
|
|
for (sfb = ptr_aac_dec_channel_info->str_ics_info.max_sfb - 1; sfb >= 0;
|
|
sfb--) {
|
|
WORD32 sfb_cb = *ptr_code_book_short++;
|
|
if (sfb_cb == ZERO_HCB)
|
|
*ptr_scale_fact_short++ = 0;
|
|
else {
|
|
{
|
|
WORD32 pns_present = 0;
|
|
WORD pns_band;
|
|
|
|
ia_pns_info_struct *ptr_pns_info =
|
|
&ptr_aac_dec_channel_info->str_pns_info;
|
|
|
|
if (sfb_cb == NOISE_HCB && (ptr_pns_info->pns_active != 1)) {
|
|
pns_present = 1;
|
|
}
|
|
|
|
if (!pns_present) {
|
|
UWORD32 read_word1;
|
|
|
|
read_word1 = read_word << bit_pos;
|
|
|
|
ixheaacd_huffman_decode(read_word1, &index, &length, hcod_sf,
|
|
table_idx);
|
|
|
|
bit_pos += length;
|
|
ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
|
|
it_bit_buff->ptr_bit_buf_end);
|
|
|
|
ixheaacd_aac_read_byte_corr1(&ptr_read_next, &bit_pos, &read_word,
|
|
it_bit_buff->ptr_bit_buf_end);
|
|
|
|
norm_value = index - 60;
|
|
}
|
|
|
|
else {
|
|
WORD32 noise_start_value;
|
|
UWORD32 temp;
|
|
|
|
temp = (read_word << bit_pos);
|
|
temp = ((UWORD32)temp >> (32 - 9));
|
|
noise_start_value = temp;
|
|
bit_pos += 9;
|
|
|
|
ixheaacd_aac_read_byte_corr1(&ptr_read_next, &bit_pos, &read_word,
|
|
it_bit_buff->ptr_bit_buf_end);
|
|
|
|
norm_value = noise_start_value - 256;
|
|
ptr_pns_info->pns_active = 1;
|
|
|
|
ptr_pns_info->noise_energy =
|
|
ptr_aac_dec_channel_info->global_gain - NOISE_OFFSET;
|
|
}
|
|
|
|
if ((object_type != AOT_ER_AAC_ELD) &&
|
|
(object_type != AOT_ER_AAC_LD)) {
|
|
if (sfb_cb > NOISE_HCB) {
|
|
position = position + norm_value;
|
|
*ptr_scale_fact_short++ = -position;
|
|
} else if (sfb_cb < NOISE_HCB) {
|
|
factor = factor + norm_value;
|
|
*ptr_scale_fact_short++ = factor;
|
|
} else {
|
|
ptr_pns_info->noise_energy =
|
|
ixheaacd_add16_sat(ptr_pns_info->noise_energy, norm_value);
|
|
|
|
pns_band = (num_win_group << 4) +
|
|
ptr_aac_dec_channel_info->str_ics_info.max_sfb - sfb -
|
|
1;
|
|
ptr_aac_dec_channel_info->ptr_scale_factor[pns_band] =
|
|
ptr_pns_info->noise_energy;
|
|
|
|
ptr_pns_info->pns_used[pns_band] = 1;
|
|
ptr_scale_fact_short++;
|
|
}
|
|
} else {
|
|
if ((sfb_cb == INTENSITY_HCB) || (sfb_cb == INTENSITY_HCB2)) {
|
|
position = position + norm_value;
|
|
*ptr_scale_fact_short++ = -position;
|
|
} else if (sfb_cb == NOISE_HCB) {
|
|
ptr_pns_info->noise_energy =
|
|
ixheaacd_add16_sat(ptr_pns_info->noise_energy, norm_value);
|
|
|
|
pns_band = (num_win_group << 4) +
|
|
ptr_aac_dec_channel_info->str_ics_info.max_sfb - sfb -
|
|
1;
|
|
ptr_aac_dec_channel_info->ptr_scale_factor[pns_band] =
|
|
ptr_pns_info->noise_energy;
|
|
|
|
ptr_pns_info->pns_used[pns_band] = 1;
|
|
ptr_scale_fact_short++;
|
|
|
|
} else {
|
|
factor = factor + norm_value;
|
|
*ptr_scale_fact_short++ = factor;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
it_bit_buff->ptr_read_next = ptr_read_next - increment;
|
|
|
|
it_bit_buff->bit_pos = 7 - bit_pos;
|
|
{
|
|
WORD bits_consumed;
|
|
bits_consumed = ((it_bit_buff->ptr_read_next - start_read_pos) << 3) +
|
|
(start_bit_pos - it_bit_buff->bit_pos);
|
|
it_bit_buff->cnt_bits -= bits_consumed;
|
|
}
|
|
}
|