Commit 44372bba authored by hsd's avatar hsd Committed by sagnowski
Browse files

allow dynamic lc3plus dec reconfiguration while the ISAR frame duration stays the same

parent 7e397bd1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -165,6 +165,7 @@
#define FIX_FLOAT_1560_SVD_NO_OPT_MAX_W_SIGN            /* FhG: float issue 1560: Avoid optimizing the division on the result of maxWithSign() with -funsafe-math-optimizations */
#define FIX_2095_REMOVE_UNUSED_ISAR_TABLES              /* Dolby: remove unused ISAR */
#define FIX_FLOAT_1582_STEREO_DFT_QUANTIZE_ITD          /* FhG: float issue 1582: Remove unncessary statement from stereo_dft_quantize_itd() */
#define FIX_1234_SPLIT_REND_LC3PLUS_RECONFIGURE         /* Fhg: Allow dynamic reconfiguration of the LC3plus Decoder when bitstream format changes */

/* #################### End BE switches ################################## */

+279 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@

*******************************************************************************************************/

#include <stdbool.h>
#include <stdint.h>
#include "options.h"
#include "prot.h"
@@ -41,6 +42,205 @@
#include "wmc_auto.h"


#ifdef FIX_1234_SPLIT_REND_LC3PLUS_RECONFIGURE
static ivas_error isar_lc3plus_dec_init_handle(
    const LC3PLUS_CONFIG config,    /* i  : LC3plus decoder configuration   */
    ISAR_LC3PLUS_DEC_HANDLE *handle /* o  : decoder handle                  */
)
{
    LC3PLUS_Error err;
    int32_t decoder_size;
    int16_t i;

    if ( 0 == config.lc3plus_frame_duration_us )
    {
        ISAR_LC3PLUS_DEC_Close( handle );
        return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid lc3plus_frame_duration_us (0)\n" );
    }

    if ( config.channels > ISAR_LC3PLUS_MAX_NUM_DECODERS )
    {
        ISAR_LC3PLUS_DEC_Close( handle );
        return IVAS_ERROR( IVAS_ERR_INIT_ERROR, "Maximum number of channels exceeds ISAR_LC3PLUS_MAX_NUM_DECODERS\n" );
    }

    ( *handle )->num_decs = 0;
    ( *handle )->pcm_conversion_buffer = NULL;
    ( *handle )->handles = NULL;
    ( *handle )->selective_decoding_states = NULL;
    ( *handle )->bitstream_caches = NULL;

    if ( ( ( *handle )->handles = malloc( config.channels * sizeof( ISAR_LC3PLUS_DEC_HANDLE ) ) ) == NULL )
    {
        ISAR_LC3PLUS_DEC_Close( handle );
        return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" );
    }

    if ( ( ( *handle )->selective_decoding_states = malloc( config.channels * sizeof( ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE * ) ) ) == NULL )
    {
        ISAR_LC3PLUS_DEC_Close( handle );
        return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" );
    }

    for ( i = 0; i < config.channels; ++i )
    {
        ( *handle )->handles[i] = NULL;
        ( *handle )->selective_decoding_states[i] = NULL;
    }

    if ( ( ( *handle )->bitstream_caches = malloc( config.channels * sizeof( ISAR_LC3PLUS_DEC_BITSTREAM_CACHE * ) ) ) == NULL )
    {
        ISAR_LC3PLUS_DEC_Close( handle );
        return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" );
    }
    for ( i = 0; i < config.channels; ++i )
    {
        ( *handle )->bitstream_caches[i] = NULL;
    }

    ( *handle )->num_decs = config.channels;
    for ( int32_t iCh = 0; iCh < config.channels; iCh++ )
    {
        ( *handle )->selective_decoding_states[iCh] = NULL;
        if ( NULL != ( *handle )->bitstream_caches )
        {
            ( *handle )->bitstream_caches[iCh] = NULL;
        }
        /* allocate and configure LC3plus decoder */
        decoder_size = lc3plus_dec_get_size( config.samplerate, 1 );
        if ( 0 == decoder_size )
        {
            ISAR_LC3PLUS_DEC_Close( handle );
            return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_dec_get_size failed\n" );
        }

        if ( ( ( *handle )->handles[iCh] = malloc( decoder_size ) ) == NULL )
        {
            ISAR_LC3PLUS_DEC_Close( handle );
            return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" );
        }

        err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, config.high_res_mode_enabled );

        if ( LC3PLUS_OK != err )
        {
            ISAR_LC3PLUS_DEC_Close( handle );
            return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_init failed\n" );
        }

        err = lc3plus_dec_set_frame_dms( ( *handle )->handles[iCh], IVAS_LC3PLUS_UsToLC3plusFrameDuration( config.lc3plus_frame_duration_us ) );
        if ( LC3PLUS_OK != err )
        {
            ISAR_LC3PLUS_DEC_Close( handle );
            return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_set_frame_dms failed\n" );
        }

        /* allocate and configure per LC3plus decoder skip state  */
        if ( ( ( *handle )->selective_decoding_states[iCh] = malloc( sizeof( ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE ) ) ) == NULL )
        {
            ISAR_LC3PLUS_DEC_Close( handle );
            return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" );
        }

        ( *handle )->selective_decoding_states[iCh]->has_skipped_a_frame = 0;
        ( *handle )->selective_decoding_states[iCh]->shall_decode_cached_frame = 0;
        ( *handle )->selective_decoding_states[iCh]->frame_action = DEC_ACTION_DECODE_AND_USE;

        /* allocate and configure per LC3plus decoder bitstream cache */
        if ( ( ( *handle )->bitstream_caches[iCh] = malloc( sizeof( ISAR_LC3PLUS_DEC_BITSTREAM_CACHE ) ) ) == NULL )
        {
            ISAR_LC3PLUS_DEC_Close( handle );
            return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" );
        }

        ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/;

        if ( ( ( *handle )->bitstream_caches[iCh]->bitstream_cache = malloc( ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity ) ) == NULL )
        {
            ISAR_LC3PLUS_DEC_Close( handle );
            return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" );
        }
        ( *handle )->bitstream_caches[iCh]->bitstream_cache_size = 0;
    }

    ( *handle )->config = config;
    if ( config.isar_frame_duration_us < config.lc3plus_frame_duration_us || config.isar_frame_duration_us % config.lc3plus_frame_duration_us != 0 )
    {
        ISAR_LC3PLUS_DEC_Close( handle );
        return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" );
    }

    if ( ( ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 ) ) == NULL )
    {
        ISAR_LC3PLUS_DEC_Close( handle );
        return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder wrapper pcm_conversion_buffer\n" );
    }
    
    return IVAS_ERR_OK;
}

