Commit 10265cef authored by Lauros Pajunen's avatar Lauros Pajunen
Browse files

Add support for IVAS rtpdump reading and writing

parent a3ab1bf0
Loading
Loading
Loading
Loading
Loading
+124 −0
Original line number Diff line number Diff line
@@ -37,6 +37,9 @@
#include "bitstream_reader.h"
#include "evs_rtp_payload.h"
#include "ism_file_writer.h"
#ifdef IVAS_RTPDUMP
#include "ivas_rtp_payload.h"
#endif
#include "jbm_file_writer.h"
#include "hrtf_file_reader.h"
#include "ls_custom_file_reader.h"
@@ -1730,10 +1733,18 @@ static void usage_dec( void )
    fprintf( stdout, "--------\n" );
    fprintf( stdout, "-VOIP               : VoIP mode: RTP in G192\n" );
    fprintf( stdout, "-VOIP_hf_only=0     : VoIP mode: EVS RTP Payload Format hf_only=0 in rtpdump\n" );
#ifdef IVAS_RTPDUMP
    fprintf( stdout, "-VOIP_hf_only=1     : VoIP mode: EVS or IVAS RTP Payload Format hf_only=1 in rtpdump\n" );
    fprintf( stdout, "                      The decoder may read rtpdump files containing TS26.445 Annex A.2.2\n" );
    fprintf( stdout, "                      EVS RTP Payload Format or rtpdump files containing TS26.253 Annex A\n" );
    fprintf( stdout, "                      IVAS RTP Payload Format. The SDP parameter hf_only is required.\n" );
    fprintf( stdout, "                      Reading RFC4867 AMR/AMR-WB RTP payload format is not supported.\n" );
#else
    fprintf( stdout, "-VOIP_hf_only=1     : VoIP mode: EVS RTP Payload Format hf_only=1 in rtpdump\n" );
    fprintf( stdout, "                      The decoder may read rtpdump files containing TS26.445 Annex A.2.2\n" );
    fprintf( stdout, "                      EVS RTP Payload Format. The SDP parameter hf_only is required.\n" );
    fprintf( stdout, "                      Reading RFC4867 AMR/AMR-WB RTP payload format is not supported.\n" );
#endif
#ifdef SUPPORT_JBM_TRACEFILE
    fprintf( stdout, "-Tracefile TF       : VoIP mode: Generate trace file named TF\n" );
