Commit 6e54b843 authored by hsd's avatar hsd
Browse files

extend unit test scenarios to cover frame-by-frame lc3plus format switching,...

extend unit test scenarios to cover frame-by-frame lc3plus format switching, as introduced with FIX_1515_ISAR_FRAME_SIZES_IN_RTP
parent 8a3d5bc8
Loading
Loading
Loading
Loading
+282 −0
Original line number Diff line number Diff line
@@ -177,6 +177,234 @@ static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config, uint32_t bps )

    return 0;
}
#ifdef FIX_1515_ISAR_FRAME_SIZES_IN_RTP
static int encodeAndDecodeOneStereoFrameWithConfigSwitch( LC3PLUS_CONFIG config_01, uint32_t bps_01, LC3PLUS_CONFIG config_02, uint32_t bps_02 )
{
    ivas_error err;
    int32_t encDelay = -1;
    int32_t decDelay = -1;

    ISAR_LC3PLUS_ENC_HANDLE encHandle;
    err = ISAR_LC3PLUS_ENC_Open( config_01, bps_01, &encHandle );
    if ( IVAS_ERR_OK != err )
    {
        return err;
    }

    err = ISAR_LC3PLUS_ENC_GetDelay( encHandle, &encDelay );
    if ( IVAS_ERR_OK != err )
    {
        ISAR_LC3PLUS_ENC_Close( &encHandle );
        return err;
    }
    if ( encDelay == -1 || encDelay == 0 )
    {
        ISAR_LC3PLUS_ENC_Close( &encHandle );
        return IVAS_ERROR( IVAS_ERR_INTERNAL, "encDelay is zero or uninitialized\n" );
    }

    /* encode one frame */
    int16_t numSamplesPerChannels = config_01.samplerate / ( 1000000 / config_01.isar_frame_duration_us );
#ifdef LC3PLUS_UNIT_TEST_BASOP
    PcmSample *pcm_in[2];
    PcmSample pcm_in_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( PcmSample )];
    memset( pcm_in_ch1, 0, numSamplesPerChannels * sizeof( PcmSample ) );
    PcmSample pcm_in_ch2[MAX_SAMPLES_PER_CHANNEL * sizeof( PcmSample )];
    memset( pcm_in_ch2, 0, numSamplesPerChannels * sizeof( PcmSample ) );
#else
    float *pcm_in[2];
    float pcm_in_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )];
    memset( pcm_in_ch1, 0, numSamplesPerChannels * sizeof( float ) );
    float pcm_in_ch2[MAX_SAMPLES_PER_CHANNEL * sizeof( float )];
    memset( pcm_in_ch2, 0, numSamplesPerChannels * sizeof( float ) );
#endif
    pcm_in[0] = pcm_in_ch1;
    pcm_in[1] = pcm_in_ch2;

    int32_t bitstreamSizePerIvasFrame_01 = 0;
    err = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame_01 );
    if ( IVAS_ERR_OK != err )
    {
        ISAR_LC3PLUS_ENC_Close( &encHandle );
        return err;
    }
    uint8_t *bitstream_out_01 = malloc( bitstreamSizePerIvasFrame_01 );
    memset( bitstream_out_01, 0, bitstreamSizePerIvasFrame_01 );

    int perChannelBitrate = lc3plus_enc_get_real_bitrate( encHandle->handles[0] );
    int perLc3plusFrameDataBlockOctets = encHandle->num_ftds * perChannelBitrate / 8 / ( 1000 * 1000 / config_01.lc3plus_frame_duration_us );
    int targetOctets = bps_01 / 8 / ( 1000 * 1000 / config_01.isar_frame_duration_us );
    printf( "IVAS-FS=%i LC3plus-FS=%i ch=%i targetBps=%i targetOctets=%i\n", config_01.isar_frame_duration_us, config_01.lc3plus_frame_duration_us, config_01.channels, bps_01, targetOctets );
    printf( "  coreBps=%i corePerChBps=%i coreCodecOctets=%i nFtds=%i \n", perChannelBitrate * encHandle->num_encs, perChannelBitrate, perLc3plusFrameDataBlockOctets, encHandle->num_ftds );
    int pfOctets = bitstreamSizePerIvasFrame_01 - perLc3plusFrameDataBlockOctets;
    int pfBps = pfOctets * 8 * ( 1000 * 1000 / config_01.isar_frame_duration_us );
    printf( "  payloadFormatBps=%i payloadFormatOctets=%i \n\n", pfBps, pfOctets );
    if ( pfBps <= 0 )
    {
        ISAR_LC3PLUS_ENC_Close( &encHandle );
        return err;
    }

