Commit adaca99d authored by vaclav's avatar vaclav
Browse files

- SWITCHING_FORMAT_DEC - issue 326: Bitstream Switching (Decoder side)

- SWITCHING_FORMAT_ENC - VA: issue 325: Encoder Input format Switching
- SIMULATE_FORMAT_SWITCHING_ENC (deactivated) - debugging: simulate Input format switching
parent 9f858d30
Loading
Loading
Loading
Loading
Loading
+238 −3
Original line number Diff line number Diff line
@@ -136,13 +136,24 @@ typedef struct
 *------------------------------------------------------------------------------------------*/

static void initArgStruct( EncArguments *arg );
static bool parseCmdlIVAS_enc( int16_t argc, char *argv[], EncArguments *arg );
static bool parseCmdlIVAS_enc( int16_t argc, char *argv[], EncArguments *arg
#ifdef SWITCHING_FORMAT_ENC
                               ,
                               const bool reconfig_flag
#endif
);
static void usage_enc( void );
static bool readBandwidth( FILE *file, IVAS_ENC_BANDWIDTH *bandwidth, int32_t *bandwidthFrameCounter );
static bool readBitrate( FILE *file, int32_t *bitrate );
#ifdef SWITCHING_FORMAT_ENC
static ivas_error configureEnc( const EncArguments arg, IVAS_ENC_HANDLE hIvasEnc, const int32_t totalBitrate, const IVAS_ENC_BANDWIDTH bandwidth, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig );
#endif
#ifdef DEBUGGING
static ivas_error readForcedMode( FILE *file, IVAS_ENC_FORCED_MODE *forcedMode, int32_t *forceFrameCounter );
static IVAS_ENC_FORCED_MODE parseForcedMode( char *forcedModeChar );
#ifdef SIMULATE_FORMAT_SWITCHING_ENC
static void simulate_input_format_switching( int16_t *argc_new, char *p_argv_new[10], bool *reinit_flag );
#endif
#endif


