diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn index a0b1525afc..04683d1608 100644 --- a/modules/audio_coding/BUILD.gn +++ b/modules/audio_coding/BUILD.gn @@ -1189,9 +1189,6 @@ if (rtc_include_tests) { group("audio_coding_tests") { testonly = true public_deps = [ - ":RTPchange", - ":RTPjitter", - ":RTPtimeshift", ":acm_receive_test", ":acm_send_test", ":audio_codec_speed_tests", @@ -1213,6 +1210,7 @@ if (rtc_include_tests) { ":neteq_speed_test", ":rtp_analyze", ":rtp_encode", + ":rtp_jitter", ":rtpcat", ":webrtc_opus_fec_test", ] @@ -1611,40 +1609,6 @@ if (rtc_include_tests) { ] } - rtc_source_set("neteq_test_tools_deprecated") { - testonly = true - sources = [ - "neteq/test/NETEQTEST_DummyRTPpacket.cc", - "neteq/test/NETEQTEST_DummyRTPpacket.h", - "neteq/test/NETEQTEST_RTPpacket.cc", - "neteq/test/NETEQTEST_RTPpacket.h", - ] - - deps = [ - ":cng", - ":g711", - ":g722", - ":ilbc", - ":isac", - ":pcm16b", - "..:module_api", - "../..:webrtc_common", - "//testing/gtest", - ] - - include_dirs = [ - "neteq/include", - "neteq/test", - ] - - if (is_win) { - cflags = [ - # Disable warnings to enable Win64 build, issue 1323. - "/wd4267", # size_t to int truncation - ] - } - } - rtc_executable("rtp_encode") { testonly = true @@ -1668,16 +1632,21 @@ if (rtc_include_tests) { defines = audio_coding_defines } - rtc_executable("RTPchange") { + rtc_executable("rtp_jitter") { testonly = true + deps = audio_coding_deps + [ + "../rtp_rtcp:rtp_rtcp_format", + "../../api:array_view", + "../../rtc_base:rtc_base_approved", + "../../system_wrappers:system_wrappers_default", + ] + sources = [ - "neteq/test/RTPchange.cc", + "neteq/tools/rtp_jitter.cc", ] - deps = [ - ":neteq_test_tools_deprecated", - ] + defines = audio_coding_defines } rtc_executable("rtpcat") { @@ -1695,33 +1664,6 @@ if (rtc_include_tests) { ] } - rtc_executable("RTPtimeshift") { - testonly = true - - sources = [ - "neteq/test/RTPtimeshift.cc", - ] - - deps = [ - ":neteq_test_tools_deprecated", - "../../test:test_support", - "//testing/gtest", - ] - } - - rtc_executable("RTPjitter") { - testonly = true - deps = [ - "../..:webrtc_common", - "../../rtc_base:rtc_base_approved", - "../../test:test_support", - "//testing/gtest", - ] - sources = [ - "neteq/test/RTPjitter.cc", - ] - } - rtc_executable("rtp_analyze") { testonly = true diff --git a/modules/audio_coding/neteq/test/NETEQTEST_DummyRTPpacket.cc b/modules/audio_coding/neteq/test/NETEQTEST_DummyRTPpacket.cc deleted file mode 100644 index 37e215bc62..0000000000 --- a/modules/audio_coding/neteq/test/NETEQTEST_DummyRTPpacket.cc +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "NETEQTEST_DummyRTPpacket.h" - -#include -#include -#include - -#ifdef WIN32 -#include -#else -#include // for htons, htonl, etc -#endif - -int NETEQTEST_DummyRTPpacket::readFromFile(FILE *fp) -{ - if (!fp) - { - return -1; - } - - uint16_t length, plen; - uint32_t offset; - int packetLen = 0; - - bool readNextPacket = true; - while (readNextPacket) { - readNextPacket = false; - if (fread(&length, 2, 1, fp) == 0) - { - reset(); - return -2; - } - length = ntohs(length); - - if (fread(&plen, 2, 1, fp) == 0) - { - reset(); - return -1; - } - packetLen = ntohs(plen); - - if (fread(&offset, 4, 1, fp) == 0) - { - reset(); - return -1; - } - // Store in local variable until we have passed the reset below. - uint32_t receiveTime = ntohl(offset); - - // Use length here because a plen of 0 specifies rtcp. - length = (uint16_t) (length - _kRDHeaderLen); - - // check buffer size - if (_datagram && _memSize < length + 1) - { - reset(); - } - - if (!_datagram) - { - // Add one extra byte, to be able to fake a dummy payload of 1 byte. - _datagram = new uint8_t[length + 1]; - _memSize = length + 1; - } - memset(_datagram, 0, length + 1); - - if (length == 0) - { - _datagramLen = 0; - _rtpParsed = false; - return packetLen; - } - - // Read basic header - if (fread((unsigned short *) _datagram, 1, _kBasicHeaderLen, fp) - != (size_t)_kBasicHeaderLen) - { - reset(); - return -1; - } - _receiveTime = receiveTime; - _datagramLen = _kBasicHeaderLen; - - // Parse the basic header - webrtc::WebRtcRTPHeader tempRTPinfo; - int P, X, CC; - parseBasicHeader(&tempRTPinfo, &P, &X, &CC); - - // Check if we have to extend the header - if (X != 0 || CC != 0) - { - int newLen = _kBasicHeaderLen + CC * 4 + X * 4; - assert(_memSize >= newLen); - - // Read extension from file - size_t readLen = newLen - _kBasicHeaderLen; - if (fread(&_datagram[_kBasicHeaderLen], 1, readLen, fp) != readLen) - { - reset(); - return -1; - } - _datagramLen = newLen; - - if (X != 0) - { - int totHdrLen = calcHeaderLength(X, CC); - assert(_memSize >= totHdrLen); - - // Read extension from file - size_t readLen = totHdrLen - newLen; - if (fread(&_datagram[newLen], 1, readLen, fp) != readLen) - { - reset(); - return -1; - } - _datagramLen = totHdrLen; - } - } - _datagramLen = length; - - if (!_blockList.empty() && _blockList.count(payloadType()) > 0) - { - readNextPacket = true; - } - } - - _rtpParsed = false; - assert(_memSize > _datagramLen); - _payloadLen = 1; // Set the length to 1 byte. - return packetLen; - -} - -int NETEQTEST_DummyRTPpacket::writeToFile(FILE *fp) -{ - if (!fp) - { - return -1; - } - - uint16_t length, plen; - uint32_t offset; - - // length including RTPplay header - length = htons(_datagramLen + _kRDHeaderLen); - if (fwrite(&length, 2, 1, fp) != 1) - { - return -1; - } - - // payload length - plen = htons(_datagramLen); - if (fwrite(&plen, 2, 1, fp) != 1) - { - return -1; - } - - // offset (=receive time) - offset = htonl(_receiveTime); - if (fwrite(&offset, 4, 1, fp) != 1) - { - return -1; - } - - // Figure out the length of the RTP header. - int headerLen; - if (_datagramLen == 0) - { - // No payload at all; we are done writing to file. - headerLen = 0; - } - else - { - parseHeader(); - headerLen = _payloadPtr - _datagram; - assert(headerLen >= 0); - } - - // write RTP header - if (fwrite((unsigned short *) _datagram, 1, headerLen, fp) != - static_cast(headerLen)) - { - return -1; - } - - return (headerLen + _kRDHeaderLen); // total number of bytes written - -} - -void NETEQTEST_DummyRTPpacket::parseHeader() { - NETEQTEST_RTPpacket::parseHeader(); - // Change _payloadLen to 1 byte. The memory should always be big enough. - assert(_memSize > _datagramLen); - _payloadLen = 1; -} diff --git a/modules/audio_coding/neteq/test/NETEQTEST_DummyRTPpacket.h b/modules/audio_coding/neteq/test/NETEQTEST_DummyRTPpacket.h deleted file mode 100644 index 1ac6c9a14f..0000000000 --- a/modules/audio_coding/neteq/test/NETEQTEST_DummyRTPpacket.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef NETEQTEST_DUMMYRTPPACKET_H -#define NETEQTEST_DUMMYRTPPACKET_H - -#include "NETEQTEST_RTPpacket.h" - -class NETEQTEST_DummyRTPpacket : public NETEQTEST_RTPpacket { - public: - int readFromFile(FILE* fp) override; - int writeToFile(FILE* fp) override; - void parseHeader() override; -}; - -#endif // NETEQTEST_DUMMYRTPPACKET_H diff --git a/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.cc b/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.cc deleted file mode 100644 index 3d44fbcb25..0000000000 --- a/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.cc +++ /dev/null @@ -1,851 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "NETEQTEST_RTPpacket.h" - -#include -#include // rand -#include - -#ifdef WIN32 -#include -#else -#include // for htons, htonl, etc -#endif - -const int NETEQTEST_RTPpacket::_kRDHeaderLen = 8; -const int NETEQTEST_RTPpacket::_kBasicHeaderLen = 12; - -NETEQTEST_RTPpacket::NETEQTEST_RTPpacket() -: -_datagram(NULL), -_payloadPtr(NULL), -_memSize(0), -_datagramLen(-1), -_payloadLen(0), -_rtpParsed(false), -_receiveTime(0), -_lost(false) -{ - memset(&_rtpInfo, 0, sizeof(_rtpInfo)); - _blockList.clear(); -} - -NETEQTEST_RTPpacket::~NETEQTEST_RTPpacket() -{ - if(_datagram) - { - delete [] _datagram; - } -} - -void NETEQTEST_RTPpacket::reset() -{ - if(_datagram) { - delete [] _datagram; - } - _datagram = NULL; - _memSize = 0; - _datagramLen = -1; - _payloadLen = 0; - _payloadPtr = NULL; - _receiveTime = 0; - memset(&_rtpInfo, 0, sizeof(_rtpInfo)); - _rtpParsed = false; - -} - -int NETEQTEST_RTPpacket::skipFileHeader(FILE *fp) -{ - if (!fp) { - return -1; - } - - const int kFirstLineLength = 40; - char firstline[kFirstLineLength]; - if (fgets(firstline, kFirstLineLength, fp) == NULL) { - return -1; - } - if (strncmp(firstline, "#!rtpplay", 9) == 0) { - if (strncmp(firstline, "#!rtpplay1.0", 12) != 0) { - return -1; - } - } - else if (strncmp(firstline, "#!RTPencode", 11) == 0) { - if (strncmp(firstline, "#!RTPencode1.0", 14) != 0) { - return -1; - } - } - else - { - return -1; - } - - const int kRtpDumpHeaderSize = 4 + 4 + 4 + 2 + 2; - if (fseek(fp, kRtpDumpHeaderSize, SEEK_CUR) != 0) - { - return -1; - } - return 0; -} - -int NETEQTEST_RTPpacket::readFromFile(FILE *fp) -{ - if(!fp) - { - return(-1); - } - - uint16_t length, plen; - uint32_t offset; - int packetLen = 0; - - bool readNextPacket = true; - while (readNextPacket) { - readNextPacket = false; - if (fread(&length,2,1,fp)==0) - { - reset(); - return(-2); - } - length = ntohs(length); - - if (fread(&plen,2,1,fp)==0) - { - reset(); - return(-1); - } - packetLen = ntohs(plen); - - if (fread(&offset,4,1,fp)==0) - { - reset(); - return(-1); - } - // store in local variable until we have passed the reset below - uint32_t receiveTime = ntohl(offset); - - // Use length here because a plen of 0 specifies rtcp - length = (uint16_t) (length - _kRDHeaderLen); - - // check buffer size - if (_datagram && _memSize < length) - { - reset(); - } - - if (!_datagram) - { - _datagram = new uint8_t[length]; - _memSize = length; - } - - if (fread((unsigned short *) _datagram,1,length,fp) != length) - { - reset(); - return(-1); - } - - _datagramLen = length; - _receiveTime = receiveTime; - - if (!_blockList.empty() && _blockList.count(payloadType()) > 0) - { - readNextPacket = true; - } - } - - _rtpParsed = false; - return(packetLen); - -} - - -int NETEQTEST_RTPpacket::readFixedFromFile(FILE *fp, size_t length) -{ - if (!fp) - { - return -1; - } - - // check buffer size - if (_datagram && _memSize < static_cast(length)) - { - reset(); - } - - if (!_datagram) - { - _datagram = new uint8_t[length]; - _memSize = length; - } - - if (fread(_datagram, 1, length, fp) != length) - { - reset(); - return -1; - } - - _datagramLen = length; - _receiveTime = 0; - - if (!_blockList.empty() && _blockList.count(payloadType()) > 0) - { - // discard this payload - return readFromFile(fp); - } - - _rtpParsed = false; - return length; - -} - - -int NETEQTEST_RTPpacket::writeToFile(FILE *fp) -{ - if (!fp) - { - return -1; - } - - uint16_t length, plen; - uint32_t offset; - - // length including RTPplay header - length = htons(_datagramLen + _kRDHeaderLen); - if (fwrite(&length, 2, 1, fp) != 1) - { - return -1; - } - - // payload length - plen = htons(_datagramLen); - if (fwrite(&plen, 2, 1, fp) != 1) - { - return -1; - } - - // offset (=receive time) - offset = htonl(_receiveTime); - if (fwrite(&offset, 4, 1, fp) != 1) - { - return -1; - } - - - // write packet data - if (fwrite(_datagram, 1, _datagramLen, fp) != - static_cast(_datagramLen)) - { - return -1; - } - - return _datagramLen + _kRDHeaderLen; // total number of bytes written - -} - - -void NETEQTEST_RTPpacket::blockPT(uint8_t pt) -{ - _blockList[pt] = true; -} - - -void NETEQTEST_RTPpacket::parseHeader() -{ - if (_rtpParsed) - { - // nothing to do - return; - } - - if (_datagramLen < _kBasicHeaderLen) - { - // corrupt packet? - return; - } - - _payloadLen = parseRTPheader(&_payloadPtr); - - _rtpParsed = true; - - return; - -} - -void NETEQTEST_RTPpacket::parseHeader(webrtc::WebRtcRTPHeader* rtp_header) { - if (!_rtpParsed) { - parseHeader(); - } - if (rtp_header) { - rtp_header->header.markerBit = _rtpInfo.header.markerBit; - rtp_header->header.payloadType = _rtpInfo.header.payloadType; - rtp_header->header.sequenceNumber = _rtpInfo.header.sequenceNumber; - rtp_header->header.timestamp = _rtpInfo.header.timestamp; - rtp_header->header.ssrc = _rtpInfo.header.ssrc; - } -} - -const webrtc::WebRtcRTPHeader* NETEQTEST_RTPpacket::RTPinfo() const -{ - if (_rtpParsed) - { - return &_rtpInfo; - } - else - { - return NULL; - } -} - -uint8_t * NETEQTEST_RTPpacket::datagram() const -{ - if (_datagramLen > 0) - { - return _datagram; - } - else - { - return NULL; - } -} - -uint8_t * NETEQTEST_RTPpacket::payload() const -{ - if (_payloadLen > 0) - { - return _payloadPtr; - } - else - { - return NULL; - } -} - -size_t NETEQTEST_RTPpacket::payloadLen() -{ - parseHeader(); - return _payloadLen; -} - -int16_t NETEQTEST_RTPpacket::dataLen() const -{ - return _datagramLen; -} - -bool NETEQTEST_RTPpacket::isParsed() const -{ - return _rtpParsed; -} - -bool NETEQTEST_RTPpacket::isLost() const -{ - return _lost; -} - -uint8_t NETEQTEST_RTPpacket::payloadType() const -{ - if(_datagram && _datagramLen >= _kBasicHeaderLen) - { - webrtc::WebRtcRTPHeader tempRTPinfo; - parseRTPheader(&tempRTPinfo); - return tempRTPinfo.header.payloadType; - } - else - { - return 0; - } -} - -uint16_t NETEQTEST_RTPpacket::sequenceNumber() const -{ - if(_datagram && _datagramLen >= _kBasicHeaderLen) - { - webrtc::WebRtcRTPHeader tempRTPinfo; - parseRTPheader(&tempRTPinfo); - return tempRTPinfo.header.sequenceNumber; - } - else - { - return 0; - } -} - -uint32_t NETEQTEST_RTPpacket::timeStamp() const -{ - if(_datagram && _datagramLen >= _kBasicHeaderLen) - { - webrtc::WebRtcRTPHeader tempRTPinfo; - parseRTPheader(&tempRTPinfo); - return tempRTPinfo.header.timestamp; - } - else - { - return 0; - } -} - -uint32_t NETEQTEST_RTPpacket::SSRC() const -{ - if(_datagram && _datagramLen >= _kBasicHeaderLen) - { - webrtc::WebRtcRTPHeader tempRTPinfo; - parseRTPheader(&tempRTPinfo); - return tempRTPinfo.header.ssrc; - } - else - { - return 0; - } -} - -uint8_t NETEQTEST_RTPpacket::markerBit() const -{ - if(_datagram && _datagramLen >= _kBasicHeaderLen) - { - webrtc::WebRtcRTPHeader tempRTPinfo; - parseRTPheader(&tempRTPinfo); - return tempRTPinfo.header.markerBit; - } - else - { - return 0; - } -} - - - -int NETEQTEST_RTPpacket::setPayloadType(uint8_t pt) -{ - - if (_datagramLen < 12) - { - return -1; - } - - if (!_rtpParsed) - { - _rtpInfo.header.payloadType = pt; - } - - _datagram[1] = pt; - - return 0; - -} - -int NETEQTEST_RTPpacket::setSequenceNumber(uint16_t sn) -{ - - if (_datagramLen < 12) - { - return -1; - } - - if (!_rtpParsed) - { - _rtpInfo.header.sequenceNumber = sn; - } - - _datagram[2]=(unsigned char)((sn>>8)&0xFF); - _datagram[3]=(unsigned char)((sn)&0xFF); - - return 0; - -} - -int NETEQTEST_RTPpacket::setTimeStamp(uint32_t ts) -{ - - if (_datagramLen < 12) - { - return -1; - } - - if (!_rtpParsed) - { - _rtpInfo.header.timestamp = ts; - } - - _datagram[4]=(unsigned char)((ts>>24)&0xFF); - _datagram[5]=(unsigned char)((ts>>16)&0xFF); - _datagram[6]=(unsigned char)((ts>>8)&0xFF); - _datagram[7]=(unsigned char)(ts & 0xFF); - - return 0; - -} - -int NETEQTEST_RTPpacket::setSSRC(uint32_t ssrc) -{ - - if (_datagramLen < 12) - { - return -1; - } - - if (!_rtpParsed) - { - _rtpInfo.header.ssrc = ssrc; - } - - _datagram[8]=(unsigned char)((ssrc>>24)&0xFF); - _datagram[9]=(unsigned char)((ssrc>>16)&0xFF); - _datagram[10]=(unsigned char)((ssrc>>8)&0xFF); - _datagram[11]=(unsigned char)(ssrc & 0xFF); - - return 0; - -} - -int NETEQTEST_RTPpacket::setMarkerBit(uint8_t mb) -{ - - if (_datagramLen < 12) - { - return -1; - } - - if (_rtpParsed) - { - _rtpInfo.header.markerBit = mb; - } - - if (mb) - { - _datagram[0] |= 0x01; - } - else - { - _datagram[0] &= 0xFE; - } - - return 0; - -} - -int NETEQTEST_RTPpacket::setRTPheader(const webrtc::WebRtcRTPHeader* RTPinfo) -{ - if (_datagramLen < 12) - { - // this packet is not ok - return -1; - } - - makeRTPheader(_datagram, - RTPinfo->header.payloadType, - RTPinfo->header.sequenceNumber, - RTPinfo->header.timestamp, - RTPinfo->header.ssrc, - RTPinfo->header.markerBit); - - return 0; -} - - -int NETEQTEST_RTPpacket::splitStereo(NETEQTEST_RTPpacket* slaveRtp, - enum stereoModes mode) -{ - // if mono, do nothing - if (mode == stereoModeMono) - { - return 0; - } - - // check that the RTP header info is parsed - parseHeader(); - - // start by copying the main rtp packet - *slaveRtp = *this; - - if(_payloadLen == 0) - { - // do no more - return 0; - } - - if(_payloadLen%2 != 0) - { - // length must be a factor of 2 - return -1; - } - - switch(mode) - { - case stereoModeSample1: - { - // sample based codec with 1-byte samples - splitStereoSample(slaveRtp, 1 /* 1 byte/sample */); - break; - } - case stereoModeSample2: - { - // sample based codec with 2-byte samples - splitStereoSample(slaveRtp, 2 /* 2 bytes/sample */); - break; - } - case stereoModeFrame: - { - // frame based codec - splitStereoFrame(slaveRtp); - break; - } - case stereoModeDuplicate: - { - // frame based codec, send the whole packet to both master and slave - splitStereoDouble(slaveRtp); - break; - } - case stereoModeMono: - { - assert(false); - return -1; - } - } - - return 0; -} - - -void NETEQTEST_RTPpacket::makeRTPheader(unsigned char* rtp_data, - uint8_t payloadType, - uint16_t seqNo, - uint32_t timestamp, - uint32_t ssrc, - uint8_t markerBit) const -{ - rtp_data[0] = markerBit ? 0x81 : 0x80; - rtp_data[1] = payloadType; - rtp_data[2] = seqNo >> 8; - rtp_data[3] = seqNo & 0xFF; - rtp_data[4] = timestamp >> 24; - rtp_data[5] = (timestamp >> 16) & 0xFF; - rtp_data[6] = (timestamp >> 8) & 0xFF; - rtp_data[7] = timestamp & 0xFF; - rtp_data[8] = ssrc >> 24; - rtp_data[9] = (ssrc >> 16) & 0xFF; - rtp_data[10] = (ssrc >> 8) & 0xFF; - rtp_data[11] = ssrc & 0xFF; -} - -uint16_t NETEQTEST_RTPpacket::parseRTPheader(webrtc::WebRtcRTPHeader* RTPinfo, - uint8_t **payloadPtr) const -{ - uint16_t* rtp_data = reinterpret_cast(_datagram); - int i_P, i_X, i_CC; - - assert(_datagramLen >= 12); - parseBasicHeader(RTPinfo, &i_P, &i_X, &i_CC); - - int i_startPosition = calcHeaderLength(i_X, i_CC); - - int i_padlength = calcPadLength(i_P); - - if (payloadPtr) - { - *payloadPtr = - reinterpret_cast(&rtp_data[i_startPosition >> 1]); - } - - return static_cast(_datagramLen - i_startPosition - i_padlength); -} - - -void NETEQTEST_RTPpacket::parseBasicHeader(webrtc::WebRtcRTPHeader* RTPinfo, - int *i_P, int *i_X, int *i_CC) const -{ - uint16_t* rtp_data = reinterpret_cast(_datagram); - if (_datagramLen < 12) - { - assert(false); - return; - } - - *i_P = (rtp_data[0] >> 5) & 0x01; - *i_X = (rtp_data[0] >> 4) & 0x01; - *i_CC = rtp_data[0] & 0xF; - RTPinfo->header.markerBit = (rtp_data[0] >> 15) & 0x01; - RTPinfo->header.payloadType = (rtp_data[0] >> 8) & 0x7F; - RTPinfo->header.sequenceNumber = - (rtp_data[1] >> 8) | ((rtp_data[1] & 0xFF) << 8); - RTPinfo->header.timestamp = - ((rtp_data[2] & 0xFF) << 24) | ((rtp_data[2] & 0xFF00) << 8) | - (rtp_data[3] >> 8) | ((rtp_data[3] & 0xFF) << 8); - RTPinfo->header.ssrc = - ((rtp_data[4] & 0xFF) << 24) | ((rtp_data[4] & 0xFF00) << 8) | - (rtp_data[5] >> 8) | ((rtp_data[5] & 0xFF) << 8); -} - -int NETEQTEST_RTPpacket::calcHeaderLength(int i_X, int i_CC) const -{ - int i_extlength = 0; - uint16_t* rtp_data = reinterpret_cast(_datagram); - - if (i_X == 1) - { - // Extension header exists. - // Find out how many int32_t it consists of. - int offset = 7 + 2 * i_CC; - assert(_datagramLen > 2 * offset); - if (_datagramLen > 2 * offset) - { - i_extlength = 1 + - (((rtp_data[offset]) >> 8) | ((rtp_data[offset] & 0xFF) << 8)); - } - } - - return 12 + 4 * i_extlength + 4 * i_CC; -} - -int NETEQTEST_RTPpacket::calcPadLength(int i_P) const -{ - uint16_t* rtp_data = reinterpret_cast(_datagram); - if (i_P == 1) - { - /* Padding exists. Find out how many bytes the padding consists of. */ - if (_datagramLen & 0x1) - { - /* odd number of bytes => last byte in higher byte */ - return rtp_data[_datagramLen >> 1] & 0xFF; - } - else - { - /* even number of bytes => last byte in lower byte */ - return rtp_data[(_datagramLen >> 1) - 1] >> 8; - } - } - return 0; -} - -void NETEQTEST_RTPpacket::splitStereoSample(NETEQTEST_RTPpacket* slaveRtp, - int stride) -{ - if(!_payloadPtr || !slaveRtp || !slaveRtp->_payloadPtr - || _payloadLen == 0 || slaveRtp->_memSize < _memSize) - { - return; - } - - uint8_t *readDataPtr = _payloadPtr; - uint8_t *writeDataPtr = _payloadPtr; - uint8_t *slaveData = slaveRtp->_payloadPtr; - - while (readDataPtr - _payloadPtr < static_cast(_payloadLen)) - { - // master data - for (int ix = 0; ix < stride; ix++) { - *writeDataPtr = *readDataPtr; - writeDataPtr++; - readDataPtr++; - } - - // slave data - for (int ix = 0; ix < stride; ix++) { - *slaveData = *readDataPtr; - slaveData++; - readDataPtr++; - } - } - - _payloadLen /= 2; - slaveRtp->_payloadLen = _payloadLen; -} - - -void NETEQTEST_RTPpacket::splitStereoFrame(NETEQTEST_RTPpacket* slaveRtp) -{ - if(!_payloadPtr || !slaveRtp || !slaveRtp->_payloadPtr - || _payloadLen == 0 || slaveRtp->_memSize < _memSize) - { - return; - } - - memmove(slaveRtp->_payloadPtr, _payloadPtr + _payloadLen/2, _payloadLen/2); - - _payloadLen /= 2; - slaveRtp->_payloadLen = _payloadLen; -} -void NETEQTEST_RTPpacket::splitStereoDouble(NETEQTEST_RTPpacket* slaveRtp) -{ - if(!_payloadPtr || !slaveRtp || !slaveRtp->_payloadPtr - || _payloadLen == 0 || slaveRtp->_memSize < _memSize) - { - return; - } - - memcpy(slaveRtp->_payloadPtr, _payloadPtr, _payloadLen); - slaveRtp->_payloadLen = _payloadLen; -} - -// Get the RTP header for the RED payload indicated by argument index. -// The first RED payload is index = 0. -int NETEQTEST_RTPpacket::extractRED(int index, webrtc::WebRtcRTPHeader& red) -{ -// -// 0 1 2 3 -// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// |1| block PT | timestamp offset | block length | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// |1| ... | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// |0| block PT | -// +-+-+-+-+-+-+-+-+ -// - - parseHeader(); - - uint8_t* ptr = payload(); - uint8_t* payloadEndPtr = ptr + payloadLen(); - int num_encodings = 0; - int total_len = 0; - - while ((ptr < payloadEndPtr) && (*ptr & 0x80)) - { - int len = ((ptr[2] & 0x03) << 8) + ptr[3]; - if (num_encodings == index) - { - // Header found. - red.header.payloadType = ptr[0] & 0x7F; - uint32_t offset = (ptr[1] << 6) + (ptr[2] >> 2); - red.header.sequenceNumber = sequenceNumber(); - red.header.timestamp = timeStamp() - offset; - red.header.markerBit = markerBit(); - red.header.ssrc = SSRC(); - return len; - } - ++num_encodings; - total_len += len; - ptr += 4; - } - if ((ptr < payloadEndPtr) && (num_encodings == index)) - { - // Last header. - red.header.payloadType = ptr[0] & 0x7F; - red.header.sequenceNumber = sequenceNumber(); - red.header.timestamp = timeStamp(); - red.header.markerBit = markerBit(); - red.header.ssrc = SSRC(); - ++ptr; - return payloadLen() - (ptr - payload()) - total_len; - } - return -1; -} - -// Randomize the payload, not the RTP header. -void NETEQTEST_RTPpacket::scramblePayload(void) -{ - parseHeader(); - - for (size_t i = 0; i < _payloadLen; ++i) - { - _payloadPtr[i] = static_cast(rand()); - } -} diff --git a/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h b/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h deleted file mode 100644 index e4fe9c4012..0000000000 --- a/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef NETEQTEST_RTPPACKET_H -#define NETEQTEST_RTPPACKET_H - -#include -#include -#include "typedefs.h" // NOLINT(build/include) -#include "modules/include/module_common_types.h" - -enum stereoModes { - stereoModeMono, - stereoModeSample1, - stereoModeSample2, - stereoModeFrame, - stereoModeDuplicate -}; - -class NETEQTEST_RTPpacket -{ -public: - NETEQTEST_RTPpacket(); - bool operator !() const { return (dataLen() < 0); }; - virtual ~NETEQTEST_RTPpacket(); - void reset(); - static int skipFileHeader(FILE *fp); - virtual int readFromFile(FILE *fp); - int readFixedFromFile(FILE *fp, size_t len); - virtual int writeToFile(FILE *fp); - void blockPT(uint8_t pt); - virtual void parseHeader(); - void parseHeader(webrtc::WebRtcRTPHeader* rtp_header); - const webrtc::WebRtcRTPHeader* RTPinfo() const; - uint8_t * datagram() const; - uint8_t * payload() const; - size_t payloadLen(); - int16_t dataLen() const; - bool isParsed() const; - bool isLost() const; - uint32_t time() const { return _receiveTime; }; - - uint8_t payloadType() const; - uint16_t sequenceNumber() const; - uint32_t timeStamp() const; - uint32_t SSRC() const; - uint8_t markerBit() const; - - int setPayloadType(uint8_t pt); - int setSequenceNumber(uint16_t sn); - int setTimeStamp(uint32_t ts); - int setSSRC(uint32_t ssrc); - int setMarkerBit(uint8_t mb); - void setTime(uint32_t receiveTime) { _receiveTime = receiveTime; }; - - int setRTPheader(const webrtc::WebRtcRTPHeader* RTPinfo); - - int splitStereo(NETEQTEST_RTPpacket* slaveRtp, enum stereoModes mode); - - int extractRED(int index, webrtc::WebRtcRTPHeader& red); - - void scramblePayload(void); - - uint8_t * _datagram; - uint8_t * _payloadPtr; - int _memSize; - int16_t _datagramLen; - size_t _payloadLen; - webrtc::WebRtcRTPHeader _rtpInfo; - bool _rtpParsed; - uint32_t _receiveTime; - bool _lost; - std::map _blockList; - -protected: - static const int _kRDHeaderLen; - static const int _kBasicHeaderLen; - - void parseBasicHeader(webrtc::WebRtcRTPHeader* RTPinfo, int *i_P, int *i_X, - int *i_CC) const; - int calcHeaderLength(int i_X, int i_CC) const; - -private: - void makeRTPheader(unsigned char* rtp_data, uint8_t payloadType, - uint16_t seqNo, uint32_t timestamp, - uint32_t ssrc, uint8_t markerBit) const; - uint16_t parseRTPheader(webrtc::WebRtcRTPHeader* RTPinfo, - uint8_t **payloadPtr = NULL) const; - uint16_t parseRTPheader(uint8_t **payloadPtr = NULL) - { return parseRTPheader(&_rtpInfo, payloadPtr);}; - int calcPadLength(int i_P) const; - void splitStereoSample(NETEQTEST_RTPpacket* slaveRtp, int stride); - void splitStereoFrame(NETEQTEST_RTPpacket* slaveRtp); - void splitStereoDouble(NETEQTEST_RTPpacket* slaveRtp); -}; - -#endif //NETEQTEST_RTPPACKET_H diff --git a/modules/audio_coding/neteq/test/RTPchange.cc b/modules/audio_coding/neteq/test/RTPchange.cc deleted file mode 100644 index 3e900024b8..0000000000 --- a/modules/audio_coding/neteq/test/RTPchange.cc +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include -#include - -#include "modules/audio_coding/neteq/test/NETEQTEST_DummyRTPpacket.h" -#include "modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h" - -#define FIRSTLINELEN 40 -//#define WEBRTC_DUMMY_RTP - -static bool pktCmp(NETEQTEST_RTPpacket *a, NETEQTEST_RTPpacket *b) { - return (a->time() < b->time()); -} - -int main(int argc, char* argv[]) { - FILE* in_file = fopen(argv[1], "rb"); - if (!in_file) { - printf("Cannot open input file %s\n", argv[1]); - return -1; - } - printf("Input RTP file: %s\n", argv[1]); - - FILE* stat_file = fopen(argv[2], "rt"); - if (!stat_file) { - printf("Cannot open timing file %s\n", argv[2]); - return -1; - } - printf("Timing file: %s\n", argv[2]); - - FILE* out_file = fopen(argv[3], "wb"); - if (!out_file) { - printf("Cannot open output file %s\n", argv[3]); - return -1; - } - printf("Output RTP file: %s\n\n", argv[3]); - - // Read all statistics and insert into map. - // Read first line. - char temp_str[100]; - if (fgets(temp_str, 100, stat_file) == NULL) { - printf("Failed to read timing file %s\n", argv[2]); - return -1; - } - // Define map. - std::map, uint32_t> packet_stats; - uint16_t seq_no; - uint32_t ts; - uint32_t send_time; - - while (fscanf(stat_file, - "%hu %u %u %*i %*i\n", &seq_no, &ts, &send_time) == 3) { - std::pair - temp_pair = std::pair(seq_no, ts); - - packet_stats[temp_pair] = send_time; - } - - fclose(stat_file); - - // Read file header and write directly to output file. - char first_line[FIRSTLINELEN]; - if (fgets(first_line, FIRSTLINELEN, in_file) == NULL) { - printf("Failed to read first line of input file %s\n", argv[1]); - return -1; - } - fputs(first_line, out_file); - // start_sec + start_usec + source + port + padding - const unsigned int kRtpDumpHeaderSize = 4 + 4 + 4 + 2 + 2; - if (fread(first_line, 1, kRtpDumpHeaderSize, in_file) - != kRtpDumpHeaderSize) { - printf("Failed to read RTP dump header from input file %s\n", argv[1]); - return -1; - } - if (fwrite(first_line, 1, kRtpDumpHeaderSize, out_file) - != kRtpDumpHeaderSize) { - printf("Failed to write RTP dump header to output file %s\n", argv[3]); - return -1; - } - - std::vector packet_vec; - - while (1) { - // Insert in vector. -#ifdef WEBRTC_DUMMY_RTP - NETEQTEST_RTPpacket *new_packet = new NETEQTEST_DummyRTPpacket(); -#else - NETEQTEST_RTPpacket *new_packet = new NETEQTEST_RTPpacket(); -#endif - if (new_packet->readFromFile(in_file) < 0) { - // End of file. - break; - } - - // Look for new send time in statistics vector. - std::pair temp_pair = - std::pair(new_packet->sequenceNumber(), - new_packet->timeStamp()); - - uint32_t new_send_time = packet_stats[temp_pair]; - new_packet->setTime(new_send_time); // Set new send time. - packet_vec.push_back(new_packet); // Insert in vector. - } - - // Sort the vector according to send times. - std::sort(packet_vec.begin(), packet_vec.end(), pktCmp); - - std::vector::iterator it; - for (it = packet_vec.begin(); it != packet_vec.end(); it++) { - // Write to out file. - if ((*it)->writeToFile(out_file) < 0) { - printf("Error writing to file\n"); - return -1; - } - // Delete packet. - delete *it; - } - - fclose(in_file); - fclose(out_file); - - return 0; -} diff --git a/modules/audio_coding/neteq/test/RTPjitter.cc b/modules/audio_coding/neteq/test/RTPjitter.cc deleted file mode 100644 index ca73292832..0000000000 --- a/modules/audio_coding/neteq/test/RTPjitter.cc +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -//TODO(hlundin): Reformat file to meet style guide. - -/* header includes */ -#include -#include -#include -#include -#ifdef WIN32 -#include -#include -#endif -#ifdef WEBRTC_LINUX -#include -#endif - -#include - -#include "test/gtest.h" -#include "typedefs.h" // NOLINT(build/include) - -/*********************/ -/* Misc. definitions */ -/*********************/ - -#define FIRSTLINELEN 40 -#define CHECK_NOT_NULL(a) if((a)==NULL){ \ - fprintf(stderr,"\n %s \n line: %d \nerror at %s\n",__FILE__,__LINE__,#a ); \ - return(-1);} - -struct arr_time { - float time; - uint32_t ix; -}; - -int filelen(FILE *fid) -{ - fpos_t cur_pos; - int len; - - if (!fid || fgetpos(fid, &cur_pos)) { - return(-1); - } - - fseek(fid, 0, SEEK_END); - len = ftell(fid); - - fsetpos(fid, &cur_pos); - - return (len); -} - -int compare_arr_time(const void *x, const void *y); - -int main(int argc, char* argv[]) -{ - unsigned int dat_len, rtp_len, Npack, k; - arr_time *time_vec; - char firstline[FIRSTLINELEN]; - unsigned char* rtp_vec = NULL; - unsigned char** packet_ptr = NULL; - unsigned char* temp_packet = NULL; - const unsigned int kRtpDumpHeaderSize = 4 + 4 + 4 + 2 + 2; - uint16_t len; - uint32_t *offset; - -/* check number of parameters */ - if (argc != 4) { - /* print help text and exit */ - printf("Apply jitter on RTP stream.\n"); - printf("Reads an RTP stream and packet timing from two files.\n"); - printf("The RTP stream is modified to have the same jitter as described in " - "the timing files.\n"); - printf("The format of the RTP stream file should be the same as for \n"); - printf("rtpplay, and can be obtained e.g., from Ethereal by using\n"); - printf("Statistics -> RTP -> Show All Streams -> [select a stream] -> " - "Save As\n\n"); - printf("Usage:\n\n"); - printf("%s RTP_infile dat_file RTP_outfile\n", argv[0]); - printf("where:\n"); - - printf("RTP_infile : RTP stream input file\n\n"); - - printf("dat_file : file with packet arrival times in ms\n\n"); - - printf("RTP_outfile : RTP stream output file\n\n"); - - return(0); - } - - FILE* in_file=fopen(argv[1],"rb"); - CHECK_NOT_NULL(in_file); - printf("Input file: %s\n",argv[1]); - FILE* dat_file=fopen(argv[2],"rb"); - CHECK_NOT_NULL(dat_file); - printf("Dat-file: %s\n",argv[2]); - FILE* out_file=fopen(argv[3],"wb"); - CHECK_NOT_NULL(out_file); - printf("Output file: %s\n\n",argv[3]); - - // add 1000 bytes to avoid (rare) strange error. - time_vec = (arr_time *) malloc(sizeof(arr_time) - *(filelen(dat_file)/sizeof(float)) + 1000); - if (time_vec==NULL) { - fprintf(stderr, "Error: could not allocate memory for reading dat file\n"); - goto closing; - } - - dat_len=0; - while(fread(&(time_vec[dat_len].time),sizeof(float),1,dat_file)>0) { - time_vec[dat_len].ix=dat_len; - dat_len++; - } - - if (dat_len == 0) { - fprintf(stderr, "Error: dat_file is empty, no arrival time is given.\n"); - goto closing; - } - - qsort(time_vec,dat_len,sizeof(arr_time),compare_arr_time); - - - rtp_vec = (unsigned char *) malloc(sizeof(unsigned char)*filelen(in_file)); - if (rtp_vec==NULL) { - fprintf(stderr,"Error: could not allocate memory for reading rtp file\n"); - goto closing; - } - - // read file header and write directly to output file - EXPECT_TRUE(fgets(firstline, FIRSTLINELEN, in_file) != NULL); - EXPECT_GT(fputs(firstline, out_file), 0); - EXPECT_EQ(kRtpDumpHeaderSize, fread(firstline, 1, kRtpDumpHeaderSize, - in_file)); - EXPECT_EQ(kRtpDumpHeaderSize, fwrite(firstline, 1, kRtpDumpHeaderSize, - out_file)); - - // read all RTP packets into vector - rtp_len=0; - Npack=0; - - // read length of first packet. - len=(uint16_t) fread(&rtp_vec[rtp_len], sizeof(unsigned char), 2, in_file); - while(len==2) { - len = ntohs(*((uint16_t *)(rtp_vec + rtp_len))); - rtp_len += 2; - if(fread(&rtp_vec[rtp_len], sizeof(unsigned char), - len-2, in_file)!=(unsigned) (len-2)) { - fprintf(stderr,"Error: currupt packet length\n"); - goto closing; - } - rtp_len += len-2; - Npack++; - - // read length of next packet. - len=(uint16_t) fread(&rtp_vec[rtp_len], sizeof(unsigned char), 2, in_file); - } - - if (Npack == 0) { - fprintf(stderr, "Error: No RTP packet found.\n"); - goto closing; - } - - packet_ptr = (unsigned char **) malloc(Npack*sizeof(unsigned char*)); - - packet_ptr[0]=rtp_vec; - k=1; - while(k= 0 ) { - *offset = htonl((uint32_t) time_vec[k].time); - } - else { - *offset = htonl((uint32_t) 0); - fprintf(stderr, "Warning: negative receive time in dat file transformed" - " to 0.\n"); - } - - // write packet to file - if (fwrite(temp_packet, sizeof(unsigned char), - ntohs(*((uint16_t*) temp_packet)), - out_file) != - ntohs(*((uint16_t*) temp_packet))) { - return -1; - } - } - } - - -closing: - free(time_vec); - free(rtp_vec); - if (packet_ptr != NULL) { - free(packet_ptr); - } - fclose(in_file); - fclose(dat_file); - fclose(out_file); - - return(0); -} - - - -int compare_arr_time(const void *xp, const void *yp) { - - if(((arr_time *)xp)->time == ((arr_time *)yp)->time) - return(0); - else if(((arr_time *)xp)->time > ((arr_time *)yp)->time) - return(1); - - return(-1); -} diff --git a/modules/audio_coding/neteq/test/RTPtimeshift.cc b/modules/audio_coding/neteq/test/RTPtimeshift.cc deleted file mode 100644 index a2429f1033..0000000000 --- a/modules/audio_coding/neteq/test/RTPtimeshift.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h" -#include "test/gtest.h" - -#define FIRSTLINELEN 40 - -int main(int argc, char* argv[]) { - if (argc < 4 || argc > 6) { - printf( - "Usage: RTPtimeshift in.rtp out.rtp newStartTS [newStartSN " - "[newStartArrTime]]\n"); - exit(1); - } - - FILE* inFile = fopen(argv[1], "rb"); - if (!inFile) { - printf("Cannot open input file %s\n", argv[1]); - return (-1); - } - printf("Input RTP file: %s\n", argv[1]); - - FILE* outFile = fopen(argv[2], "wb"); - if (!outFile) { - printf("Cannot open output file %s\n", argv[2]); - return (-1); - } - printf("Output RTP file: %s\n\n", argv[2]); - - // Read file header and write directly to output file. - const unsigned int kRtpDumpHeaderSize = 4 + 4 + 4 + 2 + 2; - char firstline[FIRSTLINELEN]; - EXPECT_TRUE(fgets(firstline, FIRSTLINELEN, inFile) != NULL); - EXPECT_GT(fputs(firstline, outFile), 0); - EXPECT_EQ(kRtpDumpHeaderSize, - fread(firstline, 1, kRtpDumpHeaderSize, inFile)); - EXPECT_EQ(kRtpDumpHeaderSize, - fwrite(firstline, 1, kRtpDumpHeaderSize, outFile)); - NETEQTEST_RTPpacket packet; - int packLen = packet.readFromFile(inFile); - if (packLen < 0) { - exit(1); - } - - // Get new start TS and start SeqNo from arguments. - uint32_t TSdiff = atoi(argv[3]) - packet.timeStamp(); - uint16_t SNdiff = 0; - uint32_t ATdiff = 0; - if (argc > 4) { - int startSN = atoi(argv[4]); - if (startSN >= 0) - SNdiff = startSN - packet.sequenceNumber(); - if (argc > 5) { - int startTS = atoi(argv[5]); - if (startTS >= 0) - ATdiff = startTS - packet.time(); - } - } - - while (packLen >= 0) { - packet.setTimeStamp(packet.timeStamp() + TSdiff); - packet.setSequenceNumber(packet.sequenceNumber() + SNdiff); - packet.setTime(packet.time() + ATdiff); - - packet.writeToFile(outFile); - - packLen = packet.readFromFile(inFile); - } - - fclose(inFile); - fclose(outFile); - - return 0; -} diff --git a/modules/audio_coding/neteq/tools/rtp_jitter.cc b/modules/audio_coding/neteq/tools/rtp_jitter.cc new file mode 100644 index 0000000000..d92fed06cf --- /dev/null +++ b/modules/audio_coding/neteq/tools/rtp_jitter.cc @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include +#include +#include +#include +#include + +#include "api/array_view.h" +#include "modules/rtp_rtcp/source/byte_io.h" +#include "rtc_base/buffer.h" +#include "rtc_base/flags.h" +#include "typedefs.h" // NOLINT(build/include) + +namespace webrtc { +namespace test { +namespace { + +DEFINE_bool(help, false, "Print help message"); + +constexpr size_t kRtpDumpHeaderLength = 8; + +// Returns the next packet or an empty buffer if end of file was encountered. +rtc::Buffer ReadNextPacket(FILE* file) { + // Read the rtpdump header for the next packet. + rtc::Buffer buffer; + buffer.SetData(kRtpDumpHeaderLength, [&](rtc::ArrayView x) { + return fread(x.data(), 1, x.size(), file); + }); + if (buffer.size() != kRtpDumpHeaderLength) { + return rtc::Buffer(); + } + + // Get length field. This is the total length for this packet written to file, + // including the kRtpDumpHeaderLength bytes already read. + const uint16_t len = ByteReader::ReadBigEndian(buffer.data()); + RTC_CHECK_GE(len, kRtpDumpHeaderLength); + + // Read remaining data from file directly into buffer. + buffer.AppendData(len - kRtpDumpHeaderLength, [&](rtc::ArrayView x) { + return fread(x.data(), 1, x.size(), file); + }); + if (buffer.size() != len) { + buffer.Clear(); + } + return buffer; +} + +struct PacketAndTime { + rtc::Buffer packet; + int time; +}; + +void WritePacket(const PacketAndTime& packet, FILE* file) { + // Write the first 4 bytes from the original packet. + const auto* payload_ptr = packet.packet.data(); + RTC_CHECK_EQ(fwrite(payload_ptr, 4, 1, file), 1); + payload_ptr += 4; + + // Convert the new time offset to network endian, and write to file. + uint8_t time[sizeof(uint32_t)]; + ByteWriter::WriteBigEndian(time, packet.time); + RTC_CHECK_EQ(fwrite(time, sizeof(uint32_t), 1, file), 1); + payload_ptr += 4; // Skip the old time in the original payload. + + // Write the remaining part of the payload. + RTC_DCHECK_EQ(payload_ptr - packet.packet.data(), kRtpDumpHeaderLength); + RTC_CHECK_EQ( + fwrite(payload_ptr, packet.packet.size() - kRtpDumpHeaderLength, 1, file), + 1); +} + +int RunRtpJitter(int argc, char* argv[]) { + const std::string program_name = argv[0]; + const std::string usage = + "Tool for alternating the arrival times in an RTP dump file.\n" + "Example usage:\n" + + program_name + " input.rtp arrival_times_ms.txt output.rtp\n\n"; + if (rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, true) || FLAG_help || + argc != 4) { + printf("%s", usage.c_str()); + return FLAG_help ? 0 : 1; + } + + printf("Input RTP file: %s\n", argv[1]); + FILE* in_file = fopen(argv[1], "rb"); + RTC_CHECK(in_file) << "Could not open file " << argv[1] << " for reading"; + printf("Timing file: %s\n", argv[2]); + std::ifstream timing_file(argv[2]); + printf("Output file: %s\n", argv[3]); + FILE* out_file = fopen(argv[3], "wb"); + RTC_CHECK(out_file) << "Could not open file " << argv[2] << " for writing"; + + // Copy the RTP file header to the output file. + char header_string[30]; + RTC_CHECK(fgets(header_string, 30, in_file)); + fprintf(out_file, "%s", header_string); + uint8_t file_header[16]; + RTC_CHECK_EQ(fread(file_header, sizeof(file_header), 1, in_file), 1); + RTC_CHECK_EQ(fwrite(file_header, sizeof(file_header), 1, out_file), 1); + + // Read all time values from the timing file. Store in a vector. + std::vector new_arrival_times; + int new_time; + while (timing_file >> new_time) { + new_arrival_times.push_back(new_time); + } + + // Read all packets from the input RTP file, but no more than the number of + // new time values. Store RTP packets together with new time values. + auto time_it = new_arrival_times.begin(); + std::vector packets; + while (1) { + auto packet = ReadNextPacket(in_file); + if (packet.empty() || time_it == new_arrival_times.end()) { + break; + } + packets.push_back({std::move(packet), *time_it}); + ++time_it; + } + + // Sort on new time values. + std::sort(packets.begin(), packets.end(), + [](const PacketAndTime& a, const PacketAndTime& b) { + return a.time < b.time; + }); + + // Write packets to output file. + for (const auto& p : packets) { + WritePacket(p, out_file); + } + + fclose(in_file); + fclose(out_file); + return 0; +} + +} // namespace +} // namespace test +} // namespace webrtc + +int main(int argc, char* argv[]) { + return webrtc::test::RunRtpJitter(argc, argv); +}