#endif
@@ -2936,14 +2947,25 @@ static ivas_error printBitstreamInfoVoip(
    bool previewFailed = true;
    ivas_error error = IVAS_ERR_OK;
    FILE *f_rtpstream = NULL;
#ifdef IVAS_RTPDUMP
    IVAS_RTPDUMP_DEPACKER rtpdumpDepacker;
    IVAS_RTPDUMP_DEPACKER_ERROR rtpdumpDepackerError = IVAS_RTPDUMP_DEPACKER_NO_ERROR;
#else
    EVS_RTPDUMP_DEPACKER rtpdumpDepacker;
    EVS_RTPDUMP_DEPACKER_ERROR rtpdumpDepackerError = EVS_RTPDUMP_DEPACKER_NO_ERROR;
#endif
    uint8_t au[( IVAS_MAX_BITS_PER_FRAME + 7 ) >> 3];
    int16_t auSizeBits;
    uint8_t *auPtr = NULL;
#ifdef IVAS_RTPDUMP
    bool evsIvasModeBit;
    uint16_t bitrateIndex;
    bool ivasIndicatorOrQBit;
#else
    bool isAMRWB_IOmode;
    uint16_t frameTypeIndex;
    bool qBit;
#endif
    uint32_t nextPacketRcvTime_ms = 0;
    uint16_t rtpSequenceNumber;
    uint32_t rtpTimeStamp;
@@ -2961,7 +2983,11 @@ static ivas_error printBitstreamInfoVoip(
                goto cleanup;
            }

#ifdef IVAS_RTPDUMP
            rtpdumpDepackerError = IVAS_RTPDUMP_DEPACKER_open( &rtpdumpDepacker, f_rtpstream );
#else
            rtpdumpDepackerError = EVS_RTPDUMP_DEPACKER_open( &rtpdumpDepacker, f_rtpstream, arg.inputFormat == IVAS_DEC_INPUT_FORMAT_RTPDUMP_HF );
#endif
            if ( rtpdumpDepackerError != EVS_RTPDUMP_DEPACKER_NO_ERROR )
            {
                fprintf( stderr, "error in EVS_RTPDUMP_DEPACKER_open(): %d\n", rtpdumpDepackerError );
@@ -2982,12 +3008,20 @@ static ivas_error printBitstreamInfoVoip(
        if ( arg.inputFormat == IVAS_DEC_INPUT_FORMAT_G192 )
        {
            error = BS_Reader_ReadVoipFrame_compact( hBsReader, au, &auSizeBits, &rtpSequenceNumber, &rtpTimeStamp, &nextPacketRcvTime_ms );
#ifdef IVAS_RTPDUMP
            ivasIndicatorOrQBit = 1; /* good q_bit for INPUT_FORMAT_G192 */
#else
            qBit = 1; /* good q_bit for INPUT_FORMAT_G192 */
#endif
        }
        else
        {
            auPtr = au; /* might have been set to RTP packet in prev call */
#ifdef IVAS_RTPDUMP
            rtpdumpDepackerError = IVAS_RTPDUMP_DEPACKER_readNextFrame( &rtpdumpDepacker, &rtpSequenceNumber, &rtpTimeStamp, &nextPacketRcvTime_ms, &evsIvasModeBit, &bitrateIndex, &ivasIndicatorOrQBit, &auPtr, (uint16_t *) &auSizeBits );
#else
            rtpdumpDepackerError = EVS_RTPDUMP_DEPACKER_readNextFrame( &rtpdumpDepacker, &rtpSequenceNumber, &rtpTimeStamp, &nextPacketRcvTime_ms, &isAMRWB_IOmode, &frameTypeIndex, &qBit, &auPtr, (uint16_t *) &auSizeBits );
#endif

            /* EVS RTP payload format has timescale 16000, JBM uses 1000 internally */
            rtpTimeStamp = rtpTimeStamp / 16;
@@ -2997,7 +3031,11 @@ static ivas_error printBitstreamInfoVoip(
            fprintf( stderr, "failed to read first RTP packet\n" );
            goto cleanup;
        }
#ifdef IVAS_RTPDUMP
    } while ( !ivasIndicatorOrQBit || auSizeBits < MIN_NUM_BITS_ACTIVE_FRAME || auSizeBits == NUM_BITS_SID_IVAS_5K2 );
#else
    } while ( !qBit || auSizeBits < MIN_NUM_BITS_ACTIVE_FRAME || auSizeBits == NUM_BITS_SID_IVAS_5K2 );
#endif

    BS_Reader_Rewind( hBsReader );

@@ -3011,7 +3049,11 @@ static ivas_error printBitstreamInfoVoip(

cleanup:

#ifdef IVAS_RTPDUMP
    IVAS_RTPDUMP_DEPACKER_close( &rtpdumpDepacker );
#else
    EVS_RTPDUMP_DEPACKER_close( &rtpdumpDepacker );
#endif

    if ( previewFailed && error == IVAS_ERR_OK )
    {
@@ -3076,12 +3118,23 @@ static ivas_error decodeVoIP(
    int32_t delayTimeScale = -1;
    int16_t i;
    FILE *f_rtpstream = NULL;
#ifdef IVAS_RTPDUMP
    IVAS_RTPDUMP_DEPACKER rtpdumpDepacker;
    IVAS_RTPDUMP_DEPACKER_ERROR rtpdumpDepackerError = IVAS_RTPDUMP_DEPACKER_NO_ERROR;
#else
    EVS_RTPDUMP_DEPACKER rtpdumpDepacker;
    EVS_RTPDUMP_DEPACKER_ERROR rtpdumpDepackerError = EVS_RTPDUMP_DEPACKER_NO_ERROR;
#endif
    uint8_t *auPtr = NULL;
#ifdef IVAS_RTPDUMP
    bool evsIvasModeBit;
    uint16_t bitrateIndex;
    bool ivasIndicatorOrQBit;
#else
    bool isAMRWB_IOmode;
    uint16_t frameTypeIndex;
    bool qBit;
#endif

    IVAS_DEC_BS_FORMAT bsFormat = IVAS_DEC_BS_UNKOWN;
    IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS];
@@ -3131,12 +3184,21 @@ static ivas_error decodeVoIP(
                goto cleanup;
            }

#ifdef IVAS_RTPDUMP
            rtpdumpDepackerError = IVAS_RTPDUMP_DEPACKER_open( &rtpdumpDepacker, f_rtpstream );
            if ( rtpdumpDepackerError != IVAS_RTPDUMP_DEPACKER_NO_ERROR )
            {
                fprintf( stderr, "error in IVAS_RTPDUMP_DEPACKER_open(): %d\n", rtpdumpDepackerError );
                goto cleanup;
            }
#else
            rtpdumpDepackerError = EVS_RTPDUMP_DEPACKER_open( &rtpdumpDepacker, f_rtpstream, arg.inputFormat == IVAS_DEC_INPUT_FORMAT_RTPDUMP_HF );
            if ( rtpdumpDepackerError != EVS_RTPDUMP_DEPACKER_NO_ERROR )
            {
                fprintf( stderr, "error in EVS_RTPDUMP_DEPACKER_open(): %d\n", rtpdumpDepackerError );
                goto cleanup;
            }
#endif
            break;
        case IVAS_DEC_INPUT_FORMAT_G192:
            auPtr = au;
@@ -3173,17 +3235,29 @@ static ivas_error decodeVoIP(
    if ( arg.inputFormat == IVAS_DEC_INPUT_FORMAT_G192 )
    {
        error = BS_Reader_ReadVoipFrame_compact( hBsReader, au, &auSize, &rtpSequenceNumber, &rtpTimeStamp, &nextPacketRcvTime_ms );
#ifdef IVAS_RTPDUMP
        ivasIndicatorOrQBit = 1; /* good q_bit for INPUT_FORMAT_G192 */
#else
        qBit = 1; /* good q_bit for INPUT_FORMAT_G192 */
#endif
    }
    else
    {
        auPtr = au; /* might have been set to RTP packet in prev call */
#ifdef IVAS_RTPDUMP
        rtpdumpDepackerError = IVAS_RTPDUMP_DEPACKER_readNextFrame(&rtpdumpDepacker, &rtpSequenceNumber, &rtpTimeStamp, &nextPacketRcvTime_ms, &evsIvasModeBit, &bitrateIndex, &ivasIndicatorOrQBit, &auPtr, (uint16_t *) &auSize );
#else
        rtpdumpDepackerError = EVS_RTPDUMP_DEPACKER_readNextFrame( &rtpdumpDepacker, &rtpSequenceNumber, &rtpTimeStamp, &nextPacketRcvTime_ms, &isAMRWB_IOmode, &frameTypeIndex, &qBit, &auPtr, (uint16_t *) &auSize );
#endif

        /* EVS RTP payload format has timescale 16000, JBM uses 1000 internally */
        rtpTimeStamp = rtpTimeStamp / 16;
    }
#ifdef IVAS_RTPDUMP
    if ( error != IVAS_ERR_OK || rtpdumpDepackerError != IVAS_RTPDUMP_DEPACKER_NO_ERROR )
#else
    if ( error != IVAS_ERR_OK || rtpdumpDepackerError != EVS_RTPDUMP_DEPACKER_NO_ERROR )
#endif
    {
        fprintf( stderr, "failed to read first RTP packet\n" );
        goto cleanup;
@@ -3328,7 +3402,11 @@ static ivas_error decodeVoIP(
        while ( nextPacketRcvTime_ms <= systemTime_ms )
        {
            /* feed the previous read packet into the receiver now */
#ifdef IVAS_RTPDUMP
            error = IVAS_DEC_VoIP_FeedFrame(hIvasDec, auPtr, auSize, rtpSequenceNumber, rtpTimeStamp, nextPacketRcvTime_ms, ivasIndicatorOrQBit );
#else
            error = IVAS_DEC_VoIP_FeedFrame( hIvasDec, auPtr, auSize, rtpSequenceNumber, rtpTimeStamp, nextPacketRcvTime_ms, qBit );
#endif
            if ( error != IVAS_ERR_OK )
            {
                fprintf( stderr, "\nError in IVAS_DEC_VoIP_FeedFrame: %s\n", IVAS_DEC_GetErrorMessage( error ) );
@@ -3341,28 +3419,66 @@ static ivas_error decodeVoIP(
            {
                error = BS_Reader_ReadVoipFrame_compact( hBsReader, au, &auSize, &rtpSequenceNumber, &rtpTimeStamp, &nextPacketRcvTime_ms );

#ifdef IVAS_RTPDUMP
                ivasIndicatorOrQBit = 1; /* good q_bit for VOIP_G192_RTP */
#else
                qBit = 1; /* good q_bit for VOIP_G192_RTP */
#endif
            }
            else
            {
                auPtr = au; /* might have been set to RTP packet in prev call */
#ifdef IVAS_RTPDUMP
                rtpdumpDepackerError = IVAS_RTPDUMP_DEPACKER_readNextFrame( &rtpdumpDepacker, &rtpSequenceNumber, &rtpTimeStamp,
                                                                            &nextPacketRcvTime_ms,
                                                                            &evsIvasModeBit, &bitrateIndex, &ivasIndicatorOrQBit,
                                                                            &auPtr, (uint16_t *) &auSize );
                /* IVAS RTP payload format has timescale 16000, JBM uses 1000 internally */
                rtpTimeStamp = rtpTimeStamp / 16;

                /* parse PI data */
                error = IVAS_DEC_parsePIdata( hIvasDec, &rtpdumpDepacker.PIdataCurrentFrame, &rtpdumpDepacker.PIdataDepackerState );
                if ( error != IVAS_ERR_OK )
                {
                    fprintf( stderr, "\nError in IVAS_DEC_parsePIdata: %s\n", IVAS_DEC_GetErrorMessage( error ) );
                    goto cleanup;
                }
                IVAS_DEC_resetPIdataCurrentFrame( &rtpdumpDepacker.PIdataCurrentFrame );
#else
                rtpdumpDepackerError = EVS_RTPDUMP_DEPACKER_readNextFrame( &rtpdumpDepacker, &rtpSequenceNumber, &rtpTimeStamp,
                                                                           &nextPacketRcvTime_ms,
                                                                           &isAMRWB_IOmode, &frameTypeIndex, &qBit,
                                                                           &auPtr, (uint16_t *) &auSize );
                /* EVS RTP payload format has timescale 16000, JBM uses 1000 internally */
                rtpTimeStamp = rtpTimeStamp / 16;
#endif

            }
#ifdef IVAS_RTPDUMP
            if ( error == IVAS_ERR_END_OF_FILE || rtpdumpDepackerError == IVAS_RTPDUMP_DEPACKER_EOF )
#else
            if ( error == IVAS_ERR_END_OF_FILE || rtpdumpDepackerError == EVS_RTPDUMP_DEPACKER_EOF )
#endif
            {
                /* finished reading */
                nextPacketRcvTime_ms = (uint32_t) -1;
            }
#ifdef IVAS_RTPDUMP
            else if ( error != IVAS_ERR_OK )
#else
            else if ( error != IVAS_ERR_OK || rtpdumpDepackerError != EVS_RTPDUMP_DEPACKER_NO_ERROR )
#endif
            {
                fprintf( stderr, "\nError in BS_Reader_ReadVoipFrame_compact, error code: %d\n", error );
                goto cleanup;
            }
#ifdef IVAS_RTPDUMP
            else if ( rtpdumpDepackerError != IVAS_RTPDUMP_DEPACKER_NO_ERROR )
            {
                fprintf( stderr, "\nError in IVAS_RTPDUMP_DEPACKER_readNextFrame, error code: %d\n", error );
                goto cleanup;
            }
#endif
        }

        /* we are finished when all packets have been received and jitter buffer is empty */
@@ -3524,6 +3640,10 @@ static ivas_error decodeVoIP(
            }
        }

#ifdef IVAS_RTPDUMP
        IVAS_DEC_resetExternalOrientations(hIvasDec);
#endif

        if ( !arg.quietModeEnabled )
        {
            fprintf( stdout, "%-8d\b\b\b\b\b\b\b\b", frame );
@@ -3668,7 +3788,11 @@ static ivas_error decodeVoIP(

cleanup:

#ifdef IVAS_RTPDUMP
    IVAS_RTPDUMP_DEPACKER_close( &rtpdumpDepacker );
#else
    EVS_RTPDUMP_DEPACKER_close( &rtpdumpDepacker );
#endif
    AudioFileWriter_close( &afWriter );
    JbmOffsetFileWriter_close( &jbmOffsetWriter );
#ifdef SUPPORT_JBM_TRACEFILE
+278 −4

File changed.

Preview size limit exceeded, changes collapsed.

+52 −0
Original line number Diff line number Diff line
@@ -163,6 +163,58 @@ Word16 rate2EVSmode(
    return rate2AMRWB_IOmode( brate );
}

#ifdef IVAS_RTPDUMP
/*-------------------------------------------------------------------*
 * rate2IVASmode()
 *
 * Lookup IVAS mode. Note: FRAME_NO_DATA frames should be looked up with rate2EVSmode().
 *-------------------------------------------------------------------*/
Word16 rate2IVASmode(
    const Word32 brate  /* i  : bitrate                                               */
)
{
    switch ( brate )
    {
        /* IVAS modes */
        case IVAS_SID_5k2:
            return IVAS_TOC_SID;
        case IVAS_13k2:
            return IVAS_TOC_13200;
        case IVAS_16k4:
            return IVAS_TOC_16400;
        case IVAS_24k4:
            return IVAS_TOC_24400;
        case IVAS_32k:
            return IVAS_TOC_32000;
        case IVAS_48k:
            return IVAS_TOC_48000;
        case IVAS_64k:
            return IVAS_TOC_64000;
        case IVAS_80k:
            return IVAS_TOC_80000;
        case IVAS_96k:
            return IVAS_TOC_96000;
        case IVAS_128k:
            return IVAS_TOC_128000;
        case IVAS_160k:
            return IVAS_TOC_160000;
        case IVAS_192k:
            return IVAS_TOC_192000;
        case IVAS_256k:
            return IVAS_TOC_256000;
        case IVAS_384k:
            return IVAS_TOC_384000;
        case IVAS_512k:
            return IVAS_TOC_512000;
        default:
            break;
    }

    return -1;
}

#endif

/*-------------------------------------------------------------------*
 * ind_list_realloc()
 *
+25 −0
Original line number Diff line number Diff line
@@ -36,6 +36,9 @@
/* options.h needed for debugging/development features
 * It should be stripped for delivery along with debugging switches */
#include "options.h"
#ifdef IVAS_RTPDUMP
#include <stdbool.h>
#endif
#include <stdint.h>
#include <stdio.h>
#include "ivas_error.h"
@@ -213,6 +216,28 @@ typedef struct _IVAS_JBM_TRACE_DATA

} IVAS_JBM_TRACE_DATA;

#ifdef IVAS_RTPDUMP
typedef struct
{
    bool PIdataPresent;
    char *sceneOrientation;
    char *deviceOrientationCompensated;
    char *deviceOrientationUncompensated;
    char *acousticEnvironmentId;
    char *acousticEnvironmentOnlyLateReverb;
    char *acousticEnvironmentLateReverbAndEarlyReflections;
    bool enableHeadTracking;
    bool disableHeadTracking;
} PI_DATA_CURRENT_FRAME;

typedef struct
{
    bool sceneOrientationSaved;
    IVAS_QUATERNION sceneOrientationQuat;
    bool deviceOrientationSaved;
    IVAS_QUATERNION deviceOrientationQuat;
} PI_DATA_DEPACKER_STATE;
#endif

/*----------------------------------------------------------------------------------*
 * Split rendering API constants, structures, and enums
+23 −0
Original line number Diff line number Diff line
@@ -1772,6 +1772,29 @@ typedef enum

} STEREO_DMX_EVS_PRC;

#ifdef IVAS_RTPDUMP
/* "IVAS bit rate" column in table A.3.3.3.2-1 of TS26.253 Annex A */
typedef enum
{
    IVAS_TOC_13200 = 0x0,    // 0000
    IVAS_TOC_16400 = 0x1,    // 0001
    IVAS_TOC_24400 = 0x2,    // 0010
    IVAS_TOC_32000 = 0x3,    // 0011
    IVAS_TOC_48000 = 0x4,    // 0100
    IVAS_TOC_64000 = 0x5,    // 0101
    IVAS_TOC_80000 = 0x6,    // 0110
    IVAS_TOC_96000 = 0x7,    // 0111
    IVAS_TOC_128000 = 0x8,   // 1000
    IVAS_TOC_160000 = 0x9,   // 1001
    IVAS_TOC_192000 = 0xA,   // 1010
    IVAS_TOC_256000 = 0xB,   // 1011
    IVAS_TOC_384000 = 0xC,   // 1100
    IVAS_TOC_512000 = 0xD,   // 1101
    IVAS_TOC_RESERVED = 0xE, // 1110
    IVAS_TOC_SID = 0xF       // 1111
} IVAS_TOC_BITRATE_INDEX;

#endif
#endif
/* clang-format on */
/* IVAS_CNST_H  */
Loading