Note: We no longer publish the latest version of our code here. We primarily use a kumc-bmi github organization. The heron ETL repository, in particular, is not public. Peers in the informatics community should see MultiSiteDev for details on requesting access.

source: webrtc/webrtc/modules/audio_coding/neteq4/test/NETEQTEST_RTPpacket.cc @ 0:4bda6873e34c

pub_scrub_3792 tip
Last change on this file since 0:4bda6873e34c was 0:4bda6873e34c, checked in by Michael Prittie <mprittie@…>, 6 years ago

Scrubbed password for publication.

File size: 18.8 KB
Line 
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
23const int NETEQTEST_RTPpacket::_kRDHeaderLen = 8;
24const int NETEQTEST_RTPpacket::_kBasicHeaderLen = 12;
25
26NETEQTEST_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
41NETEQTEST_RTPpacket::~NETEQTEST_RTPpacket()
42{
43    if(_datagram)
44    {
45        delete [] _datagram;
46    }
47}
48
49void 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
65int 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
99int 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;
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
171int 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
211int 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
255void NETEQTEST_RTPpacket::blockPT(uint8_t pt)
256{
257    _blockList[pt] = true;
258}
259
260
261void 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
283void 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
296const webrtc::WebRtcRTPHeader* NETEQTEST_RTPpacket::RTPinfo() const
297{
298    if (_rtpParsed)
299    {
300        return &_rtpInfo;
301    }
302    else
303    {
304        return NULL;
305    }
306}
307
308uint8_t * NETEQTEST_RTPpacket::datagram() const
309{
310    if (_datagramLen > 0)
311    {
312        return _datagram;
313    }
314    else
315    {
316        return NULL;
317    }
318}
319
320uint8_t * NETEQTEST_RTPpacket::payload() const
321{
322    if (_payloadLen > 0)
323    {
324        return _payloadPtr;
325    }
326    else
327    {
328        return NULL;
329    }
330}
331
332int16_t NETEQTEST_RTPpacket::payloadLen()
333{
334    parseHeader();
335    return _payloadLen;
336}
337
338int16_t NETEQTEST_RTPpacket::dataLen() const
339{
340    return _datagramLen;
341}
342
343bool NETEQTEST_RTPpacket::isParsed() const
344{
345    return _rtpParsed;
346}
347
348bool NETEQTEST_RTPpacket::isLost() const
349{
350    return _lost;
351}
352
353uint8_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
369uint16_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
385uint32_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
401uint32_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
417uint8_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
435int 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
454int 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
474int 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
496int 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
518int 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
544int 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
563int 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
627void 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
654uint16_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
677void 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
710int 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
731int 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
751void 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
786void 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}
799void 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.
813int 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.
867void 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}
Note: See TracBrowser for help on using the repository browser.