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 size_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     if(_datagram && _datagramLen >= _kBasicHeaderLen)
    356     {
    357         webrtc::WebRtcRTPHeader tempRTPinfo;
    358         parseRTPheader(&tempRTPinfo);
    359         return tempRTPinfo.header.payloadType;
    360     }
    361     else
    362     {
    363         return 0;
    364     }
    365 }
    366 
    367 uint16_t NETEQTEST_RTPpacket::sequenceNumber() const
    368 {
    369     if(_datagram && _datagramLen >= _kBasicHeaderLen)
    370     {
    371         webrtc::WebRtcRTPHeader tempRTPinfo;
    372         parseRTPheader(&tempRTPinfo);
    373         return tempRTPinfo.header.sequenceNumber;
    374     }
    375     else
    376     {
    377         return 0;
    378     }
    379 }
    380 
    381 uint32_t NETEQTEST_RTPpacket::timeStamp() const
    382 {
    383     if(_datagram && _datagramLen >= _kBasicHeaderLen)
    384     {
    385         webrtc::WebRtcRTPHeader tempRTPinfo;
    386         parseRTPheader(&tempRTPinfo);
    387         return tempRTPinfo.header.timestamp;
    388     }
    389     else
    390     {
    391         return 0;
    392     }
    393 }
    394 
    395 uint32_t NETEQTEST_RTPpacket::SSRC() const
    396 {
    397     if(_datagram && _datagramLen >= _kBasicHeaderLen)
    398     {
    399         webrtc::WebRtcRTPHeader tempRTPinfo;
    400         parseRTPheader(&tempRTPinfo);
    401         return tempRTPinfo.header.ssrc;
    402     }
    403     else
    404     {
    405         return 0;
    406     }
    407 }
    408 
    409 uint8_t  NETEQTEST_RTPpacket::markerBit() const
    410 {
    411     if(_datagram && _datagramLen >= _kBasicHeaderLen)
    412     {
    413         webrtc::WebRtcRTPHeader tempRTPinfo;
    414         parseRTPheader(&tempRTPinfo);
    415         return tempRTPinfo.header.markerBit;
    416     }
    417     else
    418     {
    419         return 0;
    420     }
    421 }
    422 
    423 
    424 
    425 int NETEQTEST_RTPpacket::setPayloadType(uint8_t pt)
    426 {
    427 
    428     if (_datagramLen < 12)
    429     {
    430         return -1;
    431     }
    432 
    433     if (!_rtpParsed)
    434     {
    435         _rtpInfo.header.payloadType = pt;
    436     }
    437 
    438     _datagram[1] = pt;
    439 
    440     return 0;
    441 
    442 }
    443 
    444 int NETEQTEST_RTPpacket::setSequenceNumber(uint16_t sn)
    445 {
    446 
    447     if (_datagramLen < 12)
    448     {
    449         return -1;
    450     }
    451 
    452     if (!_rtpParsed)
    453     {
    454         _rtpInfo.header.sequenceNumber = sn;
    455     }
    456 
    457     _datagram[2]=(unsigned char)((sn>>8)&0xFF);
    458     _datagram[3]=(unsigned char)((sn)&0xFF);
    459 
    460     return 0;
    461 
    462 }
    463 
    464 int NETEQTEST_RTPpacket::setTimeStamp(uint32_t ts)
    465 {
    466 
    467     if (_datagramLen < 12)
    468     {
    469         return -1;
    470     }
    471 
    472     if (!_rtpParsed)
    473     {
    474         _rtpInfo.header.timestamp = ts;
    475     }
    476 
    477     _datagram[4]=(unsigned char)((ts>>24)&0xFF);
    478     _datagram[5]=(unsigned char)((ts>>16)&0xFF);
    479     _datagram[6]=(unsigned char)((ts>>8)&0xFF);
    480     _datagram[7]=(unsigned char)(ts & 0xFF);
    481 
    482     return 0;
    483 
    484 }
    485 
    486 int NETEQTEST_RTPpacket::setSSRC(uint32_t ssrc)
    487 {
    488 
    489     if (_datagramLen < 12)
    490     {
    491         return -1;
    492     }
    493 
    494     if (!_rtpParsed)
    495     {
    496         _rtpInfo.header.ssrc = ssrc;
    497     }
    498 
    499     _datagram[8]=(unsigned char)((ssrc>>24)&0xFF);
    500     _datagram[9]=(unsigned char)((ssrc>>16)&0xFF);
    501     _datagram[10]=(unsigned char)((ssrc>>8)&0xFF);
    502     _datagram[11]=(unsigned char)(ssrc & 0xFF);
    503 
    504     return 0;
    505 
    506 }
    507 
    508 int NETEQTEST_RTPpacket::setMarkerBit(uint8_t mb)
    509 {
    510 
    511     if (_datagramLen < 12)
    512     {
    513         return -1;
    514     }
    515 
    516     if (_rtpParsed)
    517     {
    518         _rtpInfo.header.markerBit = mb;
    519     }
    520 
    521     if (mb)
    522     {
    523         _datagram[0] |= 0x01;
    524     }
    525     else
    526     {
    527         _datagram[0] &= 0xFE;
    528     }
    529 
    530     return 0;
    531 
    532 }
    533 
    534 int NETEQTEST_RTPpacket::setRTPheader(const webrtc::WebRtcRTPHeader* RTPinfo)
    535 {
    536     if (_datagramLen < 12)
    537     {
    538         // this packet is not ok
    539         return -1;
    540     }
    541 
    542     makeRTPheader(_datagram,
    543         RTPinfo->header.payloadType,
    544         RTPinfo->header.sequenceNumber,
    545         RTPinfo->header.timestamp,
    546         RTPinfo->header.ssrc,
    547         RTPinfo->header.markerBit);
    548 
    549     return 0;
    550 }
    551 
    552 
    553 int NETEQTEST_RTPpacket::splitStereo(NETEQTEST_RTPpacket* slaveRtp,
    554                                      enum stereoModes mode)
    555 {
    556     // if mono, do nothing
    557     if (mode == stereoModeMono)
    558     {
    559         return 0;
    560     }
    561 
    562     // check that the RTP header info is parsed
    563     parseHeader();
    564 
    565     // start by copying the main rtp packet
    566     *slaveRtp = *this;
    567 
    568     if(_payloadLen == 0)
    569     {
    570         // do no more
    571         return 0;
    572     }
    573 
    574     if(_payloadLen%2 != 0)
    575     {
    576         // length must be a factor of 2
    577         return -1;
    578     }
    579 
    580     switch(mode)
    581     {
    582     case stereoModeSample1:
    583         {
    584             // sample based codec with 1-byte samples
    585             splitStereoSample(slaveRtp, 1 /* 1 byte/sample */);
    586             break;
    587         }
    588     case stereoModeSample2:
    589         {
    590             // sample based codec with 2-byte samples
    591             splitStereoSample(slaveRtp, 2 /* 2 bytes/sample */);
    592             break;
    593         }
    594     case stereoModeFrame:
    595         {
    596             // frame based codec
    597             splitStereoFrame(slaveRtp);
    598             break;
    599         }
    600     case stereoModeDuplicate:
    601         {
    602             // frame based codec, send the whole packet to both master and slave
    603             splitStereoDouble(slaveRtp);
    604             break;
    605         }
    606     case stereoModeMono:
    607         {
    608             assert(false);
    609             return -1;
    610         }
    611     }
    612 
    613     return 0;
    614 }
    615 
    616 
    617 void NETEQTEST_RTPpacket::makeRTPheader(unsigned char* rtp_data,
    618                                         uint8_t payloadType,
    619                                         uint16_t seqNo,
    620                                         uint32_t timestamp,
    621                                         uint32_t ssrc,
    622                                         uint8_t markerBit) const
    623 {
    624     rtp_data[0] = markerBit ? 0x81 : 0x80;
    625     rtp_data[1] = payloadType;
    626     rtp_data[2] = seqNo >> 8;
    627     rtp_data[3] = seqNo & 0xFF;
    628     rtp_data[4] = timestamp >> 24;
    629     rtp_data[5] = (timestamp >> 16) & 0xFF;
    630     rtp_data[6] = (timestamp >> 8) & 0xFF;
    631     rtp_data[7] = timestamp & 0xFF;
    632     rtp_data[8] = ssrc >> 24;
    633     rtp_data[9] = (ssrc >> 16) & 0xFF;
    634     rtp_data[10] = (ssrc >> 8) & 0xFF;
    635     rtp_data[11] = ssrc & 0xFF;
    636 }
    637 
    638 uint16_t NETEQTEST_RTPpacket::parseRTPheader(webrtc::WebRtcRTPHeader* RTPinfo,
    639                                              uint8_t **payloadPtr) const
    640 {
    641     uint16_t* rtp_data = reinterpret_cast<uint16_t*>(_datagram);
    642     int i_P, i_X, i_CC;
    643 
    644     assert(_datagramLen >= 12);
    645     parseBasicHeader(RTPinfo, &i_P, &i_X, &i_CC);
    646 
    647     int i_startPosition = calcHeaderLength(i_X, i_CC);
    648 
    649     int i_padlength = calcPadLength(i_P);
    650 
    651     if (payloadPtr)
    652     {
    653         *payloadPtr =
    654             reinterpret_cast<uint8_t*>(&rtp_data[i_startPosition >> 1]);
    655     }
    656 
    657     return static_cast<uint16_t>(_datagramLen - i_startPosition - i_padlength);
    658 }
    659 
    660 
    661 void NETEQTEST_RTPpacket::parseBasicHeader(webrtc::WebRtcRTPHeader* RTPinfo,
    662                                            int *i_P, int *i_X, int *i_CC) const
    663 {
    664     uint16_t* rtp_data = reinterpret_cast<uint16_t*>(_datagram);
    665     if (_datagramLen < 12)
    666     {
    667         assert(false);
    668         return;
    669     }
    670 
    671     *i_P = (rtp_data[0] >> 5) & 0x01;
    672     *i_X = (rtp_data[0] >> 4) & 0x01;
    673     *i_CC = rtp_data[0] & 0xF;
    674     RTPinfo->header.markerBit = (rtp_data[0] >> 15) & 0x01;
    675     RTPinfo->header.payloadType = (rtp_data[0] >> 8) & 0x7F;
    676     RTPinfo->header.sequenceNumber =
    677         (rtp_data[1] >> 8) | ((rtp_data[1] & 0xFF) << 8);
    678     RTPinfo->header.timestamp =
    679         ((rtp_data[2] & 0xFF) << 24) | ((rtp_data[2] & 0xFF00) << 8) |
    680         (rtp_data[3] >> 8) | ((rtp_data[3] & 0xFF) << 8);
    681     RTPinfo->header.ssrc =
    682         ((rtp_data[4] & 0xFF) << 24) | ((rtp_data[4] & 0xFF00) << 8) |
    683         (rtp_data[5] >> 8) | ((rtp_data[5] & 0xFF) << 8);
    684 }
    685 
    686 int NETEQTEST_RTPpacket::calcHeaderLength(int i_X, int i_CC) const
    687 {
    688     int i_extlength = 0;
    689     uint16_t* rtp_data = reinterpret_cast<uint16_t*>(_datagram);
    690 
    691     if (i_X == 1)
    692     {
    693         // Extension header exists.
    694         // Find out how many int32_t it consists of.
    695         int offset = 7 + 2 * i_CC;
    696         assert(_datagramLen > 2 * offset);
    697         if (_datagramLen > 2 * offset)
    698         {
    699             i_extlength = 1 +
    700                 (((rtp_data[offset]) >> 8) | ((rtp_data[offset] & 0xFF) << 8));
    701         }
    702     }
    703 
    704     return 12 + 4 * i_extlength + 4 * i_CC;
    705 }
    706 
    707 int NETEQTEST_RTPpacket::calcPadLength(int i_P) const
    708 {
    709     uint16_t* rtp_data = reinterpret_cast<uint16_t*>(_datagram);
    710     if (i_P == 1)
    711     {
    712         /* Padding exists. Find out how many bytes the padding consists of. */
    713         if (_datagramLen & 0x1)
    714         {
    715             /* odd number of bytes => last byte in higher byte */
    716             return rtp_data[_datagramLen >> 1] & 0xFF;
    717         }
    718         else
    719         {
    720             /* even number of bytes => last byte in lower byte */
    721             return rtp_data[(_datagramLen >> 1) - 1] >> 8;
    722         }
    723     }
    724     return 0;
    725 }
    726 
    727 void NETEQTEST_RTPpacket::splitStereoSample(NETEQTEST_RTPpacket* slaveRtp,
    728                                             int stride)
    729 {
    730     if(!_payloadPtr || !slaveRtp || !slaveRtp->_payloadPtr
    731         || _payloadLen == 0 || slaveRtp->_memSize < _memSize)
    732     {
    733         return;
    734     }
    735 
    736     uint8_t *readDataPtr = _payloadPtr;
    737     uint8_t *writeDataPtr = _payloadPtr;
    738     uint8_t *slaveData = slaveRtp->_payloadPtr;
    739 
    740     while (readDataPtr - _payloadPtr < static_cast<ptrdiff_t>(_payloadLen))
    741     {
    742         // master data
    743         for (int ix = 0; ix < stride; ix++) {
    744             *writeDataPtr = *readDataPtr;
    745             writeDataPtr++;
    746             readDataPtr++;
    747         }
    748 
    749         // slave data
    750         for (int ix = 0; ix < stride; ix++) {
    751             *slaveData = *readDataPtr;
    752             slaveData++;
    753             readDataPtr++;
    754         }
    755     }
    756 
    757     _payloadLen /= 2;
    758     slaveRtp->_payloadLen = _payloadLen;
    759 }
    760 
    761 
    762 void NETEQTEST_RTPpacket::splitStereoFrame(NETEQTEST_RTPpacket* slaveRtp)
    763 {
    764     if(!_payloadPtr || !slaveRtp || !slaveRtp->_payloadPtr
    765         || _payloadLen == 0 || slaveRtp->_memSize < _memSize)
    766     {
    767         return;
    768     }
    769 
    770     memmove(slaveRtp->_payloadPtr, _payloadPtr + _payloadLen/2, _payloadLen/2);
    771 
    772     _payloadLen /= 2;
    773     slaveRtp->_payloadLen = _payloadLen;
    774 }
    775 void NETEQTEST_RTPpacket::splitStereoDouble(NETEQTEST_RTPpacket* slaveRtp)
    776 {
    777     if(!_payloadPtr || !slaveRtp || !slaveRtp->_payloadPtr
    778         || _payloadLen == 0 || slaveRtp->_memSize < _memSize)
    779     {
    780         return;
    781     }
    782 
    783     memcpy(slaveRtp->_payloadPtr, _payloadPtr, _payloadLen);
    784     slaveRtp->_payloadLen = _payloadLen;
    785 }
    786 
    787 // Get the RTP header for the RED payload indicated by argument index.
    788 // The first RED payload is index = 0.
    789 int NETEQTEST_RTPpacket::extractRED(int index, webrtc::WebRtcRTPHeader& red)
    790 {
    791 //
    792 //  0                   1                    2                   3
    793 //  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
    794 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    795 // |1|   block PT  |  timestamp offset         |   block length    |
    796 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    797 // |1|    ...                                                      |
    798 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    799 // |0|   block PT  |
    800 // +-+-+-+-+-+-+-+-+
    801 //
    802 
    803     parseHeader();
    804 
    805     uint8_t* ptr = payload();
    806     uint8_t* payloadEndPtr = ptr + payloadLen();
    807     int num_encodings = 0;
    808     int total_len = 0;
    809 
    810     while ((ptr < payloadEndPtr) && (*ptr & 0x80))
    811     {
    812         int len = ((ptr[2] & 0x03) << 8) + ptr[3];
    813         if (num_encodings == index)
    814         {
    815             // Header found.
    816             red.header.payloadType = ptr[0] & 0x7F;
    817             uint32_t offset = (ptr[1] << 6) + (ptr[2] >> 2);
    818             red.header.sequenceNumber = sequenceNumber();
    819             red.header.timestamp = timeStamp() - offset;
    820             red.header.markerBit = markerBit();
    821             red.header.ssrc = SSRC();
    822             return len;
    823         }
    824         ++num_encodings;
    825         total_len += len;
    826         ptr += 4;
    827     }
    828     if ((ptr < payloadEndPtr) && (num_encodings == index))
    829     {
    830         // Last header.
    831         red.header.payloadType = ptr[0] & 0x7F;
    832         red.header.sequenceNumber = sequenceNumber();
    833         red.header.timestamp = timeStamp();
    834         red.header.markerBit = markerBit();
    835         red.header.ssrc = SSRC();
    836         ++ptr;
    837         return payloadLen() - (ptr - payload()) - total_len;
    838     }
    839     return -1;
    840 }
    841 
    842 // Randomize the payload, not the RTP header.
    843 void NETEQTEST_RTPpacket::scramblePayload(void)
    844 {
    845     parseHeader();
    846 
    847     for (size_t i = 0; i < _payloadLen; ++i)
    848     {
    849         _payloadPtr[i] = static_cast<uint8_t>(rand());
    850     }
    851 }
    852