static void isar_lc3plus_dec_deinit_handle(
    ISAR_LC3PLUS_DEC_HANDLE handle  /* i/o: decoder handle                  */
)
{
    if ( NULL == handle )
    {
        return;
    }
    for ( uint32_t iDec = 0; iDec < handle->num_decs; iDec++ )
    {
        if ( NULL != handle->handles && NULL != handle->handles[iDec] )
        {
            lc3plus_free_decoder_structs( handle->handles[iDec] );
            free( handle->handles[iDec] );
        }

        if ( NULL != handle->selective_decoding_states && NULL != handle->selective_decoding_states[iDec] )
        {
            free( handle->selective_decoding_states[iDec] );
        }

        if ( NULL != handle->bitstream_caches && NULL != handle->bitstream_caches[iDec] )
        {
            free( handle->bitstream_caches[iDec]->bitstream_cache );
            free( handle->bitstream_caches[iDec] );
        }
    }

    if ( NULL != handle->pcm_conversion_buffer )
    {
        free( handle->pcm_conversion_buffer );
    }
    free( handle->handles );

    if ( NULL != handle->bitstream_caches )
    {
        free( handle->bitstream_caches );
    }
    free( handle->selective_decoding_states );

    return;
}

/*-------------------------------------------------------------------------
 * ISAR_LC3PLUS_DEC_Open()
 *
 *
 *------------------------------------------------------------------------*/

ivas_error ISAR_LC3PLUS_DEC_Open(
    const LC3PLUS_CONFIG config,    /* i  : LC3plus decoder configuration   */
    ISAR_LC3PLUS_DEC_HANDLE *handle /* o  : decoder handle                  */
)
{
    if ( ( *handle = malloc( sizeof( struct ISAR_LC3PLUS_DEC_HANDLE ) ) ) == NULL )
    {
        return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" );
    }

    return isar_lc3plus_dec_init_handle( config, handle );
}
#else
/*-------------------------------------------------------------------------
 * ISAR_LC3PLUS_DEC_Open()
 *
@@ -185,7 +385,7 @@ ivas_error ISAR_LC3PLUS_DEC_Open(

    return IVAS_ERR_OK;
}

#endif

/*-------------------------------------------------------------------------
 * ISAR_LC3PLUS_DEC_GetDelay()
@@ -232,6 +432,29 @@ ivas_error ISAR_LC3PLUS_DEC_GetDelay(
}


#ifdef FIX_1234_SPLIT_REND_LC3PLUS_RECONFIGURE
/*-------------------------------------------------------------------------
 * ISAR_LC3PLUS_DEC_Close()
 *
 *
 *------------------------------------------------------------------------*/

