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