767 lines
16 KiB
C++
767 lines
16 KiB
C++
|
/*
|
||
|
* 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 "NETEQTEST_RTPpacket.h"
|
||
|
|
||
|
#include <string.h>
|
||
|
|
||
|
#ifdef WIN32
|
||
|
#include <winsock2.h>
|
||
|
#else
|
||
|
#include <netinet/in.h> // for htons, htonl, etc
|
||
|
#endif
|
||
|
|
||
|
#define HDR_SIZE 8 // rtpplay packet header size in bytes
|
||
|
|
||
|
|
||
|
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(const NETEQTEST_RTPpacket& copyFromMe)
|
||
|
{
|
||
|
|
||
|
memcpy(this, ©FromMe, sizeof(NETEQTEST_RTPpacket));
|
||
|
|
||
|
_datagram = NULL;
|
||
|
_payloadPtr = NULL;
|
||
|
|
||
|
if(copyFromMe._datagram)
|
||
|
{
|
||
|
_datagram = new WebRtc_UWord8[_memSize];
|
||
|
|
||
|
if(_datagram)
|
||
|
{
|
||
|
memcpy(_datagram, copyFromMe._datagram, _memSize);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(copyFromMe._payloadPtr)
|
||
|
{
|
||
|
_payloadPtr = _datagram + (copyFromMe._payloadPtr - copyFromMe._datagram);
|
||
|
}
|
||
|
|
||
|
_blockList = copyFromMe._blockList;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
NETEQTEST_RTPpacket & NETEQTEST_RTPpacket::operator = (const NETEQTEST_RTPpacket & other)
|
||
|
{
|
||
|
if (this != &other) // protect against invalid self-assignment
|
||
|
{
|
||
|
|
||
|
// deallocate datagram memory if allocated
|
||
|
if(_datagram)
|
||
|
{
|
||
|
delete[] _datagram;
|
||
|
}
|
||
|
|
||
|
// do shallow copy
|
||
|
memcpy(this, &other, sizeof(NETEQTEST_RTPpacket));
|
||
|
|
||
|
// reset pointers
|
||
|
_datagram = NULL;
|
||
|
_payloadPtr = NULL;
|
||
|
|
||
|
if(other._datagram)
|
||
|
{
|
||
|
_datagram = new WebRtc_UWord8[other._memSize];
|
||
|
_memSize = other._memSize;
|
||
|
|
||
|
if(_datagram)
|
||
|
{
|
||
|
memcpy(_datagram, other._datagram, _memSize);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(other._payloadPtr)
|
||
|
{
|
||
|
_payloadPtr = _datagram + (other._payloadPtr - other._datagram);
|
||
|
}
|
||
|
|
||
|
// copy the blocking list (map)
|
||
|
_blockList = other._blockList;
|
||
|
|
||
|
}
|
||
|
|
||
|
// by convention, always return *this
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
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::readFromFile(FILE *fp)
|
||
|
{
|
||
|
if(!fp)
|
||
|
{
|
||
|
return(-1);
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord16 length, plen;
|
||
|
WebRtc_UWord32 offset;
|
||
|
|
||
|
if (fread(&length,2,1,fp)==0)
|
||
|
{
|
||
|
reset();
|
||
|
return(-2);
|
||
|
}
|
||
|
length = ntohs(length);
|
||
|
|
||
|
if (fread(&plen,2,1,fp)==0)
|
||
|
{
|
||
|
reset();
|
||
|
return(-1);
|
||
|
}
|
||
|
int packetLen = ntohs(plen);
|
||
|
|
||
|
if (fread(&offset,4,1,fp)==0)
|
||
|
{
|
||
|
reset();
|
||
|
return(-1);
|
||
|
}
|
||
|
WebRtc_UWord32 receiveTime = ntohl(offset); // store in local variable until we have passed the reset below
|
||
|
|
||
|
// Use length here because a plen of 0 specifies rtcp
|
||
|
length = (WebRtc_UWord16) (length - HDR_SIZE);
|
||
|
|
||
|
// check buffer size
|
||
|
if (_datagram && _memSize < length)
|
||
|
{
|
||
|
reset();
|
||
|
}
|
||
|
|
||
|
if (!_datagram)
|
||
|
{
|
||
|
_datagram = new WebRtc_UWord8[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)
|
||
|
{
|
||
|
// discard this payload
|
||
|
return(readFromFile(fp));
|
||
|
}
|
||
|
|
||
|
return(packetLen);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
int NETEQTEST_RTPpacket::readFixedFromFile(FILE *fp, int length)
|
||
|
{
|
||
|
if(!fp)
|
||
|
{
|
||
|
return(-1);
|
||
|
}
|
||
|
|
||
|
// check buffer size
|
||
|
if (_datagram && _memSize < length)
|
||
|
{
|
||
|
reset();
|
||
|
}
|
||
|
|
||
|
if (!_datagram)
|
||
|
{
|
||
|
_datagram = new WebRtc_UWord8[length];
|
||
|
_memSize = length;
|
||
|
}
|
||
|
|
||
|
if (fread((unsigned short *) _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));
|
||
|
}
|
||
|
|
||
|
return(length);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
int NETEQTEST_RTPpacket::writeToFile(FILE *fp)
|
||
|
{
|
||
|
if(!fp)
|
||
|
{
|
||
|
return(-1);
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord16 length, plen;
|
||
|
WebRtc_UWord32 offset;
|
||
|
|
||
|
// length including RTPplay header
|
||
|
length = htons(_datagramLen + HDR_SIZE);
|
||
|
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((unsigned short *) _datagram, 1, _datagramLen, fp) != _datagramLen)
|
||
|
{
|
||
|
return(-1);
|
||
|
}
|
||
|
|
||
|
return(_datagramLen + HDR_SIZE); // total number of bytes written
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void NETEQTEST_RTPpacket::blockPT(WebRtc_UWord8 pt)
|
||
|
{
|
||
|
_blockList[pt] = true;
|
||
|
}
|
||
|
|
||
|
|
||
|
void NETEQTEST_RTPpacket::parseHeader()
|
||
|
{
|
||
|
if (_rtpParsed)
|
||
|
{
|
||
|
// nothing to do
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (_datagramLen < 12)
|
||
|
{
|
||
|
// corrupt packet?
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
_payloadLen = parseRTPheader(_datagram, _datagramLen, &_rtpInfo, &_payloadPtr);
|
||
|
|
||
|
_rtpParsed = true;
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
void NETEQTEST_RTPpacket::parseHeader(WebRtcNetEQ_RTPInfo & rtpInfo)
|
||
|
{
|
||
|
if (!_rtpParsed)
|
||
|
{
|
||
|
// parse the header
|
||
|
parseHeader();
|
||
|
}
|
||
|
|
||
|
memcpy(&rtpInfo, &_rtpInfo, sizeof(WebRtcNetEQ_RTPInfo));
|
||
|
}
|
||
|
|
||
|
WebRtcNetEQ_RTPInfo const * NETEQTEST_RTPpacket::RTPinfo() const
|
||
|
{
|
||
|
if (_rtpParsed)
|
||
|
{
|
||
|
return &_rtpInfo;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord8 * NETEQTEST_RTPpacket::datagram() const
|
||
|
{
|
||
|
if (_datagramLen > 0)
|
||
|
{
|
||
|
return _datagram;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord8 * NETEQTEST_RTPpacket::payload() const
|
||
|
{
|
||
|
if (_payloadLen > 0)
|
||
|
{
|
||
|
return _payloadPtr;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
WebRtc_Word16 NETEQTEST_RTPpacket::payloadLen() const
|
||
|
{
|
||
|
return _payloadLen;
|
||
|
}
|
||
|
|
||
|
WebRtc_Word16 NETEQTEST_RTPpacket::dataLen() const
|
||
|
{
|
||
|
return _datagramLen;
|
||
|
}
|
||
|
|
||
|
bool NETEQTEST_RTPpacket::isParsed() const
|
||
|
{
|
||
|
return _rtpParsed;
|
||
|
}
|
||
|
|
||
|
bool NETEQTEST_RTPpacket::isLost() const
|
||
|
{
|
||
|
return _lost;
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord8 NETEQTEST_RTPpacket::payloadType() const
|
||
|
{
|
||
|
WebRtcNetEQ_RTPInfo tempRTPinfo;
|
||
|
|
||
|
if(_datagram)
|
||
|
{
|
||
|
parseRTPheader(_datagram, _datagramLen, &tempRTPinfo);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return tempRTPinfo.payloadType;
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord16 NETEQTEST_RTPpacket::sequenceNumber() const
|
||
|
{
|
||
|
WebRtcNetEQ_RTPInfo tempRTPinfo;
|
||
|
|
||
|
if(_datagram)
|
||
|
{
|
||
|
parseRTPheader(_datagram, _datagramLen, &tempRTPinfo);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return tempRTPinfo.sequenceNumber;
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord32 NETEQTEST_RTPpacket::timeStamp() const
|
||
|
{
|
||
|
WebRtcNetEQ_RTPInfo tempRTPinfo;
|
||
|
|
||
|
if(_datagram)
|
||
|
{
|
||
|
parseRTPheader(_datagram, _datagramLen, &tempRTPinfo);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return tempRTPinfo.timeStamp;
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord32 NETEQTEST_RTPpacket::SSRC() const
|
||
|
{
|
||
|
WebRtcNetEQ_RTPInfo tempRTPinfo;
|
||
|
|
||
|
if(_datagram)
|
||
|
{
|
||
|
parseRTPheader(_datagram, _datagramLen, &tempRTPinfo);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return tempRTPinfo.SSRC;
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord8 NETEQTEST_RTPpacket::markerBit() const
|
||
|
{
|
||
|
WebRtcNetEQ_RTPInfo tempRTPinfo;
|
||
|
|
||
|
if(_datagram)
|
||
|
{
|
||
|
parseRTPheader(_datagram, _datagramLen, &tempRTPinfo);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return tempRTPinfo.markerBit;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
int NETEQTEST_RTPpacket::setPayloadType(WebRtc_UWord8 pt)
|
||
|
{
|
||
|
|
||
|
if (_datagramLen < 12)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (!_rtpParsed)
|
||
|
{
|
||
|
_rtpInfo.payloadType = pt;
|
||
|
}
|
||
|
|
||
|
_datagram[1]=(unsigned char)(pt & 0xFF);
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
int NETEQTEST_RTPpacket::setSequenceNumber(WebRtc_UWord16 sn)
|
||
|
{
|
||
|
|
||
|
if (_datagramLen < 12)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (!_rtpParsed)
|
||
|
{
|
||
|
_rtpInfo.sequenceNumber = sn;
|
||
|
}
|
||
|
|
||
|
_datagram[2]=(unsigned char)((sn>>8)&0xFF);
|
||
|
_datagram[3]=(unsigned char)((sn)&0xFF);
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
int NETEQTEST_RTPpacket::setTimeStamp(WebRtc_UWord32 ts)
|
||
|
{
|
||
|
|
||
|
if (_datagramLen < 12)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (!_rtpParsed)
|
||
|
{
|
||
|
_rtpInfo.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(WebRtc_UWord32 ssrc)
|
||
|
{
|
||
|
|
||
|
if (_datagramLen < 12)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (!_rtpParsed)
|
||
|
{
|
||
|
_rtpInfo.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(WebRtc_UWord8 mb)
|
||
|
{
|
||
|
|
||
|
if (_datagramLen < 12)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (_rtpParsed)
|
||
|
{
|
||
|
_rtpInfo.markerBit = mb;
|
||
|
}
|
||
|
|
||
|
if (mb)
|
||
|
{
|
||
|
_datagram[0] |= 0x01;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_datagram[0] &= 0xFE;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
int NETEQTEST_RTPpacket::setRTPheader(const WebRtcNetEQ_RTPInfo *RTPinfo)
|
||
|
{
|
||
|
if (_datagramLen < 12)
|
||
|
{
|
||
|
// this packet is not ok
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
makeRTPheader(_datagram,
|
||
|
RTPinfo->payloadType,
|
||
|
RTPinfo->sequenceNumber,
|
||
|
RTPinfo->timeStamp,
|
||
|
RTPinfo->SSRC,
|
||
|
RTPinfo->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;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
void NETEQTEST_RTPpacket::makeRTPheader(unsigned char* rtp_data, WebRtc_UWord8 payloadType, WebRtc_UWord16 seqNo, WebRtc_UWord32 timestamp, WebRtc_UWord32 ssrc, WebRtc_UWord8 markerBit) const
|
||
|
{
|
||
|
rtp_data[0]=(unsigned char)0x80;
|
||
|
if (markerBit)
|
||
|
{
|
||
|
rtp_data[0] |= 0x01;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rtp_data[0] &= 0xFE;
|
||
|
}
|
||
|
rtp_data[1]=(unsigned char)(payloadType & 0xFF);
|
||
|
rtp_data[2]=(unsigned char)((seqNo>>8)&0xFF);
|
||
|
rtp_data[3]=(unsigned char)((seqNo)&0xFF);
|
||
|
rtp_data[4]=(unsigned char)((timestamp>>24)&0xFF);
|
||
|
rtp_data[5]=(unsigned char)((timestamp>>16)&0xFF);
|
||
|
|
||
|
rtp_data[6]=(unsigned char)((timestamp>>8)&0xFF);
|
||
|
rtp_data[7]=(unsigned char)(timestamp & 0xFF);
|
||
|
|
||
|
rtp_data[8]=(unsigned char)((ssrc>>24)&0xFF);
|
||
|
rtp_data[9]=(unsigned char)((ssrc>>16)&0xFF);
|
||
|
|
||
|
rtp_data[10]=(unsigned char)((ssrc>>8)&0xFF);
|
||
|
rtp_data[11]=(unsigned char)(ssrc & 0xFF);
|
||
|
}
|
||
|
|
||
|
|
||
|
WebRtc_UWord16 NETEQTEST_RTPpacket::parseRTPheader(const WebRtc_UWord8 *datagram, int datagramLen, WebRtcNetEQ_RTPInfo *RTPinfo, WebRtc_UWord8 **payloadPtr) const
|
||
|
{
|
||
|
WebRtc_Word16 *rtp_data = (WebRtc_Word16 *) datagram;
|
||
|
int i_P, i_X, i_CC, i_extlength=-1, i_padlength=0, i_startPosition;
|
||
|
|
||
|
i_P=(((WebRtc_UWord16)(rtp_data[0] & 0x20))>>5); /* Extract the P bit */
|
||
|
i_X=(((WebRtc_UWord16)(rtp_data[0] & 0x10))>>4); /* Extract the X bit */
|
||
|
i_CC=(WebRtc_UWord16)(rtp_data[0] & 0xF); /* Get the CC number */
|
||
|
RTPinfo->markerBit = (WebRtc_UWord8) ((rtp_data[0] >> 15) & 0x01); /* Get the marker bit */
|
||
|
RTPinfo->payloadType = (WebRtc_UWord8) ((rtp_data[0] >> 8) & 0x7F); /* Get the coder type */
|
||
|
RTPinfo->sequenceNumber = ((( ((WebRtc_UWord16)rtp_data[1]) >> 8) & 0xFF) |
|
||
|
( ((WebRtc_UWord16)(rtp_data[1] & 0xFF)) << 8)); /* Get the packet number */
|
||
|
RTPinfo->timeStamp = ((((WebRtc_UWord16)rtp_data[2]) & 0xFF) << 24) |
|
||
|
((((WebRtc_UWord16)rtp_data[2]) & 0xFF00) << 8) |
|
||
|
((((WebRtc_UWord16)rtp_data[3]) >> 8) & 0xFF) |
|
||
|
((((WebRtc_UWord16)rtp_data[3]) & 0xFF) << 8); /* Get timestamp */
|
||
|
RTPinfo->SSRC=((((WebRtc_UWord16)rtp_data[4]) & 0xFF) << 24) |
|
||
|
((((WebRtc_UWord16)rtp_data[4]) & 0xFF00) << 8) |
|
||
|
((((WebRtc_UWord16)rtp_data[5]) >> 8) & 0xFF) |
|
||
|
((((WebRtc_UWord16)rtp_data[5]) & 0xFF) << 8); /* Get the SSRC */
|
||
|
|
||
|
if (i_X==1) {
|
||
|
/* Extention header exists. Find out how many WebRtc_Word32 it consists of */
|
||
|
i_extlength=((( ((WebRtc_UWord16)rtp_data[7+2*i_CC]) >> 8) & 0xFF) |
|
||
|
( ((WebRtc_UWord16)(rtp_data[7+2*i_CC]&0xFF)) << 8));
|
||
|
}
|
||
|
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 */
|
||
|
i_padlength=(rtp_data[datagramLen>>1] & 0xFF);
|
||
|
} else {
|
||
|
/* even number of bytes => last byte in lower byte */
|
||
|
i_padlength=(((WebRtc_UWord16)rtp_data[(datagramLen>>1)-1]) >> 8);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
i_startPosition=12+4*(i_extlength+1)+4*i_CC;
|
||
|
|
||
|
if (payloadPtr) {
|
||
|
*payloadPtr = (WebRtc_UWord8*) &rtp_data[i_startPosition>>1];
|
||
|
}
|
||
|
|
||
|
return (WebRtc_UWord16) (datagramLen-i_startPosition-i_padlength);
|
||
|
}
|
||
|
|
||
|
//void NETEQTEST_RTPpacket::splitStereoSample(WebRtc_UWord8 *data, WebRtc_UWord16 *lenBytes, WebRtc_UWord8 *slaveData, WebRtc_UWord16 *slaveLenBytes, int stride)
|
||
|
void NETEQTEST_RTPpacket::splitStereoSample(NETEQTEST_RTPpacket& slaveRtp, int stride)
|
||
|
{
|
||
|
if(!_payloadPtr || !slaveRtp._payloadPtr
|
||
|
|| _payloadLen <= 0 || slaveRtp._memSize < _memSize)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord8 *readDataPtr = _payloadPtr;
|
||
|
WebRtc_UWord8 *writeDataPtr = _payloadPtr;
|
||
|
WebRtc_UWord8 *slaveData = slaveRtp._payloadPtr;
|
||
|
|
||
|
while (readDataPtr - _payloadPtr < _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(WebRtc_UWord8 *data, WebRtc_UWord16 *lenBytes, WebRtc_UWord8 *slaveData, WebRtc_UWord16 *slaveLenBytes)
|
||
|
void NETEQTEST_RTPpacket::splitStereoFrame(NETEQTEST_RTPpacket& slaveRtp)
|
||
|
{
|
||
|
if(!_payloadPtr || !slaveRtp._payloadPtr
|
||
|
|| _payloadLen <= 0 || slaveRtp._memSize < _memSize)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
memmove(slaveRtp._payloadPtr, _payloadPtr + _payloadLen/2, _payloadLen/2);
|
||
|
|
||
|
_payloadLen /= 2;
|
||
|
slaveRtp._payloadLen = _payloadLen;
|
||
|
}
|
||
|
|