void ISAR_LC3PLUS_DEC_Close(
    ISAR_LC3PLUS_DEC_HANDLE *handle /* i/o: Pointer to LC3plus decoder handle   */
)
{
    if ( NULL == handle || NULL == *handle )
    {
        return;
    }
    isar_lc3plus_dec_deinit_handle( *handle );

    free( *handle );
    *handle = NULL;

    return;
}
#else
/*-------------------------------------------------------------------------
 * ISAR_LC3PLUS_DEC_Close()
 *
@@ -283,6 +506,7 @@ void ISAR_LC3PLUS_DEC_Close(

    return;
}
#endif


/*-------------------------------------------------------------------------
@@ -341,6 +565,9 @@ static ivas_error isar_LC3PLUS_DEC_Decode_or_Conceal_internal(
    int32_t ivasSampleIndex;
    int16_t numSamplesPerLC3plusChannel;
    ivas_error err;
#ifdef FIX_1234_SPLIT_REND_LC3PLUS_RECONFIGURE
    bool reInitRequired = false;
#endif

    if ( NULL == handle )
    {
@@ -368,7 +595,9 @@ static ivas_error isar_LC3PLUS_DEC_Decode_or_Conceal_internal(
        return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" );
    }

#ifndef FIX_1234_SPLIT_REND_LC3PLUS_RECONFIGURE
    config_num_media_times = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us;
#endif
    if ( !badFrameIndicator )
    {
        if ( LC3PLUS_RTP_payload_deserialize( &payload, bitstream_in, bitstream_in_size ) != LC3PLUS_RTP_ERR_NO_ERROR )
@@ -383,6 +612,34 @@ static ivas_error isar_LC3PLUS_DEC_Decode_or_Conceal_internal(
        {
            return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (number of channels) in bitstream is not supported\n" );
        }
#ifdef FIX_1234_SPLIT_REND_LC3PLUS_RECONFIGURE
        if ( payload.frame_duration_us != handle->config.lc3plus_frame_duration_us )
        {
            if (payload.num_media_times * payload.frame_duration_us == handle->config.isar_frame_duration_us)
            {
                reInitRequired = true;
            }
            else
            {
                return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (frame duration) in bitstream is only supported when the ISAR frame duration stays the same\n" );
            }
        }
        if ( payload.high_resolution_enabled != handle->config.high_res_mode_enabled )
        {
            reInitRequired = true;
        }
        if ( payload.num_media_times != handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us )
        {
            if (payload.num_media_times * payload.frame_duration_us == handle->config.isar_frame_duration_us)
            {
                reInitRequired = true;
            }
            else
            {
                return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (number of media times per frame data block) in bitstream is only supported when the ISAR frame duration stays the same\n" );
            }
        }
#else
        if ( payload.frame_duration_us != handle->config.lc3plus_frame_duration_us )
        {
            return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (frame duration) in bitstream is not supported\n" );
@@ -395,8 +652,29 @@ static ivas_error isar_LC3PLUS_DEC_Decode_or_Conceal_internal(
        {
            return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (number of media times per frame data block) in bitstream is not supported\n" );
        }
#endif
    }

#ifdef FIX_1234_SPLIT_REND_LC3PLUS_RECONFIGURE
    if (reInitRequired)
    {
        isar_lc3plus_dec_deinit_handle( handle );
        LC3PLUS_CONFIG newConfig;
        newConfig.channels = payload.num_channels;
        newConfig.samplerate = payload.sampling_rate_hz;
        newConfig.high_res_mode_enabled = payload.high_resolution_enabled;
        newConfig.isar_frame_duration_us = payload.num_media_times * payload.frame_duration_us;
        newConfig.lc3plus_frame_duration_us = payload.frame_duration_us;
        newConfig.samplerate =  payload.sampling_rate_hz;
        err = isar_lc3plus_dec_init_handle(newConfig , &handle );
        if (err != IVAS_ERR_OK)
        {
            return IVAS_ERROR( err, "ISAR_LC3PLUS_DEC_Open failed\n" );
        }
    }

    config_num_media_times = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us;
#endif
    numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / config_num_media_times );
    for ( iDec = 0; iDec < handle->num_decs; iDec++ )
    {