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()
39 memset(&_rtpInfo, 0, sizeof(_rtpInfo));
43 NETEQTEST_RTPpacket::~NETEQTEST_RTPpacket()
51 void NETEQTEST_RTPpacket::reset()
62 memset(&_rtpInfo, 0, sizeof(_rtpInfo));
67 int NETEQTEST_RTPpacket::skipFileHeader(FILE *fp)
73 const int kFirstLineLength = 40;
74 char firstline[kFirstLineLength];
75 if (fgets(firstline, kFirstLineLength, fp) == NULL) {
78 if (strncmp(firstline, "#!rtpplay", 9) == 0) {
79 if (strncmp(firstline, "#!rtpplay1.0", 12) != 0) {
83 else if (strncmp(firstline, "#!RTPencode", 11) == 0) {
84 if (strncmp(firstline, "#!RTPencode1.0", 14) != 0) {
93 const int kRtpDumpHeaderSize = 4 + 4 + 4 + 2 + 2;
94 if (fseek(fp, kRtpDumpHeaderSize, SEEK_CUR) != 0)
101 int NETEQTEST_RTPpacket::readFromFile(FILE *fp)
108 uint16_t length, plen;
112 bool readNextPacket = true;
113 while (readNextPacket) {
114 readNextPacket = false;
115 if (fread(&length,2,1,fp)==0)
120 length = ntohs(length);
122 if (fread(&plen,2,1,fp)==0)
127 packetLen = ntohs(plen);
129 if (fread(&offset,4,1,fp)==0)
134 // store in local variable until we have passed the reset below
135 uint32_t receiveTime = ntohl(offset);
137 // Use length here because a plen of 0 specifies rtcp
138 length = (uint16_t) (length - _kRDHeaderLen);
141 if (_datagram && _memSize < length)
148 _datagram = new uint8_t[length];
152 if (fread((unsigned short *) _datagram,1,length,fp) != length)
158 _datagramLen = length;
159 _receiveTime = receiveTime;
161 if (!_blockList.empty() && _blockList.count(payloadType()) > 0)
163 readNextPacket = true;
166 if (_filterSSRC && _selectSSRC != SSRC())
168 readNextPacket = true;
177 int NETEQTEST_RTPpacket::readFixedFromFile(FILE *fp, size_t length)
185 if (_datagram && _memSize < static_cast<int>(length))
192 _datagram = new uint8_t[length];
196 if (fread(_datagram, 1, length, fp) != length)
202 _datagramLen = length;
205 if (!_blockList.empty() && _blockList.count(payloadType()) > 0)
207 // discard this payload
208 return readFromFile(fp);
216 int NETEQTEST_RTPpacket::writeToFile(FILE *fp)
223 uint16_t length, plen;
226 // length including RTPplay header
227 length = htons(_datagramLen + _kRDHeaderLen);
228 if (fwrite(&length, 2, 1, fp) != 1)
234 plen = htons(_datagramLen);
235 if (fwrite(&plen, 2, 1, fp) != 1)
240 // offset (=receive time)
241 offset = htonl(_receiveTime);
242 if (fwrite(&offset, 4, 1, fp) != 1)
249 if (fwrite(_datagram, 1, _datagramLen, fp) !=
250 static_cast<size_t>(_datagramLen))
255 return _datagramLen + _kRDHeaderLen; // total number of bytes written
260 void NETEQTEST_RTPpacket::blockPT(uint8_t pt)
262 _blockList[pt] = true;
265 void NETEQTEST_RTPpacket::selectSSRC(uint32_t ssrc)
271 void NETEQTEST_RTPpacket::parseHeader()
279 if (_datagramLen < _kBasicHeaderLen)
285 _payloadLen = parseRTPheader(&_payloadPtr);
293 void NETEQTEST_RTPpacket::parseHeader(WebRtcNetEQ_RTPInfo & rtpInfo)
301 memcpy(&rtpInfo, &_rtpInfo, sizeof(WebRtcNetEQ_RTPInfo));
304 WebRtcNetEQ_RTPInfo const * NETEQTEST_RTPpacket::RTPinfo() const
316 uint8_t * NETEQTEST_RTPpacket::datagram() const
318 if (_datagramLen > 0)
328 uint8_t * NETEQTEST_RTPpacket::payload() const
340 int16_t NETEQTEST_RTPpacket::payloadLen()
346 int16_t NETEQTEST_RTPpacket::dataLen() const
351 bool NETEQTEST_RTPpacket::isParsed() const
356 bool NETEQTEST_RTPpacket::isLost() const
361 uint8_t NETEQTEST_RTPpacket::payloadType() const
363 WebRtcNetEQ_RTPInfo tempRTPinfo;
365 if(_datagram && _datagramLen >= _kBasicHeaderLen)
367 parseRTPheader(&tempRTPinfo);
374 return tempRTPinfo.payloadType;
377 uint16_t NETEQTEST_RTPpacket::sequenceNumber() const
379 WebRtcNetEQ_RTPInfo tempRTPinfo;
381 if(_datagram && _datagramLen >= _kBasicHeaderLen)
383 parseRTPheader(&tempRTPinfo);
390 return tempRTPinfo.sequenceNumber;
393 uint32_t NETEQTEST_RTPpacket::timeStamp() const
395 WebRtcNetEQ_RTPInfo tempRTPinfo;
397 if(_datagram && _datagramLen >= _kBasicHeaderLen)
399 parseRTPheader(&tempRTPinfo);
406 return tempRTPinfo.timeStamp;
409 uint32_t NETEQTEST_RTPpacket::SSRC() const
411 WebRtcNetEQ_RTPInfo tempRTPinfo;
413 if(_datagram && _datagramLen >= _kBasicHeaderLen)
415 parseRTPheader(&tempRTPinfo);
422 return tempRTPinfo.SSRC;
425 uint8_t NETEQTEST_RTPpacket::markerBit() const
427 WebRtcNetEQ_RTPInfo tempRTPinfo;
429 if(_datagram && _datagramLen >= _kBasicHeaderLen)
431 parseRTPheader(&tempRTPinfo);
438 return tempRTPinfo.markerBit;
443 int NETEQTEST_RTPpacket::setPayloadType(uint8_t pt)
446 if (_datagramLen < 12)
453 _rtpInfo.payloadType = pt;
456 _datagram[1]=(unsigned char)(pt & 0xFF);
462 int NETEQTEST_RTPpacket::setSequenceNumber(uint16_t sn)
465 if (_datagramLen < 12)
472 _rtpInfo.sequenceNumber = sn;
475 _datagram[2]=(unsigned char)((sn>>8)&0xFF);
476 _datagram[3]=(unsigned char)((sn)&0xFF);
482 int NETEQTEST_RTPpacket::setTimeStamp(uint32_t ts)
485 if (_datagramLen < 12)
492 _rtpInfo.timeStamp = ts;
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);
504 int NETEQTEST_RTPpacket::setSSRC(uint32_t ssrc)
507 if (_datagramLen < 12)
514 _rtpInfo.SSRC = ssrc;
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);
526 int NETEQTEST_RTPpacket::setMarkerBit(uint8_t mb)
529 if (_datagramLen < 12)
536 _rtpInfo.markerBit = mb;
541 _datagram[0] |= 0x01;
545 _datagram[0] &= 0xFE;
552 int NETEQTEST_RTPpacket::setRTPheader(const WebRtcNetEQ_RTPInfo *RTPinfo)
554 if (_datagramLen < 12)
556 // this packet is not ok
560 makeRTPheader(_datagram,
561 RTPinfo->payloadType,
562 RTPinfo->sequenceNumber,
571 int NETEQTEST_RTPpacket::splitStereo(NETEQTEST_RTPpacket* slaveRtp,
572 enum stereoModes mode)
574 // if mono, do nothing
575 if (mode == stereoModeMono)
580 // check that the RTP header info is parsed
583 // start by copying the main rtp packet
592 if(_payloadLen%2 != 0)
594 // length must be a factor of 2
600 case stereoModeSample1:
602 // sample based codec with 1-byte samples
603 splitStereoSample(slaveRtp, 1 /* 1 byte/sample */);
606 case stereoModeSample2:
608 // sample based codec with 2-byte samples
609 splitStereoSample(slaveRtp, 2 /* 2 bytes/sample */);
612 case stereoModeFrame:
615 splitStereoFrame(slaveRtp);
618 case stereoModeDuplicate:
620 // frame based codec, send the whole packet to both master and slave
621 splitStereoDouble(slaveRtp);
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
637 rtp_data[0]=(unsigned char)0x80;
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);
652 rtp_data[6]=(unsigned char)((timestamp>>8)&0xFF);
653 rtp_data[7]=(unsigned char)(timestamp & 0xFF);
655 rtp_data[8]=(unsigned char)((ssrc>>24)&0xFF);
656 rtp_data[9]=(unsigned char)((ssrc>>16)&0xFF);
658 rtp_data[10]=(unsigned char)((ssrc>>8)&0xFF);
659 rtp_data[11]=(unsigned char)(ssrc & 0xFF);
663 NETEQTEST_RTPpacket::parseRTPheader(WebRtcNetEQ_RTPInfo *RTPinfo,
664 uint8_t **payloadPtr) const
666 int16_t *rtp_data = (int16_t *) _datagram;
669 assert(_datagramLen >= 12);
670 parseBasicHeader(RTPinfo, &i_P, &i_X, &i_CC);
672 int i_startPosition = calcHeaderLength(i_X, i_CC);
674 int i_padlength = calcPadLength(i_P);
678 *payloadPtr = (uint8_t*) &rtp_data[i_startPosition >> 1];
681 return (uint16_t) (_datagramLen - i_startPosition - i_padlength);
685 void NETEQTEST_RTPpacket::parseBasicHeader(WebRtcNetEQ_RTPInfo *RTPinfo,
686 int *i_P, int *i_X, int *i_CC) const
688 int16_t *rtp_data = (int16_t *) _datagram;
689 if (_datagramLen < 12)
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));
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);
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);
717 int NETEQTEST_RTPpacket::calcHeaderLength(int i_X, int i_CC) const
720 int16_t *rtp_data = (int16_t *) _datagram;
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))
729 i_extlength = (((((uint16_t) rtp_data[7 + 2 * i_CC]) >> 8)
730 & 0xFF) | (((uint16_t) (rtp_data[7 + 2 * i_CC] & 0xFF))
735 return 12 + 4 * i_extlength + 4 * i_CC;
738 int NETEQTEST_RTPpacket::calcPadLength(int i_P) const
740 int16_t *rtp_data = (int16_t *) _datagram;
743 /* Padding exists. Find out how many bytes the padding consists of. */
744 if (_datagramLen & 0x1)
746 /* odd number of bytes => last byte in higher byte */
747 return rtp_data[_datagramLen >> 1] & 0xFF;
751 /* even number of bytes => last byte in lower byte */
752 return ((uint16_t) rtp_data[(_datagramLen >> 1) - 1]) >> 8;
758 void NETEQTEST_RTPpacket::splitStereoSample(NETEQTEST_RTPpacket* slaveRtp,
761 if(!_payloadPtr || !slaveRtp || !slaveRtp->_payloadPtr
762 || _payloadLen <= 0 || slaveRtp->_memSize < _memSize)
767 uint8_t *readDataPtr = _payloadPtr;
768 uint8_t *writeDataPtr = _payloadPtr;
769 uint8_t *slaveData = slaveRtp->_payloadPtr;
771 while (readDataPtr - _payloadPtr < _payloadLen)
774 for (int ix = 0; ix < stride; ix++) {
775 *writeDataPtr = *readDataPtr;
781 for (int ix = 0; ix < stride; ix++) {
782 *slaveData = *readDataPtr;
789 slaveRtp->_payloadLen = _payloadLen;
793 void NETEQTEST_RTPpacket::splitStereoFrame(NETEQTEST_RTPpacket* slaveRtp)
795 if(!_payloadPtr || !slaveRtp || !slaveRtp->_payloadPtr
796 || _payloadLen <= 0 || slaveRtp->_memSize < _memSize)
801 memmove(slaveRtp->_payloadPtr, _payloadPtr + _payloadLen/2, _payloadLen/2);
804 slaveRtp->_payloadLen = _payloadLen;
806 void NETEQTEST_RTPpacket::splitStereoDouble(NETEQTEST_RTPpacket* slaveRtp)
808 if(!_payloadPtr || !slaveRtp || !slaveRtp->_payloadPtr
809 || _payloadLen <= 0 || slaveRtp->_memSize < _memSize)
814 memcpy(slaveRtp->_payloadPtr, _payloadPtr, _payloadLen);
815 slaveRtp->_payloadLen = _payloadLen;
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)
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 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
829 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
836 uint8_t* ptr = payload();
837 uint8_t* payloadEndPtr = ptr + payloadLen();
838 int num_encodings = 0;
841 while ((ptr < payloadEndPtr) && (*ptr & 0x80))
843 int len = ((ptr[2] & 0x03) << 8) + ptr[3];
844 if (num_encodings == index)
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();
859 if ((ptr < payloadEndPtr) && (num_encodings == index))
862 red.payloadType = ptr[0] & 0x7F;
863 red.sequenceNumber = sequenceNumber();
864 red.timeStamp = timeStamp();
865 red.markerBit = markerBit();
868 return payloadLen() - (ptr - payload()) - total_len;
873 // Randomize the payload, not the RTP header.
874 void NETEQTEST_RTPpacket::scramblePayload(void)
878 for (int i = 0; i < _payloadLen; ++i)
880 _payloadPtr[i] = static_cast<uint8_t>(rand());