@@ -198,7 +209,12 @@ int main(

    IVAS_ENC_PrintDisclaimer();

    if ( !parseCmdlIVAS_enc( (int16_t) argc, argv, &arg ) )
    if ( !parseCmdlIVAS_enc( (int16_t) argc, argv, &arg
#ifdef SWITCHING_FORMAT_ENC
                             ,
                             false
#endif
                             ) )
    {
        /* Error printout done internally in parseCmdlIVAS_enc() */
        goto cleanup;
@@ -217,7 +233,9 @@ int main(
    /*------------------------------------------------------------------------------------------*
     * Open input audio file
     *------------------------------------------------------------------------------------------*/

    int32_t inFileSampleRate = 0;

    if ( AudioFileReader_open( &audioReader, arg.inputWavFilename, &inFileSampleRate ) != IVAS_ERR_OK )
    {
        fprintf( stderr, "\nCan't open %s\n\n", arg.inputWavFilename );
@@ -373,6 +391,12 @@ int main(
     * Configure and initialize (allocate memory for static variables) the encoder
     *------------------------------------------------------------------------------------------*/

#ifdef SWITCHING_FORMAT_ENC
    if ( ( error = configureEnc( arg, hIvasEnc, totalBitrate, bandwidth, caConfig ) ) != IVAS_ERR_OK )
    {
        goto cleanup;
    }
#else
    switch ( arg.inputFormat )
    {
        case IVAS_ENC_INPUT_MONO:
@@ -444,6 +468,7 @@ int main(
            fprintf( stderr, "\nInvalid input type\n\n" );
            goto cleanup;
    }
#endif

    if ( ( error = IVAS_ENC_PrintConfig( hIvasEnc, caConfig.channelAwareModeEnabled ) ) != IVAS_ERR_OK )
    {
@@ -565,8 +590,53 @@ int main(
     * - Write the parameters into output bitstream file
     *------------------------------------------------------------------------------------------*/

#ifdef SWITCHING_FORMAT_ENC
    bool reinit_flag = false;
    char *p_argv_new[10];
    int16_t argc_new = -1;
#endif

    while ( 1 )
    {
#ifdef SWITCHING_FORMAT_ENC
#ifdef SIMULATE_FORMAT_SWITCHING_ENC
        /* simulate input format switching */
        simulate_input_format_switching( &argc_new, p_argv_new, &reinit_flag );
#endif

        /* Reinitialization of the encoder in case of application parameter(s) change (e.g. change of IVAS input format) */
        if ( reinit_flag )
        {
            IVAS_ENC_Close_Reinit( &hIvasEnc );

            if ( !parseCmdlIVAS_enc( argc_new, p_argv_new, &arg, true ) )
            {
                goto cleanup;
            }

            /* Configure and initialize (allocate memory for static variables) the encoder */
            if ( ( error = configureEnc( arg, hIvasEnc, totalBitrate, bandwidth, caConfig ) ) != IVAS_ERR_OK )
            {
                goto cleanup;
            }

            /* Allocate input data buffer */
            int16_t pcmBufSize_new;
            if ( ( error = IVAS_ENC_GetInputBufferSize( hIvasEnc, &pcmBufSize_new ) ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "\nGetInputBufferSize failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) );
                goto cleanup;
            }

            if ( pcmBufSize_new != pcmBufSize )
            {
                free( pcmBuf );
                pcmBuf = malloc( pcmBufSize_new * sizeof( int16_t ) );
                pcmBufSize = pcmBufSize_new;
            }
        }
#endif

        /* Read the input data */
        if ( ( error = AudioFileReader_read( audioReader, pcmBuf, pcmBufSize, &numSamplesRead ) ) != IVAS_ERR_OK )
        {
@@ -864,7 +934,12 @@ static void initArgStruct( EncArguments *arg )
static bool parseCmdlIVAS_enc(
    int16_t argc,
    char *argv[],
    EncArguments *arg )
    EncArguments *arg
#ifdef SWITCHING_FORMAT_ENC
    ,
    const bool reconfig_flag
#endif
)
{
    int16_t i, j;
    char argv_to_upper[FILENAME_MAX];
@@ -1457,6 +1532,17 @@ static bool parseCmdlIVAS_enc(
        }
    } /* end of while  */

#ifdef SWITCHING_FORMAT_ENC
    /*-----------------------------------------------------------------*
     * Return in case of reconfiguration
     *-----------------------------------------------------------------*/

    if ( reconfig_flag == true )
    {
        return true;
    }
#endif

    /*-----------------------------------------------------------------*
     * Mandatory input arguments
     *-----------------------------------------------------------------*/
@@ -1739,6 +1825,99 @@ static bool readBitrate(
}


#ifdef SWITCHING_FORMAT_ENC
/*---------------------------------------------------------------------*
 * configureEnc()
 *
 * Configure and initialize the encoder
 *---------------------------------------------------------------------*/

static ivas_error configureEnc(
    const EncArguments arg,
    IVAS_ENC_HANDLE hIvasEnc,
    const int32_t totalBitrate,
    const IVAS_ENC_BANDWIDTH bandwidth,
    const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig )
{
    ivas_error error = IVAS_ERR_UNKNOWN;

    switch ( arg.inputFormat )
    {
        case IVAS_ENC_INPUT_MONO:
            if ( ( error = IVAS_ENC_ConfigureForMono( hIvasEnc, arg.inputFs, totalBitrate, arg.max_bwidth_user, bandwidth, arg.dtxConfig, caConfig, arg.inputFormatConfig.stereoToMonoDownmix ) ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "\nIVAS_ENC_ConfigureForMono failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) );
                return error;
            }
            break;
        case IVAS_ENC_INPUT_STEREO:
#ifdef DEBUGGING
            if ( ( error = IVAS_ENC_ConfigureForStereo( hIvasEnc, arg.inputFs, totalBitrate, arg.max_bwidth_user, bandwidth, arg.dtxConfig, arg.inputFormatConfig.stereoMode ) ) != IVAS_ERR_OK )
#else
            if ( ( error = IVAS_ENC_ConfigureForStereo( hIvasEnc, arg.inputFs, totalBitrate, arg.max_bwidth_user, bandwidth, arg.dtxConfig ) ) != IVAS_ERR_OK )
#endif
            {
                fprintf( stderr, "\nIVAS_ENC_ConfigureForStereo failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) );
                return error;
            }
            break;
        case IVAS_ENC_INPUT_ISM:
            if ( ( error = IVAS_ENC_ConfigureForObjects( hIvasEnc, arg.inputFs, totalBitrate, arg.max_bwidth_user, bandwidth, arg.dtxConfig, arg.inputFormatConfig.ism.numObjects ) ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "\nIVAS_ENC_ConfigureForObjects failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) );
                return error;
            }
            break;
        case IVAS_ENC_INPUT_SBA:
            if ( ( error =
                       IVAS_ENC_ConfigureForAmbisonics(
                           hIvasEnc,
                           arg.inputFs,
                           totalBitrate,
                           arg.max_bwidth_user,
                           bandwidth,
                           arg.dtxConfig,
                           arg.inputFormatConfig.sba.order,
                           arg.inputFormatConfig.sba.isPlanar,
#ifdef DEBUG_AGC_ENCODER_CMD_OPTION
                           arg.agc,
#endif
                           arg.pca
#ifdef DEBUG_SBA_AUDIO_DUMP
                           ,
                           &numTransportChannels
#endif
                           ) ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "\nIVAS_ENC_ConfigureForAmbisonics failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) );
                return error;
            }

            break;
        case IVAS_ENC_INPUT_MASA:
            if ( ( error = IVAS_ENC_ConfigureForMasa( hIvasEnc, arg.inputFs, totalBitrate, arg.max_bwidth_user, bandwidth, arg.dtxConfig, arg.inputFormatConfig.masaVariant ) ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "\nIVAS_ENC_ConfigureForMasa failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) );
                return error;
            }
            break;
        case IVAS_ENC_INPUT_MC:
            if ( ( error = IVAS_ENC_ConfigureForMultichannel( hIvasEnc, arg.inputFs, totalBitrate, arg.max_bwidth_user, bandwidth, arg.dtxConfig, arg.inputFormatConfig.mcLayout ) ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "\nIVAS_ENC_ConfigureForMultichannel failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) );
                return error;
            }
            break;
        default:
            fprintf( stderr, "\nInvalid input type\n\n" );
            return error;
    }

    return error;
}
#endif


#ifdef DEBUGGING
/*---------------------------------------------------------------------*
 * parseForcedMode()
@@ -1823,4 +2002,60 @@ static ivas_error readForcedMode(

    return IVAS_ERR_OK;
}


#ifdef SIMULATE_FORMAT_SWITCHING_ENC
/*---------------------------------------------------------------------*
 * simulate_input_format_switching()
 *
 * Simulation of IVAS input format switching
 *---------------------------------------------------------------------*/

#define ENC_FORMAT_VARIANTS 7

char input_params[ENC_FORMAT_VARIANTS][6][50] = {
    { "1", { "-stereo" } },
    { "4", { "-ism" }, { "2" }, { "NULL" }, { "NULL" } },
    { "2", { "-MC" }, { "5_1" } },
    { "2", { "-sba" }, { "3" } },
    { "3", { "-ism" }, { "1" }, { "NULL" } },
    { "2", { "-sba" }, { "-2" } },
    { "2", { "-MC" }, { "7_1_4" } },
};

static void simulate_input_format_switching(
    int16_t *argc_new,
    char *p_argv_new[10],
    bool *reinit_flag )
{
    int16_t i;
    static int16_t ff = -1;

    *reinit_flag = 0;
    *argc_new = -1;
    *p_argv_new = NULL;

    if ( frame % 20 == 0 )
    {
        ff++;
        if ( ff > ENC_FORMAT_VARIANTS - 1 )
        {
            ff = 0;
        }
        *reinit_flag = 1;
    }

    if ( *reinit_flag )
    {
        *argc_new = (int16_t) atoi( input_params[ff][0] );
        for ( i = 0; i < *argc_new + 1; i++ )
        {
            p_argv_new[i] = input_params[ff][i];
        }
        *argc_new += 5; /* 4 mandatory parameters + executable name */
    }

    return;
}
#endif
#endif
+11 −0
Original line number Diff line number Diff line
@@ -410,12 +410,23 @@ void destroy_core_dec(

void ivas_destroy_dec(
    Decoder_Struct *st_ivas                                     /* i/o: IVAS decoder structure                  */
#ifdef SWITCHING_FORMAT_DEC
    ,
    const int16_t flag_all                                      /* i  : 1 == destroy external data handles      */
#endif
);

void ivas_initialize_handles_dec(
    Decoder_Struct *st_ivas                                     /* i/o: IVAS decoder structure                  */
);

#ifdef SWITCHING_FORMAT_DEC
void ivas_decoder_init_highlevel_params(
    const IVAS_FORMAT ivas_format,                              /* i  : IVAS format                             */
    Decoder_Struct *st_ivas                                     /* i/o: IVAS decoder structure                  */
);
#endif

ivas_error ivas_core_enc(
    SCE_ENC_HANDLE hSCE,                                                     /* i/o: SCE encoder structure                   */
    CPE_ENC_HANDLE hCPE,                                                     /* i/o: CPE encoder structure                   */
+5 −0
Original line number Diff line number Diff line
@@ -168,6 +168,11 @@
#define FIX_317                                         /* FhG: issue 317 - address sanitizer error in MDCT-Stereo PLC */


#define SWITCHING_FORMAT_DEC                            /* VA: issue 326: Bitstream Switching (Decoder side) */
#define SWITCHING_FORMAT_ENC                            /* VA: issue 325: Encoder Input format Switching */
/*#define SIMULATE_FORMAT_SWITCHING_ENC*/               /* VA: debugging: simulate Input format switching */


/* ################## End DEVELOPMENT switches ######################### */
/* clang-format on */
#endif
+135 −43
Original line number Diff line number Diff line
@@ -69,6 +69,12 @@ ivas_error ivas_dec_setup(
    Decoder_State *st;
    int32_t ivas_total_brate;
    ivas_error error;
#ifdef SWITCHING_FORMAT_DEC
    IVAS_FORMAT ivas_format_old;

    ivas_format_old = st_ivas->ivas_format;
#endif

    error = IVAS_ERR_OK;

    num_bits_read = 0;
@@ -82,9 +88,24 @@ ivas_error ivas_dec_setup(

    ivas_read_format( st_ivas, &num_bits_read );

#ifdef SWITCHING_FORMAT_DEC
    /*-------------------------------------------------------------------*
     * Reinitialize the decoder in case of the IVAS format change
     *-------------------------------------------------------------------*/

    if ( is_DTXrate( ivas_total_brate ) == 0 )
    if ( ivas_format_old != st_ivas->ivas_format && st_ivas->ini_frame > 0 )
    {
        IVAS_FORMAT ivas_format_read = st_ivas->ivas_format;

        /* Destroy the decoder handle */
        st_ivas->ivas_format = ivas_format_old;
        ivas_destroy_dec( st_ivas, 0 );

        /* set decoder high level parameters */
        ivas_decoder_init_highlevel_params( ivas_format_read, st_ivas );
    }
#endif

    /*-------------------------------------------------------------------*
     * Read IVAS format related signaling:
     * - in ISM  : read number of objects
@@ -93,6 +114,8 @@ ivas_error ivas_dec_setup(
     * - in MC   : read LS setup
     *-------------------------------------------------------------------*/

    if ( is_DTXrate( ivas_total_brate ) == 0 )
    {
        if ( st_ivas->ivas_format == STEREO_FORMAT )
        {
            element_mode_flag = 1;
@@ -157,6 +180,10 @@ ivas_error ivas_dec_setup(
            }
            else
            {
#ifdef SWITCHING_FORMAT_DEC
                st_ivas->sba_mode = ivas_sba_mode_select( ivas_total_brate );
#endif

                ivas_sba_config( ivas_total_brate, st_ivas->sba_analysis_order, -1, &( st_ivas->nchan_transport ), st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init );
            }
        }
@@ -364,8 +391,9 @@ static ivas_error ivas_read_format(
                else
                {
                    st_ivas->ivas_format = SBA_FORMAT;

#ifndef SWITCHING_FORMAT_DEC
                    st_ivas->sba_mode = ivas_sba_mode_select( ivas_total_brate );
#endif
                }
                ( *num_bits_read )++;
                break;
@@ -796,7 +824,6 @@ ivas_error ivas_init_decoder(
    }
    else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT )
    {

        if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK )
        {
            return error;
@@ -811,6 +838,10 @@ ivas_error ivas_init_decoder(
        }
        else if ( st_ivas->ivas_format == SBA_FORMAT )
        {
#ifdef SWITCHING_FORMAT_DEC
            st_ivas->sba_mode = ivas_sba_mode_select( ivas_total_brate );
#endif

            if ( st_ivas->sba_mode == SBA_MODE_SPAR )
            {
                if ( ( error = ivas_spar_dec_open( st_ivas ) ) != IVAS_ERR_OK )
@@ -1563,6 +1594,53 @@ void ivas_initialize_handles_dec(
}


#ifdef SWITCHING_FORMAT_DEC
/*-----------------------------------------------------------------
 * ivas_initialize_handles_dec()
 *
 * initialize high-level parameters
 *-----------------------------------------------------------------*/

void ivas_decoder_init_highlevel_params(
    const IVAS_FORMAT ivas_format, /* i  : IVAS format              */
    Decoder_Struct *st_ivas        /* i/o: IVAS decoder structure   */
)
{
    st_ivas->ivas_format = ivas_format;

    if ( ivas_format == MONO_FORMAT )
    {
        st_ivas->codec_mode = 0; /* unknown before first frame */
        st_ivas->element_mode_init = EVS_MONO;
        st_ivas->transport_config = AUDIO_CONFIG_INVALID;
        st_ivas->intern_config = AUDIO_CONFIG_INVALID;
        st_ivas->writeFECoffset = 0;
    }
    else
    {
        st_ivas->codec_mode = 0; /* unknown before first frame */
        st_ivas->element_mode_init = -1;
        st_ivas->transport_config = AUDIO_CONFIG_INVALID;
        st_ivas->intern_config = AUDIO_CONFIG_INVALID;
        st_ivas->renderer_type = RENDERER_DISABLE;
        st_ivas->ini_frame = 0;
        st_ivas->ini_active_frame = 0;
        st_ivas->writeFECoffset = 0;

        st_ivas->ism_mode = ISM_MODE_NONE;
        st_ivas->sba_mode = SBA_MODE_NONE;
        st_ivas->mc_mode = MC_MODE_NONE;

        st_ivas->sba_order = 0;
        st_ivas->sba_planar = 0;
        st_ivas->sba_analysis_order = 0;
    }

    return;
}
#endif


/*-------------------------------------------------------------------------
 * ivas_destroy_dec()
 *
@@ -1571,6 +1649,10 @@ void ivas_initialize_handles_dec(

void ivas_destroy_dec(
    Decoder_Struct *st_ivas /* i/o: IVAS decoder handle      */
#ifdef SWITCHING_FORMAT_DEC
    ,
    const int16_t flag_all /* i  : 1 == destroy external data handles */
#endif
)
{
    int16_t i, n;
@@ -1736,6 +1818,10 @@ void ivas_destroy_dec(
        st_ivas->hMonoDmxRenderer = NULL;
    }

#ifdef SWITCHING_FORMAT_DEC
    if ( flag_all )
    {
#endif
        /* Head track data handle */
        if ( st_ivas->hHeadTrackData != NULL )
        {
@@ -1779,9 +1865,14 @@ void ivas_destroy_dec(
        /* Config. Renderer */
        ivas_render_config_close( &( st_ivas->hRenderConfig ) );

#ifdef SWITCHING_FORMAT_DEC
    }
#endif

    /* Limiter struct */
    ivas_limiter_close( &( st_ivas->hLimiter ) );

#ifndef SWITCHING_FORMAT_DEC
    if ( st_ivas->hDecoderConfig != NULL )
    {
        free( st_ivas->hDecoderConfig );
@@ -1790,6 +1881,7 @@ void ivas_destroy_dec(

    /* main IVAS handle */
    free( st_ivas );
#endif

    return;
}
+5 −0
Original line number Diff line number Diff line
@@ -1060,8 +1060,13 @@ void ivas_param_mc_dec_close(
        hParamMC->hoa_encoder = NULL;
    }

#ifdef SWITCHING_FORMAT_DEC
    free( *hParamMC_out );
    *hParamMC_out = NULL;
#else
    free( hParamMC );
    hParamMC = NULL;
#endif

    return;
}
Loading