diff --git a/CMakeLists.txt b/CMakeLists.txt index fe516c9ec8bd55971abf1ff8c1c8b954f5646a9f..bae6fa624ebf843f67e5bad98d09961d4465519c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -165,7 +165,7 @@ file(GLOB libDecSrcs "lib_dec/*.c") file(GLOB libDecHeaders "lib_dec/*.h") add_library(lib_dec ${libDecSrcs} ${libDecHeaders}) target_link_libraries(lib_dec lib_com lib_rend lib_debug lib_isar) -target_include_directories(lib_dec PUBLIC lib_dec lib_rend PRIVATE lib_enc lib_isar) +target_include_directories(lib_dec PUBLIC lib_dec lib_rend PRIVATE lib_enc lib_isar lib_util) file(GLOB libUtilSrcs "lib_util/*.c") file(GLOB libUtilHeaders "lib_util/*.h") diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 3c7ea3e597de37d9377fc8ad745a158d37ca713c..5f60decb0897b11ebf8cc0f4c70413da41322f0e 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -68,7 +68,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_rend;..\lib_lc3plus;..\lib_util;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -109,7 +109,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_rend;..\lib_lc3plus;..\lib_util;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) true diff --git a/apps/decoder.c b/apps/decoder.c index ed96f7919618ff1fc2c47531da14f77b5b81b8de..99b0cc4f3474988c6ca03148e3baa873fcee6bfe 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -63,6 +63,9 @@ #include "flp_debug.h" #endif +#ifdef FIXED_RTP_SEQUENCE_NUM +#define RANDOM_INITSEED ( 0xFEEDFADE ) +#endif #define WMC_TOOL_SKIP @@ -133,7 +136,9 @@ typedef struct bool tsmEnabled; IVAS_RENDER_FRAMESIZE renderFramesize; #ifdef IVAS_RTPDUMP + bool applyPiData; char *piOutputFilename; + bool rtpOutSR; #endif #ifdef DEBUGGING #ifdef DEBUG_FOA_AGC @@ -447,6 +452,9 @@ int main( asked_frame_size = arg.renderFramesize; uint16_t aeID = arg.aeSequence.count > 0 ? arg.aeSequence.pID[0] : 65535; +#ifdef IVAS_RTPDUMP + arg.enableHeadRotation = arg.enableHeadRotation || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM; +#endif if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputConfig, arg.renderFramesize, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.enableExternalOrientation, arg.orientation_tracking, arg.renderConfigEnabled, arg.non_diegetic_pan_enabled, arg.non_diegetic_pan_gain, arg.dpidEnabled, aeID, arg.objEditEnabled, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) @@ -485,7 +493,9 @@ int main( goto cleanup; } +#ifndef IVAS_RTPDUMP arg.enableHeadRotation = true; +#endif } /*------------------------------------------------------------------------------------------* @@ -976,7 +986,9 @@ static bool parseCmdlIVAS_dec( arg->enableExternalOrientation = false; arg->externalOrientationTrajFileName = NULL; #ifdef IVAS_RTPDUMP + arg->applyPiData = false; arg->piOutputFilename = NULL; + arg->rtpOutSR = false; #endif #ifdef SUPPORT_JBM_TRACEFILE @@ -1077,6 +1089,16 @@ static bool parseCmdlIVAS_dec( arg->piOutputFilename = argv[i++]; } + else if ( strcmp( argv_to_upper, "-APPLYPIDATA" ) == 0 ) + { + arg->applyPiData = true; + i++; + } + else if ( strcmp( argv_to_upper, "-RTPOUTSR" ) == 0 ) + { + arg->rtpOutSR = true; + i++; + } #endif #ifdef SUPPORT_JBM_TRACEFILE else if ( strcmp( argv_to_upper, "-TRACEFILE" ) == 0 ) @@ -1669,6 +1691,8 @@ static void usage_dec( void ) 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" ); fprintf( stdout, "-PiDataFile PF Log the timestampped PI data.\n" ); + fprintf( stdout, "-ApplyPiData Apply the PI data found in the rtp packet.\n" ); + fprintf( stdout, "-rtpOutSR : Split Rendering bitstream RTPDump output \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" ); @@ -1777,6 +1801,9 @@ static ivas_error initOnFirstGoodFrame( IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS], /* o : */ int16_t *pNumOutChannels, /* o : */ uint16_t *pNumObj, /* o : */ +#ifdef IVAS_RTPDUMP + IVAS_RTP *srRtp, /* o : */ +#endif SplitFileReadWrite **splitRendWriter ) { int16_t isSplitRend, isSplitCoded; @@ -1828,6 +1855,14 @@ static ivas_error initOnFirstGoodFrame( ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; int16_t splitRendIsarFrameSizeMs; int16_t lc3plusHighRes; +#ifdef FIXED_RTP_SEQUENCE_NUM + /* Ideally ssrc is negotiated via SDP and sequence number is radomized but we + use fixed seed for random num generator for regression based tests. Any realtime + application should implement this initialization seperately */ + srand( RANDOM_INITSEED ); + uint32_t ssrc = ( (uint32_t) rand() & 0x0000FFFF ) | ( (uint32_t) rand() << 16 ); + uint16_t seqNumInitVal = (uint16_t) ( rand() & 0xFFFF ); +#endif if ( ( error = IVAS_DEC_GetDelay( hIvasDec, delayNumSamples_temp, &delayTimeScale_temp ) ) != IVAS_ERR_OK ) { @@ -1841,7 +1876,45 @@ static ivas_error initOnFirstGoodFrame( return error; } +#ifdef IVAS_RTPDUMP + /* Split Rendering RTPDump Output file */ + if ( arg.rtpOutSR && srRtp != NULL ) + { + FILE *fParamsSR = NULL; + char srParamsFile[FILENAME_MAX], *ext = ".sr.txt"; + strncpy( srParamsFile, arg.outputWavFilename, FILENAME_MAX - sizeof( ext ) ); + strncat( srParamsFile, ext, sizeof( ext ) + 1 ); + + /* Write the Split Rendering Params passed from SDP to srParamsFile */ + fParamsSR = fopen( srParamsFile, "w" ); + if ( NULL != fParamsSR ) + { + fprintf( fParamsSR, "CODEC = %s;\nDOF = %d;\nFRAMESIZE = %d;\nRENDERSIZE = %d;\nLC3PLUS_HIGHRES = %d;\n", + splitRendCodec == ISAR_SPLIT_REND_CODEC_LC3PLUS ? "LC3PLUS" : "LCLD", + poseCorrection, + splitRendCodecFrameSizeMs, + splitRendIsarFrameSizeMs, + lc3plusHighRes ); + fclose( fParamsSR ); + fParamsSR = NULL; + } + + + /* Split Rendering RTPDump Output file */ +#ifdef FIXED_RTP_SEQUENCE_NUM + if ( ( error = IVAS_RTP_WRITER_Init( srRtp, arg.outputWavFilename, 1000 / ( IVAS_NUM_FRAMES_PER_SEC * splitRendCodecFrameSizeMs ), ssrc, seqNumInitVal ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_RTP_WRITER_Init( srRtp, arg.outputWavFilename, 1000 / ( IVAS_NUM_FRAMES_PER_SEC * splitRendCodecFrameSizeMs ) ) ) != IVAS_ERR_OK ) +#endif + { + fprintf( stderr, "\nError: Can't open SR output bitstream file for RTP output %s \n\n", arg.outputWavFilename ); + return error; + } + } + else if ( isSplitCoded ) +#else if ( isSplitCoded ) +#endif { if ( ( error = split_rend_writer_open( splitRendWriter, arg.outputWavFilename, delayNumSamples_temp[0], delayTimeScale_temp, splitRendCodec, poseCorrection, splitRendCodecFrameSizeMs, splitRendIsarFrameSizeMs, arg.output_Fs, lc3plusHighRes ) ) != IVAS_ERR_OK ) { @@ -1875,6 +1948,74 @@ static ivas_error initOnFirstGoodFrame( } } +#ifdef IVAS_RTPDUMP + if ( !arg.rtpOutSR ) + { + int16_t pcmFrameSize; + if ( ( error = IVAS_DEC_GetOutputBufferSize( hIvasDec, &pcmFrameSize ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetOutputBufferSize, error code: %d\n", error ); + return error; + } + + /* Write zeros to the output audio buffer */ + int16_t *zeroBuf = calloc( pcmFrameSize, sizeof( int16_t ) ); + if ( zeroBuf == NULL ) + { + fprintf( stdout, "Error: Unable to allocate memory for output buffer.\n" ); + return IVAS_ERR_FAILED_ALLOC; + } + + for ( int16_t i = 0; i < numInitialBadFrames; ++i ) + { +#ifdef FIX_1119_SPLIT_RENDERING_VOIP + if ( isSplitRend ) +#else + if ( *splitRendWriter != NULL ) +#endif + { + ISAR_SPLIT_REND_BITS_DATA splitRendBitsZero; + splitRendBitsZero.bits_buf = NULL; + splitRendBitsZero.bits_read = 0; + splitRendBitsZero.bits_written = 0; + splitRendBitsZero.buf_len = 0; + splitRendBitsZero.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + splitRendBitsZero.pose_correction = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + splitRendBitsZero.codec_frame_size_ms = 0; + splitRendBitsZero.isar_frame_size_ms = 20; + + if ( split_rend_write_bitstream_to_file( *splitRendWriter, splitRendBitsZero.bits_buf, &splitRendBitsZero.bits_read, &splitRendBitsZero.bits_written ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to write to bitstream file!\n" ); + return error; + } + } + +#ifdef FIX_1119_SPLIT_RENDERING_VOIP + if ( !isSplitCoded ) +#else + else +#endif + { + if ( *pRemainingDelayNumSamples < *numOutSamples ) + { + if ( ( error = AudioFileWriter_write( *ppAfWriter, zeroBuf, *numOutSamples * *pNumOutChannels - ( *pRemainingDelayNumSamples * *pNumOutChannels ) ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + return error; + } + *pRemainingDelayNumSamples = 0; + } + else + { + *pRemainingDelayNumSamples -= *numOutSamples; + } + } + } + + free( zeroBuf ); + } +#else int16_t pcmFrameSize; if ( ( error = IVAS_DEC_GetOutputBufferSize( hIvasDec, &pcmFrameSize ) ) != IVAS_ERR_OK ) { @@ -1939,6 +2080,8 @@ static ivas_error initOnFirstGoodFrame( free( zeroBuf ); +#endif + /* Open other output files if EXT output config - now details about ISM or MASA are known */ if ( arg.outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL ) { @@ -2031,7 +2174,11 @@ static ivas_error initOnFirstGoodFrame( } } +#ifdef IVAS_RTPDUMP + if ( arg.rtpOutSR || *splitRendWriter != NULL ) +#else if ( *splitRendWriter != NULL ) +#endif { if ( numOutSamples == NULL || vec_pos_len == NULL ) { @@ -2575,7 +2722,11 @@ static ivas_error decodeG192( /* Once good frame decoded, catch up */ if ( decodedGoodFrame ) { +#ifdef IVAS_RTPDUMP + if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, &nOutSamples, &vec_pos_len, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, NULL, &splitRendWriter ) ) != IVAS_ERR_OK ) +#else if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, &nOutSamples, &vec_pos_len, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, &splitRendWriter ) ) != IVAS_ERR_OK ) +#endif { goto cleanup; } @@ -2942,7 +3093,11 @@ static ivas_error printBitstreamInfoVoip( case IVAS_DEC_INPUT_FORMAT_RTPDUMP: case IVAS_DEC_INPUT_FORMAT_RTPDUMP_HF: #ifdef IVAS_RTPDUMP - if ( ( error = IVAS_RTP_READER_Init( &ivasRtp, arg.inputBitstreamFilename, arg.piOutputFilename ) ) != IVAS_ERR_OK ) +#ifdef RTP_S4_251135_CR26253_0016_REV1 + if ( ( error = IVAS_RTP_READER_Init( &ivasRtp, 0, arg.inputBitstreamFilename, arg.piOutputFilename, arg.outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL, arg.outputWavFilename ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_RTP_READER_Init( &ivasRtp, arg.inputBitstreamFilename, arg.piOutputFilename, arg.outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL, arg.outputWavFilename ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "error in IVAS_RTP_READER_Init(): %d\n", error ); goto cleanup; @@ -2984,7 +3139,11 @@ static ivas_error printBitstreamInfoVoip( { auPtr = au; /* might have been set to RTP packet in prev call */ #ifdef IVAS_RTPDUMP +#ifdef RTP_S4_251135_CR26253_0016_REV1 + error = IVAS_RTP_ReadNextFrame( &ivasRtp, auPtr, &auSizeBits, &rtpTimeStamp, &rtpSequenceNumber, &nextPacketRcvTime_ms, NULL, &qBit ); +#else error = IVAS_RTP_ReadNextFrame( &ivasRtp, auPtr, &auSizeBits, &rtpTimeStamp, &rtpSequenceNumber, &nextPacketRcvTime_ms, &qBit ); +#endif #else rtpdumpDepackerError = EVS_RTPDUMP_DEPACKER_readNextFrame( &rtpdumpDepacker, &rtpSequenceNumber, &rtpTimeStamp, &nextPacketRcvTime_ms, &isAMRWB_IOmode, &frameTypeIndex, &qBit, &auPtr, (uint16_t *) &auSizeBits ); #endif @@ -3090,6 +3249,9 @@ static ivas_error decodeVoIP( int16_t i; #ifdef IVAS_RTPDUMP IVAS_RTP ivasRtp = { 0 }; + IVAS_RTP srRtp = { 0 }; + IVAS_RTP_SR_INFO srInfo = { true, false, 0, IVAS_SR_TRANSPORT_LCLD }; + int32_t initialTsOffsetSystemAndRTP = 0; #else FILE *f_rtpstream = NULL; EVS_RTPDUMP_DEPACKER rtpdumpDepacker; @@ -3168,7 +3330,11 @@ static ivas_error decodeVoIP( case IVAS_DEC_INPUT_FORMAT_RTPDUMP: case IVAS_DEC_INPUT_FORMAT_RTPDUMP_HF: #ifdef IVAS_RTPDUMP - if ( ( error = IVAS_RTP_READER_Init( &ivasRtp, arg.inputBitstreamFilename, arg.piOutputFilename ) ) != IVAS_ERR_OK ) +#ifdef RTP_S4_251135_CR26253_0016_REV1 + if ( ( error = IVAS_RTP_READER_Init( &ivasRtp, 0, arg.inputBitstreamFilename, arg.piOutputFilename, arg.outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL, arg.outputWavFilename ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_RTP_READER_Init( &ivasRtp, arg.inputBitstreamFilename, arg.piOutputFilename, arg.outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL, arg.outputWavFilename ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "error in IVAS_RTP_READER_Init(): %d\n", error ); goto cleanup; @@ -3231,7 +3397,12 @@ static ivas_error decodeVoIP( { auPtr = au; /* might have been set to RTP packet in prev call */ #ifdef IVAS_RTPDUMP +#ifdef RTP_S4_251135_CR26253_0016_REV1 + error = IVAS_RTP_ReadNextFrame( &ivasRtp, auPtr, &auSize, &rtpTimeStamp, &rtpSequenceNumber, &nextPacketRcvTime_ms, NULL, &qBit ); +#else error = IVAS_RTP_ReadNextFrame( &ivasRtp, auPtr, &auSize, &rtpTimeStamp, &rtpSequenceNumber, &nextPacketRcvTime_ms, &qBit ); +#endif + initialTsOffsetSystemAndRTP = rtpTimeStamp - systemTime_ms * 16; /* For time mapping */ #else rtpdumpDepackerError = EVS_RTPDUMP_DEPACKER_readNextFrame( &rtpdumpDepacker, &rtpSequenceNumber, &rtpTimeStamp, &nextPacketRcvTime_ms, &isAMRWB_IOmode, &frameTypeIndex, &qBit, &auPtr, (uint16_t *) &auSize ); #endif @@ -3414,7 +3585,11 @@ static ivas_error decodeVoIP( { auPtr = au; /* might have been set to RTP packet in prev call */ #ifdef IVAS_RTPDUMP +#ifdef RTP_S4_251135_CR26253_0016_REV1 + error = IVAS_RTP_ReadNextFrame( &ivasRtp, au, &auSize, &rtpTimeStamp, &rtpSequenceNumber, &nextPacketRcvTime_ms, NULL, &qBit ); +#else error = IVAS_RTP_ReadNextFrame( &ivasRtp, au, &auSize, &rtpTimeStamp, &rtpSequenceNumber, &nextPacketRcvTime_ms, &qBit ); +#endif /* IVAS RTP payload format has timescale 16000, JBM uses 1000 internally */ rtpTimeStamp = rtpTimeStamp / 16; @@ -3459,6 +3634,28 @@ static ivas_error decodeVoIP( /* decode and get samples */ while ( nSamplesRendered < nOutSamples ) { +#ifdef IVAS_RTPDUMP + if ( arg.applyPiData ) + { + /* Rudimentry Time Mapping to map system time to rtp timestamp */ + uint32_t piTs = systemTime_ms * 16 + initialTsOffsetSystemAndRTP; + uint32_t numPiData = 0; + + while ( ivasRtp.nProcPiData + numPiData < ivasRtp.nReadPiData && + ivasRtp.piData[ivasRtp.nProcPiData + numPiData].timestamp <= piTs ) + { + numPiData++; + } + + if ( ( error = IVAS_RTP_FeedPiDataToDecoder( hIvasDec, &ivasRtp.piData[ivasRtp.nProcPiData], numPiData ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + ivasRtp.nProcPiData += numPiData; + } +#endif #ifdef FIX_1119_SPLIT_RENDERING_VOIP if ( isSplitRend ) { @@ -3575,7 +3772,11 @@ static ivas_error decodeVoIP( #else if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, &nOutSamples, NULL, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, #endif +#ifdef IVAS_RTPDUMP + &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, &srRtp, &splitRendWriter ) ) != IVAS_ERR_OK ) +#else &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, &splitRendWriter ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "Error in initOnFirstGoodFrame(): %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -3588,7 +3789,11 @@ static ivas_error decodeVoIP( } /* Write current frame */ +#ifdef IVAS_RTPDUMP + if ( !srRtp.hPack && decodedGoodFrame ) +#else if ( decodedGoodFrame ) +#endif { #ifdef FIX_1119_SPLIT_RENDERING_VOIP if ( isSplitRend ) @@ -3673,8 +3878,25 @@ static ivas_error decodeVoIP( goto cleanup; } } + + IVAS_RTP_WriteExtPiData( ivasRtp.f_piExtOut, ivasRtp.piData, ivasRtp.nReadPiData, numObj ); + } + } +#ifdef IVAS_RTPDUMP + else if ( decodedGoodFrame ) + { + srInfo.bitrateKbps = splitRendBits->bits_written * 1000 / splitRendBits->codec_frame_size_ms; + srInfo.codec = ( splitRendBits->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) ? IVAS_SR_TRANSPORT_LC3PLUS : IVAS_SR_TRANSPORT_LCLD; + if ( ( error = IVAS_RTP_WriteNextFrame( &srRtp, splitRendBits->bits_buf, &srInfo, (int16_t) splitRendBits->bits_written, false, false ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while pushing SR audio bitstream to RTP pack\n", ivas_error_to_string( error ) ); + goto cleanup; } + splitRendBits->bits_written = 0; + splitRendBits->bits_read = 0; } +#endif + vec_pos_update = ( vec_pos_update + 1 ) % vec_pos_len; if ( vec_pos_update == 0 ) @@ -3773,6 +3995,8 @@ static ivas_error decodeVoIP( goto cleanup; } } + + IVAS_RTP_WriteExtPiData( ivasRtp.f_piExtOut, ivasRtp.piData, ivasRtp.nReadPiData, numObj ); } } @@ -3826,6 +4050,8 @@ static ivas_error decodeVoIP( { fprintf( stdout, "\nOutput MASA metadata file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); } + + fprintf( stdout, "\nOutput PI data file: %s\n", IVAS_RTP_GetExtPiFilePath( &ivasRtp ) ); } /*------------------------------------------------------------------------------------------* @@ -3837,6 +4063,7 @@ static ivas_error decodeVoIP( cleanup: #ifdef IVAS_RTPDUMP + IVAS_RTP_Term( &srRtp ); IVAS_RTP_Term( &ivasRtp ); #else EVS_RTPDUMP_DEPACKER_close( &rtpdumpDepacker ); diff --git a/apps/encoder.c b/apps/encoder.c index 44fda79373b257c91adccbe9d0e54191c78e7383..9f4e1d3cf51e6fc9e9ecb28489cceefa5bda9a0e 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -50,6 +50,9 @@ #include "flp_debug.h" #endif +#ifdef FIXED_RTP_SEQUENCE_NUM +#define RANDOM_INITSEED ( 0xFEEDDEAF ) +#endif #define WMC_TOOL_SKIP @@ -231,6 +234,15 @@ int main( IVAS_RTP ivasRtp = { 0 }; #endif +#ifdef FIXED_RTP_SEQUENCE_NUM + /* Ideally ssrc is negotiated via SDP and sequence number is radomized but we + use fixed seed for random num generator for regression based tests. Any realtime + application should implement this initialization seperately */ + srand( RANDOM_INITSEED ); + uint32_t ssrc = ( (uint32_t) rand() & 0x0000FFFF ) | ( (uint32_t) rand() << 16 ); + uint16_t seqNumInitVal = (uint16_t) ( rand() & 0xFFFF ); +#endif + /*------------------------------------------------------------------------------------------* * Parse command-line arguments *------------------------------------------------------------------------------------------*/ @@ -628,7 +640,11 @@ int main( if ( arg.rtpdumpOutput ) { +#ifdef FIXED_RTP_SEQUENCE_NUM + if ( ( error = IVAS_RTP_WRITER_Init( &ivasRtp, arg.outputBitstreamFilename, arg.numFramesPerPacket, ssrc, seqNumInitVal ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_RTP_WRITER_Init( &ivasRtp, arg.outputBitstreamFilename, arg.numFramesPerPacket ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nError: Can't open output bitstream file for RTP output %s \n\n", arg.outputBitstreamFilename ); goto cleanup; @@ -874,7 +890,11 @@ int main( goto cleanup; } +#ifdef RTP_S4_251135_CR26253_0016_REV1 + if ( ( error = IVAS_RTP_WriteNextFrame( &ivasRtp, au, NULL, numBits, isMono, forcePacket ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_RTP_WriteNextFrame( &ivasRtp, au, numBits, isMono, forcePacket ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nError %s while pushing audio frame to RTP pack\n", IVAS_ENC_GetErrorMessage( error ) ); goto cleanup; diff --git a/apps/isar_post_rend.c b/apps/isar_post_rend.c index 26fa12f6d41f74d931f72c06e14b20c291fbedfc..7d8fd0939fe88432bceb8c600130ad9ba0794c52 100644 --- a/apps/isar_post_rend.c +++ b/apps/isar_post_rend.c @@ -48,6 +48,9 @@ #include "debug.h" #endif #include "wmc_auto.h" +#ifdef RTP_S4_251135_CR26253_0016_REV1 +#include "ivas_rtp_file.h" +#endif #define WMC_TOOL_SKIP @@ -78,6 +81,9 @@ static typedef struct { +#ifdef RTP_S4_251135_CR26253_0016_REV1 + bool srRtp; +#endif IVAS_AUDIO_CONFIG audioConfig; int32_t inputChannelIndex; float gain_dB; @@ -99,6 +105,9 @@ typedef struct char executableName[POST_REND_MAX_CLI_ARG_LENGTH]; char inputFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; char outputFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + char srParamsFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; +#endif int32_t sampleRate; InputConfig inConfig; OutputConfig outConfig; @@ -128,6 +137,9 @@ typedef enum CmdLnOptionId_listFormats, CmdLnOptionId_SplitRendBFIFile, CmdLnOptionId_framing, +#ifdef RTP_S4_251135_CR26253_0016_REV1 + CmdLnOptionId_srParamsFile, +#endif } CmdLnOptionId; static const CmdLnParser_Option cliOptions[] = { @@ -203,6 +215,14 @@ static const CmdLnParser_Option cliOptions[] = { .matchShort = "fr", .description = "Set Render audio framing.", }, +#ifdef RTP_S4_251135_CR26253_0016_REV1 + { + .id = CmdLnOptionId_srParamsFile, + .match = "sr_params", + .matchShort = "s", + .description = "Path to the split rendering init params file", + }, +#endif }; @@ -214,7 +234,11 @@ static const int32_t numCliOptions = sizeof( cliOptions ) / sizeof( CmdLnParser_ static void printSupportedAudioConfigs( void ); +#ifdef RTP_S4_251135_CR26253_0016_REV1 +static IVAS_AUDIO_CONFIG parseAudioConfig( const char *configString, bool *srRtp ); +#else static IVAS_AUDIO_CONFIG parseAudioConfig( const char *configString ); +#endif static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer ); @@ -302,12 +326,20 @@ static bool parseInConfig( } /* Check for single-format inputs. The given string should map to a member of AUDIO_CONFIG enum. */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + bool srRtp = false; + IVAS_AUDIO_CONFIG audioConfig = parseAudioConfig( inFormatStr, &srRtp ); +#else IVAS_AUDIO_CONFIG audioConfig = parseAudioConfig( inFormatStr ); +#endif switch ( audioConfig ) { case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: inConfig->numBinBuses = 1; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + inConfig->binBuses[0].srRtp = srRtp; +#endif inConfig->binBuses[0].audioConfig = audioConfig; inConfig->binBuses[0].inputChannelIndex = 0; inConfig->binBuses[0].gain_dB = 0.0f; @@ -358,11 +390,19 @@ static bool parseRenderFramesize( static IVAS_AUDIO_CONFIG parseAudioConfig( +#ifdef RTP_S4_251135_CR26253_0016_REV1 + const char *configString, + bool *srRtp ) +#else const char *configString ) +#endif { char charBuf[25]; charBuf[24] = '\0'; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + *srRtp = false; +#endif strncpy( charBuf, configString, sizeof( charBuf ) - 1 ); charBuf[sizeof( charBuf ) - 1] = '\0'; to_upper( charBuf ); @@ -379,6 +419,13 @@ static IVAS_AUDIO_CONFIG parseAudioConfig( { return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED; } +#ifdef RTP_S4_251135_CR26253_0016_REV1 + if ( strcmp( charBuf, "RTPDUMP" ) == 0 ) + { + *srRtp = true; + return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED; + } +#endif return IVAS_AUDIO_CONFIG_INVALID; } @@ -435,6 +482,9 @@ static CmdlnArgs defaultArgs( strncpy( args.executableName, executableName, POST_REND_MAX_CLI_ARG_LENGTH ); clearString( args.inputFilePath ); clearString( args.outputFilePath ); +#ifdef RTP_S4_251135_CR26253_0016_REV1 + clearString( args.srParamsFilePath ); +#endif args.sampleRate = 0; args.outConfig.audioConfig = IVAS_AUDIO_CONFIG_INVALID; @@ -542,6 +592,12 @@ static void parseOption( } break; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + case CmdLnOptionId_srParamsFile: + assert( numOptionValues == 1 ); + strncpy( args->srParamsFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + break; +#endif default: assert( 0 && "This should be unreachable - all command line options should be explicitly handled." ); break; @@ -578,6 +634,9 @@ static void printSupportedAudioConfigs( void ) "BINAURAL (output only)", "BINAURAL_SPLIT_PCM", "BINAURAL_SPLIT_CODED", +#ifdef RTP_S4_251135_CR26253_0016_REV1 + "RTPDUMP", +#endif }; fprintf( stdout, "Supported audio formats:\n" ); @@ -670,6 +729,96 @@ static void convertOutputBuffer( return; } +#ifdef RTP_S4_251135_CR26253_0016_REV1 +static void trim( char *str ) +{ + char c; + int r = 0, w = 0; + while ( ( c = str[r] ) != 0 && ( c == ' ' || c == '\t' || c == ';' ) ) + { + r++; + } + + while ( ( c = str[r] ) != 0 && ( c != ' ' && c != '\t' && c != ';' ) ) + { + str[w++] = c; + r++; + } + str[w] = 0; +} + +static ivas_error parseSRParamsFile( + const char *srParamsFilePath, + ISAR_SPLIT_REND_CODEC *codec, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, + int16_t *codec_frame_size_ms, + int16_t *isar_frame_size_ms, + int16_t *lc3plusHighRes ) +{ + FILE *fParamSR = fopen( srParamsFilePath, "r" ); + if ( NULL == fParamSR ) + { + fprintf( stderr, "error in opening srParams File %s)\n", srParamsFilePath ); + return IVAS_ERR_FAILED_FILE_OPEN; + } + + *codec = ISAR_SPLIT_REND_CODEC_NONE; + *poseCorrection = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + *codec_frame_size_ms = 5; + *lc3plusHighRes = 0; + + while ( !feof( fParamSR ) ) + { + char key[16], value[16]; + if ( 2 == fscanf( fParamSR, "%15s = %15s", key, value ) ) + { + trim( key ); + trim( value ); + + if ( 0 == strncmp( key, "CODEC", 5 ) ) + { + *codec = ( 0 == strncmp( value, "LCLD", 4 ) ) ? ISAR_SPLIT_REND_CODEC_LCLD : *codec; + *codec = ( 0 == strncmp( value, "LC3PLUS", 7 ) ) ? ISAR_SPLIT_REND_CODEC_LC3PLUS : *codec; + } + else if ( 0 == strncmp( key, "DOF", 3 ) ) + { + int val = atoi( value ); + if ( val == 0 || val == 1 ) + { + *poseCorrection = ( val == 0 ) ? ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE : ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + } + } + else if ( 0 == strncmp( key, "FRAMESIZE", 9 ) ) + { + int val = atoi( value ); + if ( val == 5 || val == 10 || val == 20 ) + { + *codec_frame_size_ms = (int16_t) val; + } + } + else if ( 0 == strncmp( key, "RENDERSIZE", 9 ) ) + { + int val = atoi( value ); + if ( val == 5 || val == 10 || val == 20 ) + { + *isar_frame_size_ms = (int16_t) val; + } + } + else if ( 0 == strncmp( key, "LC3PLUS_HIGHRES", 15 ) ) + { + int val = atoi( value ); + if ( val == 0 || val == 1 ) + { + *lc3plusHighRes = (int16_t) val; + } + } + } + } + + fclose( fParamSR ); + return IVAS_ERR_OK; +} +#endif /*------------------------------------------------------------------------------------------* * main() @@ -710,6 +859,9 @@ int main( int16_t i, numChannels; ivas_error error = IVAS_ERR_OK; bool splitBinNeedsNewFrame = true; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + IVAS_RTP srRTP = { 0 }; +#endif #ifdef WMOPS reset_wmops(); @@ -736,6 +888,9 @@ int main( convert_backslash( args.inputFilePath ); convert_backslash( args.outputFilePath ); convert_backslash( args.headRotationFilePath ); +#ifdef RTP_S4_251135_CR26253_0016_REV1 + convert_backslash( args.srParamsFilePath ); +#endif /*------------------------------------------------------------------------------------------* * Open head-rotation file @@ -790,8 +945,34 @@ int main( } } +#ifdef RTP_S4_251135_CR26253_0016_REV1 + if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].srRtp ) ) + { + error = parseSRParamsFile( args.srParamsFilePath, + &bitsBuffer.config.codec, + &bitsBuffer.config.poseCorrection, + &bitsBuffer.config.codec_frame_size_ms, + &bitsBuffer.config.isar_frame_size_ms, + &bitsBuffer.config.lc3plusHighRes ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "\nCould not open split rend params file %s\n", args.srParamsFilePath ); + goto cleanup; + } + + if ( ( error = IVAS_RTP_READER_Init( &srRTP, (uint32_t) bitsBuffer.config.codec_frame_size_ms, args.inputFilePath, NULL, false, NULL ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "error in IVAS_RTP_READER_Init(): %d\n", error ); + goto cleanup; + } + audioReader = NULL; + } + /*if split renderer is running in post renderer mode*/ + else if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) +#else /*if split renderer is running in post renderer mode*/ if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) +#endif { error = split_rend_reader_open( &hSplitRendFileReadWrite, args.inputFilePath, @@ -991,7 +1172,53 @@ int main( num_in_channels = inBuffer.config.numChannels; numSamplesRead = 0; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + if ( srRTP.hRtpFile && splitBinNeedsNewFrame ) + { + IVAS_RTP_SR_INFO srInfo = { 0 }; + uint32_t rtpTimeStamp = 0, nextPacketRcvTime_ms = 0; + uint16_t rtpSequenceNumber = 0; + int16_t auSizeBits = 0; + bool qBit = false; + uint8_t *bitBuffer = bitsBuffer.bits; + int16_t frameMS = 0; + + numSamplesRead = (int16_t) inBufferSize; + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + + while ( frameMS < bitsBuffer.config.isar_frame_size_ms ) + { + error = IVAS_RTP_ReadNextFrame( &srRTP, bitBuffer, &auSizeBits, &rtpTimeStamp, &rtpSequenceNumber, &nextPacketRcvTime_ms, &srInfo, &qBit ); + if ( error != IVAS_ERR_OK ) + { + if ( error == IVAS_ERR_END_OF_FILE ) + { + numSamplesRead = 0; + } + else + { + fprintf( stderr, "\nUnable to read from bitstream file!\n" ); + goto cleanup; + } + } + /* Ensure a SR RTP stream was received */ + if ( !srInfo.valid ) + { + fprintf( stderr, "\nNon-SR RTP stream detected !\n" ); + goto cleanup; + } + + bitBuffer += ( auSizeBits + 7 ) / 8; + bitsBuffer.config.bitsWritten += auSizeBits; + bitsBuffer.config.codec = srInfo.codec == IVAS_SR_TRANSPORT_LC3PLUS ? ISAR_SPLIT_REND_CODEC_LC3PLUS : ISAR_SPLIT_REND_CODEC_LCLD; + frameMS += bitsBuffer.config.codec_frame_size_ms; + } + } + else if ( ( hSplitRendFileReadWrite != NULL ) && splitBinNeedsNewFrame ) +#else if ( ( hSplitRendFileReadWrite != NULL ) && splitBinNeedsNewFrame ) +#endif { ivas_error error_tmp; diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index bd168207f074a035bddfc3d385902d78357c8a5f..d05817443d721c58f7474044e547beb201260aaf 100755 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -808,7 +808,19 @@ void ivas_apply_non_diegetic_panning( const int16_t output_frame /* i : output frame length per channel */ ); +#ifdef IVAS_RTPDUMP +void QuaternionProduct( + const IVAS_QUATERNION q1, + const IVAS_QUATERNION q2, + IVAS_QUATERNION *const r +); + +void QuaternionInverse( + const IVAS_QUATERNION q, + IVAS_QUATERNION *const r +); +#endif /*----------------------------------------------------------------------------------* * JBM prototypes *----------------------------------------------------------------------------------*/ diff --git a/lib_com/options.h b/lib_com/options.h index e455aa059df3ccdb294f55d956cd13727bf4306d..4920494a35ba409143438cced0ff5e66d3ca3de9 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -161,6 +161,7 @@ #define RTP_S4_251135_CR26253_0016_REV1 /* RTP Pack/Unpack API corresponding to CR 26253 */ #define IVAS_RTPDUMP /* RTPDUMP writing and reading for IVAS payloads */ +#define FIXED_RTP_SEQUENCE_NUM /* Remove random sequence number initialization */ /* ################### Start BE switches ################################# */ /* only BE switches wrt selection floating point code */ diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index fecb412e6d2f5f5d6e9c56595e36c0ac16811fb9..60808714ca483d496c57d63a40762cf7a116930a 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -1026,7 +1026,11 @@ ivas_error ivas_binRenderer_open( ivas_dirac_dec_get_response( (int16_t) ls_azimuth_CICP19[k], (int16_t) ls_elevation_CICP19[k], hBinRenderer->hReverb->foa_enc[k], 1 ); } } +#ifdef IVAS_RTPDUMP + else if ( st_ivas->ivas_format == MC_FORMAT && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) ) +#else else if ( st_ivas->ivas_format == MC_FORMAT && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) +#endif { if ( ( error = efap_init_data( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth, st_ivas->hIntSetup.ls_elevation, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) { diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index b53d8cc200e37b05b5d7afff622016d7f9cc0174..31f47c4dfdf03f541bbe35d64895bd4d04b4babd 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2082,7 +2082,11 @@ void ivas_dirac_dec_render_sf( { mvs2s( &hSpatParamRendCom->azimuth[md_idx][hDirAC->hConfig->enc_param_start_band], &azimuth[hDirAC->hConfig->enc_param_start_band], hSpatParamRendCom->num_freq_bands - hDirAC->hConfig->enc_param_start_band ); mvs2s( &hSpatParamRendCom->elevation[md_idx][hDirAC->hConfig->enc_param_start_band], &elevation[hDirAC->hConfig->enc_param_start_band], hSpatParamRendCom->num_freq_bands - hDirAC->hConfig->enc_param_start_band ); +#ifdef IVAS_RTPDUMP + if ( ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) && st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) +#else if ( ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) && st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) +#endif { num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band]; rotateAziEle_DirAC( azimuth, elevation, num_freq_bands, hSpatParamRendCom->num_freq_bands, p_Rmat ); diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 80b8c7e5e961c7713b4de1e009490e5fe82e7b40..7e09074af0431592f1b423e7985adcbda5c6ee82 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -2148,7 +2148,11 @@ ivas_error ivas_init_decoder( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { +#ifdef IVAS_RTPDUMP + if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM && st_ivas->ivas_format == MC_FORMAT && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) ) +#else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM && st_ivas->ivas_format == MC_FORMAT && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) +#endif { if ( ( error = efap_init_data( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth, st_ivas->hIntSetup.ls_elevation, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) { diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index b0ce85ce51f4b7b4ed9909e243f2a3494820669e..fb1acc52aeffdee21169fa25a13a4fc00a5e0016 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -401,7 +401,11 @@ ivas_error ivas_param_mc_dec_open( ivas_param_mc_dec_compute_interpolator( 0, 0, DEFAULT_JBM_CLDFB_TIMESLOTS, hParamMC->h_output_synthesis_params.interpolator ); /* Head or external rotation */ +#ifdef IVAS_RTPDUMP + if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) ) +#else if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) +#endif { if ( ( hParamMC->hoa_encoder = (float *) malloc( st_ivas->hTransSetup.nchan_out_woLFE * MAX_INTERN_CHANNELS * sizeof( float ) ) ) == NULL ) { diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec.c index d6c5ceec40972c7f8dd0a6cde4ce0a62091f9ff1..3724372ab04b30da4f4c26d8de5feec2b93bf365 100644 --- a/lib_dec/ivas_mc_paramupmix_dec.c +++ b/lib_dec/ivas_mc_paramupmix_dec.c @@ -349,7 +349,11 @@ ivas_error ivas_mc_paramupmix_dec_open( } /* Head or external rotation */ +#ifdef IVAS_RTPDUMP + if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) ) +#else if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) +#endif { if ( ( hMCParamUpmix->hoa_encoder = (float *) malloc( st_ivas->hTransSetup.nchan_out_woLFE * MAX_INTERN_CHANNELS * sizeof( float ) ) ) == NULL ) { diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index abc6f074e0799f102247571a97fa99c98861c6f8..6ffd1b4f7e6ae990259f4b05f66cd7a1f442d534 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -1142,7 +1142,11 @@ static ivas_error ivas_mc_dec_reconfig( { ivas_binRenderer_close( &st_ivas->hBinRenderer ); +#ifdef IVAS_RTPDUMP + if ( ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) ) +#else if ( ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) +#endif { efap_free_data( &st_ivas->hEFAPdata ); } diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config.c index 17ce37c4d454239048bca6305d2f19337b12a030..b4b241815dd11075e142dd2a595cfa0935b692c3 100644 --- a/lib_dec/ivas_output_config.c +++ b/lib_dec/ivas_output_config.c @@ -71,7 +71,11 @@ void ivas_renderer_select( * Binaural rendering configurations *-----------------------------------------------------------------*/ +#ifdef IVAS_RTPDUMP + if ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) +#else if ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) +#endif { st_ivas->hCombinedOrientationData->shd_rot_max_order = -1; } @@ -142,7 +146,11 @@ void ivas_renderer_select( *internal_config = IVAS_AUDIO_CONFIG_7_1_4; } +#ifdef IVAS_RTPDUMP + if ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) +#else if ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) +#endif { nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); @@ -185,7 +193,11 @@ void ivas_renderer_select( if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) { +#ifdef IVAS_RTPDUMP + if ( ( st_ivas->transport_config == IVAS_AUDIO_CONFIG_5_1 || st_ivas->transport_config == IVAS_AUDIO_CONFIG_7_1 ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) && st_ivas->mc_mode == MC_MODE_MCT ) +#else if ( ( st_ivas->transport_config == IVAS_AUDIO_CONFIG_5_1 || st_ivas->transport_config == IVAS_AUDIO_CONFIG_7_1 ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) && st_ivas->mc_mode == MC_MODE_MCT ) +#endif { *renderer_type = RENDERER_BINAURAL_OBJECTS_TD; } @@ -200,7 +212,11 @@ void ivas_renderer_select( *renderer_type = RENDERER_BINAURAL_FASTCONV; } +#ifdef IVAS_RTPDUMP + if ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) +#else if ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) +#endif { /* force HOA3 domain for rotation*/ *internal_config = IVAS_AUDIO_CONFIG_HOA3; diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index fc63961eda08cc6e81624ab2d2bb6d13171749ad..d8a602beb091edc727cf3211d122c4be7c22f721 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -5542,3 +5542,132 @@ ivas_error IVAS_DEC_is_split_rendering_coded_out( return IVAS_ERR_OK; } + +/*---------------------------------------------------------------------* + * IVAS_DEC_feedSinglePIorientation( ) + * + * Feed a single orientation PI data to external orientation handle. + *---------------------------------------------------------------------*/ + +static ivas_error IVAS_DEC_feedSinglePIorientation( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + bool isOrientationSaved, /* i : flag to indicate if an orientation for this PI type was previously saved */ + IVAS_QUATERNION *savedOrientation /* i : previously saved orientation for this PI type */ +) +{ + int16_t i; + ivas_error error = IVAS_ERR_OK; + IVAS_QUATERNION savedInvOrientation; + + if ( isOrientationSaved ) + { + if ( !hIvasDec->st_ivas->hExtOrientationData ) + { + if ( ( error = ivas_external_orientation_open( &( hIvasDec->st_ivas->hExtOrientationData ), hIvasDec->st_ivas->hDecoderConfig->render_framesize ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( !hIvasDec->st_ivas->hCombinedOrientationData ) + { + if ( ( error = ivas_combined_orientation_open( &( hIvasDec->st_ivas->hCombinedOrientationData ), hIvasDec->st_ivas->hDecoderConfig->output_Fs, hIvasDec->st_ivas->hDecoderConfig->render_framesize ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + QuaternionInverse( *savedOrientation, &savedInvOrientation ); + + /* use the new PI orientation or the previously saved orientation in processing */ + for ( i = 0; i < hIvasDec->st_ivas->hExtOrientationData->num_subframes; i++ ) + { + QuaternionProduct( hIvasDec->st_ivas->hExtOrientationData->Quaternions[i], savedInvOrientation, + &hIvasDec->st_ivas->hExtOrientationData->Quaternions[i] ); + hIvasDec->st_ivas->hExtOrientationData->enableExternalOrientation[i] = true; + } + hIvasDec->updateOrientation = true; + } + return error; +} + + +#ifdef RTP_S4_251135_CR26253_0016_REV1 +/*---------------------------------------------------------------------* + * IVAS_DEC_setDiegeticInput( ) + * + * Set isDiegeticInput flag for combined orientation handle based on PI data. + *---------------------------------------------------------------------*/ + +static void IVAS_DEC_setDiegeticInputPI( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const bool *diegeticPIValues /* i : diegetic values for the input stream */ +) +{ + if ( hIvasDec->st_ivas->hCombinedOrientationData != NULL ) + { + int8_t i; + for ( i = 0; i < ( 1 + IVAS_MAX_NUM_OBJECTS ); i++ ) + { + hIvasDec->st_ivas->hCombinedOrientationData->isDiegeticInputPI[i] = diegeticPIValues[i]; + } + hIvasDec->st_ivas->hCombinedOrientationData->isDiegeticInputPISet = true; + } +} +#endif + +#ifdef IVAS_RTPDUMP +ivas_error IVAS_RTP_FeedPiDataToDecoder( IVAS_DEC_HANDLE hIvasDec, PIDATA_TS *piData, uint32_t numPiData ) +{ + ivas_error error = IVAS_ERR_OK; + while ( numPiData-- ) + { + uint32_t piDataType = piData->data.noPiData.piDataType; + switch ( piDataType ) + { + case IVAS_PI_SCENE_ORIENTATION: + { + IVAS_QUATERNION *quat = &piData->data.scene.orientation; +#ifdef DEBUGGING + fprintf( stdout, "PI_SCENE_ORIENTATION : %f, %f, %f, %f\n", quat->w, quat->x, quat->y, quat->z ); +#endif + error = IVAS_DEC_feedSinglePIorientation( hIvasDec, true, quat ); + } + break; + + case IVAS_PI_DEVICE_ORIENTATION_COMPENSATED: + { + IVAS_QUATERNION *quat = &piData->data.deviceCompensated.orientation; +#ifdef DEBUGGING + fprintf( stdout, "PI_DEVICE_ORIENTATION : %f, %f, %f, %f\n", quat->w, quat->x, quat->y, quat->z ); +#endif + error = IVAS_DEC_feedSinglePIorientation( hIvasDec, true, quat ); + } + break; + +#ifdef RTP_S4_251135_CR26253_0016_REV1 + case IVAS_PI_DIEGETIC_TYPE: + { +#ifdef DEBUGGING + fprintf( stdout, "PI_DIEGETIC_TYPE : %d, %d, %d, %d, %d\n", piData->data.digeticIndicator.isDiegetic[0], piData->data.digeticIndicator.isDiegetic[1], piData->data.digeticIndicator.isDiegetic[2], piData->data.digeticIndicator.isDiegetic[3], piData->data.digeticIndicator.isDiegetic[4] ); +#endif + IVAS_DEC_setDiegeticInputPI( hIvasDec, piData->data.digeticIndicator.isDiegetic ); + } + break; +#endif + + default: + { + /* NOT HANDLED PI DATA - DO NOTHING */ + } + break; + } + if ( error != IVAS_ERR_OK ) + { + return error; + } + piData++; + } + return error; +} +#endif diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index a35dbd6ef4ce66c7fbde2a86e3bde5503fd341ca..d0d2b501d847425d71c701665cda87ba15f71d36 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -557,6 +557,11 @@ void IVAS_DEC_PrintDisclaimer( void ); +#ifdef IVAS_RTPDUMP +#include "ivas_rtp_pi_data.h" +ivas_error IVAS_RTP_FeedPiDataToDecoder( IVAS_DEC_HANDLE hIvasDec, PIDATA_TS *piData, uint32_t numPiData ); +#endif + /* clang-format on */ #endif diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index ae80304ee04ae85ea7bf3e40026aa3718a8004a0..56cd7bed4d49b4e1968916cbe3ca19ccaf962741 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -1348,6 +1348,7 @@ ivas_error ivas_render_config_init_from_rom( * Quaternion operations *----------------------------------------------------------------------------------*/ +#ifndef IVAS_RTPDUMP void QuaternionProduct( const IVAS_QUATERNION q1, const IVAS_QUATERNION q2, @@ -1359,6 +1360,7 @@ void QuaternionInverse( IVAS_QUATERNION *const r ); +#endif void QuaternionSlerp( const IVAS_QUATERNION q1, const IVAS_QUATERNION q2, diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index b9286d3d96b01ae9bddcb24319badb17319c024c..95361e116a0128101eb30f9a3d1f73ee0213f0a4 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -706,6 +706,7 @@ ivas_error ivas_external_orientation_open( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for external orientation memory\n" ) ); } ( *hExtOrientationData )->num_subframes = num_subframes; + /* Enable head rotation and disable external orientation as default */ for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { @@ -715,6 +716,7 @@ ivas_error ivas_external_orientation_open( ( *hExtOrientationData )->numFramesToTargetOrientation[i] = 0; ( *hExtOrientationData )->Quaternions[i] = identity; } + return IVAS_ERR_OK; } @@ -822,6 +824,14 @@ ivas_error ivas_combined_orientation_open( ( *hCombinedOrientationData )->subframe_idx = 0; ( *hCombinedOrientationData )->subframe_size = (int16_t) ( fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); ( *hCombinedOrientationData )->cur_subframe_samples_rendered = 0; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + + for ( i = 0; i < ( 1 + IVAS_MAX_NUM_OBJECTS ); i++ ) + { + ( *hCombinedOrientationData )->isDiegeticInputPI[i] = true; + } + ( *hCombinedOrientationData )->isDiegeticInputPISet = false; +#endif return IVAS_ERR_OK; } @@ -979,11 +989,30 @@ ivas_error combine_external_and_head_orientations( } else if ( hExtOrientationData == NULL && headRotQuaternions != NULL ) { +#ifdef RTP_S4_251135_CR26253_0016_REV1 + /* Disable head rotation if diegetic PI data indicating non-diegetic audio is received */ + if ( hCombinedOrientationData->isDiegeticInputPISet && !hCombinedOrientationData->isDiegeticInputPI[0] && !hCombinedOrientationData->isDiegeticInputPI[1] && !hCombinedOrientationData->isDiegeticInputPI[2] && !hCombinedOrientationData->isDiegeticInputPI[3] && !hCombinedOrientationData->isDiegeticInputPI[4] ) + { + for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + hCombinedOrientationData->Quaternions[i] = identity; + } + } + else + { + /* Head rotation only */ + for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + hCombinedOrientationData->Quaternions[i] = headRotQuaternions[i]; + } + } +#else /* Head rotation only */ for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) { hCombinedOrientationData->Quaternions[i] = headRotQuaternions[i]; } +#endif } if ( hExtOrientationData != NULL ) @@ -1060,6 +1089,40 @@ ivas_error combine_external_and_head_orientations( hCombinedOrientationData->Quaternion_frozen_head = identity; hCombinedOrientationData->isHeadRotationFrozen = 0; } +#ifdef RTP_S4_251135_CR26253_0016_REV1 + /* Disable head rotation if diegetic PI data indicating non-diegetic audio is received */ + if ( hCombinedOrientationData->isDiegeticInputPISet && !hCombinedOrientationData->isDiegeticInputPI[0] && !hCombinedOrientationData->isDiegeticInputPI[1] && !hCombinedOrientationData->isDiegeticInputPI[2] && !hCombinedOrientationData->isDiegeticInputPI[3] && !hCombinedOrientationData->isDiegeticInputPI[4] ) + { + continue; + } + else + { + /* Use the most recent head rotation */ + if ( hExtOrientationData->enableHeadRotation[i] == 1 ) + { + if ( hExtOrientationData->enableExternalOrientation[i] > 0 ) + { + QuaternionProduct( hCombinedOrientationData->Quaternions[i], headRotQuaternions[i], &hCombinedOrientationData->Quaternions[i] ); + } + else + { + hCombinedOrientationData->Quaternions[i] = headRotQuaternions[i]; + } + } + /* Use the freezed head rotation */ + else if ( hExtOrientationData->enableHeadRotation[i] == 2 ) + { + if ( hExtOrientationData->enableExternalOrientation[i] > 0 ) + { + QuaternionProduct( hCombinedOrientationData->Quaternions[i], hCombinedOrientationData->Quaternion_frozen_head, &hCombinedOrientationData->Quaternions[i] ); + } + else + { + hCombinedOrientationData->Quaternions[i] = hCombinedOrientationData->Quaternion_frozen_head; + } + } + } +#else /* Use the most recent head rotation */ if ( hExtOrientationData->enableHeadRotation[i] == 1 ) { @@ -1084,6 +1147,7 @@ ivas_error combine_external_and_head_orientations( hCombinedOrientationData->Quaternions[i] = hCombinedOrientationData->Quaternion_frozen_head; } } +#endif /* Reset the combined orientations to identity */ if ( hExtOrientationData->enableHeadRotation[i] == 0 && hExtOrientationData->enableExternalOrientation[i] == 0 ) @@ -1182,6 +1246,16 @@ ivas_error combine_external_and_head_orientations( hCombinedOrientationData->subframe_idx_start = 0; hCombinedOrientationData->cur_subframe_samples_rendered_start = 0; +#ifdef IVAS_RTPDUMP + /* Reset external orientations */ + if ( hExtOrientationData != NULL ) + { + for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + hExtOrientationData->Quaternions[i] = identity; + } + } +#endif return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 891f9013e5d6ae0e17cfbbcc37a99e3600acd951..6730875f6c39f5bc185b2323ca286e20576bc899 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -710,6 +710,10 @@ typedef struct ivas_combined_orientation_struct int16_t cur_subframe_samples_rendered; int16_t subframe_idx_start; int16_t cur_subframe_samples_rendered_start; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + bool isDiegeticInputPI[1 + IVAS_MAX_NUM_OBJECTS]; + bool isDiegeticInputPISet; +#endif } COMBINED_ORIENTATION_DATA, *COMBINED_ORIENTATION_HANDLE; /*----------------------------------------------------------------------------------* diff --git a/lib_util/ivas_rtp_api.h b/lib_util/ivas_rtp_api.h index 06c56cd70f15f1ec34f4d5a464f1fe572d5e1a07..8e551c5ffcf303a9314a438aaa12eadb7357c086 100644 --- a/lib_util/ivas_rtp_api.h +++ b/lib_util/ivas_rtp_api.h @@ -33,7 +33,6 @@ #ifndef IVAS_RTP_API_H #define IVAS_RTP_API_H -#include #include #include "common_api_types.h" @@ -275,6 +274,7 @@ typedef struct { bool valid; /* Valid Split Rendering Info for/in the ToC */ bool diegetic; /* SR content digetic */ + uint32_t bitrateKbps; /* SR bitrate in kbps */ IVAS_RTP_SR_TRANSPORT codec; /* SR Transport Codec used*/ } IVAS_RTP_SR_INFO; #endif /* RTP_S4_251135_CR26253_0016_REV1 */ @@ -309,8 +309,10 @@ void IVAS_RTP_PACK_Close( ); /* Update the RTP Header structure */ +#ifdef FIXED_RTP_SEQUENCE_NUM ivas_error IVAS_RTP_PACK_UpdateHeader( IVAS_RTP_PACK_HANDLE hIvasPack, /* i/o: pointer to an IVAS rtp packer handle to be opened */ + uint16_t seqNumInitVal, /* i : Initial sequence number to be used for 1st packet */ uint32_t ssrc, /* i : Unique 32-bit Source ID as negotiated during SDP */ uint8_t numCC, /* i : numCC indicates no. of contributing sources */ uint32_t *csrc, /* i : SSRCs of contributing Sources for a mixed stream */ @@ -318,6 +320,17 @@ ivas_error IVAS_RTP_PACK_UpdateHeader( uint16_t numExtensionBytes, /* i : length of the extension data */ uint8_t *extData /* i : extension data pointer */ ); +#else +ivas_error IVAS_RTP_PACK_UpdateHeader( + IVAS_RTP_PACK_HANDLE hIvasPack, /* i/o: pointer to an IVAS rtp packer handle to be opened */ + uint32_t ssrc, /* i : Unique 32-bit Source ID as negotiated during SDP */ + uint8_t numCC, /* i : numCC indicates no. of contributing sources */ + uint32_t *csrc, /* i : SSRCs of contributing Sources for a mixed stream */ + uint16_t extHeaderId, /* i : extension header ID */ + uint16_t numExtensionBytes, /* i : length of the extension data */ + uint8_t *extData /* i : extension data pointer */ +); +#endif /* Add requests for remote sender using a key value pair api * each key must be provided with a corresponding value type @@ -345,7 +358,7 @@ ivas_error IVAS_RTP_PACK_PushFrame( IVAS_RTP_PACK_HANDLE hIvasPack, /* i/o : IVAS rtp packer handle */ IVAS_RTP_CODEC codecId, /* i : Codec type (IVAS/EVS) */ #ifdef RTP_S4_251135_CR26253_0016_REV1 - IVAS_RTP_SR_INFO *srInfo, /* i : Split Rendering Info (NULL if absent) */ + const IVAS_RTP_SR_INFO *srInfo, /* i : Split Rendering Info (NULL if absent) */ #endif /* RTP_S4_251135_CR26253_0016_REV1 */ const IVAS_DATA_BUFFER *frameBuffer /* i : packed frame bitstream for IVAS/EVS */ ); @@ -407,6 +420,9 @@ typedef struct IVAS_RTP_UNPACK *IVAS_RTP_UNPACK_HANDLE; /* rtp unpacker handle t typedef struct { uint32_t maxFramesPerPacket; /* maximum no of frame per packet expected during the session */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + uint32_t srCodecFrameSizeMs; /* split rendering transport codec frame size in ms (5/10/20) set by sdp negotiation */ +#endif } IVAS_RTP_UNPACK_CONFIG; /* Open an instance of the RTP unpacker and return a handle to rtp unpacker on success diff --git a/lib_util/ivas_rtp_file.c b/lib_util/ivas_rtp_file.c index 8555480efd332900c9fceda25bd914b60bd9e18e..05fb6767cd02d90d03b47cc0f93024591b521aff 100644 --- a/lib_util/ivas_rtp_file.c +++ b/lib_util/ivas_rtp_file.c @@ -34,6 +34,10 @@ #include "ivas_rtp_file.h" #include "ivas_error_utils.h" +#ifdef FIXED_RTP_SEQUENCE_NUM +#define DEFAULT_RANDOM_SEED ( 0xFEEDDEAF ) +#endif + struct IVAS_RTP_FILE { bool isFileWriter; @@ -139,9 +143,9 @@ static ivas_error IvasRtpFile_Read( static const char *const PiDataNames[IVAS_PI_MAX_ID] = { "SCENE_ORIENTATION", "DEVICE_ORIENTATION_COMPENSATED", "DEVICE_ORIENTATION_UNCOMPENSATED", "ACOUSTIC_ENVIRONMENT", "AUDIO_DESCRIPTION", "ISM_NUM", "ISM_ID", "ISM_GAIN", "ISM_ORIENTATION", - "ISM_POSITION", "ISM_DISTANCE_ATTENUATION", "ISM_DIRECTIVITY", "DIEGETIC_TYPE", "RESERVED13", + "ISM_POSITION", "ISM_DISTANCE_ATTENUATION", "ISM_DIRECTIVITY", "DIEGETIC_TYPE", "DYNAMIC_AUDIO_SUPPRESSION_INDICATION", "AUDIO_FOCUS_INDICATION", "RESERVED15", "PLAYBACK_DEVICE_ORIENTATION", "HEAD_ORIENTATION", "LISTENER_POSITION", - "DYNAMIC_AUDIO_SUPPRESSION", "AUDIO_FOCUS_REQUEST", "PI_LATENCY", "R_ISM_ID", "R_ISM_GAIN", + "DYNAMIC_AUDIO_SUPPRESSION_REQUEST", "AUDIO_FOCUS_REQUEST", "PI_LATENCY", "R_ISM_ID", "R_ISM_GAIN", "R_ISM_ORIENTATION", "R_ISM_POSITION", "R_ISM_DIRECTION", "RESERVED27", "RESERVED28", "RESERVED29", "RESERVED30", "NO_DATA" }; @@ -273,9 +277,20 @@ void IVAS_RTP_LogPiData( fprintf( f_piDataOut, "\n\t\t}" ); } break; - case IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION: + case IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION_REQUEST: { - const IVAS_PIDATA_DYNAMIC_SUPPRESSION *das = &cur->data.dynSuppression; + const IVAS_PIDATA_DYNAMIC_SUPPRESSION *das = &cur->data.dynSuppressionRequest; + fprintf( f_piDataOut, "{\n" ); + fprintf( f_piDataOut, "\t\t\t\"preferSpeech\": %s,\n", das->speech ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t\"preferMusic\": %s,\n", das->music ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t\"preferAmbiance\": %s,\n", das->ambiance ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t\"level\": %d", das->sli ); + fprintf( f_piDataOut, "\n\t\t}" ); + } + break; + case IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION_INDICATION: + { + const IVAS_PIDATA_DYNAMIC_SUPPRESSION *das = &cur->data.dynSuppressionIndication; fprintf( f_piDataOut, "{\n" ); fprintf( f_piDataOut, "\t\t\t\"preferSpeech\": %s,\n", das->speech ? "true" : "false" ); fprintf( f_piDataOut, "\t\t\t\"preferMusic\": %s,\n", das->music ? "true" : "false" ); @@ -284,7 +299,6 @@ void IVAS_RTP_LogPiData( fprintf( f_piDataOut, "\n\t\t}" ); } break; - case IVAS_PI_RESERVED13: case IVAS_PI_AUDIO_FOCUS_REQUEST: { fprintf( f_piDataOut, "{" ); @@ -337,6 +351,262 @@ void IVAS_RTP_LogPiData( fprintf( f_piDataOut, "\n\t}" ); } +void IVAS_RTP_WriteExtPiData( + FILE *f_piDataOut, /* i/o : Output csv file handle to dump PI data for external output */ + const PIDATA_TS *piData, /* i : PI Data + Timestamp array containing all PI data in current packet */ + uint32_t nPiDataPresent, /* i : Number of valid elements in the piData array */ + uint16_t numObj /* i : Number of objects */ +) +{ + if ( f_piDataOut == NULL || piData == NULL || nPiDataPresent == 0 ) + { + return; + } + + int i = 0; + + while ( nPiDataPresent-- > 0 ) + { + const PIDATA_TS *cur = piData++; + + /* The writing follows the pattern of: timestamp, PI DATA TYPE, PI DATA */ + + fprintf( f_piDataOut, "%d,%s,", cur->timestamp, PiDataNames[cur->data.noPiData.piDataType] ); + switch ( cur->data.noPiData.piDataType ) + { + case IVAS_PI_SCENE_ORIENTATION: + { + fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.scene.orientation.w, cur->data.scene.orientation.x, cur->data.scene.orientation.y, cur->data.scene.orientation.z ); + } + break; + case IVAS_PI_DEVICE_ORIENTATION_COMPENSATED: + { + fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.deviceCompensated.orientation.w, cur->data.deviceCompensated.orientation.x, cur->data.deviceCompensated.orientation.y, cur->data.deviceCompensated.orientation.z ); + } + break; + case IVAS_PI_DEVICE_ORIENTATION_UNCOMPENSATED: + { + fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.deviceUnCompensated.orientation.w, cur->data.deviceUnCompensated.orientation.x, cur->data.deviceUnCompensated.orientation.y, cur->data.deviceUnCompensated.orientation.z ); + } + break; + case IVAS_PI_ACOUSTIC_ENVIRONMENT: + { + fprintf( f_piDataOut, "%d", cur->data.acousticEnv.aeid ); + if ( cur->data.acousticEnv.availLateReverb ) + { + fprintf( f_piDataOut, ",%f,%f,%f", cur->data.acousticEnv.rt60[0], cur->data.acousticEnv.rt60[1], cur->data.acousticEnv.rt60[2] ); + fprintf( f_piDataOut, ",%f,%f,%f", cur->data.acousticEnv.dsr[0], cur->data.acousticEnv.dsr[1], cur->data.acousticEnv.dsr[2] ); + } + if ( cur->data.acousticEnv.availEarlyReflections ) + { + fprintf( f_piDataOut, ",%f,%f,%f", cur->data.acousticEnv.roomDimensions.x, cur->data.acousticEnv.roomDimensions.y, cur->data.acousticEnv.roomDimensions.z ); + fprintf( f_piDataOut, ",%f,%f,%f,%f,%f,%f", cur->data.acousticEnv.absorbCoeffs[0], cur->data.acousticEnv.absorbCoeffs[1], cur->data.acousticEnv.absorbCoeffs[2], cur->data.acousticEnv.absorbCoeffs[3], cur->data.acousticEnv.absorbCoeffs[4], cur->data.acousticEnv.absorbCoeffs[5] ); + } + } + break; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + case IVAS_PI_AUDIO_DESCRIPTION: + { + uint32_t nEntries = cur->data.audioDesc.nValidEntries; + const IVAS_AUDIO_ID *audioId = cur->data.audioDesc.audioId; + + while ( nEntries-- > 0 ) + { + fprintf( f_piDataOut, "%d,%d,%d,%d,%d", audioId->speech, audioId->music, audioId->ambiance, audioId->editable, audioId->binaural ); + audioId++; + } + } + break; + case IVAS_PI_ISM_NUM: + { + fprintf( f_piDataOut, "%d", cur->data.ismNum.numObjects ); + } + break; + case IVAS_PI_ISM_ID: + { + for ( i = 0; i < numObj; ++i ) + { + if ( i != 0 ) + { + fprintf( f_piDataOut, "," ); + } + fprintf( f_piDataOut, "%d", cur->data.ismId.id[i] ); + } + } + break; + case IVAS_PI_ISM_GAIN: + { + for ( i = 0; i < numObj; ++i ) + { + if ( i != 0 ) + { + fprintf( f_piDataOut, "," ); + } + fprintf( f_piDataOut, "%d", cur->data.ismGain.dB[i] ); + } + } + break; + case IVAS_PI_ISM_ORIENTATION: + { + for ( i = 0; i < numObj; ++i ) + { + if ( i != 0 ) + { + fprintf( f_piDataOut, "," ); + } + fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.ismOrientation.orientation[i].w, cur->data.ismOrientation.orientation[i].x, cur->data.ismOrientation.orientation[i].y, cur->data.ismOrientation.orientation[i].z ); + } + } + break; + case IVAS_PI_ISM_POSITION: + { + for ( i = 0; i < numObj; ++i ) + { + if ( i != 0 ) + { + fprintf( f_piDataOut, "," ); + } + fprintf( f_piDataOut, "%f,%f,%f", cur->data.ismPosition.position[i].x, cur->data.ismPosition.position[i].y, cur->data.ismPosition.position[i].z ); + } + } + break; + case IVAS_PI_ISM_DISTANCE_ATTENUATION: + { + for ( i = 0; i < numObj; ++i ) + { + if ( i != 0 ) + { + fprintf( f_piDataOut, "," ); + } + fprintf( f_piDataOut, "%f,%f,%f", cur->data.ismAttenuation.distAtten[i].ref_dist, cur->data.ismAttenuation.distAtten[i].max_dist, cur->data.ismAttenuation.distAtten[i].roll ); + } + } + break; + case IVAS_PI_ISM_DIRECTIVITY: + { + for ( i = 0; i < numObj; ++i ) + { + if ( i != 0 ) + { + fprintf( f_piDataOut, "," ); + } + fprintf( f_piDataOut, "%d,%d,%f", cur->data.ismDirectivity.directivity[i].innerConeAngle, cur->data.ismDirectivity.directivity[i].outerConeAngle, cur->data.ismDirectivity.directivity[i].outerAttenuationdB ); + } + } + break; + case IVAS_PI_DIEGETIC_TYPE: + { + const bool *isDiegetic = cur->data.digeticIndicator.isDiegetic; + fprintf( f_piDataOut, "%d,%d,%d,%d,%d", isDiegetic[0], isDiegetic[1], isDiegetic[2], isDiegetic[3], isDiegetic[4] ); + } + break; + case IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION_INDICATION: + { + const IVAS_PIDATA_DYNAMIC_SUPPRESSION *das = &cur->data.dynSuppressionIndication; + fprintf( f_piDataOut, "%d,%d,%d,%d", das->speech, das->music, das->ambiance, das->sli ); + } + break; + case IVAS_PI_AUDIO_FOCUS_INDICATION: + { + if ( cur->data.focusIndication.availDirection ) + { + fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.focusIndication.direction.w, cur->data.focusIndication.direction.x, cur->data.focusIndication.direction.y, cur->data.focusIndication.direction.z ); + if ( cur->data.focusIndication.availLevel ) + { + fprintf( f_piDataOut, "," ); + } + } + if ( cur->data.focusIndication.availLevel ) + { + fprintf( f_piDataOut, "%d", cur->data.focusIndication.flvl ); + } + } + break; + case IVAS_PI_PLAYBACK_DEVICE_ORIENTATION: + { + fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.playbackOrientation.orientation.w, cur->data.playbackOrientation.orientation.x, cur->data.playbackOrientation.orientation.y, cur->data.playbackOrientation.orientation.z ); + } + break; + case IVAS_PI_HEAD_ORIENTATION: + { + fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.headOrientation.orientation.w, cur->data.headOrientation.orientation.x, cur->data.headOrientation.orientation.y, cur->data.headOrientation.orientation.z ); + } + break; + case IVAS_PI_LISTENER_POSITION: + { + fprintf( f_piDataOut, "%f,%f,%f", cur->data.listnerPosition.position.x, cur->data.listnerPosition.position.y, cur->data.listnerPosition.position.z ); + } + break; + case IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION_REQUEST: + { + const IVAS_PIDATA_DYNAMIC_SUPPRESSION *das = &cur->data.dynSuppressionRequest; + fprintf( f_piDataOut, "%d,%d,%d,%d", das->speech, das->music, das->ambiance, das->sli ); + } + break; + case IVAS_PI_AUDIO_FOCUS_REQUEST: + { + + if ( cur->data.focusRequest.availDirection ) + { + fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.focusRequest.direction.w, cur->data.focusRequest.direction.x, cur->data.focusRequest.direction.y, cur->data.focusRequest.direction.z ); + if ( cur->data.focusRequest.availLevel ) + { + fprintf( f_piDataOut, "," ); + } + } + if ( cur->data.focusRequest.availLevel ) + { + fprintf( f_piDataOut, "%d", cur->data.focusRequest.flvl ); + } + } + break; + case IVAS_PI_PI_LATENCY: + { + fprintf( f_piDataOut, "%d", cur->data.piLatency.latency ); + } + break; + case IVAS_PI_R_ISM_ID: + { + fprintf( f_piDataOut, "%d", cur->data.ismEditId.id ); + } + break; + case IVAS_PI_R_ISM_GAIN: + { + fprintf( f_piDataOut, "%d", cur->data.ismEditGain.piDataType ); + } + break; + case IVAS_PI_R_ISM_ORIENTATION: + { + fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.ismEditOrientation.orientation.w, cur->data.ismEditOrientation.orientation.x, cur->data.ismEditOrientation.orientation.y, cur->data.ismEditOrientation.orientation.z ); + } + break; + case IVAS_PI_R_ISM_POSITION: + { + fprintf( f_piDataOut, "%f,%f,%f", cur->data.ismEditPosition.position.x, cur->data.ismEditPosition.position.y, cur->data.ismEditPosition.position.z ); + } + break; + case IVAS_PI_R_ISM_DIRECTION: + { + fprintf( f_piDataOut, "%f,%f", cur->data.ismEditDirection.azimuth, cur->data.ismEditDirection.elevation ); + } + break; + case IVAS_PI_RESERVED15: + case IVAS_PI_RESERVED27: + case IVAS_PI_RESERVED28: + case IVAS_PI_RESERVED29: + case IVAS_PI_RESERVED30: + break; +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + } + fprintf( f_piDataOut, "\n" ); + } +} + +const char *IVAS_RTP_GetExtPiFilePath( IVAS_RTP *rtp ) +{ + return rtp->piExtFilename; +} + void IVAS_RTP_Term( IVAS_RTP *rtp /* i/o : IVAS RTP File reader/writer handle */ ) @@ -378,6 +648,12 @@ void IVAS_RTP_Term( rtp->f_piDataOut = NULL; } + if ( rtp->f_piExtOut != NULL ) + { + fclose( rtp->f_piExtOut ); + rtp->f_piExtOut = NULL; + } + if ( rtp->hRtpFile != NULL ) { IvasRtpFile_Close( &rtp->hRtpFile ); @@ -388,10 +664,18 @@ void IVAS_RTP_Term( ivas_error IVAS_RTP_WRITER_Init( IVAS_RTP *rtp, /* i/o : IVAS RTP File writer handle */ const char *outputBitstreamFilename, /* i : RTP Dump filename */ - uint32_t numFramesPerPacket /* i : No. of frames per packet desired */ +#ifdef FIXED_RTP_SEQUENCE_NUM + uint32_t numFramesPerPacket, /* i : No. of frames per packet desired */ + uint32_t SSRC, /* i : SSRC for RTP Header */ + uint16_t seqNumInitVal /* i : Initial seq number in rtp header */ +#else + uint32_t numFramesPerPacket /* i : No. of frames per packet desired */ +#endif ) { +#ifndef FIXED_RTP_SEQUENCE_NUM uint32_t SSRC = ( rand() & 0xFFFF ) | ( (uint32_t) rand() << 16 ); +#endif ivas_error error = IVAS_ERR_OK; memset( rtp, 0, sizeof( IVAS_RTP ) ); @@ -410,7 +694,11 @@ ivas_error IVAS_RTP_WRITER_Init( return error; } +#ifdef FIXED_RTP_SEQUENCE_NUM + error = IVAS_RTP_PACK_UpdateHeader( rtp->hPack, seqNumInitVal, SSRC, 0, NULL, 0, 0, NULL ); +#else error = IVAS_RTP_PACK_UpdateHeader( rtp->hPack, SSRC, 0, NULL, 0, 0, NULL ); +#endif if ( error != IVAS_ERR_OK ) { fprintf( stderr, "error in IVAS_RTP_PACK_UpdateHeader(): %d\n", error ); @@ -421,9 +709,14 @@ ivas_error IVAS_RTP_WRITER_Init( } ivas_error IVAS_RTP_READER_Init( - IVAS_RTP *rtp, /* i/o : IVAS RTP File reader handle */ + IVAS_RTP *rtp, /* i/o : IVAS RTP File reader handle */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + uint32_t srCodecFrameSizeMs, /* i : SR Codec Framesize in ms */ +#endif const char *inputBitstreamFilename, /* i : Input rtpdump filename */ - const char *piOutputFilename /* i : Output PI data json filename */ + const char *piOutputFilename, /* i : Output PI data json filename */ + bool isExtOutput, /* i : External output mode */ + const char *outputWavFilename /* i : name of the output audio file */ ) { ivas_error error = IVAS_ERR_OK; @@ -431,6 +724,7 @@ ivas_error IVAS_RTP_READER_Init( memset( rtp, 0, sizeof( IVAS_RTP ) ); rtp->unpackCfg.maxFramesPerPacket = IVAS_MAX_FRAMES_PER_RTP_PACKET; + rtp->unpackCfg.srCodecFrameSizeMs = srCodecFrameSizeMs; rtp->rtpPacket.buffer = rtp->packet; rtp->rtpPacket.capacity = sizeof( rtp->packet ); @@ -453,14 +747,38 @@ ivas_error IVAS_RTP_READER_Init( } fprintf( rtp->f_piDataOut, "{\n" ); } + + if ( isExtOutput ) + { + char ext_pi[12]; + + /* sizeof( ext_pi ) accounts for terminating NULL, don't subtract extra 1 */ + const int32_t maxNameLenWithoutExt = FILENAME_MAX - (int32_t) sizeof( ext_pi ); + strncpy( rtp->piExtFilename, outputWavFilename, maxNameLenWithoutExt ); + snprintf( ext_pi, sizeof( ext_pi ), ".pidata.csv" ); + + /* strlen( metadata_filename[0] ) doesn't account for terminating NULL, subtract extra 1 */ + const int32_t maxNumCharactersToAppend = FILENAME_MAX - (int32_t) strlen( rtp->piExtFilename ) - 1; + strncat( rtp->piExtFilename, ext_pi, maxNumCharactersToAppend ); + + rtp->f_piExtOut = fopen( rtp->piExtFilename, "w" ); + if ( rtp->f_piExtOut == NULL ) + { + fprintf( stderr, "could not open: %s\n", rtp->piExtFilename ); + return IVAS_ERR_FAILED_FILE_OPEN; + } + } } return error; } ivas_error IVAS_RTP_WriteNextFrame( - IVAS_RTP *rtp, /* i/o : IVAS RTP File writer handle */ - uint8_t *au, /* i : IVAS Compressed AU (Packed frame) */ + IVAS_RTP *rtp, /* i/o : IVAS RTP File writer handle */ + uint8_t *au, /* i : IVAS Compressed AU (Packed frame) */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + const IVAS_RTP_SR_INFO *srInfo, /* i : Split rendering info in present, else NULL */ +#endif int16_t auSizeBits, /* i : Frame size in bits */ bool isMono, /* i : input was evs(true) or ivas(false) */ bool forcePacket /* i : force packets with whatever frames pushed so far */ @@ -479,7 +797,7 @@ ivas_error IVAS_RTP_WriteNextFrame( error = IVAS_RTP_PACK_PushFrame( rtp->hPack, isMono ? IVAS_RTP_EVS : IVAS_RTP_IVAS, #ifdef RTP_S4_251135_CR26253_0016_REV1 - NULL, + srInfo, #endif /* RTP_S4_251135_CR26253_0016_REV1 */ &packedFrame ); if ( error != IVAS_ERR_OK ) @@ -487,7 +805,7 @@ ivas_error IVAS_RTP_WriteNextFrame( return error; } - while ( rtp->nWrittenPiData-- > 0 ) + while ( rtp->nWrittenPiData > 0 ) { PIDATA_TS *piDataTs = &rtp->piData[nProcPiData++]; if ( ( error = IVAS_RTP_PACK_PushPiData( rtp->hPack, (const IVAS_PIDATA_GENERIC *) &piDataTs->data ) ) != IVAS_ERR_OK ) @@ -495,6 +813,7 @@ ivas_error IVAS_RTP_WriteNextFrame( fprintf( stderr, "\nError %s while pushing scene orientation\n", ivas_error_to_string( error ) ); return error; } + rtp->nWrittenPiData--; } if ( forcePacket || IVAS_RTP_PACK_GetNumFrames( rtp->hPack ) == rtp->packCfg.maxFramesPerPacket ) @@ -525,7 +844,10 @@ ivas_error IVAS_RTP_ReadNextFrame( uint32_t *rtpTimeStamp, /* o : RTP Timestamp for this frame */ uint16_t *rtpSequenceNumber, /* o : RTP sequence number for this packet */ uint32_t *nextPacketRcvTime_ms, /* i/o : Clock indicating packet receive times need in JBM */ - bool *qBit /* o : AMRWB Q bite as indicated in the RTP packet */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + IVAS_RTP_SR_INFO *srInfo, /* o : Split Rendering info if SR RTP frame unpacked */ +#endif + bool *qBit /* o : AMRWB Q bite as indicated in the RTP packet */ ) { ivas_error error = IVAS_ERR_OK; @@ -603,6 +925,12 @@ ivas_error IVAS_RTP_ReadNextFrame( rtp->isAMRWB_IOmode = isAMRWB_IOmode; } +#ifdef RTP_S4_251135_CR26253_0016_REV1 + if ( srInfo != NULL ) + { + *srInfo = rtp->srInfo; + } +#endif *qBit = !rtp->speechLostIndicated; rtp->numFramesInPacket--; rtp->numFramesProduced++; diff --git a/lib_util/ivas_rtp_file.h b/lib_util/ivas_rtp_file.h index 2a58dc1c967b01c191bc2625965c31eb4425f387..70f8c99f0e076eaf4d4c9633513864bfbe6e763e 100644 --- a/lib_util/ivas_rtp_file.h +++ b/lib_util/ivas_rtp_file.h @@ -46,6 +46,8 @@ typedef struct IVAS_RTP_FILE_HANDLE hRtpFile; FILE *f_piDataOut; + FILE *f_piExtOut; + char piExtFilename[FILENAME_MAX]; IVAS_RTP_CODEC codecId; uint32_t nWrittenPiData; uint32_t nReadPiData; @@ -68,12 +70,26 @@ typedef struct #endif } IVAS_RTP; +#ifdef FIXED_RTP_SEQUENCE_NUM +ivas_error IVAS_RTP_WRITER_Init( IVAS_RTP *rtp, const char *outputBitstreamFilename, uint32_t numFramesPerPacket, uint32_t SSRC, uint16_t seqNumInitVal ); +#else ivas_error IVAS_RTP_WRITER_Init( IVAS_RTP *rtp, const char *outputBitstreamFilename, uint32_t numFramesPerPacket ); -ivas_error IVAS_RTP_READER_Init( IVAS_RTP *rtp, const char *inputBitstreamFilename, const char *piOutputFilename ); +#endif +#ifdef RTP_S4_251135_CR26253_0016_REV1 +ivas_error IVAS_RTP_READER_Init( IVAS_RTP *rtp, uint32_t srCodecFrameSizeMs, const char *inputBitstreamFilename, const char *piOutputFilename, bool isExtOutput, const char *outputWavFilename ); +#else +ivas_error IVAS_RTP_READER_Init( IVAS_RTP *rtp, const char *inputBitstreamFilename, const char *piOutputFilename, bool isExtOutput, const char *outputWavFilename ); +#endif void IVAS_RTP_Term( IVAS_RTP *rtp ); +#ifdef RTP_S4_251135_CR26253_0016_REV1 +ivas_error IVAS_RTP_WriteNextFrame( IVAS_RTP *rtp, uint8_t *au, const IVAS_RTP_SR_INFO *srInfo, int16_t auSizeBits, bool isMono, bool forcePacket ); +ivas_error IVAS_RTP_ReadNextFrame( IVAS_RTP *rtp, uint8_t *au, int16_t *auSizeBits, uint32_t *rtpTimeStamp, uint16_t *rtpSequenceNumber, uint32_t *nextPacketRcvTime_ms, IVAS_RTP_SR_INFO *srInfo, bool *qBit ); +#else ivas_error IVAS_RTP_WriteNextFrame( IVAS_RTP *rtp, uint8_t *au, int16_t auSizeBits, bool isMono, bool forcePacket ); ivas_error IVAS_RTP_ReadNextFrame( IVAS_RTP *rtp, uint8_t *au, int16_t *auSizeBits, uint32_t *rtpTimeStamp, uint16_t *rtpSequenceNumber, uint32_t *nextPacketRcvTime_ms, bool *qBit ); +#endif void IVAS_RTP_LogPiData( FILE *f_piDataOut, const PIDATA_TS *piData, uint32_t nPiDataPresent ); - +void IVAS_RTP_WriteExtPiData( FILE *f_piDataOut, const PIDATA_TS *piData, uint32_t nPiDataPresent, uint16_t numObj ); +const char *IVAS_RTP_GetExtPiFilePath( IVAS_RTP *rtp ); #endif /* IVAS_RTP_FILE_H */ diff --git a/lib_util/ivas_rtp_internal.h b/lib_util/ivas_rtp_internal.h index f3569ca031ac7c8c60d0d31efb7f60b06644f9d7..dc3dd9c1292ced08e6e6edd6b2b0b30a8d917fe2 100644 --- a/lib_util/ivas_rtp_internal.h +++ b/lib_util/ivas_rtp_internal.h @@ -96,11 +96,19 @@ enum IVAS_RTP_HEADER_BITS EBYTE_CMR_T_IVAS = 0xF0, /* Initial E-byte indicating IVAS modes */ EBYTE_CMR_T_NO_REQ = 0xFF, /* If no bitrate and no CA mode requested for IVAS/EVS */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 EBYTE_BANDWIDTH_REQUEST = 0x80, /* Subsequent E-byte for Bandwidth Request */ EBYTE_FORMAT_REQUEST = 0x90, /* Subsequent E-byte for Format Request */ EBYTE_SUBFORMAT_REQUEST = 0x9F, /* Subsequent E-byte for SubFormat Request */ EBYTE_PI_INDICATOR = 0xA0, /* Subsequent E-byte for PI Indicator */ EBYTE_SR_REQUEST = 0xB0, /* Subsequent E-byte for Split Rendering Request */ +#else + EBYTE_BANDWIDTH_REQUEST = 0x40, /* Subsequent E-byte for Bandwidth Request */ + EBYTE_FORMAT_REQUEST = 0x50, /* Subsequent E-byte for Format Request */ + EBYTE_SUBFORMAT_REQUEST = 0x9F, /* Subsequent E-byte for SubFormat Request */ + EBYTE_PI_INDICATOR = 0x60, /* Subsequent E-byte for PI Indicator */ + EBYTE_SR_REQUEST = 0x70, /* Subsequent E-byte for Split Rendering Request */ +#endif PI_HEADER_PF_LAST = 0x00, /* Last PI header of the Payload in PI Header */ PI_HEADER_PF_NOT_LAST = 0x80, /* Another PI header follows after this in PI Header */ diff --git a/lib_util/ivas_rtp_payload.c b/lib_util/ivas_rtp_payload.c index e759f674bc8794401f92bcad6755d311d81e3c1a..98846adf847ea0b9cd930dd35ee18abd03f14564 100644 --- a/lib_util/ivas_rtp_payload.c +++ b/lib_util/ivas_rtp_payload.c @@ -32,7 +32,9 @@ #include #include #include +#ifndef FIXED_RTP_SEQUENCE_NUM #include +#endif #include "common_api_types.h" #ifdef IVAS_RTPDUMP @@ -182,6 +184,9 @@ static const uint32_t amrWBIOFrameSizeInBits[] = { /* Update the RTP Header structure */ ivas_error IVAS_RTP_PACK_UpdateHeader( IVAS_RTP_PACK_HANDLE hPack, /* i/o: pointer to an IVAS rtp packer handle to be opened */ +#ifdef FIXED_RTP_SEQUENCE_NUM + uint16_t seqNumInitVal, /* i : Initial sequence number to be used for 1st packet */ +#endif uint32_t ssrc, /* i : Unique 32-bit Source ID as negotiated during SDP */ uint8_t numCC, /* i : numCC indicates no. of contributing sources */ uint32_t *csrc, /* i : SSRCs of contributing Sources for a mixed stream */ @@ -197,6 +202,9 @@ ivas_error IVAS_RTP_PACK_UpdateHeader( return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "CC must be less than 16" ); } +#ifdef FIXED_RTP_SEQUENCE_NUM + header->seqNumber = seqNumInitVal; +#endif header->ssrc = ssrc; header->CC = numCC; if ( csrc != NULL ) @@ -229,11 +237,16 @@ static void InitRtpHeader( RTP_HEADER *header /* RTP header structure */ ) { +#ifdef FIXED_RTP_SEQUENCE_NUM + memset( header, 0, sizeof( *header ) ); + header->version = 2; +#else time_t t; memset( header, 0, sizeof( *header ) ); srand( (uint32_t) time( &t ) ); header->version = 2; header->seqNumber = rand() & 0xFFFF; +#endif } static ivas_error PackRtpHeader( @@ -835,18 +848,17 @@ static void packEBytes( #ifdef RTP_S4_251135_CR26253_0016_REV1 static ivas_error getSRToCByte( - IVAS_RTP_SR_INFO *srInfo, /* i : Split Rendering Info */ - uint32_t bitrateKbps, /* i : Bitrate in kbps */ - uint8_t *tocByte /* o : toc byte 2 */ + const IVAS_RTP_SR_INFO *srInfo, /* i : Split Rendering Info */ + uint8_t *tocByte /* o : toc byte 2 */ ) { uint8_t bitIdx, codecId, digetic; - if ( bitrateKbps < 256000 || bitrateKbps > 512000 ) + if ( srInfo->bitrateKbps < 256000 || srInfo->bitrateKbps > 512000 ) { return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Unsupported bitrate for SR" ); } - bitIdx = ( ( bitrateKbps / 128000u ) - 1 ) & MASK_2BIT; + bitIdx = ( ( srInfo->bitrateKbps / 128000u ) - 1 ) & MASK_2BIT; codecId = (uint8_t) srInfo->codec; digetic = srInfo->diegetic ? 1 : 0; @@ -882,7 +894,7 @@ ivas_error IVAS_RTP_PACK_PushFrame( IVAS_RTP_PACK_HANDLE hPack, /* i/o : IVAS rtp packer handle */ IVAS_RTP_CODEC codecId, /* i : Codec type (IVAS/EVS) */ #ifdef RTP_S4_251135_CR26253_0016_REV1 - IVAS_RTP_SR_INFO *srInfo, /* i : Split Rendering Info */ + const IVAS_RTP_SR_INFO *srInfo, /* i : Split Rendering Info */ #endif /* RTP_S4_251135_CR26253_0016_REV1 */ const IVAS_DATA_BUFFER *frameBuffer /* i : packed frame bitstream for IVAS/EVS */ ) @@ -907,7 +919,8 @@ ivas_error IVAS_RTP_PACK_PushFrame( else if ( srInfo != NULL && srInfo->valid ) { tocByte = TOC_INDICATE_SR; - error = getSRToCByte( srInfo, bitrate, &tocByte1 ); + frameLengthInBits = frameBuffer->length * 8; + error = getSRToCByte( srInfo, &tocByte1 ); ERR_CHECK_RETURN( error ); } #endif @@ -1339,7 +1352,11 @@ static uint32_t parseSubsequentEByte( const IVAS_DATA_BUFFER *payload, uint32_t while ( nBytes < payload->length ) { uint8_t byte = payload->buffer[nBytes]; +#ifdef RTP_S4_251135_CR26253_0016_REV1 uint8_t ET = ( byte & ( ~MASK_4BIT ) ); +#else + uint8_t ET = ( byte & ( ~MASK_3BIT ) ); +#endif if ( ( byte & EBYTE_TOC_HEADER_BIT ) == 0 ) { @@ -1388,14 +1405,18 @@ static uint32_t parseSubsequentEByte( const IVAS_DATA_BUFFER *payload, uint32_t break; #endif default: /* Reserved for future use - unhandled atm */ - assert( 0 ); + break; } } return nBytes; } +#ifdef RTP_S4_251135_CR26253_0016_REV1 +static ivas_error parseToCByte( const IVAS_DATA_BUFFER *payload, uint32_t *numBytes, uint32_t *numFrames, TOC_INFO *toc, uint32_t maxNumberOfToCBytes, uint32_t srCodecFrameSizeMs ) +#else static ivas_error parseToCByte( const IVAS_DATA_BUFFER *payload, uint32_t *numBytes, uint32_t *numFrames, TOC_INFO *toc, uint32_t maxNumberOfToCBytes ) +#endif { bool headerFollows = true; uint32_t nBytes = *numBytes; @@ -1462,7 +1483,8 @@ static ivas_error parseToCByte( const IVAS_DATA_BUFFER *payload, uint32_t *numBy toc->srInfo.valid = true; toc->srInfo.diegetic = ( byte >> 6 ) & MASK_1BIT; toc->srInfo.codec = IVAS_SR_TRANSPORT_LCLD + ( ( byte >> 5 ) & MASK_1BIT ); - toc->auNumBits = ( SR_BR + 1 ) * 128000u / IVAS_NUM_FRAMES_PER_SEC; + toc->srInfo.bitrateKbps = ( SR_BR + 1 ) * 128000u; + toc->auNumBits = toc->srInfo.bitrateKbps * srCodecFrameSizeMs / 1000; } else { @@ -1644,7 +1666,12 @@ ivas_error IVAS_RTP_UNPACK_PushPayload( nBytes = parseSubsequentEByte( payload, nBytes, hUnpack->requests, &piDataIndicated ); /* Unpack the ToC Bytes => Extract number of frames in packet */ + +#ifdef RTP_S4_251135_CR26253_0016_REV1 + error = parseToCByte( payload, &nBytes, &numFrames, toc, sizeof( toc ) / sizeof( toc[0] ), hUnpack->initConfig.srCodecFrameSizeMs ); +#else error = parseToCByte( payload, &nBytes, &numFrames, toc, sizeof( toc ) / sizeof( toc[0] ) ); +#endif ERR_CHECK_RETURN( error ); /* Read frame bits */ diff --git a/lib_util/ivas_rtp_pi_data.c b/lib_util/ivas_rtp_pi_data.c index 7150cfe4a80bd911f5adfd3bedc946e4db90fc0b..8db9d41f9df241e317cdcf606e0fcc682c4a0a8c 100644 --- a/lib_util/ivas_rtp_pi_data.c +++ b/lib_util/ivas_rtp_pi_data.c @@ -396,7 +396,7 @@ static ivas_error packDynamicSuppression( const IVAS_PIDATA_GENERIC *piData, uin return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space in DAS PI data buffer" ); } - buffer[nBytes++] = ( IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION ); /* PF/PM populated during final packing */ + buffer[nBytes++] = ( das->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ buffer[nBytes++] = 2u; buffer[nBytes++] = ( das->speech ? PI_AD_SPEECH_INDICATED : 0 ) | @@ -419,7 +419,6 @@ static ivas_error unpackDynamicSuppression( const uint8_t *buffer, uint32_t numD } das->size = sizeof( IVAS_PIDATA_AUDIO_DESC ); - das->piDataType = IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION; das->speech = ( buffer[0] & PI_AD_SPEECH_INDICATED ) != 0; das->music = ( buffer[0] & PI_AD_MUSIC_INDICATED ) != 0; das->ambiance = ( buffer[0] & PI_AD_AMBIANCE_INDICATED ) != 0; diff --git a/lib_util/ivas_rtp_pi_data.h b/lib_util/ivas_rtp_pi_data.h index 3fc95f8d8db2fc7211c2685c78e9a9b61a2797f6..dc4c7f8bafd5eda274df74b419677fd28ec1c64a 100644 --- a/lib_util/ivas_rtp_pi_data.h +++ b/lib_util/ivas_rtp_pi_data.h @@ -48,38 +48,38 @@ typedef enum IVAS_PI_DEVICE_ORIENTATION_UNCOMPENSATED, /* orientation of device in unit quaternions (un-compensated) */ IVAS_PI_ACOUSTIC_ENVIRONMENT, /* describe the acoustic environment */ #ifdef RTP_S4_251135_CR26253_0016_REV1 - IVAS_PI_AUDIO_DESCRIPTION, /* audio content description (voice/music/ambiance) */ - IVAS_PI_ISM_NUM, /* Number of objects */ - IVAS_PI_ISM_ID, /* id of each object */ - IVAS_PI_ISM_GAIN, /* gain of each object */ - IVAS_PI_ISM_ORIENTATION, /* orientation of each object */ - IVAS_PI_ISM_POSITION, /* position of each object */ - IVAS_PI_ISM_DISTANCE_ATTENUATION, /* distance attenuation for each object */ - IVAS_PI_ISM_DIRECTIVITY, /* directivity of each object */ - IVAS_PI_DIEGETIC_TYPE, /* digetic audio indication */ - IVAS_PI_RESERVED13, /* reserved */ - IVAS_PI_AUDIO_FOCUS_INDICATION, /* audio focus indication (direction in Quaternions and/or level) */ - IVAS_PI_RESERVED15, /* reserved */ + IVAS_PI_AUDIO_DESCRIPTION, /* audio content description (voice/music/ambiance) */ + IVAS_PI_ISM_NUM, /* Number of objects */ + IVAS_PI_ISM_ID, /* id of each object */ + IVAS_PI_ISM_GAIN, /* gain of each object */ + IVAS_PI_ISM_ORIENTATION, /* orientation of each object */ + IVAS_PI_ISM_POSITION, /* position of each object */ + IVAS_PI_ISM_DISTANCE_ATTENUATION, /* distance attenuation for each object */ + IVAS_PI_ISM_DIRECTIVITY, /* directivity of each object */ + IVAS_PI_DIEGETIC_TYPE, /* digetic audio indication */ + IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION_INDICATION, /* audio suppression indication */ + IVAS_PI_AUDIO_FOCUS_INDICATION, /* audio focus indication (direction in Quaternions and/or level) */ + IVAS_PI_RESERVED15, /* reserved */ /* Reverse direction PI types */ - IVAS_PI_PLAYBACK_DEVICE_ORIENTATION, /* orientation of the playback device in quaternions */ - IVAS_PI_HEAD_ORIENTATION, /* head orientation of the listener in Quaternions */ - IVAS_PI_LISTENER_POSITION, /* position of the listener in 3D space */ - IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION, /* receiver’s preference with respect to audio suppression */ - IVAS_PI_AUDIO_FOCUS_REQUEST, /* direction of interest for the listener in Quaternions and/or audio focus level */ - IVAS_PI_PI_LATENCY, /* round-trip latency for PI frames */ - IVAS_PI_R_ISM_ID, /* id of an object for editing */ - IVAS_PI_R_ISM_GAIN, /* editing request for gain factor for received object */ - IVAS_PI_R_ISM_ORIENTATION, /* editing request for orientation for received object */ - IVAS_PI_R_ISM_POSITION, /* editing request for position for received object */ - IVAS_PI_R_ISM_DIRECTION, /* editing request for direction for received object */ - IVAS_PI_RESERVED27, /* reserved */ - IVAS_PI_RESERVED28, /* reserved */ - IVAS_PI_RESERVED29, /* reserved */ - IVAS_PI_RESERVED30, /* reserved */ -#endif /* RTP_S4_251135_CR26253_0016_REV1 */ - IVAS_PI_NO_DATA = 31, /* Indicates an empty PI data frame */ - IVAS_PI_MAX_ID /* Max number of PI data IDs supprted */ + IVAS_PI_PLAYBACK_DEVICE_ORIENTATION, /* orientation of the playback device in quaternions */ + IVAS_PI_HEAD_ORIENTATION, /* head orientation of the listener in Quaternions */ + IVAS_PI_LISTENER_POSITION, /* position of the listener in 3D space */ + IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION_REQUEST, /* receiver’s preference with respect to audio suppression */ + IVAS_PI_AUDIO_FOCUS_REQUEST, /* direction of interest for the listener in Quaternions and/or audio focus level */ + IVAS_PI_PI_LATENCY, /* round-trip latency for PI frames */ + IVAS_PI_R_ISM_ID, /* id of an object for editing */ + IVAS_PI_R_ISM_GAIN, /* editing request for gain factor for received object */ + IVAS_PI_R_ISM_ORIENTATION, /* editing request for orientation for received object */ + IVAS_PI_R_ISM_POSITION, /* editing request for position for received object */ + IVAS_PI_R_ISM_DIRECTION, /* editing request for direction for received object */ + IVAS_PI_RESERVED27, /* reserved */ + IVAS_PI_RESERVED28, /* reserved */ + IVAS_PI_RESERVED29, /* reserved */ + IVAS_PI_RESERVED30, /* reserved */ +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + IVAS_PI_NO_DATA = 31, /* Indicates an empty PI data frame */ + IVAS_PI_MAX_ID /* Max number of PI data IDs supprted */ } IVAS_PI_TYPE; /* cartesian coordinates (X,Y,Z) in 3D space */ @@ -305,9 +305,9 @@ typedef enum IVAS_FLVL_FOCUS_LEVEL_LEVEL_10, /* Audio focus level 10 */ IVAS_FLVL_FOCUS_LEVEL_LEVEL_11, /* Audio focus level 11 */ IVAS_FLVL_FOCUS_LEVEL_LEVEL_12, /* Audio focus level 12 */ - IVAS_FLVL_FOCUS_LEVEL_LEVEL_13, /* Audio focus level 13 */ - IVAS_FLVL_DEFAULT_AUDIO_FOCUS, /* Default audio focus */ IVAS_FLVL_MAX_AUDIO_FOCUS, /* Apply max audio focus */ + IVAS_FLVL_DEFAULT_AUDIO_FOCUS, /* Default audio focus */ + IVAS_FLVL_NO_PREFERENCE, /* No preference / No indication */ } IVAS_FLVL; typedef struct @@ -335,7 +335,7 @@ typedef struct */ typedef enum { - IVAS_SLI_NO_SUPPRESSION = 0, /* Apply no suppression */ + IVAS_SLI_MIN_SUPPRESSION = 0, /* Apply min suppression */ IVAS_SLI_SUPPRESSION_LEVEL_1, /* Suppression level 1 */ IVAS_SLI_SUPPRESSION_LEVEL_2, /* Suppression level 2 */ IVAS_SLI_SUPPRESSION_LEVEL_3, /* Suppression level 3 */ @@ -347,16 +347,16 @@ typedef enum IVAS_SLI_SUPPRESSION_LEVEL_9, /* Suppression level 9 */ IVAS_SLI_SUPPRESSION_LEVEL_10, /* Suppression level 10 */ IVAS_SLI_SUPPRESSION_LEVEL_11, /* Suppression level 11 */ - IVAS_SLI_SUPPRESSION_LEVEL_12, /* Suppression level 12 */ - IVAS_SLI_SUPPRESSION_LEVEL_13, /* Suppression level 13 */ - IVAS_SLI_SUPPRESSION_LEVEL_14, /* Suppression level 14 */ IVAS_SLI_MAX_SUPPRESSION, /* Apply max suppression */ + IVAS_SLI_NO_SUPPRESSION, /* Apply no suppression */ + IVAS_SLI_DEFAULT_SUPPRESSION, /* Apply default suppression */ + IVAS_SLI_NO_PREFERENCE, /* No preference / No indication */ } IVAS_SLI; typedef struct { size_t size; /* sizeof(IVAS_PIDATA_DYNAMIC_SUPPRESSION) */ - uint32_t piDataType; /* IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION */ + uint32_t piDataType; /* IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION_REQUEST or IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION_INDICATION */ bool speech; /* receiver's preference is voice/speech */ bool music; /* receiver's preference is music */ bool ambiance; /* receiver's preference is background ambiance */ @@ -443,12 +443,13 @@ typedef union IVAS_PIDATA_ISM_ATTENUATION ismAttenuation; IVAS_PIDATA_ISM_DIRECTIVITY ismDirectivity; IVAS_PIDATA_DIEGETIC digeticIndicator; + IVAS_PIDATA_DYNAMIC_SUPPRESSION dynSuppressionIndication; IVAS_PIDATA_AUDIO_FOCUS focusIndication; IVAS_PIDATA_ORIENTATION playbackOrientation; IVAS_PIDATA_ORIENTATION headOrientation; IVAS_PIDATA_LISTENER_POSITION listnerPosition; - IVAS_PIDATA_DYNAMIC_SUPPRESSION dynSuppression; + IVAS_PIDATA_DYNAMIC_SUPPRESSION dynSuppressionRequest; IVAS_PIDATA_AUDIO_FOCUS focusRequest; IVAS_PIDATA_REVERSE_PI_LATENCY piLatency; IVAS_PIDATA_ISM_EDIT_ID ismEditId; diff --git a/tests/rtp/ivasrtp.py b/tests/rtp/ivasrtp.py index 94584e901b3a12dd8af370f24db9ac108fc77afc..b09333fc46c5b2797607efb6d11b5078ec033924 100644 --- a/tests/rtp/ivasrtp.py +++ b/tests/rtp/ivasrtp.py @@ -177,13 +177,13 @@ class PIDATAS(str, Enum): ISM_DISTANCE_ATTENUATION = "ISM_DISTANCE_ATTENUATION" ISM_DIRECTIVITY = "ISM_DIRECTIVITY" DIEGETIC_TYPE = "DIEGETIC_TYPE" - RESERVED13 = "RESERVED13" + DYNAMIC_AUDIO_SUPPRESSION_INDICATION = "DYNAMIC_AUDIO_SUPPRESSION_INDICATION" AUDIO_FOCUS_INDICATION = "AUDIO_FOCUS_INDICATION" RESERVED15 = "RESERVED15" PLAYBACK_DEVICE_ORIENTATION = "PLAYBACK_DEVICE_ORIENTATION" HEAD_ORIENTATION = "HEAD_ORIENTATION" LISTENER_POSITION = "LISTENER_POSITION" - DYNAMIC_AUDIO_SUPPRESSION = "DYNAMIC_AUDIO_SUPPRESSION" + DYNAMIC_AUDIO_SUPPRESSION_REQUEST = "DYNAMIC_AUDIO_SUPPRESSION_REQUEST" AUDIO_FOCUS_REQUEST = "AUDIO_FOCUS_REQUEST" PI_LATENCY = "PI_LATENCY" R_ISM_ID = "R_ISM_ID" @@ -199,7 +199,7 @@ class PIDATAS(str, Enum): class SUPPRESSION_LEVEL(int, Enum): - SUPPRESSION_LEVEL_NONE = 0 + SUPPRESSION_LEVEL_MIN = 0 SUPPRESSION_LEVEL_1 = 1 SUPPRESSION_LEVEL_2 = 2 SUPPRESSION_LEVEL_3 = 3 @@ -211,10 +211,10 @@ class SUPPRESSION_LEVEL(int, Enum): SUPPRESSION_LEVEL_9 = 9 SUPPRESSION_LEVEL_10 = 10 SUPPRESSION_LEVEL_11 = 11 - SUPPRESSION_LEVEL_12 = 12 - SUPPRESSION_LEVEL_13 = 13 - SUPPRESSION_LEVEL_14 = 14 - SUPPRESSION_LEVEL_MAX = 15 + SUPPRESSION_LEVEL_MAX = 12 + SUPPRESSION_LEVEL_NONE = 13 + SUPPRESSION_LEVEL_DEFAULT = 14 + SUPPRESSION_LEVEL_NO_PREFERENCE = 15 class AUDIO_FOCUS_LEVEL(int, Enum): @@ -231,7 +231,7 @@ class AUDIO_FOCUS_LEVEL(int, Enum): AUDIO_FOCUS_LEVEL_10 = 10 AUDIO_FOCUS_LEVEL_11 = 11 AUDIO_FOCUS_LEVEL_12 = 12 - AUDIO_FOCUS_LEVEL_13 = 13 + AUDIO_FOCUS_LEVEL_MAX = 13 AUDIO_FOCUS_LEVEL_DEFAULT = 14 AUDIO_FOCUS_LEVEL_NO_PREFERENCE = 15 @@ -938,13 +938,13 @@ PIDataUnpacker = [ unpackUnsupported, # ISM_DISTANCE_ATTENUATION unpackUnsupported, # ISM_DIRECTIVITY unpackDiegetic, # DIEGETIC_TYPE - unpackUnsupported, # RESERVED13 + unpackDAS, # DYNAMIC_AUDIO_SUPPRESSION_INDICATION unpackAudioFocus, # AUDIO_FOCUS_INDICATION unpackUnsupported, # RESERVED15 unpackOrientation, # PLAYBACK_DEVICE_ORIENTATION unpackOrientation, # HEAD_ORIENTATION unpackPosition, # LISTENER_POSITION - unpackDAS, # DYNAMIC_AUDIO_SUPPRESSION + unpackDAS, # DYNAMIC_AUDIO_SUPPRESSION_REQUEST unpackAudioFocus, # AUDIO_FOCUS_REQUEST unpackUnsupported, # PI_LATENCY unpackUnsupported, # R_ISM_ID @@ -973,13 +973,13 @@ PIDataPacker = [ packUnsupported, # ISM_DISTANCE_ATTENUATION packUnsupported, # ISM_DIRECTIVITY packDiegetic, # DIEGETIC_TYPE - packUnsupported, # RESERVED13 + packDAS, # DYNAMIC_AUDIO_SUPPRESSION_INDICATION packAudioFocus, # AUDIO_FOCUS_INDICATION packUnsupported, # RESERVED15 packOrientation, # PLAYBACK_DEVICE_ORIENTATION packOrientation, # HEAD_ORIENTATION packPosition, # LISTENER_POSITION - packDAS, # DYNAMIC_AUDIO_SUPPRESSION + packDAS, # DYNAMIC_AUDIO_SUPPRESSION_REQUEST packAudioFocus, # AUDIO_FOCUS_DIRECTION packUnsupported, # PI_LATENCY packUnsupported, # R_ISM_ID @@ -1484,7 +1484,7 @@ class IvasRtp: or piTypes == PIDATAS.R_ISM_POSITION ): data = POSITION(**dataDict) - elif piTypes == PIDATAS.DYNAMIC_AUDIO_SUPPRESSION: + elif "DYNAMIC_AUDIO_SUPPRESSION" in piTypes: data = DYNAMIC_AUDIO_SUPPRESSION(**dataDict) elif "AUDIO_FOCUS" in piTypes: data = AUDIO_FOCUS(**dataDict) diff --git a/tests/rtp/test_rtp.py b/tests/rtp/test_rtp.py index fd177fc84e10542ab35299a38b0ffa5a0cf7528a..44d08a91e16033ddae42c6859ce5858052535df1 100644 --- a/tests/rtp/test_rtp.py +++ b/tests/rtp/test_rtp.py @@ -237,7 +237,7 @@ def generatePiData(startTs: int, endTs: int) -> dict: pidata["HEAD_ORIENTATION"] = someOrientation() pidata["AUDIO_FOCUS_REQUEST"] = random.choice(someAuFocusList)() pidata["LISTENER_POSITION"] = somePosition() - pidata["DYNAMIC_AUDIO_SUPPRESSION"] = someDAS() + pidata["DYNAMIC_AUDIO_SUPPRESSION_REQUEST"] = someDAS() pidata["AUDIO_DESCRIPTION"] = [someDesc() for n in range(random.randint(1, 5))] pidata["DIEGETIC_TYPE"] = someDIG() pidata["ACOUSTIC_ENVIRONMENT"] = ACOUSTIC_ENVIRONMENT(