diff --git a/lib_com/options.h b/lib_com/options.h index a35227e091783968f01e1dc13ea4acb27796197d..a1b8b0fd33730680ef98bd354c0c144b771a854c 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -154,6 +154,8 @@ #define FIX_I13_TCX_TNS_ISSUE /* Issue 13: Fix reported artifacts. Bug in TNS with TCX5 */ #define FIX_I120_INV_SQRT /* Issue 120: inv_sqrt() shall be used instead of 1 / sqrt() to measure the correct complexity */ +#define ISM_BITRATE_SWITCHING /* Issue 115: Support for Bitrate Switching in ISM */ + /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index be2b9eb350e27d198e8862c7d97c0442cc700dd6..b76c88739d533f2beae3d41f54596e07937a9414 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -1003,6 +1003,207 @@ void ivas_param_ism_params_to_masa_param_mapping( return; } + + +#ifdef ISM_BITRATE_SWITCHING +static ivas_error ivas_ism_format_bitrate_switching( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t last_nchan_trans, /* i : last number of SCE channels in the bitstream */ + const ISM_MODE last_ism_mode, /* i : last ISM mode */ + const int16_t num_obj /* i : number of objects in the bitstream */ +) +{ + int16_t sce_id; + ivas_error error; + int32_t element_brate_tmp[MAX_NUM_OBJECTS]; + + error = IVAS_ERR_OK; + + ivas_ism_config(st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, num_obj, NULL, NULL, NULL, element_brate_tmp, NULL, NULL); + + if (st_ivas->nchan_transport > last_nchan_trans) + { + /* Initialize for new bitrate */ + for (sce_id = 0;sce_id < last_nchan_trans;sce_id++) + { + st_ivas->hSCE[sce_id]->element_brate = st_ivas->hDecoderConfig->ivas_total_brate / st_ivas->nchan_transport; + st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ + } + + /* Initialize some memories */ + for (sce_id = last_nchan_trans; sce_id < st_ivas->nchan_transport; sce_id++) + { + if ((error = create_sce_dec(st_ivas, sce_id, element_brate_tmp[sce_id])) != IVAS_ERR_OK) + { + return error; + } + } + } + else + { + /* Initialize for new bitrate */ + for (sce_id = 0;sce_id < st_ivas->nchan_transport; sce_id++) + { + st_ivas->hSCE[sce_id]->element_brate = st_ivas->hDecoderConfig->ivas_total_brate / st_ivas->nchan_transport; + st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ + } + + /* Destroy the core coder memory */ + for (; sce_id < last_nchan_trans; sce_id++) + { + destroy_sce_dec(st_ivas->hSCE[sce_id]); + st_ivas->hSCE[sce_id] = NULL; + } + + } + + /* destroy the memory of hp20*/ + if (st_ivas->mem_hp20_out != NULL) + { + for (sce_id = 0; sce_id < last_nchan_trans; sce_id++) + { + count_free(st_ivas->mem_hp20_out[sce_id]); + st_ivas->mem_hp20_out[sce_id] = NULL; + } + count_free(st_ivas->mem_hp20_out); + st_ivas->mem_hp20_out = NULL; + } + + /* re initialize the memory of hp20 */ + /* set number of input channels used for analysis/coding */ + + if (st_ivas->nchan_transport > 0) + { + if ((st_ivas->mem_hp20_out = (float **)count_malloc(st_ivas->nchan_transport * sizeof(float *))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n")); + } + } + else + { + st_ivas->mem_hp20_out = NULL; + } + + for (sce_id = 0; sce_id < st_ivas->nchan_transport; sce_id++) + { + if ((st_ivas->mem_hp20_out[sce_id] = (float *)count_malloc(L_HP20_MEM * sizeof(float))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n")); + } + + set_f(st_ivas->mem_hp20_out[sce_id], 0.0f, L_HP20_MEM); + } + + + /* Initialize the needed renderer struct and destroy the unnecessary renderer struct */ + + /* select the renderer */ + ivas_renderer_select(st_ivas); + ivas_output_init(&(st_ivas->hIntSetup), st_ivas->intern_config); + if ((st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC) && (st_ivas->ism_mode == ISM_MODE_DISC)) + { + ivas_output_init(&(st_ivas->hIntSetup), st_ivas->hDecoderConfig->output_config); + } + + if (st_ivas->ism_mode != last_ism_mode) + { + /* EFAP handle */ + efap_free_data(&st_ivas->hEFAPdata); + } + + if (st_ivas->ism_mode == ISM_MODE_DISC && last_ism_mode == ISM_MODE_PARAM) + { + /* switching from ParamISM to DiscISM */ + + /* close the ParamISM struct */ + if (st_ivas->hDirAC != NULL) + { + ivas_param_ism_dec_close(st_ivas->hDirAC, st_ivas->hDecoderConfig->output_config); + st_ivas->hDirAC = NULL; + } + + if (st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL) + { + /* close the parametric binaural renderer */ + ivas_dirac_dec_close_binaural_data(&st_ivas->hDiracDecBin); + + /* Open the TD Binaural renderer */ + ivas_td_binaural_open(st_ivas); + } + else + { + /* close the ISM renderer and reinitialize */ + if (st_ivas->hIsmRendererData != NULL) + { + count_free(st_ivas->hIsmRendererData); + st_ivas->hIsmRendererData = NULL; + } + ivas_ism_renderer_open(st_ivas); + } + + if (st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM) + { + /* close the parametric binaural renderer */ + ivas_dirac_dec_close_binaural_data(&st_ivas->hDiracDecBin); + + /* Open Crend Binaural renderer */ + ivas_crend_open(st_ivas); + } + } + + if (st_ivas->ism_mode == ISM_MODE_PARAM && last_ism_mode == ISM_MODE_DISC) + { + /* switching from DiscISM to ParamISM */ + + /* Initialize the ParamISM struct */ + ivas_param_ism_dec_open(st_ivas); + + if (st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL) + { + /* open the parametric binaural renderer */ + ivas_dirac_dec_init_binaural_data(st_ivas); + + /* Close the TD Binaural renderer */ + if (st_ivas->hBinRendererTd != NULL) + { + ivas_td_binaural_close(&st_ivas->hBinRendererTd); + } + + if (st_ivas->hHrtfTD != NULL) + { + st_ivas->hHrtfTD = NULL; + } + } + else + { + /* Close the ISM renderer */ + if (st_ivas->hIsmRendererData != NULL) + { + count_free(st_ivas->hIsmRendererData); + st_ivas->hIsmRendererData = NULL; + } + } + + if (st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM) + { + /* open the parametric binaural renderer */ + ivas_dirac_dec_init_binaural_data(st_ivas); + + /* close the crend binaural renderer */ + ivas_crend_close(st_ivas); + + if (st_ivas->hHrtf != NULL) + { + st_ivas->hHrtf = NULL; + } + } + + } + + return error; +} +#endif + /*------------------------------------------------------------------------- * ivas_ism_dec_config() * @@ -1019,13 +1220,24 @@ ivas_error ivas_ism_dec_config( int32_t ivas_total_brate; ISM_MODE last_ism_mode; ivas_error error; +#ifdef ISM_BITRATE_SWITCHING + int16_t last_nchan_trans; +#endif error = IVAS_ERR_OK; ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; /* store last frame ISM mode */ - last_ism_mode = st_ivas->ism_mode; + last_ism_mode = st_ivas->ism_mode; +#ifdef ISM_BITRATE_SWITCHING + /* Assumes that num of input objects are constant */ + last_nchan_trans = num_obj; + if (last_ism_mode == ISM_MODE_PARAM) + { + last_nchan_trans = 2; + } +#endif if ( !st_ivas->bfi && ivas_total_brate != IVAS_SID_5k2 && ivas_total_brate != FRAME_NO_DATA ) { @@ -1044,18 +1256,31 @@ ivas_error ivas_ism_dec_config( if ( st_ivas->ini_active_frame != 0 ) { +#ifdef ISM_BITRATE_SWITCHING + /* ISM format/bitrate switching */ + if ((st_ivas->hDecoderConfig->last_ivas_total_brate != IVAS_SID_5k2) && (st_ivas->hDecoderConfig->last_ivas_total_brate != FRAME_NO_DATA)) + { + if ((st_ivas->ism_mode != last_ism_mode) || (st_ivas->hDecoderConfig->ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate)) + { + ivas_ism_format_bitrate_switching(st_ivas, last_nchan_trans, last_ism_mode, num_obj); + st_ivas->nSCE = st_ivas->nchan_transport; + } + } +#else /* ISM format switching */ if ( st_ivas->ism_mode != last_ism_mode ) { /*ivas_ism_dec_reconfigure( st_ivas );*/ return IVAS_ERROR( IVAS_ERR_RECONFIGURE_NOT_SUPPORTED, "\n\n!!! Error: ISM format switching not supported yet!!!\n\n" ); } +#endif } } else if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_5k2 ) { st_ivas->nchan_transport = num_obj; } + switch ( num_obj ) { case 1: diff --git a/lib_enc/ivas_ism_param_enc.c b/lib_enc/ivas_ism_param_enc.c index e515f7e204a4311457456a4b1bf68bb0ceaaf567..e8a23d6b39f512c4b02856d35f056182d7804e7b 100644 --- a/lib_enc/ivas_ism_param_enc.c +++ b/lib_enc/ivas_ism_param_enc.c @@ -415,20 +415,156 @@ ivas_error ivas_ism_enc_config( { ivas_error error; ISM_MODE last_ism_mode; +#ifdef ISM_BITRATE_SWITCHING + int16_t last_nSCE; + int16_t sce_id, n; +#endif error = IVAS_ERR_OK; last_ism_mode = st_ivas->ism_mode; +#ifdef ISM_BITRATE_SWITCHING + last_nSCE = st_ivas->nSCE; +#endif /* select ISM format mode */ st_ivas->ism_mode = ivas_ism_mode_select( st_ivas->hEncoderConfig->nchan_inp, st_ivas->hEncoderConfig->ivas_total_brate ); +#ifdef ISM_BITRATE_SWITCHING + /* ISM format switching */ + if ( (st_ivas->ism_mode != last_ism_mode) || (st_ivas->hEncoderConfig->ivas_total_brate != st_ivas->hEncoderConfig->last_ivas_total_brate) ) + { + int32_t element_brate_tmp[MAX_NUM_OBJECTS]; + Indice *ind_list_sce; /* list of indices */ + Indice *ind_list_metadata; /* list of indices */ + + /* Reset and Initialize */ + if (st_ivas->ism_mode == ISM_MODE_PARAM) + { + st_ivas->nchan_transport = 2; + } + else + { + st_ivas->nchan_transport = st_ivas->hEncoderConfig->nchan_inp; + } + + st_ivas->nSCE = st_ivas->nchan_transport; + st_ivas->nCPE = 0; + + ivas_ism_config(st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hEncoderConfig->nchan_inp, NULL, NULL, NULL, element_brate_tmp, NULL, NULL); + + if (st_ivas->nSCE > last_nSCE) + { + /* Reconfigure the core coders */ + for (sce_id = 0; sce_id < last_nSCE; sce_id++) + { + copy_encoder_config(st_ivas, st_ivas->hSCE[sce_id]->hCoreCoder[0], 0); + st_ivas->hSCE[sce_id]->element_brate = st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport; + st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ + } + + /* Initialize the extra required memory */ + ind_list_sce = st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->ind_list; + ind_list_metadata = st_ivas->hSCE[0]->hMetaData->ind_list; + + for (sce_id = last_nSCE; sce_id < st_ivas->nSCE; sce_id++) + { + /* Initialize the Core Coder */ + if ((error = create_sce_enc(st_ivas, sce_id, element_brate_tmp[sce_id])) != IVAS_ERR_OK) + { + return error; + } + + /* prepare bitstream buffers */ + st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr->ind_list = ind_list_sce + (sce_id * MAX_NUM_INDICES); + reset_indices_enc(st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr, MAX_NUM_INDICES); + + st_ivas->hSCE[sce_id]->hMetaData->ind_list = ind_list_metadata + (sce_id * MAX_BITS_METADATA); + reset_indices_enc(st_ivas->hSCE[sce_id]->hMetaData, MAX_BITS_METADATA); + } + } + else + { + /* Reconfigure the Core Coders */ + for (sce_id = 0; sce_id < st_ivas->nSCE; sce_id++) + { + copy_encoder_config(st_ivas, st_ivas->hSCE[sce_id]->hCoreCoder[0], 0); + st_ivas->hSCE[sce_id]->element_brate = st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport; + st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ + } + + /* Delete the extra memory */ + for (sce_id = st_ivas->nSCE; sce_id < last_nSCE; sce_id++) + { + if (st_ivas->hSCE[sce_id] != NULL) + { + destroy_sce_enc(st_ivas->hSCE[sce_id]); + st_ivas->hSCE[sce_id] = NULL; + } + } + } + + if ((st_ivas->ism_mode == ISM_MODE_PARAM) && (last_ism_mode == ISM_MODE_DISC)) + { + /* Initialize the memory used by ParamISM when switch to Param ISM from Disc ISM */ + if ((error = ivas_param_ism_enc_open(st_ivas)) != IVAS_ERR_OK) + { + return error; + } + } + + if ((st_ivas->ism_mode == ISM_MODE_DISC) && (last_ism_mode == ISM_MODE_PARAM)) + { + /* Reset the memory used by ParamISM when switch to Disc ISM */ + ivas_param_ism_enc_close(st_ivas->hDirAC, st_ivas->hEncoderConfig->input_Fs); + } + + /* destroy the memory of hp20*/ + if (st_ivas->mem_hp20_in != NULL) + { + for (sce_id = 0; sce_id < last_nSCE; sce_id++) + { + count_free(st_ivas->mem_hp20_in[sce_id]); + st_ivas->mem_hp20_in[sce_id] = NULL; + } + count_free(st_ivas->mem_hp20_in); + st_ivas->mem_hp20_in = NULL; + } + + /* re initialize the memory of hp20 */ + /* set number of input channels used for analysis/coding */ + n = getNumChanAnalysis(st_ivas); + + if (n > 0) + { + if ((st_ivas->mem_hp20_in = (float **)count_malloc(n * sizeof(float *))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n")); + } + } + else + { + st_ivas->mem_hp20_in = NULL; + } + + for (sce_id = 0; sce_id < n; sce_id++) + { + if ((st_ivas->mem_hp20_in[sce_id] = (float *)count_malloc(L_HP20_MEM * sizeof(float))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n")); + } + + set_f(st_ivas->mem_hp20_in[sce_id], 0.0f, L_HP20_MEM); + } + } +#else /* ISM format switching */ if ( st_ivas->ism_mode != last_ism_mode ) { /*ivas_ism_dec_reconfigure( st_ivas );*/ return IVAS_ERROR( IVAS_ERR_RECONFIGURE_NOT_SUPPORTED, "Error: ISM format switching not supported yet!!!\n\n" ); } +#endif return error; }