From da3b5b8b6b549915b25df4566fc5bf46befd45bb Mon Sep 17 00:00:00 2001 From: vaclav Date: Mon, 27 Oct 2025 15:00:46 +0100 Subject: [PATCH 1/2] port FIX_1330_JBM_MEMORY --- lib_com/ivas_prot.h | 10 ++++++ lib_com/ivas_tools.c | 12 +++++++ lib_com/options.h | 2 +- lib_dec/ivas_init_dec.c | 20 +++++++++-- lib_dec/ivas_ism_dec.c | 21 +++++++++++- lib_dec/ivas_ism_renderer.c | 23 ++++++++++--- lib_dec/ivas_jbm_dec.c | 39 +++++++++++++++++++++ lib_dec/ivas_masa_dec.c | 14 ++++++++ lib_dec/ivas_mct_dec.c | 12 ++++++- lib_dec/ivas_omasa_dec.c | 42 +++++++++++++++++++++-- lib_dec/ivas_osba_dec.c | 31 +++++++++++++++-- lib_dec/ivas_sba_dec.c | 14 ++++++-- lib_dec/ivas_stat_dec.h | 4 +++ lib_rend/ivas_output_init.c | 68 ++++++++++++++++++++++++++++++++++++- 14 files changed, 293 insertions(+), 19 deletions(-) diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 1a2710e21..b0f28fe85 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -319,8 +319,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 ); /*! r: flag to indicate if split rendering is enabled */ @@ -5868,8 +5874,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 2eff096da..6e66502dd 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -199,12 +199,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 6790fa9a9..6cb5c0465 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -196,7 +196,7 @@ #define FIX_1370_EXTERNAL_ORIENTATION_CHECK /* Nokia: add sanity check for Euler angles for external orientations */ #define NONBE_FIX_1197_OMASA_META_BUFFER /* Nokia: OMASA ISM_MASA_MODE_PARAM_ONE_OBJ history zero in rateswitching - port 251 */ #define FIX_1413_IGF_INIT_PRINTOUT /* FhG: use correct variable for IGF initiliazation */ - +#define FIX_1330_JBM_MEMORY /* VA: issue 1330: memory savings in the JBM decoder */ // object-editing feature porting #define FIX_HRTF_LOAD_API // solves API conflicts between HRTF and object-editing features diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 697eaa0c5..0a6205013 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1258,6 +1258,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; @@ -2413,7 +2416,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 ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) { @@ -2428,6 +2431,13 @@ ivas_error ivas_init_decoder( * Allocate floating-point output audio buffers *-----------------------------------------------------------------*/ +#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 #ifdef FIX_NCHAN_BUFFERS k = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); for ( n = 0; n < k; n++ ) @@ -2446,7 +2456,7 @@ ivas_error ivas_init_decoder( { st_ivas->p_output_f[n] = NULL; } - +#endif return error; } @@ -2916,14 +2926,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 cf77aae01..2f1176b55 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 ) { @@ -288,6 +294,7 @@ static ivas_error ivas_ism_bitrate_switching_dec( return error; } +#ifndef FIX_1330_JBM_MEMORY /*-----------------------------------------------------------------* * floating-point output audio buffers *-----------------------------------------------------------------*/ @@ -298,7 +305,7 @@ static ivas_error ivas_ism_bitrate_switching_dec( { return error; } - +#endif /*-----------------------------------------------------------------* * JBM TC buffers *-----------------------------------------------------------------*/ @@ -338,6 +345,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 b3c52a0ba..82fabafcf 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -194,6 +194,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++ ) @@ -203,12 +204,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++ ) { @@ -429,12 +433,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; @@ -475,13 +483,15 @@ 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++ ) @@ -491,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 ae20e268f..147d220c3 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -810,7 +810,11 @@ void ivas_jbm_dec_feed_tc_to_renderer( float *p_data_f[MAX_CLDFB_DIGEST_CHANNELS]; #endif 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; @@ -829,6 +833,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 ); @@ -2418,6 +2438,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 @@ -2477,6 +2500,10 @@ static ivas_error ivas_jbm_dec_tc_audio_allocate( } } +#ifdef FIX_1330_JBM_MEMORY + hTcBuffer->tc_buffer2 = NULL; + +#endif return IVAS_ERR_OK; } @@ -2514,6 +2541,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; @@ -2835,7 +2870,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 636739017..d2af98242 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -1327,7 +1327,11 @@ ivas_error ivas_masa_dec_reconfigure( int32_t ivas_total_brate, last_ivas_total_brate; int16_t numCldfbAnalyses_old, numCldfbSyntheses_old; #ifdef FIX_NCHAN_BUFFERS +#ifdef FIX_1330_JBM_MEMORY + int16_t nchan_out_buff; +#else int16_t nchan_out_buff_old, nchan_out_buff; +#endif #endif ivas_error error; int16_t pos_idx; @@ -1336,7 +1340,9 @@ 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; #ifdef FIX_NCHAN_BUFFERS +#ifndef FIX_1330_JBM_MEMORY nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); +#endif #endif /* Copy state to TC buffer if granularity matches and we are not in OMASA EXT rendering mode */ @@ -1483,6 +1489,9 @@ 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; @@ -1583,7 +1592,12 @@ 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 a9cbed3a9..748af9f16 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -733,11 +733,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 @@ -1361,6 +1367,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 ) { @@ -1386,8 +1393,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 43f102d12..b91ab08b2 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -197,7 +197,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; @@ -212,7 +216,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; @@ -468,7 +474,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; } @@ -672,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++ ) @@ -701,14 +719,24 @@ void ivas_omasa_dirac_rend_jbm( for ( n = 0; n < st_ivas->nchan_ism; n++ ) { 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++ ) { @@ -716,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 d85777ec7..7eb3d0735 100644 --- a/lib_dec/ivas_osba_dec.c +++ b/lib_dec/ivas_osba_dec.c @@ -307,15 +307,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; @@ -326,24 +336,41 @@ 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 a2e58a826..1096c72b6 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -111,7 +111,11 @@ 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; +#endif int16_t sba_analysis_order_old_flush; DECODER_CONFIG_HANDLE hDecoderConfig; ivas_error error; @@ -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 ); @@ -638,8 +645,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 cacc0bddd..a6cd97598 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -969,6 +969,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 93a4a17d7..3c27b8562 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -497,11 +497,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 ) @@ -531,6 +596,7 @@ ivas_error ivas_output_buff_dec( p_output_f[ch] = NULL; } } +#endif return IVAS_ERR_OK; } -- GitLab From 2cd6e818841ec6cdfb2aa00637b6b739cf8df0be Mon Sep 17 00:00:00 2001 From: vaclav Date: Mon, 27 Oct 2025 16:35:25 +0100 Subject: [PATCH 2/2] fix --- lib_dec/ivas_sba_dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 1096c72b6..bafbfad89 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -115,8 +115,8 @@ ivas_error ivas_sba_dec_reconfigure( int16_t nchan_out_buff; #else int16_t nchan_out_buff, nchan_out_buff_old; -#endif int16_t sba_analysis_order_old_flush; +#endif DECODER_CONFIG_HANDLE hDecoderConfig; ivas_error error; ISM_MODE ism_mode_old; -- GitLab