diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 8121030b1cc0ab67501bcbcfef1eb162098942ac..01bbfe77540fc6ce56a1c33a2241cd02b88382a5 100755 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -308,8 +308,14 @@ ivas_error ivas_init_decoder( ivas_error ivas_output_buff_dec( float *p_output_f[], /* i/o: output audio buffers */ +#ifdef FIX_1330_JBM_MEMORY + const int16_t nchan_out_buff, /* i : number of output channels */ + const int16_t Opt_tsm, /* i : TSM option flag */ + DECODER_TC_BUFFER_HANDLE hTcBuffer /* i : TSM buffer handle */ +#else const int16_t nchan_out_buff_old, /* i : previous frame number of output channels*/ const int16_t nchan_out_buff /* i : number of output channels */ +#endif ); ivas_error stereo_dmx_evs_init_encoder( @@ -5823,8 +5829,12 @@ void ivas_omasa_separate_object_render_jbm( const uint16_t nSamplesRendered, /* i : number of samples rendered */ float input_f[][L_FRAME48k], /* i : separated object signal */ float *output_f[], /* o : rendered time signal */ +#ifdef FIX_1330_JBM_MEMORY + const int16_t subframes_rendered /* i : number of subframes rendered */ +#else const int16_t subframes_rendered, /* i : number of subframes rendered */ const int16_t slots_rendered /* i : number of CLDFB slots rendered */ +#endif ); void ivas_omasa_encode_masa_to_total( diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index baa98da6b747e44db3de6083e908ad65c5c7f26f..b63a923a1b0678e4608e2ffa196e6185a62a9ba4 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -198,12 +198,24 @@ void ivas_buffer_deinterleaved_to_interleaved( ) { int16_t ch, m; +#ifdef FIX_1330_JBM_MEMORY + float buffer[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][L_FRAME48k]; /* temp buffer needed when "*audio[]" and "*audio_out[]" are the same */ + + for ( ch = 0; ch < n_channels; ch++ ) + { + mvr2r( audio[ch], buffer[ch], frame_length ); + } +#endif for ( ch = 0; ch < n_channels; ch++ ) { for ( m = 0; m < frame_length; m++ ) { +#ifdef FIX_1330_JBM_MEMORY + audio_out[m * n_channels + ch] = buffer[ch][m]; +#else audio_out[m * n_channels + ch] = audio[ch][m]; +#endif } } diff --git a/lib_com/options.h b/lib_com/options.h index 32c2722e32967161a6223c4ef0ec5d2dddf7d4fc..7dd1b43a0e20557dad6ebdd57944492f72316bf2 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -166,6 +166,7 @@ #define FIX_1348_OVERFLOW /* FhG: fix BASOP overflow in hq_lr_dec(), brings floating-point code inline with FX */ #define FIX_1369_HQ_LR_OVERFLOW /* FhG: fix BASOP overflow in hq_lr_enc(), brings floating-point code inline with FX */ #define FIX_1376_MISSING_ISM_METADATA /* FhG: IVAS_rend: throw error if there exists an ISM input without a corresponding metadata file path */ +#define FIX_1330_JBM_MEMORY /* VA: issue 1330: memory savings in the JBM decoder */ /* #################### End BE switches ################################## */ diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 6a066e954be9eff4664560156a7257580d02dba2..5989880c14c64d8efdbb22c7589c22d986a3c8ab 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1252,6 +1252,9 @@ ivas_error ivas_init_decoder( int16_t sce_id, cpe_id; int16_t numCldfbAnalyses, numCldfbSyntheses; int16_t granularity, n_channels_transport_jbm; +#ifdef FIX_1330_JBM_MEMORY + int16_t nchan_out_buff; +#endif int32_t output_Fs, ivas_total_brate; int32_t delay_ns; AUDIO_CONFIG output_config; @@ -2371,7 +2374,7 @@ ivas_error ivas_init_decoder( } } - if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) && st_ivas->hDecoderConfig->Opt_tsm ) + if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) && hDecoderConfig->Opt_tsm ) { if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) { @@ -2386,7 +2389,14 @@ ivas_error ivas_init_decoder( * Allocate floating-point output audio buffers *-----------------------------------------------------------------*/ - k = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); +#ifdef FIX_1330_JBM_MEMORY + nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, ivas_total_brate ); + if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff, hDecoderConfig->Opt_tsm, st_ivas->hTcBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } +#else + k = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, ivas_total_brate ); for ( n = 0; n < k; n++ ) { /* note: these are intra-frame heap memories */ @@ -2400,9 +2410,9 @@ ivas_error ivas_init_decoder( { st_ivas->p_output_f[n] = NULL; } +#endif - - return error; + return IVAS_ERR_OK; } @@ -2857,12 +2867,14 @@ void ivas_destroy_dec( /* Limiter struct */ ivas_limiter_close( &( st_ivas->hLimiter ) ); + /* Decoder configuration structure */ if ( st_ivas->hDecoderConfig != NULL ) { free( st_ivas->hDecoderConfig ); st_ivas->hDecoderConfig = NULL; } + /* JBM TC buffer structure */ ivas_jbm_dec_tc_buffer_close( &st_ivas->hTcBuffer ); if ( st_ivas->hJbmMetadata != NULL ) @@ -2871,14 +2883,18 @@ void ivas_destroy_dec( st_ivas->hJbmMetadata = NULL; } - /* floating-point output audio buffers */ + /* floating-point output audio buffers */ for ( i = 0; i < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; i++ ) { +#ifdef FIX_1330_JBM_MEMORY + st_ivas->p_output_f[i] = NULL; +#else if ( st_ivas->p_output_f[i] != NULL ) { free( st_ivas->p_output_f[i] ); st_ivas->p_output_f[i] = NULL; } +#endif } /* main IVAS handle */ diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index a76db363061b54ef55b49b11622d8385fc4c75b6..6e46c4b89d73bcc378a4d55843d62ac47b2bfebf 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -60,7 +60,11 @@ static ivas_error ivas_ism_bitrate_switching_dec( int16_t tc_nchan_tc_new; int16_t tc_nchan_allocate_new; int16_t tc_granularity_new; +#ifdef FIX_1330_JBM_MEMORY + int16_t nchan_out_buff; +#else int16_t nchan_out_buff, nchan_out_buff_old; +#endif nCPE_old = st_ivas->nCPE; nSCE_old = st_ivas->nSCE; @@ -70,7 +74,9 @@ static ivas_error ivas_ism_bitrate_switching_dec( st_ivas->ism_mode = last_ism_mode; ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); st_ivas->ism_mode = ism_mode; +#ifndef FIX_1330_JBM_MEMORY nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); +#endif if ( ( error = ivas_ism_config( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->nchan_ism, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 0 ) ) != IVAS_ERR_OK ) { @@ -266,17 +272,17 @@ static ivas_error ivas_ism_bitrate_switching_dec( return error; } +#ifndef FIX_1330_JBM_MEMORY /*-----------------------------------------------------------------* * floating-point output audio buffers *-----------------------------------------------------------------*/ nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); - if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) { return error; } - +#endif /*-----------------------------------------------------------------* * JBM TC buffers *-----------------------------------------------------------------*/ @@ -316,6 +322,18 @@ static ivas_error ivas_ism_bitrate_switching_dec( mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpatParamRendCom->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); } +#ifdef FIX_1330_JBM_MEMORY + + /*-----------------------------------------------------------------* + * floating-point output audio buffers + *-----------------------------------------------------------------*/ + + nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); + if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff, st_ivas->hDecoderConfig->Opt_tsm, st_ivas->hTcBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif return IVAS_ERR_OK; } diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 3d18fea93b13f45ab00e930f7abe4e60bde6689c..55a77e0ba8bf0c2db24fb5579614b90b093eeda3 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -193,6 +193,7 @@ void ivas_ism_render_sf( ism_md_subframe_update_jbm = st_ivas->hTcBuffer->nb_subframes - 2; } +#ifndef FIX_1330_JBM_MEMORY if ( st_ivas->hDecoderConfig->Opt_tsm ) { for ( i = 0; i < num_objects; i++ ) @@ -202,12 +203,15 @@ void ivas_ism_render_sf( } else { +#endif for ( i = 0; i < num_objects; i++ ) { mvr2r( &output_f[i][tc_offset], tc_local[i], n_samples_to_render ); p_tc[i] = tc_local[i]; } +#ifndef FIX_1330_JBM_MEMORY } +#endif for ( i = 0; i < nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; i++ ) { @@ -428,12 +432,16 @@ void ivas_omasa_separate_object_renderer_close( *-------------------------------------------------------------------------*/ void ivas_omasa_separate_object_render_jbm( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const uint16_t nSamplesRendered, /* i : number of samples rendered */ - float input_f_in[][L_FRAME48k], /* i : separated object signal */ - float *output_f[], /* o : rendered time signal */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const uint16_t nSamplesRendered, /* i : number of samples rendered */ + float input_f_in[][L_FRAME48k], /* i : separated object signal */ + float *output_f[], /* o : rendered time signal */ +#ifdef FIX_1330_JBM_MEMORY + const int16_t subframes_rendered /* i : number of subframes rendered */ +#else const int16_t subframes_rendered, /* i : number of subframes rendered */ const int16_t slots_rendered /* i : number of CLDFB slots rendered */ +#endif ) { VBAP_HANDLE hVBAPdata; @@ -474,13 +482,16 @@ void ivas_omasa_separate_object_render_jbm( num_objects = st_ivas->nchan_ism; } +#ifndef FIX_1330_JBM_MEMORY offsetSamples = slots_rendered * hSpatParamRendCom->slot_size; +#endif for ( j = 0; j < nchan_out_woLFE + num_lfe; j++ ) { output_f_local[j] = output_f[j]; } +#ifndef FIX_1330_JBM_MEMORY if ( st_ivas->hDecoderConfig->Opt_tsm ) { for ( obj = 0; obj < num_objects; obj++ ) @@ -490,11 +501,14 @@ void ivas_omasa_separate_object_render_jbm( } else { +#endif for ( obj = 0; obj < num_objects; obj++ ) { input_f[obj] = input_f_in[obj]; } +#ifndef FIX_1330_JBM_MEMORY } +#endif slots_to_render = nSamplesRendered / hSpatParamRendCom->slot_size; first_sf = subframes_rendered; diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 3caeb116035b4b4d7845a2f5e7d1fabfc9209e30..711d6a6e380d49cb8a7f5128c2953cbf8461206a 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -763,7 +763,11 @@ void ivas_jbm_dec_feed_tc_to_renderer( float tmp_buf[MAX_JBM_L_FRAME48k]; float *p_data_f[FOA_CHANNELS + MAX_NUM_OBJECTS]; int16_t n, n_render_timeslots, n_ch_cldfb; +#ifdef FIX_1330_JBM_MEMORY + int16_t ch, offset, len_offset; +#else int16_t ch; +#endif DECODER_TC_BUFFER_HANDLE hTcBuffer; hTcBuffer = st_ivas->hTcBuffer; @@ -781,6 +785,22 @@ void ivas_jbm_dec_feed_tc_to_renderer( n_ch_full_copy = min( hTcBuffer->nchan_transport_jbm, hTcBuffer->nchan_buffer_full ); n_ch_res_copy = hTcBuffer->nchan_transport_jbm - hTcBuffer->nchan_buffer_full; +#ifdef FIX_1330_JBM_MEMORY + /* buffers are shared between 'hTcBuffer->tc[]' and 'p_output_f[]': + in case of 'length(hTcBuffer->tc[]) < length(p_output_f[])', reset of TC buffers + pointers is needed after ivas_buffer_interleaved_to_deinterleaved() */ + len_offset = NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ); + if ( len_offset < L_FRAME48k ) + { + offset = 0; + for ( ch = 0; ch < max( hTcBuffer->nchan_transport_jbm, hTcBuffer->nchan_buffer_full ); ch++ ) + { + hTcBuffer->tc[ch] = &hTcBuffer->tc_buffer[offset]; + offset += len_offset; + } + } + +#endif for ( ch = 0; ch < n_ch_full_copy; ch++ ) { mvr2r( hTcBuffer->tc[ch], tmp_buf, nSamplesForRendering ); @@ -2086,6 +2106,9 @@ static ivas_error ivas_jbm_dec_tc_audio_allocate( if ( Opt_tsm ) { n_samp_full = ( NS2SA( output_Fs, MAX_JBM_L_FRAME_NS ) ); +#ifdef FIX_1330_JBM_MEMORY + n_samp_full = max( n_samp_full, L_FRAME48k ); /* buffers are shared between 'hTcBuffer->tc[]' and 'p_output_f[]': ensure minimal length */ +#endif n_samp_residual = hTcBuffer->n_samples_granularity - 1; } else @@ -2145,6 +2168,10 @@ static ivas_error ivas_jbm_dec_tc_audio_allocate( } } +#ifdef FIX_1330_JBM_MEMORY + hTcBuffer->tc_buffer2 = NULL; + +#endif return IVAS_ERR_OK; } @@ -2182,6 +2209,14 @@ static void ivas_jbm_dec_tc_audio_deallocate( hTcBuffer->tc_buffer_old[ch_idx] = NULL; } } +#ifdef FIX_1330_JBM_MEMORY + + if ( hTcBuffer->tc_buffer2 != NULL ) + { + free( hTcBuffer->tc_buffer2 ); + hTcBuffer->tc_buffer2 = NULL; + } +#endif } return; @@ -2378,7 +2413,11 @@ static void ivas_jbm_dec_tc_buffer_playout( for ( ch_idx = 0; ch_idx < st_ivas->hTcBuffer->nchan_transport_jbm; ch_idx++ ) { +#ifdef FIX_1330_JBM_MEMORY + output[ch_idx] = st_ivas->hTcBuffer->tc[ch_idx] + st_ivas->hTcBuffer->n_samples_rendered; +#else mvr2r( st_ivas->hTcBuffer->tc[ch_idx] + st_ivas->hTcBuffer->n_samples_rendered, output[ch_idx], *nSamplesRendered ); +#endif } st_ivas->hTcBuffer->subframes_rendered = last_sf; diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index b698395d75f7b4a5b55d52d6c09e34f86a1f8ad1..6886d550a88be0c29f38b1925c5779c33ac351b4 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -1320,7 +1320,11 @@ ivas_error ivas_masa_dec_reconfigure( Decoder_State **sts; int32_t ivas_total_brate, last_ivas_total_brate; int16_t numCldfbAnalyses_old, numCldfbSyntheses_old; +#ifdef FIX_1330_JBM_MEMORY + int16_t nchan_out_buff; +#else int16_t nchan_out_buff_old, nchan_out_buff; +#endif ivas_error error; int16_t pos_idx; int32_t ism_total_brate; @@ -1328,8 +1332,10 @@ ivas_error ivas_masa_dec_reconfigure( ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; last_ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate; +#ifndef FIX_1330_JBM_MEMORY nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); +#endif /* Copy state to TC buffer if granularity matches and we are not in OMASA EXT rendering mode */ if ( st_ivas->hSpatParamRendCom != NULL && st_ivas->hSpatParamRendCom->slot_size == st_ivas->hTcBuffer->n_samples_granularity && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) { @@ -1474,6 +1480,10 @@ ivas_error ivas_masa_dec_reconfigure( ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &tmp, &tmp, &tmp, st_ivas->ivas_format, st_ivas->ism_mode, ism_total_brate ); + /*-----------------------------------------------------------------* + * JBM TC buffers + *-----------------------------------------------------------------*/ + { int16_t tc_nchan_to_allocate; int16_t tc_nchan_transport; @@ -1544,7 +1554,11 @@ ivas_error ivas_masa_dec_reconfigure( if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->last_ivas_format == MASA_FORMAT ) /* note: switching with OMASA is addressed in ivas_omasa_dec_config() */ { nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); +#ifdef FIX_1330_JBM_MEMORY + if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff, st_ivas->hDecoderConfig->Opt_tsm, st_ivas->hTcBuffer ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) +#endif { return error; } diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index ddc86592d1423d56c7e5da5826c2af1a18e336c7..84bf52456d17ed8c792100c0a10a3a2d7ada565d 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -732,11 +732,17 @@ static ivas_error ivas_mc_dec_reconfig( int16_t tc_nchan_tc_new; int16_t tc_nchan_allocate_new; int16_t tc_granularity_new; +#ifdef FIX_1330_JBM_MEMORY + int16_t nchan_out_buff; +#else int16_t nchan_out_buff_old, nchan_out_buff; +#endif ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; nchan_transport_old = st_ivas->nchan_transport; +#ifndef FIX_1330_JBM_MEMORY nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); +#endif last_mc_mode = ivas_mc_mode_select( ivas_mc_map_output_config_to_mc_ls_setup( st_ivas->transport_config ), st_ivas->hDecoderConfig->last_ivas_total_brate ); /* NB: this assumes that LS config remains the same between frames */ /* temporally set the current mc_mode back to the previous one to make sure the following call to @@ -1341,6 +1347,7 @@ static ivas_error ivas_mc_dec_reconfig( return error; } } + /* transfer subframe info from central tc buffer to ParamMC or McMASA (DirAC) */ if ( st_ivas->hSpatParamRendCom != NULL ) { @@ -1365,8 +1372,11 @@ static ivas_error ivas_mc_dec_reconfig( *-----------------------------------------------------------------*/ nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); - +#ifdef FIX_1330_JBM_MEMORY + if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff, st_ivas->hDecoderConfig->Opt_tsm, st_ivas->hTcBuffer ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) +#endif { return error; } diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index beaf645fa0d1bfad365e0136c0f1025bd71ab945..628d6b4d2474718c6a7a8ec676215e6ff1dcfb93 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -200,7 +200,11 @@ ivas_error ivas_omasa_dec_config( int32_t ivas_total_brate, ism_total_brate, cpe_brate; ISM_MODE ism_mode_old; IVAS_FORMAT ivas_format_orig; +#ifdef FIX_1330_JBM_MEMORY + int16_t nchan_out_buff; +#else int16_t nchan_out_buff, nchan_out_buff_old; +#endif ivas_error error; RENDERER_TYPE old_renderer_type; @@ -215,8 +219,9 @@ ivas_error ivas_omasa_dec_config( ivas_format_orig = st_ivas->ivas_format; st_ivas->ivas_format = st_ivas->last_ivas_format; ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); +#ifndef FIX_1330_JBM_MEMORY nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); - +#endif st_ivas->ivas_format = ivas_format_orig; nSCE_old = st_ivas->nSCE; @@ -470,7 +475,11 @@ ivas_error ivas_omasa_dec_config( *-----------------------------------------------------------------*/ nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); +#ifdef FIX_1330_JBM_MEMORY + if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff, st_ivas->hDecoderConfig->Opt_tsm, st_ivas->hTcBuffer ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -673,19 +682,27 @@ void ivas_omasa_dirac_rend_jbm( ) { int16_t subframes_rendered; +#ifndef FIX_1330_JBM_MEMORY int16_t slots_rendered; +#endif int16_t n; float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k]; +#ifndef FIX_1330_JBM_MEMORY if ( !st_ivas->hDecoderConfig->Opt_tsm ) { +#endif *nSamplesRendered = min( nSamplesAsked, st_ivas->hTcBuffer->n_samples_available ); if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) { mvr2r( &output_f[CPE_CHANNELS][st_ivas->hTcBuffer->n_samples_rendered], data_separated_objects[0], *nSamplesRendered ); - if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) +#ifdef FIX_1330_JBM_MEMORY + if ( !st_ivas->hDecoderConfig->Opt_tsm && st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) +#else + if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) +#endif { /* Gain separated object, if edited */ for ( n = 0; n < st_ivas->nchan_ism; n++ ) @@ -704,14 +721,22 @@ void ivas_omasa_dirac_rend_jbm( mvr2r( &output_f[n + CPE_CHANNELS][st_ivas->hTcBuffer->n_samples_rendered], data_separated_objects[n], *nSamplesRendered ); /* Gain discrete objects, if edited */ - if ( st_ivas->hMasaIsmData->ism_gain_is_edited[n] ) +#ifdef FIX_1330_JBM_MEMORY + if ( !st_ivas->hDecoderConfig->Opt_tsm && st_ivas->hMasaIsmData->ism_gain_is_edited[n] ) +#else + if ( st_ivas->hMasaIsmData->ism_gain_is_edited[n] ) +#endif { v_multc( data_separated_objects[n], st_ivas->hMasaIsmData->gain_ism_edited[n], data_separated_objects[n], *nSamplesRendered ); } } /* Gain MASA part, if edited */ - if ( st_ivas->hMasaIsmData->masa_gain_is_edited ) +#ifdef FIX_1330_JBM_MEMORY + if ( !st_ivas->hDecoderConfig->Opt_tsm && st_ivas->hMasaIsmData->masa_gain_is_edited ) +#else + if ( st_ivas->hMasaIsmData->masa_gain_is_edited ) +#endif { for ( int16_t ch = 0; ch < 2; ch++ ) { @@ -719,14 +744,22 @@ void ivas_omasa_dirac_rend_jbm( } } } +#ifndef FIX_1330_JBM_MEMORY } +#endif subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered; +#ifndef FIX_1330_JBM_MEMORY slots_rendered = st_ivas->hSpatParamRendCom->slots_rendered; +#endif ivas_dirac_dec_render( st_ivas, nchan_transport, nSamplesAsked, nSamplesRendered, nSamplesAvailable, output_f ); +#ifdef FIX_1330_JBM_MEMORY + ivas_omasa_separate_object_render_jbm( st_ivas, *nSamplesRendered, data_separated_objects, output_f, subframes_rendered ); +#else ivas_omasa_separate_object_render_jbm( st_ivas, *nSamplesRendered, data_separated_objects, output_f, subframes_rendered, slots_rendered ); +#endif return; } diff --git a/lib_dec/ivas_osba_dec.c b/lib_dec/ivas_osba_dec.c index 17d084520437bd598ce2faa86e7bf438de5e3296..a3ff4aa5df1b7eeacfa5c474ae635a2d0ad857db 100644 --- a/lib_dec/ivas_osba_dec.c +++ b/lib_dec/ivas_osba_dec.c @@ -258,15 +258,25 @@ ivas_error ivas_osba_render_sf( ) { int16_t n; +#ifdef FIX_1330_JBM_MEMORY + float output_sba[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float *p_output_sba[MAX_OUTPUT_CHANNELS]; +#else float output_ism[MAX_OUTPUT_CHANNELS][L_FRAME48k]; float *p_output_ism[MAX_OUTPUT_CHANNELS]; +#endif ivas_error error; for ( n = 0; n < MAX_OUTPUT_CHANNELS; n++ ) { +#ifdef FIX_1330_JBM_MEMORY + p_output_sba[n] = output_sba[n]; +#else p_output_ism[n] = &output_ism[n][0]; +#endif } +#ifndef FIX_1330_JBM_MEMORY if ( !st_ivas->hDecoderConfig->Opt_tsm ) { int16_t tc_offset; @@ -276,23 +286,42 @@ ivas_error ivas_osba_render_sf( mvr2r( &p_output[n][tc_offset], &output_ism[n][tc_offset], nSamplesAsked ); } } +#endif +#ifdef FIX_1330_JBM_MEMORY + if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailableNext, p_output_sba ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK ) +#endif { return error; } if ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV_ROOM ) { +#ifdef FIX_1330_JBM_MEMORY + ivas_ism_render_sf( st_ivas, st_ivas->renderer_type, p_output, *nSamplesRendered ); +#else ivas_ism_render_sf( st_ivas, st_ivas->renderer_type, p_output_ism, *nSamplesRendered ); +#endif } for ( n = 0; n < st_ivas->hDecoderConfig->nchan_out; n++ ) { if ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV_ROOM ) { +#ifdef FIX_1330_JBM_MEMORY + v_add( p_output[n], p_output_sba[n], p_output[n], *nSamplesRendered ); +#else v_add( p_output[n], p_output_ism[n], p_output[n], *nSamplesRendered ); +#endif + } +#ifdef FIX_1330_JBM_MEMORY + else + { + mvr2r( p_output_sba[n], p_output[n], *nSamplesRendered ); } +#endif } return IVAS_ERR_OK; diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 8ddc7f040616d8de7d70a4e2372ebf531c174cdd..abeb19243d216eebc158c4bbbcfc79f0812e9a6a 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -111,8 +111,12 @@ ivas_error ivas_sba_dec_reconfigure( int32_t ivas_total_brate; int32_t last_ivas_total_brate; int16_t num_channels, num_md_sub_frames; +#ifdef FIX_1330_JBM_MEMORY + int16_t nchan_out_buff; +#else int16_t nchan_out_buff, nchan_out_buff_old; int16_t sba_analysis_order_old_flush; +#endif DECODER_CONFIG_HANDLE hDecoderConfig; ivas_error error; ISM_MODE ism_mode_old; @@ -123,15 +127,18 @@ ivas_error ivas_sba_dec_reconfigure( hDecoderConfig = st_ivas->hDecoderConfig; ivas_total_brate = hDecoderConfig->ivas_total_brate; last_ivas_total_brate = st_ivas->last_active_ivas_total_brate; +#ifndef FIX_1330_JBM_MEMORY sba_analysis_order_old_flush = st_ivas->sba_analysis_order; +#endif /*-----------------------------------------------------------------* * Set SBA high-level parameters * Save old SBA high-level parameters *-----------------------------------------------------------------*/ +#ifndef FIX_1330_JBM_MEMORY nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, sba_analysis_order_old_flush, last_ivas_total_brate ); - +#endif ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); nchan_hp20_old = getNumChanSynthesis( st_ivas ); @@ -591,8 +598,11 @@ ivas_error ivas_sba_dec_reconfigure( *-----------------------------------------------------------------*/ nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); - +#ifdef FIX_1330_JBM_MEMORY + if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff, hDecoderConfig->Opt_tsm, st_ivas->hTcBuffer ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) +#endif { return error; } diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index f7cac7160b1f21274101478f6da94f1c4c51e5c2..b93bb8bf562e147286c596a15a933ef7b10de749 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -964,6 +964,10 @@ typedef struct decoder_tc_buffer_structure int16_t num_slots; int16_t n_samples_discard; /* number of samples to discard from the beginning of the output */ +#ifdef FIX_1330_JBM_MEMORY + float *tc_buffer2; /* non-scaled buffer of output audio - needed only when '*tc_buffer* is not long enough */ + +#endif } DECODER_TC_BUFFER, *DECODER_TC_BUFFER_HANDLE; typedef struct jbm_metadata_structure diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 560f9f66618709e0f7b59a0d53d04a7a495582dd..460bf182a3d0446c4ee0a43fa28b93850209f470 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -368,11 +368,76 @@ int16_t ivas_get_nchan_buffers_dec( *-------------------------------------------------------------------*/ ivas_error ivas_output_buff_dec( - float *p_output_f[], /* i/o: output audio buffers */ + float *p_output_f[], /* i/o: output audio buffers */ +#ifdef FIX_1330_JBM_MEMORY + const int16_t nchan_out_buff, /* i : number of output channels */ + const int16_t Opt_tsm, /* i : TSM option flag */ + DECODER_TC_BUFFER_HANDLE hTcBuffer /* i : TSM buffer handle */ +#else const int16_t nchan_out_buff_old, /* i : previous frame number of output channels */ const int16_t nchan_out_buff /* i : number of output channels */ +#endif ) { +#ifdef FIX_1330_JBM_MEMORY + int16_t ch, nchan_tc_jbm, nsamp_to_allocate, n_samp_full, offset; + + for ( ch = 0; ch < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; ch++ ) + { + p_output_f[ch] = NULL; + } + + if ( hTcBuffer->tc_buffer2 != NULL ) + { + free( hTcBuffer->tc_buffer2 ); + hTcBuffer->tc_buffer2 = NULL; + } + + nchan_tc_jbm = 0; + if ( Opt_tsm ) + { + /* JBM decoding: output audio buffers are shared with audio buffers from 'hTcBuffer->tc[]' */ + nchan_tc_jbm = max( hTcBuffer->nchan_transport_jbm, hTcBuffer->nchan_buffer_full ); + } + + if ( nchan_out_buff <= nchan_tc_jbm && !Opt_tsm ) + { + for ( ch = 0; ch < nchan_out_buff; ch++ ) + { + p_output_f[ch] = hTcBuffer->tc[ch]; + } + } + else + { + for ( ch = 0; ch < nchan_tc_jbm; ch++ ) + { + p_output_f[ch] = hTcBuffer->tc[ch]; + } + + /* non-JBM decoding: allocate output audio buffers */ + /* JBM decoding: when not enough audio buffers 'hTcBuffer->tc[]', allocate additional buffers */ + n_samp_full = ( 48000 / FRAMES_PER_SEC ); + nsamp_to_allocate = ( nchan_out_buff - nchan_tc_jbm ) * n_samp_full; + + if ( nsamp_to_allocate > 0 ) + { + /* note: these are intra-frame heap memories */ + if ( ( hTcBuffer->tc_buffer2 = (float *) malloc( nsamp_to_allocate * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) ); + } + + set_zero( hTcBuffer->tc_buffer2, nsamp_to_allocate ); + } + + offset = 0; + for ( ; ch < nchan_out_buff; ch++ ) + { + p_output_f[ch] = &hTcBuffer->tc_buffer2[offset]; + offset += n_samp_full; + } + } +#else int16_t ch; if ( nchan_out_buff > nchan_out_buff_old ) @@ -400,6 +465,7 @@ ivas_error ivas_output_buff_dec( p_output_f[ch] = NULL; } } +#endif return IVAS_ERR_OK; }