diff options
Diffstat (limited to 'decoder/ixheaacd_ld_mps_config.c')
-rw-r--r-- | decoder/ixheaacd_ld_mps_config.c | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/decoder/ixheaacd_ld_mps_config.c b/decoder/ixheaacd_ld_mps_config.c new file mode 100644 index 0000000..fbcc373 --- /dev/null +++ b/decoder/ixheaacd_ld_mps_config.c @@ -0,0 +1,312 @@ +/****************************************************************************** +* * +* 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_type_def.h" +#include <ixheaacd_constants.h> +#include <ixheaacd_error_standards.h> + +#include "ixheaacd_bitbuffer.h" +#include "ixheaacd_config.h" + +#include <assert.h> + +#ifndef sign +#define sign(a) (((a) > 0) ? 1 : ((a) < 0) ? -1 : 0) +#endif + +typedef struct { + WORD32 num_input_chan; + WORD32 num_output_chan; + WORD32 num_ott_boxes; + WORD32 num_ttt_boxes; + WORD32 ott_mode_lfe[MAX_NUM_OTT]; +} TREEPROPERTIES; + +static WORD32 ixheaacd_freq_res_table[] = {0, 23, 15, 12, 9, 7, 5, 4}; + +static WORD32 ixheaacd_HRTF_freq_res_table[][8] = {{0, 28, 20, 14, 10, 7, 5, 4}, + {0, 13, 13, 8, 7, 4, 3, 3}}; + +static TREEPROPERTIES ixheaacd_tree_property_table[] = { + {1, 6, 5, 0, {0, 0, 0, 0, 1}}, {1, 6, 5, 0, {0, 0, 1, 0, 0}}, + {2, 6, 3, 1, {1, 0, 0, 0, 0}}, {2, 8, 5, 1, {1, 0, 0, 0, 0}}, + {2, 8, 5, 1, {1, 0, 0, 0, 0}}, {6, 8, 2, 0, {0, 0, 0, 0, 0}}, + {6, 8, 2, 0, {0, 0, 0, 0, 0}}, {1, 2, 1, 0, {0, 0, 0, 0, 0}}}; + +static IA_ERRORCODE ixheaacd_ld_spatial_extension_config( + ia_bit_buf_struct *it_bit_buff, ia_usac_dec_mps_config_struct *config, + WORD32 bits_available) { + WORD32 j, ch, idx, tmp, tmp_open, sac_ext_len, bits_read, n_fill_bits; + UWORD32 i; + WORD32 ba = bits_available; + + config->sac_ext_cnt = 0; + + tmp = it_bit_buff->cnt_bits; + + while (ba >= 8) { + if (config->sac_ext_cnt >= MAX_NUM_EXT_TYPES) return IA_FATAL_ERROR; + + config->bs_sac_ext_type[config->sac_ext_cnt] = + ixheaacd_read_bits_buf(it_bit_buff, 4); + ba -= 4; + + sac_ext_len = ixheaacd_read_bits_buf(it_bit_buff, 4); + ba -= 4; + + if ((ba >= 6) && (sac_ext_len > 0)) { + if (sac_ext_len == 15) { + sac_ext_len += ixheaacd_read_bits_buf(it_bit_buff, 8); + ba -= 8; + if (sac_ext_len == 15 + 255) { + sac_ext_len += ixheaacd_read_bits_buf(it_bit_buff, 16); + ba -= 16; + } + } + + switch (config->bs_sac_ext_type[config->sac_ext_cnt]) { + case 0: + config->bs_residual_coding = 1; + + config->bs_residual_sampling_freq_index = + ixheaacd_read_bits_buf(it_bit_buff, 4); + config->bs_residual_frames_per_spatial_frame = + ixheaacd_read_bits_buf(it_bit_buff, 2); + + if ((config->num_ott_boxes + config->num_ttt_boxes) > + MAX_RESIDUAL_CHANNELS) + return IA_FATAL_ERROR; + for (j = 0; j < config->num_ott_boxes + config->num_ttt_boxes; j++) { + config->bs_residual_present[j] = + ixheaacd_read_bits_buf(it_bit_buff, 1); + if (config->bs_residual_present[j]) { + config->bs_residual_bands_ld_mps[j] = + ixheaacd_read_bits_buf(it_bit_buff, 5); + } + } + break; + + case 1: + config->bs_arbitrary_downmix = 2; + + config->bs_arbitrary_downmix_residual_sampling_freq_index = + ixheaacd_read_bits_buf(it_bit_buff, 4); + config->bs_arbitrary_downmix_residual_frames_per_spatial_frame = + ixheaacd_read_bits_buf(it_bit_buff, 2); + config->bs_arbitrary_downmix_residual_bands = + ixheaacd_read_bits_buf(it_bit_buff, 5); + + break; + + case 2: + config->num_out_chan_AT = 0; + config->num_ott_boxes_AT = 0; + if (config->num_output_channels > MAX_OUTPUT_CHANNELS) + return IA_FATAL_ERROR; + for (ch = 0; ch < config->num_output_channels; ch++) { + tmp_open = 1; + idx = 0; + while ((tmp_open > 0) && (idx < MAX_ARBITRARY_TREE_INDEX)) { + config->bs_ott_box_present_AT[ch][idx] = + ixheaacd_read_bits_buf(it_bit_buff, 1); + if (config->bs_ott_box_present_AT[ch][idx]) { + config->num_ott_boxes_AT++; + tmp_open++; + } else { + config->num_out_chan_AT++; + tmp_open--; + } + idx++; + } + } + + for (i = 0; i < config->num_ott_boxes_AT; i++) { + config->bs_ott_default_cld_AT[i] = + ixheaacd_read_bits_buf(it_bit_buff, 1); + config->bs_ott_mode_lfe_AT[i] = + ixheaacd_read_bits_buf(it_bit_buff, 1); + if (config->bs_ott_mode_lfe_AT[i]) { + config->bs_ott_bands_AT[i] = + ixheaacd_read_bits_buf(it_bit_buff, 5); + } else { + config->bs_ott_bands_AT[i] = ixheaacd_freq_res_table[config->bs_freq_res]; + } + } + + for (i = 0; i < config->num_out_chan_AT; i++) { + config->bs_output_channel_pos_AT[i] = + ixheaacd_read_bits_buf(it_bit_buff, 5); + } + + break; + + default:; + } + } + + bits_read = tmp - it_bit_buff->cnt_bits; + n_fill_bits = 8 * sac_ext_len - bits_read; + + while (n_fill_bits > 7) { + ixheaacd_read_bits_buf(it_bit_buff, 8); + n_fill_bits -= 8; + } + if (n_fill_bits > 0) { + ixheaacd_read_bits_buf(it_bit_buff, n_fill_bits); + } + + ba -= 8 * sac_ext_len; + config->sac_ext_cnt++; + } + return IA_NO_ERROR; +} + +IA_ERRORCODE ixheaacd_ld_spatial_specific_config( + ia_usac_dec_mps_config_struct *config, ia_bit_buf_struct *it_bit_buff) { + WORD32 i, num_header_bits; + UWORD32 hc, hb; + WORD32 sac_header_len; + WORD32 bits_available; + WORD32 tmp = it_bit_buff->cnt_bits; + WORD32 err = 0; + + sac_header_len = tmp; + + bits_available = sac_header_len; + config->bs_sampling_freq_index = ixheaacd_read_bits_buf(it_bit_buff, 4); + if (config->bs_sampling_freq_index == 15) { + config->bs_fampling_frequency = ixheaacd_read_bits_buf(it_bit_buff, 24); + } + + config->bs_frame_length = ixheaacd_read_bits_buf(it_bit_buff, 5); + config->bs_freq_res = ixheaacd_read_bits_buf(it_bit_buff, 3); + config->bs_tree_config = ixheaacd_read_bits_buf(it_bit_buff, 4); + + if (config->bs_tree_config > 7) return IA_FATAL_ERROR; + + if (config->bs_tree_config != 15) { + config->num_ott_boxes = + ixheaacd_tree_property_table[config->bs_tree_config].num_ott_boxes; + config->num_ttt_boxes = + ixheaacd_tree_property_table[config->bs_tree_config].num_ttt_boxes; + config->num_input_channels = + ixheaacd_tree_property_table[config->bs_tree_config].num_input_chan; + config->num_output_channels = + ixheaacd_tree_property_table[config->bs_tree_config].num_output_chan; + for (i = 0; i < MAX_NUM_OTT; i++) { + config->ott_mode_lfe[i] = + ixheaacd_tree_property_table[config->bs_tree_config].ott_mode_lfe[i]; + } + } + config->bs_quant_mode = ixheaacd_read_bits_buf(it_bit_buff, 2); + if (config->bs_tree_config != 7) { + config->bs_one_icc = ixheaacd_read_bits_buf(it_bit_buff, 1); + } + config->bs_arbitrary_downmix = ixheaacd_read_bits_buf(it_bit_buff, 1); + if (config->bs_tree_config != 7) { + config->bs_fixed_gain_sur = ixheaacd_read_bits_buf(it_bit_buff, 3); + config->bs_fixed_gain_LFE = ixheaacd_read_bits_buf(it_bit_buff, 3); + } + config->bs_fixed_gain_dmx = ixheaacd_read_bits_buf(it_bit_buff, 3); + if (config->bs_tree_config != 7) { + config->bs_matrix_mode = ixheaacd_read_bits_buf(it_bit_buff, 1); + } + config->bs_temp_shape_config = ixheaacd_read_bits_buf(it_bit_buff, 2); + config->bs_decorr_config = ixheaacd_read_bits_buf(it_bit_buff, 2); + if (config->bs_tree_config != 7) { + config->bs_3D_audio_mode = ixheaacd_read_bits_buf(it_bit_buff, 1); + } else { + config->bs_3D_audio_mode = 0; + } + + // ott_config + for (i = 0; i < config->num_ott_boxes; i++) { + if (config->ott_mode_lfe[i]) { + config->bs_ott_bands[i] = ixheaacd_read_bits_buf(it_bit_buff, 5); + } else { + config->bs_ott_bands[i] = ixheaacd_freq_res_table[config->bs_freq_res]; + } + } + + // ttt_config + for (i = 0; i < config->num_ttt_boxes; i++) { + config->bs_ttt_dual_mode[i] = ixheaacd_read_bits_buf(it_bit_buff, 1); + config->bs_ttt_mode_low[i] = ixheaacd_read_bits_buf(it_bit_buff, 3); + if (config->bs_ttt_dual_mode[i]) { + config->bs_ttt_mode_high[i] = ixheaacd_read_bits_buf(it_bit_buff, 3); + config->bs_ttt_bands_low[i] = ixheaacd_read_bits_buf(it_bit_buff, 5); + config->bs_ttt_bands_high[i] = ixheaacd_freq_res_table[config->bs_freq_res]; + } else { + config->bs_ttt_bands_low[i] = ixheaacd_freq_res_table[config->bs_freq_res]; + } + } + + if (config->bs_temp_shape_config == 2) { + config->bs_env_quant_mode = ixheaacd_read_bits_buf(it_bit_buff, 1); + } + + if (config->bs_3D_audio_mode) { + config->bs_3D_audio_HRTF_set = ixheaacd_read_bits_buf(it_bit_buff, 2); + // param_HRTF_set + if (config->bs_3D_audio_HRTF_set == 0) { + config->bs_HRTF_freq_res = ixheaacd_read_bits_buf(it_bit_buff, 3); + config->bs_HRTF_num_chan = 5; + config->bs_HRTF_asymmetric = ixheaacd_read_bits_buf(it_bit_buff, 1); + + config->HRTF_num_band = ixheaacd_HRTF_freq_res_table[0][config->bs_HRTF_freq_res]; + config->HRTF_num_phase = ixheaacd_HRTF_freq_res_table[1][config->bs_HRTF_freq_res]; + + for (hc = 0; hc < config->bs_HRTF_num_chan; hc++) { + for (hb = 0; hb < config->HRTF_num_band; hb++) { + config->bs_HRTF_level_left[hc][hb] = + ixheaacd_read_bits_buf(it_bit_buff, 6); + } + for (hb = 0; hb < config->HRTF_num_band; hb++) { + config->bs_HRTF_level_right[hc][hb] = + config->bs_HRTF_asymmetric + ? ixheaacd_read_bits_buf(it_bit_buff, 6) + : config->bs_HRTF_level_left[hc][hb]; + } + config->bs_HRTF_phase[hc] = ixheaacd_read_bits_buf(it_bit_buff, 1); + for (hb = 0; hb < config->HRTF_num_phase; hb++) { + config->bs_HRTF_phase_LR[hc][hb] = + config->bs_HRTF_phase[hc] ? ixheaacd_read_bits_buf(it_bit_buff, 6) + : 0; + } + config->bs_HRTF_icc[hc] = ixheaacd_read_bits_buf(it_bit_buff, 1); + if (config->bs_HRTF_icc[hc]) { + for (hb = 0; hb < config->HRTF_num_band; hb++) + config->bs_HRTF_icc_LR[hc][hb] = + ixheaacd_read_bits_buf(it_bit_buff, 3); + } + } + } + } + + // byte_align + i = (it_bit_buff->cnt_bits & 0x7); + ixheaacd_read_bits_buf(it_bit_buff, i); + + num_header_bits = tmp - (it_bit_buff->cnt_bits); + bits_available -= num_header_bits; + + err = + ixheaacd_ld_spatial_extension_config(it_bit_buff, config, bits_available); + return err; +} |