Commit e3d323ab authored by fotopoulou's avatar fotopoulou
Browse files

enable decoder bitrate switching framework

parent 8088474c
Loading
Loading
Loading
Loading
+11 −6
Original line number Diff line number Diff line
@@ -637,6 +637,12 @@ ivas_error ivas_mc_dec_config(
    Decoder_Struct *st_ivas,                                    /* i/o: IVAS decoder structure                  */
    const int16_t idx                                           /* i  : LS config. index                        */
);
#ifdef MC_BITRATE_SWITCHING
ivas_error ivas_mc_dec_reconfig(
    Decoder_Struct *st_ivas,   /* i/o: IVAS encoder structure      */
    const int16_t last_mc_mode /* i  : last frame MC mode          */
);
#endif

/*! r: MC format mode (MCT, McMASA, ParamMC) */
MC_MODE ivas_mc_mode_select(
@@ -3501,12 +3507,6 @@ ivas_error ivas_param_mc_enc_open(
    Encoder_Struct *st_ivas                                     /* i/o: IVAS encoder handle                                 */
);
#ifdef MC_BITRATE_SWITCHING
/*-------------------------------------------------------------------------
 * ivas_param_mc_enc_open()
 *
 * Initialize Parametric MC encoder handle
 *------------------------------------------------------------------------*/

ivas_error ivas_param_mc_reconfig(
    Encoder_Struct *st_ivas /* i/o: IVAS encoder handle          */
);
@@ -3526,6 +3526,11 @@ void ivas_param_mc_enc(
ivas_error ivas_param_mc_dec_open(
    Decoder_Struct *st_ivas                                     /* i/o: IVAS decoder structure                              */
);
#ifdef MC_BITRATE_SWITCHING
ivas_error ivas_param_mc_dec_reconfig(
    Decoder_Struct *st_ivas /* i/o: IVAS decoder structure  */
);
#endif

void ivas_param_mc_dec_close(
    PARAM_MC_DEC_HANDLE *hParamMC                               /* i/o: Parametric MC decoder handle                        */
+277 −0
Original line number Diff line number Diff line
@@ -410,6 +410,283 @@ ivas_error ivas_param_mc_dec_open(
    return error;
}

#ifdef MC_BITRATE_SWITCHING
ivas_error ivas_param_mc_dec_reconfig(
    Decoder_Struct *st_ivas /* i/o: IVAS decoder structure  */
)
{
    int16_t k, nchan_transport;
    PARAM_MC_DEC_HANDLE hParamMC;
    IVAS_OUTPUT_SETUP hTransportSetup;
    int16_t nchan_out_transport;
    int16_t nchan_out_cov;
    float proto_matrix[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS];
    float proto_mtx_norm;
    int16_t max_param_band_residual;
    uint16_t config_index;
    MC_LS_SETUP mc_ls_setup;
    float frequency_axis[CLDFB_NO_CHANNELS_MAX];
    AUDIO_CONFIG output_config;
    int32_t output_Fs, ivas_total_brate;
    ivas_error error;

    error = IVAS_ERR_OK;
    hParamMC = st_ivas->hParamMC;
    /*-----------------------------------------------------------------*
     * prepare library opening
     *-----------------------------------------------------------------*/

    output_Fs = st_ivas->hDecoderConfig->output_Fs;
    output_config = st_ivas->hDecoderConfig->output_config;
    ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;

    hTransportSetup = st_ivas->hTransSetup;
    mc_ls_setup = ivas_mc_map_output_config_to_mc_ls_setup( st_ivas->transport_config );
    nchan_out_transport = st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe;
    hParamMC->hoa_encoder = NULL;


    hParamMC->ls_conv_dmx_matrix = NULL;

    if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_COV || hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO )
    {
        nchan_out_cov = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe;
    }
    else
    {
        nchan_out_cov = nchan_out_transport;
    }

    st_ivas->nchan_transport = ivas_param_mc_getNumTransportChannels( ivas_total_brate, mc_ls_setup );
    config_index = ivas_param_mc_get_configuration_index( mc_ls_setup, ivas_total_brate );
    nchan_transport = st_ivas->nchan_transport;

    switch ( nchan_transport )
    {
        case 4:
        case 3:
            st_ivas->nCPE = 2;
            st_ivas->nSCE = 0;
            st_ivas->element_mode_init = IVAS_CPE_MDCT;
            break;
        case 2:
            st_ivas->nCPE = 1;
            st_ivas->nSCE = 0;
            st_ivas->element_mode_init = IVAS_CPE_MDCT;

            break;
#ifdef DEBUGGING
        default:
            assert( 0 && "Number of TC not supported for Parametric MC!" );
#endif
    }

    /*-----------------------------------------------------------------*
     * set input parameters
     *-----------------------------------------------------------------*/

    hParamMC->slot_size = (int16_t) ( output_Fs / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX;
    hParamMC->subframe_nbslots = CLDFB_NO_COL_MAX / PARAM_MC_NSUBFRAMES_DEC;

    hParamMC->num_freq_bands = (int16_t) ( output_Fs * INV_CLDFB_BANDWIDTH + 0.5f );
    hParamMC->max_band_energy_compensation = hParamMC->num_freq_bands;
    ivas_param_mc_metadata_open( mc_ls_setup, hTransportSetup.index_lfe[0], ivas_total_brate, hParamMC->hMetadataPMC );

    /* init arrays for quantized parameters */
    hParamMC->icc_q = (float *) count_malloc( hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe * sizeof( float ) );
    hParamMC->icld_q = (float *) count_malloc( hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe * sizeof( float ) );
    set_f( hParamMC->icld_q, PARAM_MC_DEFAULT_MIN_ILD, hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe );
    set_f( hParamMC->icc_q, 0.0f, hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe );

    param_mc_set_num_synth_bands( output_Fs, hParamMC );


    /* Band Grouping */
    if ( hParamMC->hMetadataPMC->num_parameter_bands == 20 )
    {
        mvs2s( param_mc_band_grouping_20, hParamMC->band_grouping, 20 + 1 );
    }
    else if ( hParamMC->hMetadataPMC->num_parameter_bands == 14 )
    {
        mvs2s( param_mc_band_grouping_14, hParamMC->band_grouping, 14 + 1 );
    }
    else if ( hParamMC->hMetadataPMC->num_parameter_bands == 10 )
    {
        mvs2s( param_mc_band_grouping_10, hParamMC->band_grouping, 10 + 1 );
    }
    else
    {
        assert( 0 && "nbands must be 20, 14, or 10!" );
    }

    /* set max parameter band for abs cov */
    k = 0;
    while ( hParamMC->band_grouping[k] <= PARAM_MC_MAX_BAND_ABS_COV_DEC )
    {
        hParamMC->max_param_band_abs_cov = ( k++ );
    }


    /*-----------------------------------------------------------------*
     * open sub-modules
     *-----------------------------------------------------------------*/

    /* prototype signal computation */

    if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_CLDFB || hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_COV || hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO )
    {
        if ( ( error = ivas_ls_setup_conversion_open( st_ivas ) ) != IVAS_ERR_OK )
        {
            return error;
        }

        /* convert the ls conv dmx matrix into column order matrix format (nchan_out_cldfb x nchan_out) */
        if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_COV || hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO )
        {
            hParamMC->ls_conv_dmx_matrix = (float *) count_malloc( nchan_out_transport * nchan_out_cov * sizeof( float ) );
            for ( k = 0; k < nchan_out_transport; k++ )
            {
                mvr2r( st_ivas->hLsSetUpConversion->dmxMtx[k], &hParamMC->ls_conv_dmx_matrix[k * nchan_out_cov], nchan_out_cov );
            }
            /* convert ParamMC parameter bands to SFB */
            if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO )
            {
                st_ivas->hLsSetUpConversion->sfbCnt = hParamMC->num_param_bands_synth;
                for ( k = 0; k <= hParamMC->num_param_bands_synth; k++ )
                {
                    st_ivas->hLsSetUpConversion->sfbOffset[k] = PARAM_MC_BAND_TO_MDCT_BAND_RATIO * hParamMC->band_grouping[k];
                }
            }
            else
            {
                /* close the ls conversion handle immediately, it was only needed to get the DMX matrix in case of DMX in the covariance domain */
                ivas_ls_setup_conversion_close( &st_ivas->hLsSetUpConversion );
            }
        }
    }

    hParamMC->proto_matrix_int = (float *) count_malloc( nchan_out_transport * nchan_transport * sizeof( float ) );
    mvr2r( ivas_param_mc_conf[config_index].dmx_fac, hParamMC->proto_matrix_int, nchan_transport * nchan_out_transport );

    if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_COV || hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO )
    {
        matrix_product( hParamMC->ls_conv_dmx_matrix, nchan_out_cov, nchan_out_transport, 0,
                        ivas_param_mc_conf[config_index].dmx_fac, nchan_out_transport, nchan_transport, 0,
                        proto_matrix );

        if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO )
        {
            proto_mtx_norm = 1.f;
            for ( k = 0; k < nchan_transport * nchan_out_cov; k++ )
            {
                proto_mtx_norm = max( fabsf( proto_mtx_norm ), fabsf( proto_matrix[k] ) );
            }
            proto_mtx_norm = 1.f / proto_mtx_norm;

            /* transfer flattened proto_matrix to 2D in hLsSetupConversion->dmxMtx */
            for ( k = 0; k < nchan_transport; k++ )
            {
                for ( int16_t i = 0; i < nchan_out_cov; i++ )
                {
                    st_ivas->hLsSetUpConversion->dmxMtx[k][i] = proto_matrix[k * nchan_out_cov + i] * proto_mtx_norm;
                }
            }
        }
    }
    else
    {
        mvr2r( ivas_param_mc_conf[config_index].dmx_fac, proto_matrix, nchan_out_transport * nchan_transport );
    }

    if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO )
    {
        hParamMC->num_outputs_diff = 0;
        hParamMC->diff_proto_info = NULL;
        hParamMC->h_output_synthesis_params.use_onset_filters = 0;
        hParamMC->max_band_decorr = 0;
        hParamMC->h_freq_domain_decorr_ap_params = NULL;
        hParamMC->h_freq_domain_decorr_ap_state = NULL;
    }
    else
    {
        hParamMC->num_outputs_diff = nchan_out_cov;
        hParamMC->diff_proto_info = (PARAM_MC_DIFF_PROTO_INFO *) count_malloc( sizeof( PARAM_MC_DIFF_PROTO_INFO ) );

        param_mc_get_diff_proto_info( proto_matrix, nchan_transport, nchan_out_cov, hParamMC->diff_proto_info );

        /* decorrelation */
        hParamMC->h_freq_domain_decorr_ap_params = NULL;
        hParamMC->h_freq_domain_decorr_ap_state = NULL;

        ivas_dirac_dec_get_frequency_axis( frequency_axis, output_Fs, hParamMC->num_freq_bands );

        ivas_dirac_dec_decorr_open( &( hParamMC->h_freq_domain_decorr_ap_params ),
                                    &( hParamMC->h_freq_domain_decorr_ap_state ),
                                    hParamMC->num_freq_bands,
                                    hParamMC->num_outputs_diff,
                                    hParamMC->diff_proto_info->num_protos_diff,
                                    DIRAC_SYNTHESIS_COV_MC_LS,
                                    frequency_axis,
                                    nchan_transport,
                                    output_Fs );

        hParamMC->h_output_synthesis_params.use_onset_filters = 0;
        hParamMC->max_band_decorr = hParamMC->h_freq_domain_decorr_ap_params->max_band_decorr;
    }
    hParamMC->max_band_energy_compensation = hParamMC->band_grouping[hParamMC->hMetadataPMC->nbands_coded];
    max_param_band_residual = 0;

    for ( k = hParamMC->hMetadataPMC->num_parameter_bands; k >= 0; k-- )
    {
        if ( hParamMC->band_grouping[k] <= hParamMC->max_band_decorr )
        {
            max_param_band_residual = k;
            assert( hParamMC->band_grouping[k] == hParamMC->max_band_decorr );
            break;
        }
    }

    /* output synthesis */
    ivas_dirac_dec_output_synthesis_cov_open( &( hParamMC->h_output_synthesis_params ),
                                              &( hParamMC->h_output_synthesis_cov_state ),
                                              hParamMC->max_band_decorr,
                                              PARAM_MC_MAX_NSLOTS,
                                              hParamMC->hMetadataPMC->num_parameter_bands,
                                              max_param_band_residual,
                                              nchan_transport,
                                              nchan_out_cov,
                                              proto_matrix );


    /* Head rotation */
    if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && st_ivas->hDecoderConfig->Opt_Headrotation )
    {
        hParamMC->hoa_encoder = (float *) count_malloc( st_ivas->hTransSetup.nchan_out_woLFE * MAX_INTERN_CHANNELS * sizeof( float ) );
        compute_hoa_encoder_mtx( st_ivas->hTransSetup.ls_azimuth, st_ivas->hTransSetup.ls_elevation, hParamMC->hoa_encoder, st_ivas->hTransSetup.nchan_out_woLFE, HEAD_ROTATION_HOA_ORDER );
    }

    /*-----------------------------------------------------------------*
     * memory allocation
     *-----------------------------------------------------------------*/

    if ( hParamMC->max_band_decorr > 0 )
    {
        hParamMC->proto_frame_f = (float *) count_malloc( 2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands * sizeof( float ) );
        hParamMC->proto_frame_dec_f = (float *) count_malloc( 2 * nchan_out_cov * hParamMC->num_freq_bands * sizeof( float ) );
    }
    else
    {
        hParamMC->proto_frame_f = NULL;
        hParamMC->proto_frame_dec_f = NULL;
    }

    ivas_param_mc_dec_init( hParamMC, nchan_transport, nchan_out_cov );


    return error;
}
#endif

