diff --git a/apps/decoder.c b/apps/decoder.c index 82202289ef4d27d903b0167379f1424f510b5d1b..458c164ac83cb6f9ea949206acf5468a341e8213 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -179,13 +179,24 @@ static bool parseCmdlIVAS_dec( int16_t argc, char **argv, DecArguments *arg ); static void usage_dec( void ); static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtfBinary, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); #ifdef FIX_1119_SPLIT_RENDERING_VOIP +#ifdef DECODER_FORMAT_SWITCHING +static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtf, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE *phIvasDec, int16_t *pcmBuf ); +#else static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtf, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); +#endif +#else +#ifdef DDECODER_FORMAT_SWITCHING +static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtfBinary, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, IVAS_DEC_HANDLE *phIvasDec, int16_t *pcmBuf ); #else static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtfBinary, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); #endif +#endif static ivas_error load_hrtf_from_file( IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtfBinary, IVAS_DEC_HANDLE hIvasDec, const IVAS_AUDIO_CONFIG OutputConfig, const int32_t output_Fs ); static void do_object_editing_fx( IVAS_EDITABLE_PARAMETERS *editableParameters, ObjectEditFileReader *objectEditFileReader ); +#ifdef DECODER_FORMAT_SWITCHING +static ivas_error restartDecoder( IVAS_DEC_HANDLE *phIvasDec, IVAS_DEC_MODE codec, DecArguments *arg, IVAS_RENDER_CONFIG_DATA *renderConfig, IVAS_CUSTOM_LS_DATA *hLsCustomData ); +#endif /*------------------------------------------------------------------------------------------* * main() @@ -720,9 +731,17 @@ int main( if ( arg.voipMode ) { #ifdef FIX_1119_SPLIT_RENDERING_VOIP +#ifdef DECODER_FORMAT_SWITCHING + error = decodeVoIP( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, objectEditFileReader, &splitRendBits, &hIvasDec, pcmBuf ); +#else error = decodeVoIP( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, objectEditFileReader, &splitRendBits, hIvasDec, pcmBuf ); +#endif +#else +#ifdef DDECODER_FORMAT_SWITCHING + error = decodeVoIP( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, objectEditFileReader, &hIvasDec, pcmBuf ); #else error = decodeVoIP( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, objectEditFileReader, hIvasDec, pcmBuf ); +#endif #endif } else @@ -2990,7 +3009,11 @@ static ivas_error decodeVoIP( #ifdef FIX_1119_SPLIT_RENDERING_VOIP ISAR_SPLIT_REND_BITS_DATA *splitRendBits, #endif +#ifdef DECODER_FORMAT_SWITCHING + IVAS_DEC_HANDLE *phIvasDec, +#else IVAS_DEC_HANDLE hIvasDec, +#endif int16_t *pcmBuf ) { bool decodingFailed = true; /* Assume failure until cleanup is reached without errors */ @@ -3022,6 +3045,9 @@ static ivas_error decodeVoIP( int16_t delayNumSamples = -1; int32_t delayTimeScale = -1; int16_t i; +#ifdef DECODER_FORMAT_SWITCHING + IVAS_DEC_HANDLE hIvasDec = *phIvasDec; +#endif #ifdef IVAS_RTPDUMP IVAS_RTP ivasRtp = { 0 }; IVAS_RTP srRtp = { 0 }; @@ -3216,6 +3242,27 @@ static ivas_error decodeVoIP( { nSamplesRendered = 0; +#ifdef DECODER_FORMAT_SWITCHING + if ( ivasRtp.restartNeeded ) + { + IVAS_DEC_MODE newCodecInPacket = ( ivasRtp.codecId == IVAS_RTP_EVS ) ? IVAS_DEC_MODE_EVS : IVAS_DEC_MODE_IVAS; + error = restartDecoder( + &hIvasDec, + newCodecInPacket, + &arg, + NULL, /* ToDo : Provide rendererConfig */ + NULL /* ToDo : Provide LS Custom Data */ + ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "\nFailed to restart decoder from %d to %d\n", arg.decMode, newCodecInPacket ); + goto cleanup; + } + *phIvasDec = hIvasDec; /* Update for main()' s free */ + ivasRtp.restartNeeded = false; + } +#endif + /* reference vector */ if ( arg.enableReferenceVectorTracking && vec_pos_update == 0 ) { @@ -3471,6 +3518,31 @@ static ivas_error decodeVoIP( /* Placeholder for memory reallocation */ /* ... */ +#ifdef DECODER_FORMAT_SWITCHING + if ( IVAS_DEC_isRestartNeeded( hIvasDec ) ) + { + IVAS_DEC_BS_FORMAT tempFormat; + if ( ( error = IVAS_DEC_GetFormat( hIvasDec, &tempFormat ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetFormat, code: %d\n", error ); + goto cleanup; + } + IVAS_DEC_MODE codecMode = ( tempFormat == IVAS_DEC_BS_MONO ) ? IVAS_DEC_MODE_EVS : IVAS_DEC_MODE_IVAS; + error = restartDecoder( + &hIvasDec, + codecMode, + &arg, + NULL, /* ToDo : Provide rendererConfig */ + NULL /* ToDo : Provide LS Custom Data */ + ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "\nFailed to restart decoder\n" ); + goto cleanup; + } + *phIvasDec = hIvasDec; /* Update for main()' s free */ + } +#endif /* Load HRTF binary file data */ if ( arg.hrtfReaderEnabled ) @@ -4248,4 +4320,118 @@ static ivas_error load_hrtf_from_file( return IVAS_ERR_OK; } +#ifdef DECODER_FORMAT_SWITCHING + +ivas_error restartDecoder( + IVAS_DEC_HANDLE *phIvasDec, + IVAS_DEC_MODE codec, + DecArguments *arg, + IVAS_RENDER_CONFIG_DATA *renderConfig, + IVAS_CUSTOM_LS_DATA *hLsCustomData ) +{ + ivas_error error = IVAS_ERR_OK; + IVAS_DEC_HANDLE hIvasDec; + + if ( phIvasDec == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( NULL != *phIvasDec ) + { + IVAS_DEC_Close( phIvasDec ); + } + + if ( ( error = IVAS_DEC_Open( phIvasDec, codec ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Open failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + arg->decMode = codec; + + hIvasDec = *phIvasDec; + + uint16_t aeID = arg->aeSequence.count > 0 ? arg->aeSequence.pID[0] : 65535; + + IVAS_AUDIO_CONFIG outputConfig = ( codec == IVAS_DEC_MODE_IVAS ) ? arg->outputConfig : IVAS_AUDIO_CONFIG_MONO; +#ifdef FIX_1318_ROOM_SIZE_CMD_LINE + if ( ( error = IVAS_DEC_Configure( hIvasDec, arg->output_Fs, outputConfig, arg->renderFramesize, arg->customLsOutputEnabled, arg->hrtfReaderEnabled, + arg->enableHeadRotation, arg->enableExternalOrientation, arg->orientation_tracking, arg->renderConfigEnabled, arg->roomSize, arg->non_diegetic_pan_enabled, + arg->non_diegetic_pan_gain_fx, arg->dpidEnabled, aeID, arg->objEditEnabled, arg->delayCompensationEnabled ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_Configure( hIvasDec, arg->output_Fs, outputConfig, arg->renderFramesize, arg->customLsOutputEnabled, arg->hrtfReaderEnabled, + arg->enableHeadRotation, arg->enableExternalOrientation, arg->orientation_tracking, arg->renderConfigEnabled, arg->non_diegetic_pan_enabled, + arg->non_diegetic_pan_gain_fx, arg->dpidEnabled, aeID, arg->objEditEnabled, arg->delayCompensationEnabled ) ) != IVAS_ERR_OK ) +#endif + { + fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( ( error = IVAS_DEC_GetRenderFramesize( hIvasDec, &arg->renderFramesize ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( arg->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = IVAS_DEC_EnableSplitRendering( hIvasDec ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nSplit rendering configure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( ( error = IVAS_DEC_GetRenderFramesize( hIvasDec, &arg->renderFramesize ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + arg->enableHeadRotation = true; + } + + if ( arg->voipMode ) + { + if ( ( error = IVAS_DEC_EnableVoIP( hIvasDec, 60, arg->inputFormat ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nCould not enable VOIP: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + + if ( ( error = IVAS_DEC_PrintConfig( hIvasDec, 1, arg->voipMode ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_PrintConfig failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( arg->renderConfigEnabled && renderConfig != NULL ) + { + if ( ( error = IVAS_DEC_FeedRenderConfig( hIvasDec, *renderConfig ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + + if ( arg->customLsOutputEnabled && hLsCustomData != NULL ) + { + if ( ( error = IVAS_DEC_FeedCustomLsData( hIvasDec, *hLsCustomData ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedCustomLsData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + + return IVAS_ERR_OK; + +cleanup: + IVAS_DEC_Close( phIvasDec ); + return error; +} + +#endif + #undef WMC_TOOL_SKIP diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 0e607039f7cb35642d8181270e953354be7d227c..0cb0174d691783bc653a12359861190a292acb61 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -4030,7 +4030,12 @@ ivas_error ivas_output_buff_dec_fx( ); ivas_error ivas_dec_get_format_fx( +#ifdef DECODER_FORMAT_SWITCHING + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const bool isVoipMode /* i : voip mode indicator */ +#else Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +#endif ); ivas_error ivas_dec_setup( diff --git a/lib_com/options.h b/lib_com/options.h index f06deff8c79775b0d3a819c40a61694153064b1a..b6d1ca2b647e22dd5a1e7ac4d3b57b274e472264 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -169,6 +169,7 @@ #define ISM_PI_DATA /* Add reading and packing/unpacking of ISM PI data */ #define REVERSE_ISM_PI_DATA /* Add reading and packing/unpacking of reverse ISM PI data */ #define PI_LATENCY /* Support for PI latency */ +#define DECODER_FORMAT_SWITCHING /* Re-initialize the decoder when the format/subformat of the incoming stream is changed */ /* #################### End BASOP porting switches ############################ */ diff --git a/lib_dec/ivas_init_dec_fx.c b/lib_dec/ivas_init_dec_fx.c index 5300b598b50bf9cb3941820f240f5dfe09e737e6..984f02ece1139d7654e2b95bec5b25f5147b3e59 100644 --- a/lib_dec/ivas_init_dec_fx.c +++ b/lib_dec/ivas_init_dec_fx.c @@ -104,7 +104,12 @@ static AUDIO_CONFIG ivas_set_audio_config_from_sba_order( *---------------------------------------------------------------------*/ ivas_error ivas_dec_get_format_fx( +#ifdef DECODER_FORMAT_SWITCHING + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const bool isVoipMode /* i : voip mode indicator */ +#else Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +#endif ) { Word16 k, idx, num_bits_read; @@ -142,10 +147,26 @@ ivas_error ivas_dec_get_format_fx( !( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && EQ_32( st_ivas->last_ivas_format, MASA_ISM_FORMAT ) ) && !( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->last_ivas_format, MASA_FORMAT ) ) ) { +#ifdef DECODER_FORMAT_SWITCHING + IF( isVoipMode ) + { + st_ivas->restartNeeded = 1; + move16(); + return IVAS_ERR_OK; + } + ELSE + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Changing the number of ISMs is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong number of objects signalled!" ); + } +#else #ifdef DEBUGGING fprintf( stderr, "\nError: Changing the number of ISMs is not supported!\n" ); #endif return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong number of objects signalled!" ); +#endif } /*-------------------------------------------------------------------* @@ -183,10 +204,26 @@ ivas_error ivas_dec_get_format_fx( test(); IF( st_ivas->ini_frame > 0 && NE_16( nchan_ism, st_ivas->nchan_ism ) ) { +#ifdef DECODER_FORMAT_SWITCHING + IF( isVoipMode ) + { + st_ivas->restartNeeded = 1; + move16(); + return IVAS_ERR_OK; + } + ELSE + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Changing the number of ISMs is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong number of objects signalled!" ); + } +#else #ifdef DEBUGGING fprintf( stderr, "\nError: Changing the number of ISMs is not supported!\n" ); #endif return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong number of objects signalled!" ); +#endif } st_ivas->nchan_ism = nchan_ism; @@ -210,10 +247,26 @@ ivas_error ivas_dec_get_format_fx( test(); IF( st_ivas->ini_frame > 0 && NE_16( sba_planar, st_ivas->sba_planar ) ) { +#ifdef DECODER_FORMAT_SWITCHING + IF( isVoipMode ) + { + st_ivas->restartNeeded = 1; + move16(); + return IVAS_ERR_OK; + } + ELSE + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Changing the SBA planar/3D layout is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong SBA planar flag signalled!" ); + } +#else #ifdef DEBUGGING fprintf( stderr, "\nError: Changing the SBA planar/3D layout is not supported!\n" ); #endif return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong SBA planar flag signalled!" ); +#endif } /* read Ambisonic (SBA) order */ @@ -224,10 +277,26 @@ ivas_error ivas_dec_get_format_fx( test(); IF( st_ivas->ini_frame > 0 && NE_16( sba_order, st_ivas->sba_order ) ) { +#ifdef DECODER_FORMAT_SWITCHING + IF( isVoipMode ) + { + st_ivas->restartNeeded = 1; + move16(); + return IVAS_ERR_OK; + } + ELSE + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Changing the SBA order is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong SBA order signalled!" ); + } +#else #ifdef DEBUGGING fprintf( stderr, "\nError: Changing the SBA order is not supported!\n" ); #endif return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong SBA order signalled!" ); +#endif } sba_analysis_order = ivas_sba_get_analysis_order_fx( ivas_total_brate, sba_order ); @@ -235,10 +304,23 @@ ivas_error ivas_dec_get_format_fx( } ELSE IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) ) { +#ifdef DECODER_FORMAT_SWITCHING + UWord8 masaRestartCandidate; + masaRestartCandidate = 0; + move16(); +#endif /* read number of MASA transport channels */ k = extract_l( Mpy_32_32_r( ivas_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ); IF( st_ivas->bit_stream[k - 1] ) { +#ifdef DECODER_FORMAT_SWITCHING + test(); + IF( st_ivas->nchan_transport == 1 && isVoipMode ) + { + masaRestartCandidate = 1; + move16(); + } +#endif st_ivas->nchan_transport = 2; move16(); element_mode_flag = 1; @@ -246,6 +328,14 @@ ivas_error ivas_dec_get_format_fx( } ELSE { +#ifdef DECODER_FORMAT_SWITCHING + test(); + IF( st_ivas->nchan_transport == 2 && isVoipMode ) + { + masaRestartCandidate = 1; + move16(); + } +#endif st_ivas->nchan_transport = 1; move16(); } @@ -279,14 +369,38 @@ ivas_error ivas_dec_get_format_fx( element_mode_flag = 1; move16(); } +#ifdef DECODER_FORMAT_SWITCHING + ELSE IF( masaRestartCandidate > 0 ) + { + st_ivas->restartNeeded = 1; + move16(); + return IVAS_ERR_OK; + } +#endif test(); IF( st_ivas->ini_frame > 0 && NE_16( nchan_ism, st_ivas->nchan_ism ) ) { +#ifdef DECODER_FORMAT_SWITCHING + IF( isVoipMode ) + { + st_ivas->restartNeeded = 1; + move16(); + return IVAS_ERR_OK; + } + ELSE + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Changing the number of ISMs is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong number of objects signalled!" ); + } +#else #ifdef DEBUGGING fprintf( stderr, "\nError: Changing the number of ISMs is not supported!\n" ); #endif return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong number of objects signalled!" ); +#endif } st_ivas->nchan_ism = nchan_ism; @@ -305,10 +419,26 @@ ivas_error ivas_dec_get_format_fx( test(); IF( st_ivas->ini_frame > 0 && NE_16( nchan_ism, st_ivas->nchan_ism ) ) { +#ifdef DECODER_FORMAT_SWITCHING + IF( isVoipMode ) + { + st_ivas->restartNeeded = 1; + move16(); + return IVAS_ERR_OK; + } + ELSE + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Changing the number of ISMs is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong number of objects signalled!" ); + } +#else #ifdef DEBUGGING fprintf( stderr, "\nError: Changing the number of ISMs is not supported!\n" ); #endif return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong number of objects signalled!" ); +#endif } st_ivas->nchan_ism = nchan_ism; @@ -323,10 +453,26 @@ ivas_error ivas_dec_get_format_fx( test(); IF( st_ivas->ini_frame > 0 && NE_16( nchan_ism, st_ivas->nchan_ism ) ) { +#ifdef DECODER_FORMAT_SWITCHING + IF( isVoipMode ) + { + st_ivas->restartNeeded = 1; + move16(); + return IVAS_ERR_OK; + } + ELSE + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Changing the number of ISMs is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong number of objects signalled!" ); + } +#else #ifdef DEBUGGING fprintf( stderr, "\nError: Changing the number of ISMs is not supported!\n" ); #endif return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong number of objects signalled!" ); +#endif } st_ivas->nchan_ism = nchan_ism; @@ -354,10 +500,26 @@ ivas_error ivas_dec_get_format_fx( test(); IF( st_ivas->ini_frame > 0 && NE_16( sba_order, st_ivas->sba_order ) ) { +#ifdef DECODER_FORMAT_SWITCHING + IF( isVoipMode ) + { + st_ivas->restartNeeded = 1; + move16(); + return IVAS_ERR_OK; + } + ELSE + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Changing the SBA order is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong SBA order signalled!" ); + } +#else #ifdef DEBUGGING fprintf( stderr, "\nError: Changing the SBA order is not supported!\n" ); #endif return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong SBA order signalled!" ); +#endif } st_ivas->ism_mode = ivas_osba_ism_mode_select( ivas_total_brate, st_ivas->nchan_ism ); @@ -384,10 +546,26 @@ ivas_error ivas_dec_get_format_fx( test(); IF( st_ivas->ini_frame > 0 && NE_32( st_ivas->transport_config, signaled_config ) ) { +#ifdef DECODER_FORMAT_SWITCHING + IF( isVoipMode ) + { + st_ivas->restartNeeded = 1; + move16(); + return IVAS_ERR_OK; + } + ELSE + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Switching of MC configurations is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "wrong MC configuration signalled!" ); + } +#else #ifdef DEBUGGING fprintf( stderr, "\nError: Switching of MC configurations is not supported!\n" ); #endif return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "wrong MC configuration signalled!" ); +#endif } st_ivas->mc_mode = ivas_mc_mode_select_fx( ivas_mc_map_output_config_to_mc_ls_setup_fx( signaled_config ), ivas_total_brate ); @@ -486,10 +664,26 @@ ivas_error ivas_dec_get_format_fx( test(); IF( st_ivas->ini_frame > 0 && NE_16( nchan_ism, st_ivas->nchan_ism ) ) { +#ifdef DECODER_FORMAT_SWITCHING + IF( isVoipMode ) + { + st_ivas->restartNeeded = 1; + move16(); + return IVAS_ERR_OK; + } + ELSE + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Changing the number of ISMs is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong number of objects signalled!" ); + } +#else #ifdef DEBUGGING fprintf( stderr, "\nError: Changing the number of ISMs is not supported!\n" ); #endif return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong number of objects signalled!" ); +#endif } st_ivas->nchan_ism = nchan_ism; diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 8a384809d0ac1a330084897cf8c25ffbdc037c29..df8607cb5fbbdb9ecc2cc3d86569b65200e6956e 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1223,6 +1223,9 @@ typedef struct Decoder_Struct #ifdef TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR Word16 flushing; #endif +#ifdef DECODER_FORMAT_SWITCHING + UWord8 restartNeeded; /* Flag to check if the decoder requires a restart */ +#endif } Decoder_Struct; diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index dad682f73d7a61fc5ef6d75bfef2581e8ad8ae44..23a353ff03d4bb4540660bf736528d2c36b2d600 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -341,6 +341,12 @@ ivas_error IVAS_DEC_Flush( Word16 *nSamplesFlushed /* o : number of samples flushed */ ); +#ifdef DECODER_FORMAT_SWITCHING +bool IVAS_DEC_isRestartNeeded( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +); + +#endif /* Setter functions - apply changes to decoder configuration */ /*! r: error code */ diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 5ae845a46b623f1cbb36a084f067e4566e28fa2c..246fd4e297ff23a12bd73c3161dee26f8ccf30cc 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -241,6 +241,11 @@ ivas_error IVAS_DEC_Open( /* initialize pointers to handles to NULL */ ivas_initialize_handles_dec( st_ivas ); +#ifdef DECODER_FORMAT_SWITCHING + st_ivas->restartNeeded = 0; + move16(); +#endif + /* set high-level parameters */ IF( EQ_16( mode, IVAS_DEC_MODE_EVS ) ) { @@ -2159,12 +2164,24 @@ ivas_error IVAS_DEC_GetFormat( } move32(); +#ifdef DECODER_FORMAT_SWITCHING + test(); + IF( EQ_32( *format, IVAS_DEC_BS_MASA ) && hIvasDec->st_ivas->hMasa != NULL ) + { + IF( EQ_32( hIvasDec->st_ivas->hMasa->config.input_ivas_format, MASA_ISM_FORMAT ) ) + { + *format = IVAS_DEC_BS_MASA_ISM; + move32(); + } + } +#else test(); if ( EQ_32( *format, IVAS_DEC_BS_MASA ) && EQ_32( hIvasDec->st_ivas->hMasa->config.input_ivas_format, MASA_ISM_FORMAT ) ) { *format = IVAS_DEC_BS_MASA_ISM; move32(); } +#endif return IVAS_ERR_OK; } @@ -3977,7 +3994,9 @@ ivas_error IVAS_DEC_ReadFormat( { ivas_error error; Decoder_Struct *st_ivas; +#ifndef DECODER_FORMAT_SWITCHING IVAS_FORMAT ivas_format_old; +#endif ISM_MODE ism_mode_old; MC_MODE mc_mode_old; Word16 nchan_transport_old; @@ -3991,7 +4010,9 @@ ivas_error IVAS_DEC_ReadFormat( } st_ivas = hIvasDec->st_ivas; +#ifndef DECODER_FORMAT_SWITCHING ivas_format_old = st_ivas->ivas_format; +#endif ism_mode_old = st_ivas->ism_mode; mc_mode_old = st_ivas->mc_mode; nchan_transport_old = st_ivas->nchan_transport; @@ -4000,7 +4021,9 @@ ivas_error IVAS_DEC_ReadFormat( renderer_type_old = st_ivas->renderer_type; renderer_type_sec_old = ivas_renderer_secondary_select_fx( st_ivas ); move32(); +#ifndef DECODER_FORMAT_SWITCHING move32(); +#endif move32(); move16(); move32(); @@ -4018,11 +4041,22 @@ ivas_error IVAS_DEC_ReadFormat( IF( st_ivas->bfi == 0 ) { +#ifdef DECODER_FORMAT_SWITCHING + IF( NE_32( error = ivas_dec_get_format_fx( st_ivas, hIvasDec->hVoIP != NULL ), IVAS_ERR_OK ) ) +#else IF( NE_32( error = ivas_dec_get_format_fx( st_ivas ), IVAS_ERR_OK ) ) +#endif { return error; } +#ifdef DECODER_FORMAT_SWITCHING + IF( st_ivas->restartNeeded > 0 ) + { + return IVAS_ERR_OK; + } +#else + test(); test(); test(); @@ -4030,6 +4064,7 @@ ivas_error IVAS_DEC_ReadFormat( { return ( IVAS_ERROR( IVAS_ERR_INVALID_INPUT_FORMAT, "IVAS format switching is not allowed." ) ); } +#endif /* Select binaural renderer */ ivas_renderer_select( st_ivas ); @@ -5612,6 +5647,22 @@ ivas_error IVAS_DEC_Flush( } +#ifdef DECODER_FORMAT_SWITCHING +/*---------------------------------------------------------------------* + * IVAS_DEC_isRestartNeeded( ) + * + * + *---------------------------------------------------------------------*/ + +bool IVAS_DEC_isRestartNeeded( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +) +{ + return hIvasDec->st_ivas->restartNeeded > 0; +} + + +#endif /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_IsEmpty( ) *