Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_coding / neteq / test / NETEQTEST_RTPpacket.cc
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 }