#ifdef LC3PLUS_UNIT_TEST_BASOP
    Word16 Q_in[16];
    memset( Q_in, 0, sizeof( Q_in ) );
    err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out_01, bitstreamSizePerIvasFrame_01, Q_in );
#else
    err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out_01, bitstreamSizePerIvasFrame_01 );
#endif
    if ( IVAS_ERR_OK != err )
    {
        ISAR_LC3PLUS_ENC_Close( &encHandle );
        free( bitstream_out_01 );
        return err;
    }
    ISAR_LC3PLUS_ENC_Close( &encHandle );

    // Enc2
    err = ISAR_LC3PLUS_ENC_Open( config_02, bps_02, &encHandle );
    if ( IVAS_ERR_OK != err )
    {
        return err;
    }

    err = ISAR_LC3PLUS_ENC_GetDelay( encHandle, &encDelay );
    if ( IVAS_ERR_OK != err )
    {
        ISAR_LC3PLUS_ENC_Close( &encHandle );
        return err;
    }
    if ( encDelay == -1 || encDelay == 0 )
    {
        ISAR_LC3PLUS_ENC_Close( &encHandle );
        return IVAS_ERROR( IVAS_ERR_INTERNAL, "encDelay is zero or uninitialized\n" );
    }

    /* encode one frame */
    int32_t bitstreamSizePerIvasFrame_02 = 0;
    err = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame_02 );
    if ( IVAS_ERR_OK != err )
    {
        ISAR_LC3PLUS_ENC_Close( &encHandle );
        return err;
    }
    uint8_t *bitstream_out_02 = malloc( bitstreamSizePerIvasFrame_02 );
    memset( bitstream_out_02, 0, bitstreamSizePerIvasFrame_02 );

    perChannelBitrate = lc3plus_enc_get_real_bitrate( encHandle->handles[0] );
    perLc3plusFrameDataBlockOctets = encHandle->num_ftds * perChannelBitrate / 8 / ( 1000 * 1000 / config_02.lc3plus_frame_duration_us );
    targetOctets = bps_02 / 8 / ( 1000 * 1000 / config_02.isar_frame_duration_us );
    printf( "IVAS-FS=%i LC3plus-FS=%i ch=%i targetBps=%i targetOctets=%i\n", config_02.isar_frame_duration_us, config_02.lc3plus_frame_duration_us, config_02.channels, bps_02, targetOctets );
    printf( "  coreBps=%i corePerChBps=%i coreCodecOctets=%i nFtds=%i \n", perChannelBitrate * encHandle->num_encs, perChannelBitrate, perLc3plusFrameDataBlockOctets, encHandle->num_ftds );
    pfOctets = bitstreamSizePerIvasFrame_02 - perLc3plusFrameDataBlockOctets;
    pfBps = pfOctets * 8 * ( 1000 * 1000 / config_02.isar_frame_duration_us );
    printf( "  payloadFormatBps=%i payloadFormatOctets=%i \n\n", pfBps, pfOctets );
    if ( pfBps <= 0 )
    {
        ISAR_LC3PLUS_ENC_Close( &encHandle );
        return err;
    }


#ifdef LC3PLUS_UNIT_TEST_BASOP
    memset( Q_in, 0, sizeof( Q_in ) );
    err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out_02, bitstreamSizePerIvasFrame_02, Q_in );
#else
    err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out_02, bitstreamSizePerIvasFrame_02 );
