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