/*-------------------------------------------------------------------------
 * param_mc_get_num_cldfb_syntheses()
 *
+169 −1
Original line number Diff line number Diff line
@@ -622,8 +622,11 @@ ivas_error ivas_mc_dec_config(
        {
            if ( st_ivas->hDecoderConfig->last_ivas_total_brate != st_ivas->hDecoderConfig->ivas_total_brate || st_ivas->transport_config != signaled_config || last_mc_mode != st_ivas->mc_mode )
            {
                /*ivas_mc_dec_reconfigure( st_ivas );*/
#ifdef MC_BITRATE_SWITCHING
                ivas_mc_dec_reconfig( st_ivas, last_mc_mode );
#else
                return IVAS_ERROR( IVAS_ERR_RECONFIGURE_NOT_SUPPORTED, "Error: MC format switching not supported yet!!!\n\n" );
#endif
            }
        }

@@ -632,3 +635,168 @@ ivas_error ivas_mc_dec_config(

    return error;
}
#ifdef MC_BITRATE_SWITCHING
ivas_error ivas_mc_dec_reconfig(
    Decoder_Struct *st_ivas,   /* i/o: IVAS encoder structure      */
    const int16_t last_mc_mode /* i  : last frame MC mode          */
)
{
    int16_t nchan_transport_old, nSCE_old, nCPE_old, sba_dirac_stereo_flag_old;
    ivas_error error;

    error = IVAS_ERR_OK;

    nchan_transport_old = st_ivas->nchan_transport;
    nSCE_old = st_ivas->nSCE;
    nCPE_old = st_ivas->nCPE;
    sba_dirac_stereo_flag_old = st_ivas->sba_dirac_stereo_flag;

    if ( st_ivas->mc_mode == MC_MODE_MCT )
    {
        st_ivas->nSCE = 0;
        st_ivas->nCPE = st_ivas->hDecoderConfig->nchan_out / 2;

        st_ivas->nchan_transport = ivas_mc_ls_setup_get_num_channels( ivas_mc_map_output_config_to_mc_ls_setup( st_ivas->transport_config ) );

        if ( last_mc_mode != MC_MODE_MCT )
        {
            /*De-allocate handles for other MC modes*/
            if ( st_ivas->hParamMC != NULL )
            {
                ivas_param_mc_dec_close( &st_ivas->hParamMC );
                st_ivas->hParamMC = NULL;
            }

            /* De-allocate McMasa-related handles */
            if ( st_ivas->hMasa != NULL )
            {
                ivas_masa_dec_close( st_ivas->hMasa );
                st_ivas->hMasa = NULL;
            }

            if ( st_ivas->hQMetaData != NULL )
            {
                ivas_qmetadata_close( &st_ivas->hQMetaData );
                st_ivas->hQMetaData = NULL;
            }
        }
    }
    else if ( st_ivas->mc_mode == MC_MODE_PARAMMC )
    {
        if ( last_mc_mode != MC_MODE_PARAMMC )
        {
            if ( ( error = ivas_param_mc_dec_open( st_ivas ) ) != IVAS_ERR_OK )
            {
                return error;
            }
        }
        else
        {
            ivas_param_mc_dec_reconfig( st_ivas );
        }

        /* De-allocate McMasa-related handles */
        if ( st_ivas->hMasa != NULL )
        {
            ivas_masa_dec_close( st_ivas->hMasa );
            st_ivas->hMasa = NULL;
        }

        if ( st_ivas->hQMetaData != NULL )
        {
            ivas_qmetadata_close( &st_ivas->hQMetaData );
            st_ivas->hQMetaData = NULL;
        }

        if ( last_mc_mode == MC_MODE_MCT )
        {
            if ( st_ivas->hMCT != NULL )
            {
                ivas_mct_dec_close( &st_ivas->hMCT );
                st_ivas->hMCT = NULL;
            }
            /* LFE handle */
            if ( st_ivas->hLFE != NULL )
            {
                ivas_lfe_dec_close( st_ivas->hLFE );
                st_ivas->hLFE = NULL;
            }
        }
    }
    else if ( st_ivas->mc_mode == MC_MODE_MCMASA )
    {
        ivas_mcmasa_setNumTransportChannels( &( st_ivas->nchan_transport ), &( st_ivas->element_mode_init ), st_ivas->hDecoderConfig->ivas_total_brate );

        if ( last_mc_mode != MC_MODE_MCMASA )
        {
            if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK )
            {
                return error;
            }

            if ( ( error = ivas_masa_dec_open( st_ivas ) ) != IVAS_ERR_OK )
            {
                return error;
            }
        }

        if ( st_ivas->hParamMC != NULL )
        {
            ivas_param_mc_dec_close( &st_ivas->hParamMC );
            st_ivas->hParamMC = NULL;
        }

        if ( last_mc_mode == MC_MODE_MCT )
        {
            if ( st_ivas->hMCT != NULL )
            {
                ivas_mct_dec_close( &st_ivas->hMCT );
                st_ivas->hMCT = NULL;
            }
            /* LFE handle */
            if ( st_ivas->hLFE != NULL )
            {
                ivas_lfe_dec_close( st_ivas->hLFE );
                st_ivas->hLFE = NULL;
            }
        }
    }

    if ( st_ivas->nchan_transport == 1 )
    {
        st_ivas->element_mode_init = IVAS_SCE;
    }
    else
    {
        st_ivas->element_mode_init = IVAS_CPE_MDCT;
    }

    /* re-configure core coder*/
    if ( ( error = ivas_corecoder_dec_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, sba_dirac_stereo_flag_old ) ) != IVAS_ERR_OK )
    {
        return error;
    }

    /* re-configure hp20 memories */
    ivas_hp20_dec_reconfig( st_ivas, nchan_transport_old );

    /* Allocat the LFE handle that is coded seperately after the allocation of the core coders*/
    if ( st_ivas->mc_mode == MC_MODE_MCT )
    {

        if ( ( error = ivas_create_lfe_dec( &st_ivas->hLFE, st_ivas->hDecoderConfig->output_Fs, st_ivas->hHrtf != NULL ? st_ivas->hHrtf->latency_s : 0 ) ) != IVAS_ERR_OK )
        {
            return error;
        }

        /* reuse core-coder buffers for LFE decoder */
        st_ivas->hLFE->prevsynth_buf = &st_ivas->hCPE[1]->hCoreCoder[1]->old_synth_sw[0];
        st_ivas->hLFE->prior_out_buffer = &st_ivas->hCPE[1]->hCoreCoder[1]->previoussynth[0];

        set_zero( st_ivas->hLFE->prevsynth_buf, LFE_PLC_BUFLEN );
        set_zero( st_ivas->hLFE->prior_out_buffer, L_FRAME48k );
    }

    return error;
}
#endif
+0 −6
Original line number Diff line number Diff line
@@ -286,12 +286,6 @@ ivas_error ivas_corecoder_enc_reconfig(
                        st_ivas->hCPE[cpe_id]->hCoreCoder[n]->cng_sba_flag = 1;
                    }
                }
#ifdef MC_BITRATE_SWITCHING
                if ( nSCE_old )
                {
                    st_ivas->hCPE[cpe_id]->element_mode = IVAS_CPE_MDCT;
                }
#endif
            }
        }

+65 −72

File changed.

Preview size limit exceeded, changes collapsed.