From d0457d89f38c3182212953b77b7c705a34086cb4 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 31 Jan 2023 17:49:21 +0100 Subject: [PATCH 1/2] - SWITCHING_OUTPUT_CONFIG - Issue 323 - Decoder Output Format Switching - SIMULATE_SWITCHING_OUTPUT_CONFIG (deactivated) - debugging - simulate Decoder Output Format Switching --- apps/decoder.c | 113 ++++++++++++++++++++++++++++++++++------ lib_com/ivas_prot.h | 4 ++ lib_com/options.h | 4 ++ lib_dec/ivas_dec.c | 2 + lib_dec/ivas_init_dec.c | 103 +++++++++++++++++++++++------------- lib_dec/lib_dec.c | 93 +++++++++++++++++++++++++++++++++ lib_dec/lib_dec.h | 8 +++ 7 files changed, 276 insertions(+), 51 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index f018814423..3a6f400e29 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -129,6 +129,9 @@ static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS static ivas_error printBitstreamInfoVoip( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HANDLE hIvasDec ); static int16_t app_own_random( int16_t *seed ); static IVAS_DEC_FORCED_REND_MODE parseForcedRendModeDec( char *forcedRendModeChar ); +#ifdef SIMULATE_SWITCHING_OUTPUT_CONFIG +static void simulate_output_configuration_switching( IVAS_DEC_AUDIO_CONFIG *outputConfig, bool *reinit_flag ); +#endif #endif @@ -1301,6 +1304,9 @@ static ivas_error decodeG192( ivas_error error = IVAS_ERR_UNKNOWN; uint16_t numObj = 0; IVAS_DEC_BS_FORMAT bsFormat = IVAS_DEC_BS_UNKOWN; +#ifdef SWITCHING_OUTPUT_CONFIG + bool reinit_flag; +#endif IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS]; for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) @@ -1332,6 +1338,10 @@ static ivas_error decodeG192( while ( 1 ) { +#ifdef SWITCHING_OUTPUT_CONFIG + reinit_flag = false; +#endif + /* Read next frame */ if ( ( error = BS_Reader_ReadFrame_short( hBsReader, bit_stream, &num_bits, &bfi ) ) != IVAS_ERR_OK ) { @@ -1359,6 +1369,23 @@ static ivas_error decodeG192( } #endif +#ifdef SWITCHING_OUTPUT_CONFIG +#ifdef SIMULATE_SWITCHING_OUTPUT_CONFIG + /* Simulation of output configuration switching */ + simulate_output_configuration_switching( &( arg.outputFormat ), &reinit_flag ); +#endif + + /* Reinitialization of the decoder in case of application parameter(s) change (e.g. change of output config) */ + if ( reinit_flag ) + { + if ( ( error = IVAS_DEC_Reinit_Dec( hIvasDec, arg.outputFormat ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_Reinit_Dec: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } +#endif + /* Feed into decoder */ if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, bit_stream, num_bits, bfi ) ) != IVAS_ERR_OK ) { @@ -1403,22 +1430,9 @@ static ivas_error decodeG192( /* Once good frame decoded, catch up */ if ( decodedGoodFrame ) { - error = initOnFirstGoodFrame( - hIvasDec, - arg, - numInitialBadFrames, - nOutSamples, - &delayNumSamples_orig, - &delayNumSamples, - &delayTimeScale, - &bsFormat, - &afWriter, - &masaWriter, - ismWriters, - &nOutChannels, - &numObj ); - if ( error != IVAS_ERR_OK ) + if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, nOutSamples, &delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj ) ) != IVAS_ERR_OK ) { + fprintf( stderr, "\nError in initOnFirstGoodFrame, code: %d\n", error ); goto cleanup; } } @@ -2046,4 +2060,73 @@ static IVAS_DEC_FORCED_REND_MODE parseForcedRendModeDec( return IVAS_DEC_FORCE_REND_UNDEFINED; } + + +#ifdef SIMULATE_SWITCHING_OUTPUT_CONFIG +/*---------------------------------------------------------------------* + * simulate_input_format_switching() + * + * Simulation of IVAS input format switching + *---------------------------------------------------------------------*/ + +#if 1 +#define MAX_OUT_CONFIGS_SIMULATE 3 + +IVAS_DEC_AUDIO_CONFIG output_config_options[MAX_OUT_CONFIGS_SIMULATE] = { + IVAS_DEC_OUTPUT_STEREO, + IVAS_DEC_OUTPUT_BINAURAL, + IVAS_DEC_OUTPUT_BINAURAL_ROOM, +}; +#else +#define MAX_OUT_CONFIGS_SIMULATE 12 + +IVAS_DEC_AUDIO_CONFIG output_config_options[MAX_OUT_CONFIGS_SIMULATE] = { + IVAS_DEC_OUTPUT_MONO, + IVAS_DEC_OUTPUT_STEREO, + IVAS_DEC_OUTPUT_5_1, + IVAS_DEC_OUTPUT_7_1, + IVAS_DEC_OUTPUT_5_1_2, + IVAS_DEC_OUTPUT_5_1_4, + IVAS_DEC_OUTPUT_7_1_4, + /*IVAS_DEC_OUTPUT_LS_CUSTOM,*/ + IVAS_DEC_OUTPUT_FOA, + IVAS_DEC_OUTPUT_HOA2, + IVAS_DEC_OUTPUT_HOA3, + IVAS_DEC_OUTPUT_BINAURAL, + IVAS_DEC_OUTPUT_BINAURAL_ROOM, + /*IVAS_DEC_OUTPUT_EXT,*/ + /*IVAS_DEC_OUTPUT_UNKNOWN*/ +}; +#endif + +static void simulate_output_configuration_switching( + IVAS_DEC_AUDIO_CONFIG *outputConfig, + bool *reinit_flag ) +{ + static int16_t ff = -1; + IVAS_DEC_AUDIO_CONFIG outputConfig_new; + + *reinit_flag = false; + + outputConfig_new = *outputConfig; + if ( frame % 20 == 0 ) + { + ff++; + if ( ff > MAX_OUT_CONFIGS_SIMULATE - 1 ) + { + ff = 0; + } + + outputConfig_new = output_config_options[ff]; + } + + if ( *outputConfig != outputConfig_new ) + { + *reinit_flag = true; + *outputConfig = outputConfig_new; + } + + return; +} +#endif #endif diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 6f4d27d5e8..2c03be6075 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -410,6 +410,10 @@ void destroy_core_dec( void ivas_destroy_dec( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +#ifdef SWITCHING_OUTPUT_CONFIG + , + const int16_t flag_all /* i : 1 == destroy external data handles */ +#endif ); void ivas_initialize_handles_dec( diff --git a/lib_com/options.h b/lib_com/options.h index 5dddf236ea..183bd9bd7e 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -168,6 +168,10 @@ #define FIX_317 /* FhG: issue 317 - address sanitizer error in MDCT-Stereo PLC */ +#define SWITCHING_OUTPUT_CONFIG /* VA: Issue 323 - Decoder Output Format Switching */ +/*#define SIMULATE_SWITCHING_OUTPUT_CONFIG*/ /* VA: debugging - simulate Decoder Output Format Switching */ + + /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ #endif diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index e4a08b0540..7169e3960d 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -610,6 +610,8 @@ ivas_error ivas_dec( } #ifdef DEBUG_MODE_INFO + dbgwrite( &st_ivas->ivas_format, sizeof( int16_t ), 1, output_frame, "res/ivas_format.dec" ); + dbgwrite( &st_ivas->hDecoderConfig->output_config, sizeof( int16_t ), 1, output_frame, "res/output_config" ); dbgwrite( &st_ivas->bfi, sizeof( int16_t ), 1, output_frame, "res/bfi" ); dbgwrite( &st_ivas->BER_detect, sizeof( int16_t ), 1, output_frame, "res/BER_detect" ); { diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 763c83dc39..317b1d9fcc 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -553,7 +553,11 @@ ivas_error ivas_init_decoder_front( * Allocate and initialize Custom loudspeaker layout handle *--------------------------------------------------------------------*/ +#ifdef SWITCHING_OUTPUT_CONFIG + if ( st_ivas->hDecoderConfig->Opt_LsCustom && st_ivas->hLsSetupCustom == NULL ) +#else if ( st_ivas->hDecoderConfig->Opt_LsCustom ) +#endif { if ( ( error = ivas_ls_custom_open( &( st_ivas->hLsSetupCustom ) ) ) != IVAS_ERR_OK ) { @@ -565,7 +569,11 @@ ivas_error ivas_init_decoder_front( * Allocate and initialize Head-Tracking handle *--------------------------------------------------------------------*/ +#ifdef SWITCHING_OUTPUT_CONFIG + if ( st_ivas->hDecoderConfig->Opt_Headrotation && st_ivas->hHeadTrackData == NULL ) +#else if ( st_ivas->hDecoderConfig->Opt_Headrotation ) +#endif { if ( ( error = ivas_headTrack_open( &( st_ivas->hHeadTrackData ) ) ) != IVAS_ERR_OK ) { @@ -577,7 +585,11 @@ ivas_error ivas_init_decoder_front( * Allocate HRTF binary handle *--------------------------------------------------------------------*/ +#ifdef SWITCHING_OUTPUT_CONFIG + if ( st_ivas->hDecoderConfig->Opt_HRTF_binary && st_ivas->hHrtfTD == NULL ) +#else if ( st_ivas->hDecoderConfig->Opt_HRTF_binary ) +#endif { if ( ( error = ivas_HRTF_binary_open( &( st_ivas->hHrtfTD ) ) ) != IVAS_ERR_OK ) { @@ -607,9 +619,15 @@ ivas_error ivas_init_decoder_front( if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_ROOM ) { - if ( ( error = ivas_render_config_open( &( st_ivas->hRenderConfig ) ) ) != IVAS_ERR_OK ) + +#ifdef SWITCHING_OUTPUT_CONFIG + if ( st_ivas->hRenderConfig == NULL ) +#endif { - return error; + if ( ( error = ivas_render_config_open( &( st_ivas->hRenderConfig ) ) ) != IVAS_ERR_OK ) + { + return error; + } } if ( ivas_render_config_init_from_rom( &st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_ROOM ) != IVAS_ERR_OK ) @@ -1571,6 +1589,10 @@ void ivas_initialize_handles_dec( void ivas_destroy_dec( Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ +#ifdef SWITCHING_OUTPUT_CONFIG + , + const int16_t flag_all /* i : 1 == destroy external data handles */ +#endif ) { int16_t i, n; @@ -1736,52 +1758,61 @@ void ivas_destroy_dec( st_ivas->hMonoDmxRenderer = NULL; } - /* Head track data handle */ - if ( st_ivas->hHeadTrackData != NULL ) +#ifdef SWITCHING_OUTPUT_CONFIG + if ( flag_all ) { - free( st_ivas->hHeadTrackData ); - st_ivas->hHeadTrackData = NULL; - } +#endif - /* Time Domain binaural renderer handle */ - if ( st_ivas->hBinRendererTd != NULL ) - { - ivas_td_binaural_close( &st_ivas->hBinRendererTd ); - } - else if ( st_ivas->hHrtfTD != NULL ) - { - BSplineModelEvalDealloc( &st_ivas->hHrtfTD->ModelParams, &st_ivas->hHrtfTD->ModelEval ); + /* Head track data handle */ + if ( st_ivas->hHeadTrackData != NULL ) + { + free( st_ivas->hHeadTrackData ); + st_ivas->hHeadTrackData = NULL; + } - ivas_HRTF_binary_close( &st_ivas->hHrtfTD ); - } + /* Time Domain binaural renderer handle */ + if ( st_ivas->hBinRendererTd != NULL ) + { + ivas_td_binaural_close( &st_ivas->hBinRendererTd ); + } + else if ( st_ivas->hHrtfTD != NULL ) + { + BSplineModelEvalDealloc( &st_ivas->hHrtfTD->ModelParams, &st_ivas->hHrtfTD->ModelEval ); + + ivas_HRTF_binary_close( &st_ivas->hHrtfTD ); + } #ifdef HRTF_BINARY_FILE - /* CRend binaural renderer handle */ - if ( st_ivas->hSetOfHRTF != NULL ) - { - destroy_SetOfHRTF( st_ivas->hSetOfHRTF ); - ivas_HRTF_CRend_binary_close( &st_ivas->hSetOfHRTF ); - } + /* CRend binaural renderer handle */ + if ( st_ivas->hSetOfHRTF != NULL ) + { + destroy_SetOfHRTF( st_ivas->hSetOfHRTF ); + ivas_HRTF_CRend_binary_close( &st_ivas->hSetOfHRTF ); + } - /* Fastconv HRTF filters */ - if ( st_ivas->hHrtfFastConv != NULL ) - { - ivas_HRTF_fastconv_binary_close( &st_ivas->hHrtfFastConv ); - } + /* Fastconv HRTF filters */ + if ( st_ivas->hHrtfFastConv != NULL ) + { + ivas_HRTF_fastconv_binary_close( &st_ivas->hHrtfFastConv ); + } - /* Parametric binauralizer HRTF filters */ - if ( st_ivas->hHrtfParambin != NULL ) - { - ivas_HRTF_parambin_binary_close( &st_ivas->hHrtfParambin ); - } + /* Parametric binauralizer HRTF filters */ + if ( st_ivas->hHrtfParambin != NULL ) + { + ivas_HRTF_parambin_binary_close( &st_ivas->hHrtfParambin ); + } #endif - /* Config. Renderer */ - ivas_render_config_close( &( st_ivas->hRenderConfig ) ); + /* Config. Renderer */ + ivas_render_config_close( &( st_ivas->hRenderConfig ) ); +#ifdef SWITCHING_OUTPUT_CONFIG + } +#endif /* Limiter struct */ ivas_limiter_close( &( st_ivas->hLimiter ) ); +#ifndef SWITCHING_OUTPUT_CONFIG if ( st_ivas->hDecoderConfig != NULL ) { free( st_ivas->hDecoderConfig ); @@ -1790,7 +1821,7 @@ void ivas_destroy_dec( /* main IVAS handle */ free( st_ivas ); - +#endif return; } diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index c14d3318a6..fc3c792792 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -81,6 +81,10 @@ struct IVAS_DEC int16_t sdp_hf_only; /* RTP payload format parameter: only Header-Full format without zero padding for size collision avoidance */ int16_t prev_ft_speech; /* RXDTX handler: previous frametype flag for G.192 format AMRWB SID_FIRST detection */ int16_t CNG; /* RXDTX handler: CNG=1, nonCNG=0 */ + +#ifdef SWITCHING_OUTPUT_CONFIG + bool reset_flag; /* == 1 if decoder switching is requested due to change of output config. change or the IVAS format in the bit-stream changed */ +#endif }; @@ -256,7 +260,20 @@ void IVAS_DEC_Close( if ( ( *phIvasDec )->st_ivas ) { +#ifdef SWITCHING_OUTPUT_CONFIG + ivas_destroy_dec( ( *phIvasDec )->st_ivas, 1 ); + + if ( ( *phIvasDec )->st_ivas->hDecoderConfig != NULL ) + { + free( ( *phIvasDec )->st_ivas->hDecoderConfig ); + ( *phIvasDec )->st_ivas->hDecoderConfig = NULL; + } + + /* main IVAS handle */ + free( ( *phIvasDec )->st_ivas ); +#else ivas_destroy_dec( ( *phIvasDec )->st_ivas ); +#endif ( *phIvasDec )->st_ivas = NULL; } @@ -575,6 +592,82 @@ ivas_error IVAS_DEC_EnableVoIP( } +#ifdef SWITCHING_OUTPUT_CONFIG +/*---------------------------------------------------------------------* + * IVAS_DEC_Reinit_Dec( ) + * + * Reinitialize the decoder in case of application parameter(s) change + * (e.g. output config. change) + *---------------------------------------------------------------------*/ + +/*! r: error code */ +ivas_error IVAS_DEC_Reinit_Dec( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_DEC_AUDIO_CONFIG outputFormat /* i : output format */ +) +{ + Decoder_Struct *st_ivas; + DECODER_CONFIG_HANDLE hDecoderConfig; + ivas_error error; + + error = IVAS_ERR_OK; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + st_ivas = hIvasDec->st_ivas; + hDecoderConfig = st_ivas->hDecoderConfig; + + if ( hIvasDec->isInitialized == true ) + { + /* Destroy the decoder handle */ + ivas_destroy_dec( st_ivas, 0 ); + st_ivas->ini_frame = 0; + + /* take into account possible output format change */ + hDecoderConfig->output_config = mapOutputFormat( outputFormat ); + if ( hDecoderConfig->output_config == AUDIO_CONFIG_INVALID ) + { + return IVAS_ERR_WRONG_PARAMS; + } + + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + st_ivas->element_mode_init = EVS_MONO; + hDecoderConfig->nchan_out = 1; + } + + if ( outputFormat != IVAS_DEC_OUTPUT_EXT && outputFormat != IVAS_DEC_OUTPUT_LS_CUSTOM ) + { + hDecoderConfig->nchan_out = audioCfg2channels( hDecoderConfig->output_config ); + } + + if ( outputFormat == IVAS_DEC_OUTPUT_LS_CUSTOM && hDecoderConfig->Opt_LsCustom == 0 ) + { + return IVAS_ERR_WRONG_PARAMS; + } + + /* Set decoder parameters to initial values */ + if ( ( error = ivas_init_decoder_front( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + hIvasDec->st_ivas->ivas_format = MONO_FORMAT; + } + } + + hIvasDec->isInitialized = false; + + return error; +} +#endif + + /*---------------------------------------------------------------------* * IVAS_DEC_FeedFrame_Serial( ) * diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 6761ebe628..14e8a8a384 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -145,6 +145,14 @@ void IVAS_DEC_Close( /* Decoding functions - should be called with a configured decoder handle */ +#ifdef SWITCHING_OUTPUT_CONFIG +/*! r: error code */ +ivas_error IVAS_DEC_Reinit_Dec( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_DEC_AUDIO_CONFIG outputFormat /* i : output format */ +); +#endif + /*! r: error code */ ivas_error IVAS_DEC_FeedFrame_Serial( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ -- GitLab From bf58c4677aa247a1dcb357793523f8ee1cb3a0d0 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 31 Jan 2023 17:55:32 +0100 Subject: [PATCH 2/2] fix 'nOutChannels' parameter, under SWITCHING_OUTPUT_CONFIG --- apps/decoder.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/decoder.c b/apps/decoder.c index 3a6f400e29..cf6537d7ef 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1383,6 +1383,12 @@ static ivas_error decodeG192( fprintf( stderr, "\nError in IVAS_DEC_Reinit_Dec: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } + + if ( ( error = IVAS_DEC_GetNumOutputChannels( hIvasDec, &nOutChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetNumOutputChannels, code: %d\n", error ); + return error; + } } #endif -- GitLab