#endif
    if ( IVAS_ERR_OK != err )
    {
        ISAR_LC3PLUS_ENC_Close( &encHandle );
        free( bitstream_out_02 );
        return err;
    }
    ISAR_LC3PLUS_ENC_Close( &encHandle );

    /* decode one frame */
    ISAR_LC3PLUS_DEC_HANDLE decHandle;
    err = ISAR_LC3PLUS_DEC_Open( config_01, &decHandle );
    if ( IVAS_ERR_OK != err )
    {
        free( bitstream_out_01 );
        return err;
    }

    err = ISAR_LC3PLUS_DEC_GetDelay( decHandle, &decDelay );
    if ( IVAS_ERR_OK != err )
    {
        ISAR_LC3PLUS_DEC_Close( &decHandle );
        free( bitstream_out_01 );
        return err;
    }
    if ( decDelay == -1 || decDelay == 0 )
    {
        ISAR_LC3PLUS_DEC_Close( &decHandle );
        free( bitstream_out_01 );
        return IVAS_ERROR( IVAS_ERR_INTERNAL, "decDelay is zero or uninitialized\n" );
    }

#ifdef LC3PLUS_UNIT_TEST_BASOP
    PcmSample *pcm_out[2];
    PcmSample pcm_out_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( PcmSample )];
    memset( pcm_out_ch1, 0, numSamplesPerChannels * sizeof( PcmSample ) );
    PcmSample pcm_out_ch2[MAX_SAMPLES_PER_CHANNEL * sizeof( PcmSample )];
    memset( pcm_out_ch2, 0, numSamplesPerChannels * sizeof( PcmSample ) );
#else
    float *pcm_out[2];
    float pcm_out_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )];
    memset( pcm_out_ch1, 0, numSamplesPerChannels * sizeof( float ) );
    float pcm_out_ch2[MAX_SAMPLES_PER_CHANNEL * sizeof( float )];
    memset( pcm_out_ch2, 0, numSamplesPerChannels * sizeof( float ) );
#endif
    pcm_out[0] = pcm_out_ch1;
    pcm_out[1] = pcm_out_ch2;


    // err = ISAR_LC3PLUS_DEC_Conceal( decHandle, pcm_out );
    // if ( IVAS_ERR_OK != err )
    // {
    //     ISAR_LC3PLUS_DEC_Close( &decHandle );
    //     free( bitstream_out_01 );
    //     return err;
    // }

    err = ISAR_LC3PLUS_DEC_Decode( decHandle, bitstream_out_01, bitstreamSizePerIvasFrame_01, pcm_out );
    if ( IVAS_ERR_OK != err )
    {
        ISAR_LC3PLUS_DEC_Close( &decHandle );
        free( bitstream_out_01 );
        return err;
    }

    err = ISAR_LC3PLUS_DEC_Decode( decHandle, bitstream_out_02, bitstreamSizePerIvasFrame_02, pcm_out );
    if ( IVAS_ERR_OK != err )
    {
        ISAR_LC3PLUS_DEC_Close( &decHandle );
        free( bitstream_out_01 );
        return err;
    }

    err = ISAR_LC3PLUS_DEC_Decode( decHandle, bitstream_out_01, bitstreamSizePerIvasFrame_01, pcm_out );
    if ( IVAS_ERR_OK != err )
    {
        ISAR_LC3PLUS_DEC_Close( &decHandle );
        free( bitstream_out_01 );
        return err;
    }

    err = ISAR_LC3PLUS_DEC_Conceal( decHandle, pcm_out );
    if ( IVAS_ERR_OK != err )
    {
        ISAR_LC3PLUS_DEC_Close( &decHandle );
        free( bitstream_out_01 );
        return err;
    }

    ISAR_LC3PLUS_DEC_Close( &decHandle );
    free( bitstream_out_01 );

    return 0;
}
#endif


static int openCloseEncoder( void )
@@ -612,6 +840,43 @@ static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_207200bpsPerChann
    return encodeAndDecodeOneStereoFrame( config, config.channels * 207200 );
}

