From 440eef8d141263fb5de30dd4846819957b24c2db Mon Sep 17 00:00:00 2001 From: Stefan Doehla Date: Mon, 13 Apr 2026 23:26:01 +0200 Subject: [PATCH 1/5] RTPDUMP implementation from float with minimal adaptation --- lib_com/options.h | 1 + lib_util/ivas_rtp_file.c | 72 ++++++++++++++++++++++++++++- lib_util/mime_io.c | 5 +++ lib_util/rtpdump.c | 97 ++++++++++++++++++++++++++++++++++++++-- lib_util/rtpdump.h | 20 ++++++++- 5 files changed, 189 insertions(+), 6 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index c274abb89..1f949c504 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -108,6 +108,7 @@ #define FIX_BASOP_2513_EXTRA_RETURN_REND_OPEN /* Nokia: BASOP issue 2513: Removes extra return block */ #define FIX_BASOP_2514_EFAP_PORTING_ERROR /* Nokia: BASOP issue 2514: Fix wrongly ported line */ #define FIX_BASOP_2516_REND_CUSTOM_LAYOUT_PORT_BUG /* Nokia: BASOP issue 2516: Fix porting bug in setting planar state for custom layout in renderer */ +#define USE_RTPDUMP /* FhG: RTPDUMP format (rtptools standard) instead of custom format */ /* ##################### End NON-BE switches ########################### */ diff --git a/lib_util/ivas_rtp_file.c b/lib_util/ivas_rtp_file.c index 4d5065890..74b10044f 100644 --- a/lib_util/ivas_rtp_file.c +++ b/lib_util/ivas_rtp_file.c @@ -37,14 +37,26 @@ #include "ivas_error_utils.h" #include "float_to_fix_ops.h" - #define Q15 15 +#ifdef USE_RTPDUMP +#include "rtpdump.h" + +struct IVAS_RTP_FILE +{ + bool isFileWriter; + RTPDUMP_HANDLE f_rtpstream; + uint32_t offset_ms; +}; + +#else // USE_RTPDUMP + struct IVAS_RTP_FILE { bool isFileWriter; FILE *f_rtpstream; }; +#endif // USE_RTPDUMP static ivas_error IvasRtpFile_Open( const char *filePath, /* i : path to CA config file */ @@ -52,12 +64,29 @@ static ivas_error IvasRtpFile_Open( IVAS_RTP_FILE_HANDLE *phRtpFile /* o : pointer to an IVAS file reader handle */ ) { +#ifdef USE_RTPDUMP + RTPDUMP_HANDLE f_rtpstream; + RTPDUMP_ERROR rderr; + if ( isFileWriter ) + { + rderr = RTPDUMP_OpenForWriting( &f_rtpstream, filePath ); + } + else + { + rderr = RTPDUMP_OpenForReading( &f_rtpstream, filePath ); + } + if ( rderr != RTPDUMP_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_FILE_OPEN, "rtpdump open error %d", rderr ); + } +#else // USE_RTPDUMP const char *mode = isFileWriter ? "wb" : "rb"; FILE *f_rtpstream = fopen( filePath, mode ); if ( f_rtpstream == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_FILE_OPEN, "could not open: %s\n", filePath ); } +#endif // USE_RTPDUMP *phRtpFile = calloc( 1, sizeof( struct IVAS_RTP_FILE ) ); if ( *phRtpFile != NULL ) @@ -77,7 +106,11 @@ static ivas_error IvasRtpFile_Close( { if ( ( *phReader )->f_rtpstream != NULL ) { +#ifdef USE_RTPDUMP + RTPDUMP_Close( &( *phReader )->f_rtpstream, 1 ); +#else // USE_RTPDUMP fclose( ( *phReader )->f_rtpstream ); +#endif // USE_RTPDUMP ( *phReader )->f_rtpstream = NULL; } free( *phReader ); @@ -95,9 +128,20 @@ static ivas_error IvasRtpFile_Write( ivas_error error = IVAS_ERR_OK; if ( hRtpFile->isFileWriter ) { +#ifdef USE_RTPDUMP + RTPDUMP_RTPPACKET pkt; + RTPDUMP_SetDefaultRtpPacketHeader( &pkt ); + numBytes = ( numBytes > sizeof( pkt.data ) ) ? sizeof( pkt.data ) : numBytes; + memcpy( pkt.data, packet, numBytes ); + RTPDUMP_ParseRTPHeader( &pkt ); + pkt.payloadSize = (unsigned short) ( numBytes - pkt.headerSize ); + /* compute time offset in ms from RTP timestamp (16kHz clock) */ + error = ( RTPDUMP_WritePacket( hRtpFile->f_rtpstream, &pkt, pkt.timeStamp / 16 ) != RTPDUMP_NO_ERROR ) ? IVAS_ERR_FAILED_FILE_WRITE : IVAS_ERR_OK; +#else // USE_RTPDUMP uint32_t length = (uint32_t) numBytes; /* Max packet length is < 32 bits*/ fwrite( &length, sizeof( uint32_t ), 1, hRtpFile->f_rtpstream ); fwrite( packet, sizeof( uint8_t ), numBytes, hRtpFile->f_rtpstream ); +#endif // USE_RTPDUMP } else { @@ -114,12 +158,35 @@ static ivas_error IvasRtpFile_Read( ) { size_t nread = 0; +#ifndef USE_RTPDUMP uint32_t length = 0; +#endif // USE_RTPDUMP if ( hRtpFile->isFileWriter ) { return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "File open for writing cannot be read" ); } +#ifdef USE_RTPDUMP + RTPDUMP_RTPPACKET pd; + RTPDUMP_ERROR rderr = RTPDUMP_ReadPacket( hRtpFile->f_rtpstream, &pd, &hRtpFile->offset_ms ); + if ( rderr == RTPDUMP_READ_ENDOFFILE ) + { + return IVAS_ERR_END_OF_FILE; + } + if ( rderr != RTPDUMP_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_FILE_OPEN, "rtpdump read error %d", rderr ); + } + + /* copy raw data to unpack buffer */ + nread = pd.headerSize + pd.payloadSize; + if ( nread > capacity ) + { + return IVAS_ERR_INVALID_OUTPUT_BUFFER_SIZE; + } + memcpy( packet, pd.data, nread ); + *numBytes = nread; +#else // USE_RTPDUMP nread = fread( &length, sizeof( uint32_t ), 1, hRtpFile->f_rtpstream ); /* Read Packet Length */ if ( nread == 0 ) { @@ -138,6 +205,7 @@ static ivas_error IvasRtpFile_Read( { return IVAS_ERR_END_OF_FILE; } +#endif // USE_RTPDUMP return IVAS_ERR_OK; } @@ -902,6 +970,7 @@ ivas_error IVAS_RTP_WRITER_Init( return error; } + /* initialize RTP packer header sequence only in file-based mode */ #ifdef FIX_1540_EXPOSE_PT_IN_RTP_HEADER_API error = IVAS_RTP_PACK_UpdateHeader( rtp->hPack, payloadType, seqNumInitVal, SSRC, 0, NULL, 0, 0, NULL ); #else @@ -935,6 +1004,7 @@ ivas_error IVAS_RTP_READER_Init( error = IVAS_RTP_UNPACK_Open( &rtp->hUnpack, &rtp->unpackCfg ); if ( error == IVAS_ERR_OK ) { + /* Open the output file for RTPDump writing */ error = IvasRtpFile_Open( inputBitstreamFilename, false, &rtp->hRtpFile ); if ( error != IVAS_ERR_OK ) { diff --git a/lib_util/mime_io.c b/lib_util/mime_io.c index b6afcd1db..4cc7bea36 100644 --- a/lib_util/mime_io.c +++ b/lib_util/mime_io.c @@ -30,6 +30,7 @@ *******************************************************************************************************/ +#include "options.h" #include "mime_io.h" #include "mime.h" #include "prot_fx.h" @@ -317,7 +318,11 @@ static bool readByte( FILE *file, uint8_t *value ) static bool readLong( FILE *file, uint16_t *value ) { char buffer[4] = { 0 }; +#ifdef USE_RTPDUMP + if ( fread( buffer, 1, 4, file ) != 4U ) +#else if ( fread( buffer, 1, 4, file ) != 1U ) +#endif { return false; } diff --git a/lib_util/rtpdump.c b/lib_util/rtpdump.c index df51a1972..2b5ab064c 100644 --- a/lib_util/rtpdump.c +++ b/lib_util/rtpdump.c @@ -37,8 +37,8 @@ #include #include #include -#include "rtpdump.h" #include "options.h" +#include "rtpdump.h" struct RTPDUMP { @@ -81,7 +81,7 @@ static unsigned char *parseByte( unsigned char *buffer, unsigned char *value ) static int readLong( FILE *file, unsigned int *value ) { char buffer[4] = { 0 }; - if ( fread( buffer, 1, 4, file ) != 1U ) + if ( fread( buffer, 1, 4, file ) != 4U ) { return -1; } @@ -97,7 +97,7 @@ static int readLong( FILE *file, unsigned int *value ) static int readShort( FILE *file, unsigned short *value ) { char buffer[2] = { 0 }; - if ( fread( buffer, 1, 2, file ) != 1U ) + if ( fread( buffer, 1, 2, file ) != 2U ) { return -1; } @@ -199,7 +199,22 @@ static int readHeader( struct RTPDUMP *hRTPDUMP ) static int writeHeader( struct RTPDUMP *hRTPDUMP ) { /* write rtpdump header */ - fprintf( hRTPDUMP->file, "#!rtpplay%s %s/%d\n", "1.0", "127.0.0.1", 5000 ); + /* Use defaults if not configured (for backward compatibility) */ + if ( hRTPDUMP->source == 0 && hRTPDUMP->port == 0 ) + { + hRTPDUMP->source = 0x7F000001u; /* 127.0.0.1 */ + hRTPDUMP->port = 5000u; + } + + /* Format IP address for text header */ + unsigned char ip[4]; + ip[0] = (unsigned char) ( ( hRTPDUMP->source >> 24 ) & 0xFF ); + ip[1] = (unsigned char) ( ( hRTPDUMP->source >> 16 ) & 0xFF ); + ip[2] = (unsigned char) ( ( hRTPDUMP->source >> 8 ) & 0xFF ); + ip[3] = (unsigned char) ( hRTPDUMP->source & 0xFF ); + + fprintf( hRTPDUMP->file, "#!rtpplay%s %u.%u.%u.%u/%u\n", "1.0", ip[0], ip[1], ip[2], ip[3], hRTPDUMP->port ); + if ( !writeLong( hRTPDUMP->file, hRTPDUMP->startSeconds ) && !writeLong( hRTPDUMP->file, hRTPDUMP->startMicroSeconds ) && !writeLong( hRTPDUMP->file, hRTPDUMP->source ) && @@ -257,6 +272,7 @@ RTPDUMP_OpenForWriting( RTPDUMP_HANDLE *phRTPDUMP, const char *filename ) return RTPDUMP_FILE_NOT_FOUND; } + /* Write header immediately (can be updated later via RTPDUMP_SetHeaderInfo) */ if ( writeHeader( *phRTPDUMP ) != 0 ) { return RTPDUMP_INIT_ERROR; @@ -265,6 +281,79 @@ RTPDUMP_OpenForWriting( RTPDUMP_HANDLE *phRTPDUMP, const char *filename ) return RTPDUMP_NO_ERROR; } +#ifdef USE_RTPDUMP +RTPDUMP_ERROR +RTPDUMP_SetHeaderInfo( RTPDUMP_HANDLE hRTPDUMP, + uint32_t source, + uint16_t port, + uint32_t startSeconds, + uint32_t startMicroSeconds ) +{ + if ( !hRTPDUMP ) + { + return RTPDUMP_NOT_INITIALIZED; + } + + hRTPDUMP->source = source; + hRTPDUMP->port = port; + hRTPDUMP->startSeconds = startSeconds; + hRTPDUMP->startMicroSeconds = startMicroSeconds; + + /* If file is open for writing, seek back and rewrite the header */ + if ( hRTPDUMP->file ) + { + long currentPos = ftell( hRTPDUMP->file ); + if ( currentPos < 0 ) + { + return RTPDUMP_WRITE_ERROR; + } + + /* Seek to beginning and rewrite header */ + if ( fseek( hRTPDUMP->file, 0, SEEK_SET ) != 0 ) + { + return RTPDUMP_WRITE_ERROR; + } + + if ( writeHeader( hRTPDUMP ) != 0 ) + { + return RTPDUMP_WRITE_ERROR; + } + + /* Restore file position */ + if ( fseek( hRTPDUMP->file, currentPos, SEEK_SET ) != 0 ) + { + return RTPDUMP_WRITE_ERROR; + } + } + + return RTPDUMP_NO_ERROR; +} + +RTPDUMP_ERROR +RTPDUMP_GetHeaderInfo( RTPDUMP_HANDLE hRTPDUMP, + uint32_t *source, + uint16_t *port, + uint32_t *startSeconds, + uint32_t *startMicroSeconds ) +{ + if ( !hRTPDUMP ) + { + return RTPDUMP_NOT_INITIALIZED; + } + + if ( source ) + *source = hRTPDUMP->source; + if ( port ) + *port = hRTPDUMP->port; + if ( startSeconds ) + *startSeconds = hRTPDUMP->startSeconds; + if ( startMicroSeconds ) + *startMicroSeconds = hRTPDUMP->startMicroSeconds; + + return RTPDUMP_NO_ERROR; +} +#endif + RTPDUMP_ERROR RTPDUMP_ReadPacket( RTPDUMP_HANDLE hRTPDUMP, RTPDUMP_RTPPACKET *packet, diff --git a/lib_util/rtpdump.h b/lib_util/rtpdump.h index 8ddfde750..32415ab4e 100644 --- a/lib_util/rtpdump.h +++ b/lib_util/rtpdump.h @@ -43,6 +43,8 @@ extern "C" { #endif +#define RTPDUMP_MAX_PACKET_SIZE 12300 /* Maximum size of an RTP packet, 12300 to cover IVAS jumbo packets, 1458 for MTU size 1500 */ + typedef enum _RTPDUMP_ERROR { RTPDUMP_NO_ERROR = 0x0000, @@ -68,7 +70,7 @@ extern "C" unsigned short sequenceNumber; unsigned int timeStamp; unsigned int ssrc; - char data[1500 + 12]; /* raw RTP packet */ + char data[RTPDUMP_MAX_PACKET_SIZE]; /* raw RTP packet */ unsigned short headerSize; unsigned short payloadSize; } RTPDUMP_RTPPACKET; @@ -83,6 +85,22 @@ extern "C" RTPDUMP_ERROR RTPDUMP_OpenForWriting( RTPDUMP_HANDLE *phRTPDUMP, const char *filename ); +#ifdef USE_RTPDUMP + RTPDUMP_ERROR + RTPDUMP_SetHeaderInfo( RTPDUMP_HANDLE hRTPDUMP, + uint32_t source, + uint16_t port, + uint32_t startSeconds, + uint32_t startMicroSeconds ); + + RTPDUMP_ERROR + RTPDUMP_GetHeaderInfo( RTPDUMP_HANDLE hRTPDUMP, + uint32_t *source, + uint16_t *port, + uint32_t *startSeconds, + uint32_t *startMicroSeconds ); +#endif + RTPDUMP_ERROR RTPDUMP_ReadPacket( RTPDUMP_HANDLE hRTPDUMP, RTPDUMP_RTPPACKET *packet, -- GitLab From 1c71ae907a43bf7f214a674f75c8963a7b8a8d4f Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Tue, 14 Apr 2026 09:50:09 +0200 Subject: [PATCH 2/5] [revert-me] change CI ref --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3f84bc99f..7217abceb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ variables: # note: GitLab cannot reference variables defined by users in the include ref:, we need to use a YAML anchor for this # see https://docs.gitlab.com/ci/yaml/includes/#use-variables-with-include for more information - IVAS_CODEC_CI_REF: &IVAS_CODEC_CI_REF main + IVAS_CODEC_CI_REF: &IVAS_CODEC_CI_REF branch-naming-check-revise # If you need to set some config variable only in a local branch, then add an overwrite here # One example is DISABLE_HRTF - this will be set on a branch which is about to be merged and will be removed in a subsequent second MR # this is more easily done directly here in the child repo -- GitLab From 84be2854fe02fdc8449caf029ac0a955a8f3f479 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Tue, 14 Apr 2026 13:25:47 +0200 Subject: [PATCH 3/5] [revert-me] change scripts ref --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7217abceb..710451514 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,6 +9,7 @@ variables: # these lines are suposed to stay commented out to serve as an example # # set this to true to skip the external HRTF testcases in pytest calls # DISABLE_HRTF: "true" + BASOP_CI_SCRIPTS_BRANCH: 1438-rtpdump-is-not-rtpdump # all CI code and config is included from https://forge.3gpp.org/rep/ivas-codec-pc/ivas-codec-ci include: -- GitLab From 8c9a67d9cf1615958f6e5427a549ab4b484bf00f Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 16 Apr 2026 10:25:01 +0200 Subject: [PATCH 4/5] Revert "[revert-me] change scripts ref" This reverts commit 84be2854fe02fdc8449caf029ac0a955a8f3f479. --- .gitlab-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 710451514..7217abceb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,7 +9,6 @@ variables: # these lines are suposed to stay commented out to serve as an example # # set this to true to skip the external HRTF testcases in pytest calls # DISABLE_HRTF: "true" - BASOP_CI_SCRIPTS_BRANCH: 1438-rtpdump-is-not-rtpdump # all CI code and config is included from https://forge.3gpp.org/rep/ivas-codec-pc/ivas-codec-ci include: -- GitLab From e88e424c70803d49ad42fe5ecdab3e528fc2e859 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 16 Apr 2026 10:25:25 +0200 Subject: [PATCH 5/5] Revert "[revert-me] change CI ref" This reverts commit 1c71ae907a43bf7f214a674f75c8963a7b8a8d4f. --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7217abceb..3f84bc99f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ variables: # note: GitLab cannot reference variables defined by users in the include ref:, we need to use a YAML anchor for this # see https://docs.gitlab.com/ci/yaml/includes/#use-variables-with-include for more information - IVAS_CODEC_CI_REF: &IVAS_CODEC_CI_REF branch-naming-check-revise + IVAS_CODEC_CI_REF: &IVAS_CODEC_CI_REF main # If you need to set some config variable only in a local branch, then add an overwrite here # One example is DISABLE_HRTF - this will be set on a branch which is about to be merged and will be removed in a subsequent second MR # this is more easily done directly here in the child repo -- GitLab