2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
11 #include "NETEQTEST_RTPpacket.h"
14 #include <stdlib.h> // rand
20 #include <netinet/in.h> // for htons, htonl, etc
23 const int NETEQTEST_RTPpacket::_kRDHeaderLen = 8;
24 const int NETEQTEST_RTPpacket::_kBasicHeaderLen = 12;
26 NETEQTEST_RTPpacket::NETEQTEST_RTPpacket()
37 memset(&_rtpInfo, 0, sizeof(_rtpInfo));
41 NETEQTEST_RTPpacket::~NETEQTEST_RTPpacket()
49 void NETEQTEST_RTPpacket::reset()
60 memset(&_rtpInfo, 0, sizeof(_rtpInfo));
65 int NETEQTEST_RTPpacket::skipFileHeader(FILE *fp)
71 const int kFirstLineLength = 40;
72 char firstline[kFirstLineLength];
73 if (fgets(firstline, kFirstLineLength, fp) == NULL) {
76 if (strncmp(firstline, "#!rtpplay", 9) == 0) {
77 if (strncmp(firstline, "#!rtpplay1.0", 12) != 0) {
81 else if (strncmp(firstline, "#!RTPencode", 11) == 0) {
82 if (strncmp(firstline, "#!RTPencode1.0", 14) != 0) {
91 const int kRtpDumpHeaderSize = 4 + 4 + 4 + 2 + 2;
92 if (fseek(fp, kRtpDumpHeaderSize, SEEK_CUR) != 0)
99 int NETEQTEST_RTPpacket::readFromFile(FILE *fp)
106 uint16_t length, plen;
110 bool readNextPacket = true;
111 while (readNextPacket) {
112 readNextPacket = false;
113 if (fread(&length,2,1,fp)==0)
118 length = ntohs(length);
120 if (fread(&plen,2,1,fp)==0)
125 packetLen = ntohs(plen);
127 if (fread(&offset,4,1,fp)==0)
132 // store in local variable until we have passed the reset below
133 uint32_t receiveTime = ntohl(offset);
135 // Use length here because a plen of 0 specifies rtcp
136 length = (uint16_t) (length - _kRDHeaderLen);
139 if (_datagram && _memSize < length)
146 _datagram = new uint8_t[length];
150 if (fread((unsigned short *) _datagram,1,length,fp) != length)
156 _datagramLen = length;
157 _receiveTime = receiveTime;
159 if (!_blockList.empty() && _blockList.count(payloadType()) > 0)
161 readNextPacket = true;
171 int NETEQTEST_RTPpacket::readFixedFromFile(FILE *fp, size_t length)
179 if (_datagram && _memSize < static_cast<int>(length))
186 _datagram = new uint8_t[length];
190 if (fread(_datagram, 1, length, fp) != length)
196 _datagramLen = length;
199 if (!_blockList.empty() && _blockList.count(payloadType()) > 0)
201 // discard this payload
202 return readFromFile(fp);
211 int NETEQTEST_RTPpacket::writeToFile(FILE *fp)
218 uint16_t length, plen;
221 // length including RTPplay header
222 length = htons(_datagramLen + _kRDHeaderLen);
223 if (fwrite(&length, 2, 1, fp) != 1)
229 plen = htons(_datagramLen);
230 if (fwrite(&plen, 2, 1, fp) != 1)
235 // offset (=receive time)
236 offset = htonl(_receiveTime);
237 if (fwrite(&offset, 4, 1, fp) != 1)
244 if (fwrite(_datagram, 1, _datagramLen, fp) !=
245 static_cast<size_t>(_datagramLen))
250 return _datagramLen + _kRDHeaderLen; // total number of bytes written
255 void NETEQTEST_RTPpacket::blockPT(uint8_t pt)
257 _blockList[pt] = true;
261 void NETEQTEST_RTPpacket::parseHeader()
269 if (_datagramLen < _kBasicHeaderLen)
275 _payloadLen = parseRTPheader(&_payloadPtr);
283 void NETEQTEST_RTPpacket::parseHeader(webrtc::WebRtcRTPHeader* 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;
296 const webrtc::WebRtcRTPHeader* NETEQTEST_RTPpacket::RTPinfo() const
308 uint8_t * NETEQTEST_RTPpacket::datagram() const
310 if (_datagramLen > 0)
320 uint8_t * NETEQTEST_RTPpacket::payload() const
332 int16_t NETEQTEST_RTPpacket::payloadLen()
338 int16_t NETEQTEST_RTPpacket::dataLen() const
343 bool NETEQTEST_RTPpacket::isParsed() const
348 bool NETEQTEST_RTPpacket::isLost() const
353 uint8_t NETEQTEST_RTPpacket::payloadType() const
355 webrtc::WebRtcRTPHeader tempRTPinfo;
357 if(_datagram && _datagramLen >= _kBasicHeaderLen)
359 parseRTPheader(&tempRTPinfo);
366 return tempRTPinfo.header.payloadType;
369 uint16_t NETEQTEST_RTPpacket::sequenceNumber() const
371 webrtc::WebRtcRTPHeader tempRTPinfo;
373 if(_datagram && _datagramLen >= _kBasicHeaderLen)
375 parseRTPheader(&tempRTPinfo);
382 return tempRTPinfo.header.sequenceNumber;
385 uint32_t NETEQTEST_RTPpacket::timeStamp() const
387 webrtc::WebRtcRTPHeader tempRTPinfo;
389 if(_datagram && _datagramLen >= _kBasicHeaderLen)
391 parseRTPheader(&tempRTPinfo);
398 return tempRTPinfo.header.timestamp;
401 uint32_t NETEQTEST_RTPpacket::SSRC() const
403 webrtc::WebRtcRTPHeader tempRTPinfo;
405 if(_datagram && _datagramLen >= _kBasicHeaderLen)
407 parseRTPheader(&tempRTPinfo);
414 return tempRTPinfo.header.ssrc;
417 uint8_t NETEQTEST_RTPpacket::markerBit() const
419 webrtc::WebRtcRTPHeader tempRTPinfo;
421 if(_datagram && _datagramLen >= _kBasicHeaderLen)
423 parseRTPheader(&tempRTPinfo);
430 return tempRTPinfo.header.markerBit;
435 int NETEQTEST_RTPpacket::setPayloadType(uint8_t pt)
438 if (_datagramLen < 12)
445 _rtpInfo.header.payloadType = pt;
448 _datagram[1]=(unsigned char)(pt & 0xFF);
454 int NETEQTEST_RTPpacket::setSequenceNumber(uint16_t sn)
457 if (_datagramLen < 12)
464 _rtpInfo.header.sequenceNumber = sn;
467 _datagram[2]=(unsigned char)((sn>>8)&0xFF);
468 _datagram[3]=(unsigned char)((sn)&0xFF);
474 int NETEQTEST_RTPpacket::setTimeStamp(uint32_t ts)
477 if (_datagramLen < 12)
484 _rtpInfo.header.timestamp = ts;
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);
496 int NETEQTEST_RTPpacket::setSSRC(uint32_t ssrc)
499 if (_datagramLen < 12)
506 _rtpInfo.header.ssrc = ssrc;
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);
518 int NETEQTEST_RTPpacket::setMarkerBit(uint8_t mb)
521 if (_datagramLen < 12)
528 _rtpInfo.header.markerBit = mb;
533 _datagram[0] |= 0x01;
537 _datagram[0] &= 0xFE;
544 int NETEQTEST_RTPpacket::setRTPheader(const webrtc::WebRtcRTPHeader* RTPinfo)
546 if (_datagramLen < 12)
548 // this packet is not ok
552 makeRTPheader(_datagram,
553 RTPinfo->header.payloadType,
554 RTPinfo->header.sequenceNumber,
555 RTPinfo->header.timestamp,
556 RTPinfo->header.ssrc,
557 RTPinfo->header.markerBit);
563 int NETEQTEST_RTPpacket::splitStereo(NETEQTEST_RTPpacket* slaveRtp,
564 enum stereoModes mode)
566 // if mono, do nothing
567 if (mode == stereoModeMono)
572 // check that the RTP header info is parsed
575 // start by copying the main rtp packet
584 if(_payloadLen%2 != 0)
586 // length must be a factor of 2
592 case stereoModeSample1:
594 // sample based codec with 1-byte samples
595 splitStereoSample(slaveRtp, 1 /* 1 byte/sample */);
598 case stereoModeSample2:
600 // sample based codec with 2-byte samples
601 splitStereoSample(slaveRtp, 2 /* 2 bytes/sample */);
604 case stereoModeFrame:
607 splitStereoFrame(slaveRtp);
610 case stereoModeDuplicate:
612 // frame based codec, send the whole packet to both master and slave
613 splitStereoDouble(slaveRtp);
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
629 rtp_data[0]=(unsigned char)0x80;
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);
644 rtp_data[6]=(unsigned char)((timestamp>>8)&0xFF);
645 rtp_data[7]=(unsigned char)(timestamp & 0xFF);
647 rtp_data[8]=(unsigned char)((ssrc>>24)&0xFF);
648 rtp_data[9]=(unsigned char)((ssrc>>16)&0xFF);
650 rtp_data[10]=(unsigned char)((ssrc>>8)&0xFF);
651 rtp_data[11]=(unsigned char)(ssrc & 0xFF);
655 NETEQTEST_RTPpacket::parseRTPheader(webrtc::WebRtcRTPHeader* RTPinfo,
656 uint8_t **payloadPtr) const
658 int16_t *rtp_data = (int16_t *) _datagram;
661 assert(_datagramLen >= 12);
662 parseBasicHeader(RTPinfo, &i_P, &i_X, &i_CC);
664 int i_startPosition = calcHeaderLength(i_X, i_CC);
666 int i_padlength = calcPadLength(i_P);
670 *payloadPtr = (uint8_t*) &rtp_data[i_startPosition >> 1];
673 return (uint16_t) (_datagramLen - i_startPosition - i_padlength);
677 void NETEQTEST_RTPpacket::parseBasicHeader(webrtc::WebRtcRTPHeader* RTPinfo,
678 int *i_P, int *i_X, int *i_CC) const
680 int16_t *rtp_data = (int16_t *) _datagram;
681 if (_datagramLen < 12)
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));
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);
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);
710 int NETEQTEST_RTPpacket::calcHeaderLength(int i_X, int i_CC) const
713 int16_t *rtp_data = (int16_t *) _datagram;
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))
722 i_extlength = (((((uint16_t) rtp_data[7 + 2 * i_CC]) >> 8)
723 & 0xFF) | (((uint16_t) (rtp_data[7 + 2 * i_CC] & 0xFF))
728 return 12 + 4 * i_extlength + 4 * i_CC;
731 int NETEQTEST_RTPpacket::calcPadLength(int i_P) const
733 int16_t *rtp_data = (int16_t *) _datagram;
736 /* Padding exists. Find out how many bytes the padding consists of. */
737 if (_datagramLen & 0x1)
739 /* odd number of bytes => last byte in higher byte */
740 return rtp_data[_datagramLen >> 1] & 0xFF;
744 /* even number of bytes => last byte in lower byte */
745 return ((uint16_t) rtp_data[(_datagramLen >> 1) - 1]) >> 8;
751 void NETEQTEST_RTPpacket::splitStereoSample(NETEQTEST_RTPpacket* slaveRtp,
754 if(!_payloadPtr || !slaveRtp || !slaveRtp->_payloadPtr
755 || _payloadLen <= 0 || slaveRtp->_memSize < _memSize)
760 uint8_t *readDataPtr = _payloadPtr;
761 uint8_t *writeDataPtr = _payloadPtr;
762 uint8_t *slaveData = slaveRtp->_payloadPtr;
764 while (readDataPtr - _payloadPtr < _payloadLen)
767 for (int ix = 0; ix < stride; ix++) {
768 *writeDataPtr = *readDataPtr;
774 for (int ix = 0; ix < stride; ix++) {
775 *slaveData = *readDataPtr;
782 slaveRtp->_payloadLen = _payloadLen;
786 void NETEQTEST_RTPpacket::splitStereoFrame(NETEQTEST_RTPpacket* slaveRtp)
788 if(!_payloadPtr || !slaveRtp || !slaveRtp->_payloadPtr
789 || _payloadLen <= 0 || slaveRtp->_memSize < _memSize)
794 memmove(slaveRtp->_payloadPtr, _payloadPtr + _payloadLen/2, _payloadLen/2);
797 slaveRtp->_payloadLen = _payloadLen;
799 void NETEQTEST_RTPpacket::splitStereoDouble(NETEQTEST_RTPpacket* slaveRtp)
801 if(!_payloadPtr || !slaveRtp || !slaveRtp->_payloadPtr
802 || _payloadLen <= 0 || slaveRtp->_memSize < _memSize)
807 memcpy(slaveRtp->_payloadPtr, _payloadPtr, _payloadLen);
808 slaveRtp->_payloadLen = _payloadLen;
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)
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 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
822 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
829 uint8_t* ptr = payload();
830 uint8_t* payloadEndPtr = ptr + payloadLen();
831 int num_encodings = 0;
834 while ((ptr < payloadEndPtr) && (*ptr & 0x80))
836 int len = ((ptr[2] & 0x03) << 8) + ptr[3];
837 if (num_encodings == index)
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();
852 if ((ptr < payloadEndPtr) && (num_encodings == index))
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();
861 return payloadLen() - (ptr - payload()) - total_len;
866 // Randomize the payload, not the RTP header.
867 void NETEQTEST_RTPpacket::scramblePayload(void)
871 for (int i = 0; i < _payloadLen; ++i)
873 _payloadPtr[i] = static_cast<uint8_t>(rand());