#ifdef FIX_1515_ISAR_FRAME_SIZES_IN_RTP
static int encodeAndDecodeOneStereoFrameWithLc3plusConfigSwitch_ISAR_20ms(void)
{
    LC3PLUS_CONFIG config_2x10ms = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
    LC3PLUS_CONFIG config_4x5ms  = { .lc3plus_frame_duration_us =  5 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
    return encodeAndDecodeOneStereoFrameWithConfigSwitch( config_2x10ms, config_2x10ms.channels * DEFAULT_BPS, config_4x5ms,  config_4x5ms.channels * DEFAULT_BPS );
}

static int encodeAndDecodeOneStereoFrameWithLc3plusConfigSwitch_ISAR_10ms(void)
{
    LC3PLUS_CONFIG config_1x10ms = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
    LC3PLUS_CONFIG config_2x5ms  = { .lc3plus_frame_duration_us =  5 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
    return encodeAndDecodeOneStereoFrameWithConfigSwitch( config_1x10ms, config_1x10ms.channels * DEFAULT_BPS, config_2x5ms,  config_2x5ms.channels * DEFAULT_BPS );
}

static int encodeAndDecodeOneStereoFrameWithLc3plusConfigSwitch_ISAR_20ms_HighRes_switch(void)
{
    LC3PLUS_CONFIG config_2x10ms_HR_ON  = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 1 };
    LC3PLUS_CONFIG config_2x10ms_HR_OFF = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
    return encodeAndDecodeOneStereoFrameWithConfigSwitch( config_2x10ms_HR_ON, config_2x10ms_HR_ON.channels * DEFAULT_BPS, config_2x10ms_HR_OFF,  config_2x10ms_HR_OFF.channels * DEFAULT_BPS );
}

static int encodeAndDecodeOneStereoFrameWithLc3plusConfigSwitch_ISAR_10ms_to_20ms_will_fail(void)
{
    LC3PLUS_CONFIG config_1x10ms = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
    LC3PLUS_CONFIG config_2x10ms = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
    return encodeAndDecodeOneStereoFrameWithConfigSwitch( config_1x10ms, config_1x10ms.channels * DEFAULT_BPS, config_2x10ms,  config_2x10ms.channels * DEFAULT_BPS );
}

static int encodeAndDecodeOneStereoFrameWithLc3plusConfigSwitch_ISAR_20ms_to_10ms_will_fail(void)
{
    LC3PLUS_CONFIG config_2x10ms = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
    LC3PLUS_CONFIG config_1x10ms = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
    return encodeAndDecodeOneStereoFrameWithConfigSwitch( config_2x10ms,  config_2x10ms.channels * DEFAULT_BPS, config_1x10ms, config_1x10ms.channels * DEFAULT_BPS );
}
#endif

#include "ivas_lc3plus_unit_test_payload_format.c"

int main(
@@ -707,6 +972,23 @@ int main(
    if ( ret != 0 )
        return 1;
    /* end configs around the FDL threshold */
#ifdef FIX_1515_ISAR_FRAME_SIZES_IN_RTP
    ret = encodeAndDecodeOneStereoFrameWithLc3plusConfigSwitch_ISAR_20ms();
    if ( ret != 0 )
        return 1;
    ret = encodeAndDecodeOneStereoFrameWithLc3plusConfigSwitch_ISAR_10ms();
    if ( ret != 0 )
        return 1;
    ret = encodeAndDecodeOneStereoFrameWithLc3plusConfigSwitch_ISAR_20ms_HighRes_switch();
    if ( ret != 0 )
        return 1;
    ret = encodeAndDecodeOneStereoFrameWithLc3plusConfigSwitch_ISAR_20ms_to_10ms_will_fail();
    if ( ret == 0 /* will fail, switching is only supported when the ISAR frame duration stays the same*/ )
        return 1;
    ret = encodeAndDecodeOneStereoFrameWithLc3plusConfigSwitch_ISAR_10ms_to_20ms_will_fail();
    if ( ret == 0 /* will fail, switching is only supported when the ISAR frame duration stays the same*/ )
        return 1;
#endif
    ret = run_all_payload_tests();
    if ( ret != 0 )
        return 1;