From e27e616034bebc6409b9d3a03826b61bf1855071 Mon Sep 17 00:00:00 2001 From: Tapani Pihlajakuja Date: Wed, 7 Jun 2023 11:58:15 +0300 Subject: [PATCH 1/3] Implements first version of proper EXT out for MASA in JBM operation. --- apps/decoder.c | 20 ++++ lib_com/ivas_cnst.h | 3 + lib_com/ivas_prot.h | 23 +++- lib_com/options.h | 1 + lib_dec/ivas_dirac_dec.c | 8 ++ lib_dec/ivas_init_dec.c | 24 ++++ lib_dec/ivas_jbm_dec.c | 239 +++++++++++++++++++++++++++++++++++++++ lib_dec/ivas_stat_dec.h | 23 ++++ lib_dec/lib_dec.c | 13 +++ lib_dec/lib_dec.h | 6 + 10 files changed, 359 insertions(+), 1 deletion(-) diff --git a/apps/decoder.c b/apps/decoder.c index f1787da629..3f29985b62 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1562,7 +1562,11 @@ static ivas_error initOnFirstGoodFrame( /* Duplicate good first frame metadata to fill the beginning of stream. */ MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta = NULL; +#ifdef FIX_470_MASA_JBM_EXT + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 0 ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); return error; @@ -1830,7 +1834,11 @@ static ivas_error decodeG192( else if ( bsFormat == IVAS_DEC_BS_MASA ) { MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta; +#ifdef FIX_470_MASA_JBM_EXT + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 0 ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2378,7 +2386,11 @@ static ivas_error decodeVoIP( else if ( bsFormat == IVAS_DEC_BS_MASA ) { MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta; +#ifdef FIX_470_MASA_JBM_EXT + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 1 ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2761,7 +2773,11 @@ static ivas_error decodeVariableSpeed( else if ( bsFormat == IVAS_DEC_BS_MASA ) { MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta; +#ifdef FIX_470_MASA_JBM_EXT + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 1 ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2903,7 +2919,11 @@ static ivas_error decodeVariableSpeed( else if ( bsFormat == IVAS_DEC_BS_MASA ) { MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta; +#ifdef FIX_470_MASA_JBM_EXT + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 0 ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 27a361bdb8..8daa6718e4 100755 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -213,6 +213,9 @@ typedef enum #define MAX_JBM_L_FRAME_NS 40000000L #define MAX_SPAR_INTERNAL_CHANNELS IVAS_SPAR_MAX_CH #define MAX_CLDFB_DIGEST_CHANNELS 4 +#ifdef FIX_470_MASA_JBM_EXT +#define MASA_JBM_RINGBUFFER_FRAMES 3 +#endif typedef enum { diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index bb774c73bc..cb613c3db3 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -822,10 +822,21 @@ void ivas_jbm_dec_get_md_map( int16_t *map /* o : metadata index map */ ); -int16_t ivas_jbm_dec_get_num_tc_channels( +int16_t ivas_jbm_dec_get_num_tc_channels( Decoder_Struct *st_ivas /* i : IVAS decoder handle */ ); +#ifdef FIX_470_MASA_JBM_EXT +void ivas_jbm_dec_get_md_map_even_spacing( + const int16_t default_len, /* i : default frame length in metadata slots */ + const int16_t len, /* i : length of the modfied frames in metadata slots */ + const int16_t subframe_len, /* i : default length of a subframe */ + const int16_t offset, /* i : current read offset into the md buffer */ + const int16_t buf_len, /* i : length of the metadata buffer */ + int16_t *map /* o : metadata index map */ +); +#endif + TC_BUFFER_MODE ivas_jbm_dec_get_tc_buffer_mode( Decoder_Struct *st_ivas /* i : IVAS decoder handle */ ); @@ -862,6 +873,16 @@ void ivas_jbm_dec_td_renderers_adapt_subframes( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); +#ifdef FIX_470_MASA_JBM_EXT +ivas_error ivas_jbm_dec_metadata_open( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +void ivas_jbm_masa_sf_to_sf_map( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); +#endif + /*----------------------------------------------------------------------------------* * ISM prototypes diff --git a/lib_com/options.h b/lib_com/options.h index 555c98b760..28264453e3 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -167,6 +167,7 @@ #define FIX_506 /* FhG: Compiler warnings */ #define FIX_511_OPTIMIZE_PARAMBIN_GAIN_FETCH /* Nokia: Issue 511, significant optimization of parametric binauralizer gain fetching. */ #define FIX_531_BWS_ISM_BFI /* VA: issue 531: fix MemorySanitizer: use-of-uninitialized-value in ISM2 rate switching with frame errors */ +#define FIX_470_MASA_JBM_EXT /* Nokia: Issue 470, fix MASA EXT output with JBM */ /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index feb61ab063..c6bb14904b 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2305,7 +2305,15 @@ void ivas_dirac_dec_set_md_map( set_s( hDirAC->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); +#ifdef FIX_470_MASA_JBM_EXT + if ( st_ivas->ivas_format == MASA_FORMAT ) + { + ivas_jbm_dec_get_md_map_even_spacing( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, num_slots_in_subfr, 0, hDirAC->dirac_md_buffer_length, hDirAC->render_to_md_map ); + } + else if ( hDirAC->hConfig == NULL || hDirAC->hConfig->dec_param_estim == 0 ) +#else if ( hDirAC->hConfig == NULL || hDirAC->hConfig->dec_param_estim == 0 ) +#endif { ivas_jbm_dec_get_md_map( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, num_slots_in_subfr, 0, hDirAC->dirac_md_buffer_length, hDirAC->render_to_md_map ); } diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 4bb061b572..3549f2cbe6 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1407,6 +1407,19 @@ ivas_error ivas_init_decoder( } } +#ifdef FIX_470_MASA_JBM_EXT + if ( st_ivas->hJbmMetadata == NULL ) + { + if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL ) + { + if ( ( error = ivas_jbm_dec_metadata_open( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } +#endif + return error; } @@ -1629,6 +1642,9 @@ void ivas_initialize_handles_dec( st_ivas->hRenderConfig = NULL; st_ivas->hTcBuffer = NULL; +#ifdef FIX_470_MASA_JBM_EXT + st_ivas->hJbmMetadata = NULL; +#endif return; } @@ -1823,6 +1839,14 @@ void ivas_destroy_dec( ivas_jbm_dec_tc_buffer_close( &st_ivas->hTcBuffer ); +#ifdef FIX_470_MASA_JBM_EXT + if ( st_ivas->hJbmMetadata != NULL ) + { + free( st_ivas->hJbmMetadata ); + st_ivas->hJbmMetadata = NULL; + } +#endif + /* main IVAS handle */ free( st_ivas ); diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index fd0375e7be..e77d27c5af 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -54,6 +54,12 @@ static void ivas_jbm_dec_copy_tc( Decoder_Struct *st_ivas, const int16_t nSample static void ivas_jbm_dec_tc_buffer_playout( Decoder_Struct *st_ivas, const uint16_t nSamplesAsked, uint16_t *nSamplesRendered, float *output[] ); +#ifdef FIX_470_MASA_JBM_EXT +static void ivas_jbm_dec_copy_masa_meta_to_buffer( Decoder_Struct *st_ivas ); + +static void ivas_jbm_masa_sf_to_slot_map( Decoder_Struct *st_ivas, const int16_t nCldfbTs ); +#endif + /*--------------------------------------------------------------------------* * ivas_jbm_dec_tc() @@ -196,6 +202,12 @@ ivas_error ivas_jbm_dec_tc( { return error; } +#ifdef FIX_470_MASA_JBM_EXT + if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL ) + { + ivas_jbm_dec_copy_masa_meta_to_buffer( st_ivas ); + } +#endif } } else if ( st_ivas->ivas_format == SBA_FORMAT ) @@ -537,6 +549,12 @@ ivas_error ivas_jbm_dec_feed_tc_to_renderer( if ( st_ivas->hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_BUFFER ) { ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); +#ifdef FIX_470_MASA_JBM_EXT + if ( st_ivas->ivas_format == MASA_FORMAT ) + { + ivas_jbm_masa_sf_to_slot_map( st_ivas, n_render_timeslots ); + } +#endif } else if ( st_ivas->ivas_format == STEREO_FORMAT ) { @@ -1218,6 +1236,72 @@ void ivas_jbm_dec_get_md_map( } +#ifdef FIX_470_MASA_JBM_EXT +/*--------------------------------------------------------------------------* + * ivas_jbm_dec_get_md_map_even_spacing() + * + * Get an meta data map adapted to a time scale modified IVAS frame. Distribute slots evenly across the modified frame. + *--------------------------------------------------------------------------*/ +void ivas_jbm_dec_get_md_map_even_spacing( + const int16_t default_len, /* i : default frame length in metadata slots */ + const int16_t len, /* i : length of the modfied frames in metadata slots */ + const int16_t subframe_len, /* i : default length of a subframe */ + const int16_t offset, /* i : current read offset into the md buffer */ + const int16_t buf_len, /* i : length of the metadata buffer */ + int16_t *map /* o : metadata index map */ +) +{ + int16_t map_idx, sf_idx, sf_length, increment, subframes_written; + float decimal, decimal_sum, eps; + int16_t subframe_map_length[MAX_PARAM_SPATIAL_SUBFRAMES]; +#ifdef DEBUGGING + assert( default_len % 2 == 0 ); +#endif + + /* subframe map length */ + sf_length = len / subframe_len; + if ( len % subframe_len == 0 ) + { + /* even subframes */ + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + subframe_map_length[sf_idx] = sf_length; + } + } + else + { + /* uneven subframes */ + decimal = ( (float) len / (float) subframe_len ) - (float) sf_length; + decimal_sum = decimal; + eps = 0.001f; + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + increment = (int16_t) floorf( decimal_sum + eps ); + subframe_map_length[sf_idx] = sf_length + increment; + if ( increment > 0 ) + { + decimal_sum -= 1.0f; + } + decimal_sum += decimal; + } + } + + /* map slots to subframes */ + sf_idx = 0; + subframes_written = 0; + for ( map_idx = 0; map_idx < len; map_idx++ ) + { + map[map_idx] = ( offset + sf_idx ) % buf_len; + if ( map_idx - subframes_written >= subframe_map_length[sf_idx] - 1 ) + { + subframes_written += subframe_map_length[sf_idx]; + ++sf_idx; + } + } +} +#endif + + /*--------------------------------------------------------------------------* * ivas_jbm_dec_get_num_tc_channels() * @@ -1806,3 +1890,158 @@ TC_BUFFER_MODE ivas_jbm_dec_get_tc_buffer_mode( return buffer_mode; } + + +#ifdef FIX_470_MASA_JBM_EXT +/*--------------------------------------------------------------------------* + * ivas_jbm_dec_metadata_open() + * + * Open structure for metadata buffering in JBM + *--------------------------------------------------------------------------*/ +ivas_error ivas_jbm_dec_metadata_open( + Decoder_Struct *st_ivas ) +{ + JBM_METADATA_HANDLE hJbmMetadata; + if ( ( hJbmMetadata = (JBM_METADATA_HANDLE) malloc( sizeof( JBM_METADATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM metadata handle\n" ) ); + } + hJbmMetadata->sf_write_idx = 0; + hJbmMetadata->sf_md_buffer_length = MASA_JBM_RINGBUFFER_FRAMES * MAX_PARAM_SPATIAL_SUBFRAMES; + + hJbmMetadata->slot_write_idx = 0; + hJbmMetadata->slot_read_idx = 0; + hJbmMetadata->slot_md_buffer_length = MASA_JBM_RINGBUFFER_FRAMES * MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME; + + st_ivas->hJbmMetadata = hJbmMetadata; + + return IVAS_ERR_OK; +} + + +/*--------------------------------------------------------------------------* + * ivas_jbm_dec_copy_masa_meta_to_buffer() + * + * Copy decoded MASA metadata to a ring buffer + *--------------------------------------------------------------------------*/ +static void ivas_jbm_dec_copy_masa_meta_to_buffer( + Decoder_Struct *st_ivas ) +{ + int16_t sf, dir, band; + JBM_METADATA_HANDLE hJbmMetadata; + MASA_DECODER_EXT_OUT_META *extOutMeta; + int16_t write_idx; + + hJbmMetadata = st_ivas->hJbmMetadata; + extOutMeta = st_ivas->hMasa->data.extOutMeta; + + for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + write_idx = ( hJbmMetadata->sf_write_idx + sf ) % hJbmMetadata->sf_md_buffer_length; + + for ( dir = 0; dir < MASA_MAXIMUM_DIRECTIONS; dir++ ) + { + for ( band = 0; band < MASA_FREQUENCY_BANDS; band++ ) + { + hJbmMetadata->directionIndexBuffer[dir][write_idx][band] = extOutMeta->directionIndex[dir][sf][band]; + hJbmMetadata->directToTotalRatioBuffer[dir][write_idx][band] = extOutMeta->directToTotalRatio[dir][sf][band]; + hJbmMetadata->spreadCoherenceBuffer[dir][write_idx][band] = extOutMeta->spreadCoherence[dir][sf][band]; + } + } + + for ( band = 0; band < MASA_FREQUENCY_BANDS; band++ ) + { + hJbmMetadata->diffuseToTotalRatioBuffer[write_idx][band] = extOutMeta->diffuseToTotalRatio[sf][band]; + hJbmMetadata->surroundCoherenceBuffer[write_idx][band] = extOutMeta->surroundCoherence[sf][band]; + } + } +} + + +/*--------------------------------------------------------------------------* + * ivas_jbm_masa_sf_to_slot_map() + * + * Map input MASA metadata subframes to slots in JBM processing + *--------------------------------------------------------------------------*/ +static void ivas_jbm_masa_sf_to_slot_map( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t nCldfbTs /* i : number of CLDFB time slots */ +) +{ + int16_t sf_to_slot_map[MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME]; + int16_t num_slots_in_subfr; + JBM_METADATA_HANDLE hJbmMetadata; + int16_t slot_idx; + int16_t write_idx, sf_index; + + /* Set values */ + hJbmMetadata = st_ivas->hJbmMetadata; + num_slots_in_subfr = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; + + /* Map input subframes to slots */ + ivas_jbm_dec_get_md_map_even_spacing( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, num_slots_in_subfr, 0, MAX_PARAM_SPATIAL_SUBFRAMES, sf_to_slot_map ); + + for ( slot_idx = 0; slot_idx < nCldfbTs; slot_idx++ ) + { + write_idx = ( hJbmMetadata->slot_write_idx + slot_idx ) % hJbmMetadata->slot_md_buffer_length; + sf_index = ( hJbmMetadata->sf_write_idx + sf_to_slot_map[slot_idx] ) % hJbmMetadata->sf_md_buffer_length; + + hJbmMetadata->sf_to_slot_map[write_idx] = sf_index; + } + + hJbmMetadata->sf_write_idx = ( hJbmMetadata->sf_write_idx + MAX_PARAM_SPATIAL_SUBFRAMES ) % hJbmMetadata->sf_md_buffer_length; + hJbmMetadata->slot_write_idx = ( hJbmMetadata->slot_write_idx + nCldfbTs ) % hJbmMetadata->slot_md_buffer_length; +} + + +/*--------------------------------------------------------------------------* + * ivas_jbm_masa_sf_to_sf_map() + * + * Map input MASA metadata subframes to output subframes in JBM processing + *--------------------------------------------------------------------------*/ +void ivas_jbm_masa_sf_to_sf_map( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +) +{ + int16_t sf_to_sf_map[MAX_PARAM_SPATIAL_SUBFRAMES]; + JBM_METADATA_HANDLE hJbmMetadata; + MASA_DECODER_EXT_OUT_META *extOutMeta; + int16_t slot_read_idx, sf_read_idx; + int16_t sf_idx; + int16_t dir, band; + + /* Set values */ + hJbmMetadata = st_ivas->hJbmMetadata; + extOutMeta = st_ivas->hMasa->data.extOutMeta; + + /* Map slots to subframes */ + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + slot_read_idx = ( hJbmMetadata->slot_read_idx + 2 ) % hJbmMetadata->slot_md_buffer_length; /* Take the latter one of the middle slots of the output subframe */ + sf_to_sf_map[sf_idx] = hJbmMetadata->sf_to_slot_map[slot_read_idx]; + hJbmMetadata->slot_read_idx = ( hJbmMetadata->slot_read_idx + CLDFB_SLOTS_PER_SUBFRAME ) % hJbmMetadata->slot_md_buffer_length; + } + + /* Copy mapped metadata to the EXT meta buffer for writing */ + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + sf_read_idx = sf_to_sf_map[sf_idx]; + + for ( dir = 0; dir < MASA_MAXIMUM_DIRECTIONS; dir++ ) + { + for ( band = 0; band < MASA_FREQUENCY_BANDS; band++ ) + { + extOutMeta->directionIndex[dir][sf_idx][band] = hJbmMetadata->directionIndexBuffer[dir][sf_read_idx][band]; + extOutMeta->directToTotalRatio[dir][sf_idx][band] = hJbmMetadata->directToTotalRatioBuffer[dir][sf_read_idx][band]; + extOutMeta->spreadCoherence[dir][sf_idx][band] = hJbmMetadata->spreadCoherenceBuffer[dir][sf_read_idx][band]; + } + } + + for ( band = 0; band < MASA_FREQUENCY_BANDS; band++ ) + { + extOutMeta->diffuseToTotalRatio[sf_idx][band] = hJbmMetadata->diffuseToTotalRatioBuffer[sf_read_idx][band]; + extOutMeta->surroundCoherence[sf_idx][band] = hJbmMetadata->surroundCoherenceBuffer[sf_read_idx][band]; + } + } +} +#endif diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index ba8f573364..f51d9f8306 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1219,6 +1219,26 @@ typedef struct decoder_tc_buffer_structure } DECODER_TC_BUFFER, *DECODER_TC_BUFFER_HANDLE; +#ifdef FIX_470_MASA_JBM_EXT +typedef struct jbm_metadata_structure +{ + int16_t sf_write_idx; + int16_t sf_md_buffer_length; + + uint16_t directionIndexBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + uint8_t directToTotalRatioBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + uint8_t spreadCoherenceBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + uint8_t surroundCoherenceBuffer[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + uint8_t diffuseToTotalRatioBuffer[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + + int16_t slot_read_idx; + int16_t slot_write_idx; + int16_t slot_md_buffer_length; + + int16_t sf_to_slot_map[MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME * MASA_JBM_RINGBUFFER_FRAMES]; +} JBM_METADATA, *JBM_METADATA_HANDLE; +#endif + /*----------------------------------------------------------------------------------* * @@ -1308,6 +1328,9 @@ typedef struct Decoder_Struct /* JBM module */ DECODER_TC_BUFFER_HANDLE hTcBuffer; /* JBM structure */ +#ifdef FIX_470_MASA_JBM_EXT + JBM_METADATA_HANDLE hJbmMetadata; /* Structure for metadata buffering in JBM */ +#endif #ifdef DEBUGGING int32_t noClipping; /* number of clipped samples */ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 3b4618b6a2..c8027ceb1c 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -1101,8 +1101,14 @@ ivas_error IVAS_DEC_GetObjectMetadata( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetMasaMetadata( +#ifdef FIX_470_MASA_JBM_EXT + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + MASA_DECODER_EXT_OUT_META_HANDLE *hMasaExtOutMeta, /* o : pointer to handle, which will be set to point to metadata from the most recently decoded frame */ + uint8_t getFromJbmBuffer /* i : get metadata from a JBM buffer */ +#else IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ MASA_DECODER_EXT_OUT_META_HANDLE *hMasaExtOutMeta /* o : pointer to handle, which will be set to point to metadata from the most recently decoded frame */ +#endif ) { if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) @@ -1115,6 +1121,13 @@ ivas_error IVAS_DEC_GetMasaMetadata( return IVAS_ERR_WRONG_MODE; } +#ifdef FIX_470_MASA_JBM_EXT + if ( getFromJbmBuffer ) + { + ivas_jbm_masa_sf_to_sf_map( hIvasDec->st_ivas ); + } +#endif + *hMasaExtOutMeta = hIvasDec->st_ivas->hMasa->data.extOutMeta; return IVAS_ERR_OK; diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 0572ace82e..5d956afe6a 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -182,8 +182,14 @@ ivas_error IVAS_DEC_GetObjectMetadata( /*! r: error code */ ivas_error IVAS_DEC_GetMasaMetadata( +#ifdef FIX_470_MASA_JBM_EXT + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + MASA_DECODER_EXT_OUT_META_HANDLE *hMasaExtOutMeta, /* o : pointer to handle, which will be set to point to metadata from the most recently decoded frame */ + uint8_t getFromJbmBuffer /* i : get metadata from a JBM buffer */ +#else IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ MASA_DECODER_EXT_OUT_META_HANDLE *hMasaExtOutMeta /* o : pointer to handle, which will be set to point to metadata from the most recently decoded frame */ +#endif ); /*! r: error code */ -- GitLab From 600648da418f66269799e1d06a0438480bb0f62c Mon Sep 17 00:00:00 2001 From: Tapani Pihlajakuja Date: Wed, 7 Jun 2023 12:55:54 +0300 Subject: [PATCH 2/3] Fix MONO output in MASA JBM --- lib_dec/ivas_jbm_dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index e77d27c5af..63e40958bf 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -550,7 +550,7 @@ ivas_error ivas_jbm_dec_feed_tc_to_renderer( { ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); #ifdef FIX_470_MASA_JBM_EXT - if ( st_ivas->ivas_format == MASA_FORMAT ) + if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL ) { ivas_jbm_masa_sf_to_slot_map( st_ivas, n_render_timeslots ); } -- GitLab From 98d1d58139a77f5bfbda582ecf1fde477f21794c Mon Sep 17 00:00:00 2001 From: Tapani Pihlajakuja Date: Wed, 14 Jun 2023 14:45:55 +0300 Subject: [PATCH 3/3] Add support to JBM EXT out for MASA bitstream with varying 1dir and 2dir content. --- lib_dec/ivas_jbm_dec.c | 17 +++++++++++++++++ lib_dec/ivas_stat_dec.h | 1 + 2 files changed, 18 insertions(+) diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 81e72741c1..ca00d01de3 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -1964,6 +1964,8 @@ static void ivas_jbm_dec_copy_masa_meta_to_buffer( hJbmMetadata->diffuseToTotalRatioBuffer[write_idx][band] = extOutMeta->diffuseToTotalRatio[sf][band]; hJbmMetadata->surroundCoherenceBuffer[write_idx][band] = extOutMeta->surroundCoherence[sf][band]; } + + hJbmMetadata->numberOfDirections[write_idx] = extOutMeta->descriptiveMeta.numberOfDirections; } } @@ -2019,6 +2021,7 @@ void ivas_jbm_masa_sf_to_sf_map( int16_t slot_read_idx, sf_read_idx; int16_t sf_idx; int16_t dir, band; + uint8_t numberOfDirections; /* Set values */ hJbmMetadata = st_ivas->hJbmMetadata; @@ -2053,5 +2056,19 @@ void ivas_jbm_masa_sf_to_sf_map( extOutMeta->surroundCoherence[sf_idx][band] = hJbmMetadata->surroundCoherenceBuffer[sf_read_idx][band]; } } + + /* Determine the number of directions for the frame to be written */ + numberOfDirections = 0; + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + sf_read_idx = sf_to_sf_map[sf_idx]; + + if ( hJbmMetadata->numberOfDirections[sf_read_idx] == 1 ) + { + numberOfDirections = 1; + break; + } + } + extOutMeta->descriptiveMeta.numberOfDirections = numberOfDirections; } #endif diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index f4be95d594..e4bd5228cf 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1233,6 +1233,7 @@ typedef struct jbm_metadata_structure uint8_t spreadCoherenceBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; uint8_t surroundCoherenceBuffer[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; uint8_t diffuseToTotalRatioBuffer[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + uint8_t numberOfDirections[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES]; /* Descriptive metadata, value is 0 or 1 */ int16_t slot_read_idx; int16_t slot_write_idx; -- GitLab