Home | History | Annotate | Download | only in test
      1 /*
      2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "NETEQTEST_RTPpacket.h"
     12 
     13 #include <assert.h>
     14 #include <stdlib.h>  // rand
     15 #include <string.h>
     16 
     17 #ifdef WIN32
     18 #include <winsock2.h>
     19 #else
     20 #include <netinet/in.h> // for htons, htonl, etc
     21 #endif
     22 
     23 const int NETEQTEST_RTPpacket::_kRDHeaderLen = 8;
     24 const int NETEQTEST_RTPpacket::_kBasicHeaderLen = 12;
     25 
     26 NETEQTEST_RTPpacket::NETEQTEST_RTPpacket()
     27 :
     28 _datagram(NULL),
     29 _payloadPtr(NULL),
     30 _memSize(0),
     31 _datagramLen(-1),
     32 _payloadLen(0),
     33 _rtpParsed(false),
     34 _receiveTime(0),
     35 _lost(false)
     36 {
     37     memset(&_rtpInfo, 0, sizeof(_rtpInfo));
     38     _blockList.clear();
     39 }
     40 
     41 NETEQTEST_RTPpacket::~NETEQTEST_RTPpacket()
     42 {
     43     if(_datagram)
     44     {
     45         delete [] _datagram;
     46     }
     47 }
     48 
     49 void NETEQTEST_RTPpacket::reset()
     50 {
     51     if(_datagram) {
     52         delete [] _datagram;
     53     }
     54     _datagram = NULL;
     55     _memSize = 0;
     56     _datagramLen = -1;
     57     _payloadLen = 0;
     58     _payloadPtr = NULL;
     59     _receiveTime = 0;
     60     memset(&_rtpInfo, 0, sizeof(_rtpInfo));
     61     _rtpParsed = false;
     62 
     63 }
     64 
     65 int NETEQTEST_RTPpacket::skipFileHeader(FILE *fp)
     66 {
     67     if (!fp) {
     68         return -1;
     69     }
     70 
     71     const int kFirstLineLength = 40;
     72     char firstline[kFirstLineLength];
     73     if (fgets(firstline, kFirstLineLength, fp) == NULL) {
     74         return -1;
     75     }
     76     if (strncmp(firstline, "#!rtpplay", 9) == 0) {
     77         if (strncmp(firstline, "#!rtpplay1.0", 12) != 0) {
     78             return -1;
     79         }
     80     }
     81     else if (strncmp(firstline, "#!RTPencode", 11) == 0) {
     82         if (strncmp(firstline, "#!RTPencode1.0", 14) != 0) {
     83             return -1;
     84         }
     85     }
     86     else
     87     {
     88         return -1;
     89     }
     90 
     91     const int kRtpDumpHeaderSize = 4 + 4 + 4 + 2 + 2;
     92     if (fseek(fp, kRtpDumpHeaderSize, SEEK_CUR) != 0)
     93     {
     94         return -1;
     95     }
     96     return 0;
     97 }
     98 
     99 int NETEQTEST_RTPpacket::readFromFile(FILE *fp)
    100 {
    101     if(!fp)
    102     {
    103         return(-1);
    104     }
    105 
    106     uint16_t length, plen;
    107     uint32_t offset;
    108     int packetLen = 0;
    109 
    110     bool readNextPacket = true;
    111     while (readNextPacket) {
    112         readNextPacket = false;
    113         if (fread(&length,2,1,fp)==0)
    114         {
    115             reset();
    116             return(-2);
    117         }
    118         length = ntohs(length);
    119 
    120         if (fread(&plen,2,1,fp)==0)
    121         {
    122             reset();
    123             return(-1);
    124         }
    125         packetLen = ntohs(plen);
    126 
    127         if (fread(&offset,4,1,fp)==0)
    128         {
    129             reset();
    130             return(-1);
    131         }
    132         // store in local variable until we have passed the reset below
    133         uint32_t receiveTime = ntohl(offset);
    134 
    135         // Use length here because a plen of 0 specifies rtcp
    136         length = (uint16_t) (length - _kRDHeaderLen);
    137 
    138         // check buffer size
    139         if (_datagram && _memSize < length)
    140         {
    141             reset();
    142         }
    143 
    144         if (!_datagram)
    145         {
    146             _datagram = new uint8_t[length];
    147             _memSize = length;
    148         }
    149 
    150         if (fread((unsigned short *) _datagram,1,length,fp) != length)
    151         {
    152             reset();
    153             return(-1);
    154         }
    155 
    156         _datagramLen = length;
    157         _receiveTime = receiveTime;
    158 
    159         if (!_blockList.empty() && _blockList.count(payloadType()) > 0)
    160         {
    161             readNextPacket = true;
    162         }
    163     }
    164 
    165     _rtpParsed = false;
    166     return(packetLen);
    167 
    168 }
    169 
    170 
    171 int NETEQTEST_RTPpacket::readFixedFromFile(FILE *fp, size_t length)
    172 {
    173     if (!fp)
    174     {
    175         return -1;
    176     }
    177 
    178     // check buffer size
    179     if (_datagram && _memSize < static_cast<int>(length))
    180     {
    181         reset();
    182     }
    183 
    184     if (!_datagram)
    185     {
    186         _datagram = new uint8_t[length];
    187         _memSize = length;
    188     }
    189 
    190     if (fread(_datagram, 1, length, fp) != length)
    191     {
    192         reset();
    193         return -1;
    194     }
    195 
    196     _datagramLen = length;
    197     _receiveTime = 0;
    198 
    199     if (!_blockList.empty() && _blockList.count(payloadType()) > 0)
    200     {
    201         // discard this payload
    202         return readFromFile(fp);
    203     }
    204 
    205     _rtpParsed = false;
    206     return length;
    207 
    208 }
    209 
    210 
    211 int NETEQTEST_RTPpacket::writeToFile(FILE *fp)
    212 {
    213     if (!fp)
    214     {
    215         return -1;
    216     }
    217 
    218     uint16_t length, plen;
    219     uint32_t offset;
    220 
    221     // length including RTPplay header
    222     length = htons(_datagramLen + _kRDHeaderLen);
    223     if (fwrite(&length, 2, 1, fp) != 1)
    224     {
    225         return -1;
    226     }
    227 
    228     // payload length
    229     plen = htons(_datagramLen);
    230     if (fwrite(&plen, 2, 1, fp) != 1)
    231     {
    232         return -1;
    233     }
    234 
    235     // offset (=receive time)
    236     offset = htonl(_receiveTime);
    237     if (fwrite(&offset, 4, 1, fp) != 1)
    238     {
    239         return -1;
    240     }
    241 
    242 
    243     // write packet data
    244     if (fwrite(_datagram, 1, _datagramLen, fp) !=
    245             static_cast<size_t>(_datagramLen))
    246     {
    247         return -1;
    248     }
    249 
    250     return _datagramLen + _kRDHeaderLen; // total number of bytes written
    251 
    252 }
    253 
    254 
    255 void NETEQTEST_RTPpacket::blockPT(uint8_t pt)
    256 {
    257     _blockList[pt] = true;
    258 }
    259 
    260 
    261 void NETEQTEST_RTPpacket::parseHeader()
    262 {
    263     if (_rtpParsed)
    264     {
    265         // nothing to do
    266         return;
    267     }
    268 
    269     if (_datagramLen < _kBasicHeaderLen)
    270     {
    271         // corrupt packet?
    272         return;
    273     }
    274 
    275     _payloadLen = parseRTPheader(&_payloadPtr);
    276 
    277     _rtpParsed = true;
    278 
    279     return;
    280 
    281 }
    282 
    283 void NETEQTEST_RTPpacket::parseHeader(webrtc::WebRtcRTPHeader* rtp_header) {
    284   if (!_rtpParsed) {
    285     parseHeader();
    286   }
    287   if (rtp_header) {
    288     rtp_header->header.markerBit = _rtpInfo.header.markerBit;
    289     rtp_header->header.payloadType = _rtpInfo.header.payloadType;
    290     rtp_header->header.sequenceNumber = _rtpInfo.header.sequenceNumber;
    291     rtp_header->header.timestamp = _rtpInfo.header.timestamp;
    292     rtp_header->header.ssrc = _rtpInfo.header.ssrc;
    293   }
    294 }
    295 
    296 const webrtc::WebRtcRTPHeader* NETEQTEST_RTPpacket::RTPinfo() const
    297 {
    298     if (_rtpParsed)
    299     {
    300         return &_rtpInfo;
    301     }
    302     else
    303     {
    304         return NULL;
    305     }
    306 }
    307 
    308 uint8_t * NETEQTEST_RTPpacket::datagram() const
    309 {
    310     if (_datagramLen > 0)
    311     {
    312         return _datagram;
    313     }
    314     else
    315     {
    316         return NULL;
    317     }
    318 }
    319 
    320 uint8_t * NETEQTEST_RTPpacket::payload() const
    321 {
    322     if (_payloadLen > 0)
    323     {
    324         return _payloadPtr;
    325     }
    326     else
    327     {
    328         return NULL;
    329     }
    330 }
    331 
    332 int16_t NETEQTEST_RTPpacket::payloadLen()
    333 {
    334     parseHeader();
    335     return _payloadLen;
    336 }
    337 
    338 int16_t NETEQTEST_RTPpacket::dataLen() const
    339 {
    340     return _datagramLen;
    341 }
    342 
    343 bool NETEQTEST_RTPpacket::isParsed() const
    344 {
    345     return _rtpParsed;
    346 }
    347 
    348 bool NETEQTEST_RTPpacket::isLost() const
    349 {
    350     return _lost;
    351 }
    352 
    353 uint8_t  NETEQTEST_RTPpacket::payloadType() const
    354 {
    355     webrtc::WebRtcRTPHeader tempRTPinfo;
    356 
    357     if(_datagram && _datagramLen >= _kBasicHeaderLen)
    358     {
    359         parseRTPheader(&tempRTPinfo);
    360     }
    361     else
    362     {
    363         return 0;
    364     }
    365 
    366     return tempRTPinfo.header.payloadType;
    367 }
    368 
    369 uint16_t NETEQTEST_RTPpacket::sequenceNumber() const
    370 {
    371     webrtc::WebRtcRTPHeader tempRTPinfo;
    372 
    373     if(_datagram && _datagramLen >= _kBasicHeaderLen)
    374     {
    375         parseRTPheader(&tempRTPinfo);
    376     }
    377     else
    378     {
    379         return 0;
    380     }
    381 
    382     return tempRTPinfo.header.sequenceNumber;
    383 }
    384 
    385 uint32_t NETEQTEST_RTPpacket::timeStamp() const
    386 {
    387     webrtc::WebRtcRTPHeader tempRTPinfo;
    388 
    389     if(_datagram && _datagramLen >= _kBasicHeaderLen)
    390     {
    391         parseRTPheader(&tempRTPinfo);
    392     }
    393     else
    394     {
    395         return 0;
    396     }
    397 
    398     return tempRTPinfo.header.timestamp;
    399 }
    400 
    401 uint32_t NETEQTEST_RTPpacket::SSRC() const
    402 {
    403     webrtc::WebRtcRTPHeader tempRTPinfo;
    404 
    405     if(_datagram && _datagramLen >= _kBasicHeaderLen)
    406     {
    407         parseRTPheader(&tempRTPinfo);
    408     }
    409     else
    410     {
    411         return 0;
    412     }
    413 
    414     return tempRTPinfo.header.ssrc;
    415 }
    416 
    417 uint8_t  NETEQTEST_RTPpacket::markerBit() const
    418 {
    419     webrtc::WebRtcRTPHeader tempRTPinfo;
    420 
    421     if(_datagram && _datagramLen >= _kBasicHeaderLen)
    422     {
    423         parseRTPheader(&tempRTPinfo);
    424     }
    425     else
    426     {
    427         return 0;
    428     }
    429 
    430     return tempRTPinfo.header.markerBit;
    431 }
    432 
    433 
    434 
    435 int NETEQTEST_RTPpacket::setPayloadType(uint8_t pt)
    436 {
    437 
    438     if (_datagramLen < 12)
    439     {
    440         return -1;
    441     }
    442 
    443     if (!_rtpParsed)
    444     {
    445         _rtpInfo.header.payloadType = pt;
    446     }
    447 
    448     _datagram[1]=(unsigned char)(pt & 0xFF);
    449 
    450     return 0;
    451 
    452 }
    453 
    454 int NETEQTEST_RTPpacket::setSequenceNumber(uint16_t sn)
    455 {
    456 
    457     if (_datagramLen < 12)
    458     {
    459         return -1;
    460     }
    461 
    462     if (!_rtpParsed)
    463     {
    464         _rtpInfo.header.sequenceNumber = sn;
    465     }
    466 
    467     _datagram[2]=(unsigned char)((sn>>8)&0xFF);
    468     _datagram[3]=(unsigned char)((sn)&0xFF);
    469 
    470     return 0;
    471 
    472 }
    473 
    474 int NETEQTEST_RTPpacket::setTimeStamp(uint32_t ts)
    475 {
    476 
    477     if (_datagramLen < 12)
    478     {
    479         return -1;
    480     }
    481 
    482     if (!_rtpParsed)
    483     {
    484         _rtpInfo.header.timestamp = ts;
    485     }
    486 
    487     _datagram[4]=(unsigned char)((ts>>24)&0xFF);
    488     _datagram[5]=(unsigned char)((ts>>16)&0xFF);
    489     _datagram[6]=(unsigned char)((ts>>8)&0xFF);
    490     _datagram[7]=(unsigned char)(ts & 0xFF);
    491 
    492     return 0;
    493 
    494 }
    495 
    496 int NETEQTEST_RTPpacket::setSSRC(uint32_t ssrc)
    497 {
    498 
    499     if (_datagramLen < 12)
    500     {
    501         return -1;
    502     }
    503 
    504     if (!_rtpParsed)
    505     {
    506         _rtpInfo.header.ssrc = ssrc;
    507     }
    508 
    509     _datagram[8]=(unsigned char)((ssrc>>24)&0xFF);
    510     _datagram[9]=(unsigned char)((ssrc>>16)&0xFF);
    511     _datagram[10]=(unsigned char)((ssrc>>8)&0xFF);
    512     _datagram[11]=(unsigned char)(ssrc & 0xFF);
    513 
    514     return 0;
    515 
    516 }
    517 
    518 int NETEQTEST_RTPpacket::setMarkerBit(uint8_t mb)
    519 {
    520 
    521     if (_datagramLen < 12)
    522     {
    523         return -1;
    524     }
    525 
    526     if (_rtpParsed)
    527     {
    528         _rtpInfo.header.markerBit = mb;
    529     }
    530 
    531     if (mb)
    532     {
    533         _datagram[0] |= 0x01;
    534     }
    535     else
    536     {
    537         _datagram[0] &= 0xFE;
    538     }
    539 
    540     return 0;
    541 
    542 }
    543 
    544 int NETEQTEST_RTPpacket::setRTPheader(const webrtc::WebRtcRTPHeader* RTPinfo)
    545 {
    546     if (_datagramLen < 12)
    547     {
    548         // this packet is not ok
    549         return -1;
    550     }
    551 
    552     makeRTPheader(_datagram,
    553         RTPinfo->header.payloadType,
    554         RTPinfo->header.sequenceNumber,
    555         RTPinfo->header.timestamp,
    556         RTPinfo->header.ssrc,
    557         RTPinfo->header.markerBit);
    558 
    559     return 0;
    560 }
    561 
    562 
    563 int NETEQTEST_RTPpacket::splitStereo(NETEQTEST_RTPpacket* slaveRtp,
    564                                      enum stereoModes mode)
    565 {
    566     // if mono, do nothing
    567     if (mode == stereoModeMono)
    568     {
    569         return 0;
    570     }
    571 
    572     // check that the RTP header info is parsed
    573     parseHeader();
    574 
    575     // start by copying the main rtp packet
    576     *slaveRtp = *this;
    577 
    578     if(_payloadLen == 0)
    579     {
    580         // do no more
    581         return 0;
    582     }
    583 
    584     if(_payloadLen%2 != 0)
    585     {
    586         // length must be a factor of 2
    587         return -1;
    588     }
    589 
    590     switch(mode)
    591     {
    592     case stereoModeSample1:
    593         {
    594             // sample based codec with 1-byte samples
    595             splitStereoSample(slaveRtp, 1 /* 1 byte/sample */);
    596             break;
    597         }
    598     case stereoModeSample2:
    599         {
    600             // sample based codec with 2-byte samples
    601             splitStereoSample(slaveRtp, 2 /* 2 bytes/sample */);
    602             break;
    603         }
    604     case stereoModeFrame:
    605         {
    606             // frame based codec
    607             splitStereoFrame(slaveRtp);
    608             break;
    609         }
    610     case stereoModeDuplicate:
    611         {
    612             // frame based codec, send the whole packet to both master and slave
    613             splitStereoDouble(slaveRtp);
    614             break;
    615         }
    616     case stereoModeMono:
    617         {
    618             assert(false);
    619             return -1;
    620         }
    621     }
    622 
    623     return 0;
    624 }
    625 
    626 
    627 void NETEQTEST_RTPpacket::makeRTPheader(unsigned char* rtp_data, uint8_t payloadType, uint16_t seqNo, uint32_t timestamp, uint32_t ssrc, uint8_t markerBit) const
    628 {
    629     rtp_data[0]=(unsigned char)0x80;
    630     if (markerBit)
    631     {
    632         rtp_data[0] |= 0x01;
    633     }
    634     else
    635     {
    636         rtp_data[0] &= 0xFE;
    637     }
    638     rtp_data[1]=(unsigned char)(payloadType & 0xFF);
    639     rtp_data[2]=(unsigned char)((seqNo>>8)&0xFF);
    640     rtp_data[3]=(unsigned char)((seqNo)&0xFF);
    641     rtp_data[4]=(unsigned char)((timestamp>>24)&0xFF);
    642     rtp_data[5]=(unsigned char)((timestamp>>16)&0xFF);
    643 
    644     rtp_data[6]=(unsigned char)((timestamp>>8)&0xFF);
    645     rtp_data[7]=(unsigned char)(timestamp & 0xFF);
    646 
    647     rtp_data[8]=(unsigned char)((ssrc>>24)&0xFF);
    648     rtp_data[9]=(unsigned char)((ssrc>>16)&0xFF);
    649 
    650     rtp_data[10]=(unsigned char)((ssrc>>8)&0xFF);
    651     rtp_data[11]=(unsigned char)(ssrc & 0xFF);
    652 }
    653 
    654 uint16_t
    655     NETEQTEST_RTPpacket::parseRTPheader(webrtc::WebRtcRTPHeader* RTPinfo,
    656                                         uint8_t **payloadPtr) const
    657 {
    658     int16_t *rtp_data = (int16_t *) _datagram;
    659     int i_P, i_X, i_CC;
    660 
    661     assert(_datagramLen >= 12);
    662     parseBasicHeader(RTPinfo, &i_P, &i_X, &i_CC);
    663 
    664     int i_startPosition = calcHeaderLength(i_X, i_CC);
    665 
    666     int i_padlength = calcPadLength(i_P);
    667 
    668     if (payloadPtr)
    669     {
    670         *payloadPtr = (uint8_t*) &rtp_data[i_startPosition >> 1];
    671     }
    672 
    673     return (uint16_t) (_datagramLen - i_startPosition - i_padlength);
    674 }
    675 
    676 
    677 void NETEQTEST_RTPpacket::parseBasicHeader(webrtc::WebRtcRTPHeader* RTPinfo,
    678                                            int *i_P, int *i_X, int *i_CC) const
    679 {
    680     int16_t *rtp_data = (int16_t *) _datagram;
    681     if (_datagramLen < 12)
    682     {
    683         assert(false);
    684         return;
    685     }
    686 
    687     *i_P=(((uint16_t)(rtp_data[0] & 0x20))>>5); /* Extract the P bit */
    688     *i_X=(((uint16_t)(rtp_data[0] & 0x10))>>4); /* Extract the X bit */
    689     *i_CC=(uint16_t)(rtp_data[0] & 0xF); /* Get the CC number  */
    690     /* Get the marker bit */
    691     RTPinfo->header.markerBit = (uint8_t) ((rtp_data[0] >> 15) & 0x01);
    692     /* Get the coder type */
    693     RTPinfo->header.payloadType = (uint8_t) ((rtp_data[0] >> 8) & 0x7F);
    694     /* Get the packet number */
    695     RTPinfo->header.sequenceNumber =
    696         ((( ((uint16_t)rtp_data[1]) >> 8) & 0xFF) |
    697         ( ((uint16_t)(rtp_data[1] & 0xFF)) << 8));
    698     /* Get timestamp */
    699     RTPinfo->header.timestamp = ((((uint16_t)rtp_data[2]) & 0xFF) << 24) |
    700         ((((uint16_t)rtp_data[2]) & 0xFF00) << 8) |
    701         ((((uint16_t)rtp_data[3]) >> 8) & 0xFF) |
    702         ((((uint16_t)rtp_data[3]) & 0xFF) << 8);
    703     /* Get the SSRC */
    704     RTPinfo->header.ssrc = ((((uint16_t)rtp_data[4]) & 0xFF) << 24) |
    705         ((((uint16_t)rtp_data[4]) & 0xFF00) << 8) |
    706         ((((uint16_t)rtp_data[5]) >> 8) & 0xFF) |
    707         ((((uint16_t)rtp_data[5]) & 0xFF) << 8);
    708 }
    709 
    710 int NETEQTEST_RTPpacket::calcHeaderLength(int i_X, int i_CC) const
    711 {
    712     int i_extlength = 0;
    713     int16_t *rtp_data = (int16_t *) _datagram;
    714 
    715     if (i_X == 1)
    716     {
    717         // Extension header exists.
    718         // Find out how many int32_t it consists of.
    719         assert(_datagramLen > 2 * (7 + 2 * i_CC));
    720         if (_datagramLen > 2 * (7 + 2 * i_CC))
    721         {
    722             i_extlength = (((((uint16_t) rtp_data[7 + 2 * i_CC]) >> 8)
    723                 & 0xFF) | (((uint16_t) (rtp_data[7 + 2 * i_CC] & 0xFF))
    724                 << 8)) + 1;
    725         }
    726     }
    727 
    728     return 12 + 4 * i_extlength + 4 * i_CC;
    729 }
    730 
    731 int NETEQTEST_RTPpacket::calcPadLength(int i_P) const
    732 {
    733     int16_t *rtp_data = (int16_t *) _datagram;
    734     if (i_P == 1)
    735     {
    736         /* Padding exists. Find out how many bytes the padding consists of. */
    737         if (_datagramLen & 0x1)
    738         {
    739             /* odd number of bytes => last byte in higher byte */
    740             return rtp_data[_datagramLen >> 1] & 0xFF;
    741         }
    742         else
    743         {
    744             /* even number of bytes => last byte in lower byte */
    745             return ((uint16_t) rtp_data[(_datagramLen >> 1) - 1]) >> 8;
    746         }
    747     }
    748     return 0;
    749 }
    750 
    751 void NETEQTEST_RTPpacket::splitStereoSample(NETEQTEST_RTPpacket* slaveRtp,
    752                                             int stride)
    753 {
    754     if(!_payloadPtr || !slaveRtp || !slaveRtp->_payloadPtr
    755         || _payloadLen <= 0 || slaveRtp->_memSize < _memSize)
    756     {
    757         return;
    758     }
    759 
    760     uint8_t *readDataPtr = _payloadPtr;
    761     uint8_t *writeDataPtr = _payloadPtr;
    762     uint8_t *slaveData = slaveRtp->_payloadPtr;
    763 
    764     while (readDataPtr - _payloadPtr < _payloadLen)
    765     {
    766         // master data
    767         for (int ix = 0; ix < stride; ix++) {
    768             *writeDataPtr = *readDataPtr;
    769             writeDataPtr++;
    770             readDataPtr++;
    771         }
    772 
    773         // slave data
    774         for (int ix = 0; ix < stride; ix++) {
    775             *slaveData = *readDataPtr;
    776             slaveData++;
    777             readDataPtr++;
    778         }
    779     }
    780 
    781     _payloadLen /= 2;
    782     slaveRtp->_payloadLen = _payloadLen;
    783 }
    784 
    785 
    786 void NETEQTEST_RTPpacket::splitStereoFrame(NETEQTEST_RTPpacket* slaveRtp)
    787 {
    788     if(!_payloadPtr || !slaveRtp || !slaveRtp->_payloadPtr
    789         || _payloadLen <= 0 || slaveRtp->_memSize < _memSize)
    790     {
    791         return;
    792     }
    793 
    794     memmove(slaveRtp->_payloadPtr, _payloadPtr + _payloadLen/2, _payloadLen/2);
    795 
    796     _payloadLen /= 2;
    797     slaveRtp->_payloadLen = _payloadLen;
    798 }
    799 void NETEQTEST_RTPpacket::splitStereoDouble(NETEQTEST_RTPpacket* slaveRtp)
    800 {
    801     if(!_payloadPtr || !slaveRtp || !slaveRtp->_payloadPtr
    802         || _payloadLen <= 0 || slaveRtp->_memSize < _memSize)
    803     {
    804         return;
    805     }
    806 
    807     memcpy(slaveRtp->_payloadPtr, _payloadPtr, _payloadLen);
    808     slaveRtp->_payloadLen = _payloadLen;
    809 }
    810 
    811 // Get the RTP header for the RED payload indicated by argument index.
    812 // The first RED payload is index = 0.
    813 int NETEQTEST_RTPpacket::extractRED(int index, webrtc::WebRtcRTPHeader& red)
    814 {
    815 //
    816 //  0                   1                    2                   3
    817 //  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
    818 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    819 // |1|   block PT  |  timestamp offset         |   block length    |
    820 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    821 // |1|    ...                                                      |
    822 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    823 // |0|   block PT  |
    824 // +-+-+-+-+-+-+-+-+
    825 //
    826 
    827     parseHeader();
    828 
    829     uint8_t* ptr = payload();
    830     uint8_t* payloadEndPtr = ptr + payloadLen();
    831     int num_encodings = 0;
    832     int total_len = 0;
    833 
    834     while ((ptr < payloadEndPtr) && (*ptr & 0x80))
    835     {
    836         int len = ((ptr[2] & 0x03) << 8) + ptr[3];
    837         if (num_encodings == index)
    838         {
    839             // Header found.
    840             red.header.payloadType = ptr[0] & 0x7F;
    841             uint32_t offset = (ptr[1] << 6) + ((ptr[2] & 0xFC) >> 2);
    842             red.header.sequenceNumber = sequenceNumber();
    843             red.header.timestamp = timeStamp() - offset;
    844             red.header.markerBit = markerBit();
    845             red.header.ssrc = SSRC();
    846             return len;
    847         }
    848         ++num_encodings;
    849         total_len += len;
    850         ptr += 4;
    851     }
    852     if ((ptr < payloadEndPtr) && (num_encodings == index))
    853     {
    854         // Last header.
    855         red.header.payloadType = ptr[0] & 0x7F;
    856         red.header.sequenceNumber = sequenceNumber();
    857         red.header.timestamp = timeStamp();
    858         red.header.markerBit = markerBit();
    859         red.header.ssrc = SSRC();
    860         ++ptr;
    861         return payloadLen() - (ptr - payload()) - total_len;
    862     }
    863     return -1;
    864 }
    865 
    866 // Randomize the payload, not the RTP header.
    867 void NETEQTEST_RTPpacket::scramblePayload(void)
    868 {
    869     parseHeader();
    870 
    871     for (int i = 0; i < _payloadLen; ++i)
    872     {
    873         _payloadPtr[i] = static_cast<uint8_t>(rand());
    874     }
    875 }
    876