diff --git a/src/libs/jrtplib/src/rtcpcompoundpacket.h b/src/libs/jrtplib/src/rtcpcompoundpacket.h index 9625e71b..ce327019 100644 --- a/src/libs/jrtplib/src/rtcpcompoundpacket.h +++ b/src/libs/jrtplib/src/rtcpcompoundpacket.h @@ -7,7 +7,7 @@ This library was developed at the Expertise Centre for Digital Media (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for + (http://www.uhasselt.be). The library is based upon work done for my thesis at the School for Knowledge Technology (Belgium/The Netherlands). Permission is hereby granted, free of charge, to any person obtaining a @@ -53,56 +53,56 @@ class RTCPPacket; class JRTPLIB_IMPORTEXPORT RTCPCompoundPacket : public RTPMemoryObject { public: - /** Creates an RTCPCompoundPacket instance from the data in \c rawpack, installing a memory manager if specified. */ - RTCPCompoundPacket(RTPRawPacket &rawpack, RTPMemoryManager *memmgr = 0); + /** Creates an RTCPCompoundPacket instance from the data in \c rawpack, installing a memory manager if specified. */ + RTCPCompoundPacket(RTPRawPacket &rawpack, RTPMemoryManager *memmgr = 0); - /** Creates an RTCPCompoundPacket instance from the data in \c packet}, with size \c len. - * Creates an RTCPCompoundPacket instance from the data in \c packet}, with size \c len. The \c deletedata - * flag specifies if the data in \c packet should be deleted when the compound packet is destroyed. If - * specified, a memory manager will be installed. - */ - RTCPCompoundPacket(uint8_t *packet, size_t len, bool deletedata = true, RTPMemoryManager *memmgr = 0); + /** Creates an RTCPCompoundPacket instance from the data in \c packet}, with size \c len. + * Creates an RTCPCompoundPacket instance from the data in \c packet}, with size \c len. The \c deletedata + * flag specifies if the data in \c packet should be deleted when the compound packet is destroyed. If + * specified, a memory manager will be installed. + */ + RTCPCompoundPacket(uint8_t *packet, size_t len, bool deletedata = true, RTPMemoryManager *memmgr = 0); protected: - RTCPCompoundPacket(RTPMemoryManager *memmgr); // this is for the compoundpacket builder + RTCPCompoundPacket(RTPMemoryManager *memmgr); // this is for the compoundpacket builder public: - virtual ~RTCPCompoundPacket(); + virtual ~RTCPCompoundPacket(); - /** Checks if the RTCP compound packet was created successfully. - * If the raw packet data in the constructor could not be parsed, this function returns the error code of - * what went wrong. If the packet had an invalid format, the return value is \c ERR_RTP_RTCPCOMPOUND_INVALIDPACKET. - */ - int GetCreationError() { return error; } + /** Checks if the RTCP compound packet was created successfully. + * If the raw packet data in the constructor could not be parsed, this function returns the error code of + * what went wrong. If the packet had an invalid format, the return value is \c ERR_RTP_RTCPCOMPOUND_INVALIDPACKET. + */ + int GetCreationError() { return error; } - /** Returns a pointer to the data of the entire RTCP compound packet. */ - const uint8_t *GetCompoundPacketData() { return compoundpacket; } + /** Returns a pointer to the data of the entire RTCP compound packet. */ + const uint8_t *GetCompoundPacketData() { return compoundpacket; } - /** Returns the size of the entire RTCP compound packet. */ - size_t GetCompoundPacketLength() { return compoundpacketlength; } + /** Returns the size of the entire RTCP compound packet. */ + size_t GetCompoundPacketLength() { return compoundpacketlength; } - /** Starts the iteration over the individual RTCP packets in the RTCP compound packet. */ - void GotoFirstPacket() { rtcppackit = rtcppacklist.begin(); } + /** Starts the iteration over the individual RTCP packets in the RTCP compound packet. */ + void GotoFirstPacket() { rtcppackit = rtcppacklist.begin(); } - /** Returns a pointer to the next individual RTCP packet. - * Returns a pointer to the next individual RTCP packet. Note that no \c delete call may be done - * on the RTCPPacket instance which is returned. - */ - RTCPPacket *GetNextPacket() { if (rtcppackit == rtcppacklist.end()) return 0; RTCPPacket *p = *rtcppackit; rtcppackit++; return p; } + /** Returns a pointer to the next individual RTCP packet. + * Returns a pointer to the next individual RTCP packet. Note that no \c delete call may be done + * on the RTCPPacket instance which is returned. + */ + RTCPPacket *GetNextPacket() { if (rtcppackit == rtcppacklist.end()) return 0; RTCPPacket *p = *rtcppackit; rtcppackit++; return p; } #ifdef RTPDEBUG - void Dump(); + void Dump(); #endif // RTPDEBUG protected: - void ClearPacketList(); - int ParseData(uint8_t *packet, size_t len); - - int error; + void ClearPacketList(); + int ParseData(uint8_t *packet, size_t len); - const uint8_t *compoundpacket; - size_t compoundpacketlength; - bool deletepacket; - - std::list rtcppacklist; - std::list::const_iterator rtcppackit; + int error; + + const uint8_t *compoundpacket; + size_t compoundpacketlength; + bool deletepacket; + + std::list rtcppacklist; + std::list::const_iterator rtcppackit; }; } // end namespace diff --git a/src/libs/jrtplib/src/rtppacket.cpp b/src/libs/jrtplib/src/rtppacket.cpp index 90ca24d5..54c67038 100644 --- a/src/libs/jrtplib/src/rtppacket.cpp +++ b/src/libs/jrtplib/src/rtppacket.cpp @@ -7,7 +7,7 @@ This library was developed at the Expertise Centre for Digital Media (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for + (http://www.uhasselt.be). The library is based upon work done for my thesis at the School for Knowledge Technology (Belgium/The Netherlands). Permission is hereby granted, free of charge, to any person obtaining a @@ -36,12 +36,12 @@ #include "rtperrors.h" #include "rtprawpacket.h" #if ! (defined(WIN32) || defined(_WIN32_WCE)) - #include - #include +#include +#include #endif // WIN32 #ifdef RTPDEBUG - #include +#include #endif // RTPDEBUG #include "rtpdebug.h" @@ -51,306 +51,310 @@ namespace jrtplib void RTPPacket::Clear() { - hasextension = false; - hasmarker = false; - numcsrcs = 0; - payloadtype = 0; - extseqnr = 0; - timestamp = 0; - ssrc = 0; - packet = 0; - payload = 0; - packetlength = 0; - payloadlength = 0; - extid = 0; - extension = 0; - extensionlength = 0; - error = 0; - externalbuffer = false; + hasextension = false; + hasmarker = false; + numcsrcs = 0; + payloadtype = 0; + extseqnr = 0; + timestamp = 0; + ssrc = 0; + packet = 0; + payload = 0; + packetlength = 0; + payloadlength = 0; + extid = 0; + extension = 0; + extensionlength = 0; + error = 0; + externalbuffer = false; } RTPPacket::RTPPacket(RTPRawPacket &rawpack,RTPMemoryManager *mgr) : RTPMemoryObject(mgr),receivetime(rawpack.GetReceiveTime()) { - Clear(); - error = ParseRawPacket(rawpack); + Clear(); + error = ParseRawPacket(rawpack); } RTPPacket::RTPPacket(uint8_t payloadtype,const void *payloaddata,size_t payloadlen,uint16_t seqnr, - uint32_t timestamp,uint32_t ssrc,bool gotmarker,uint8_t numcsrcs,const uint32_t *csrcs, - bool gotextension,uint16_t extensionid,uint16_t extensionlen_numwords,const void *extensiondata, - size_t maxpacksize, RTPMemoryManager *mgr) : RTPMemoryObject(mgr),receivetime(0,0) + uint32_t timestamp,uint32_t ssrc,bool gotmarker,uint8_t numcsrcs,const uint32_t *csrcs, + bool gotextension,uint16_t extensionid,uint16_t extensionlen_numwords,const void *extensiondata, + size_t maxpacksize, RTPMemoryManager *mgr) : RTPMemoryObject(mgr),receivetime(0,0) { - Clear(); - error = BuildPacket(payloadtype,payloaddata,payloadlen,seqnr,timestamp,ssrc,gotmarker,numcsrcs, - csrcs,gotextension,extensionid,extensionlen_numwords,extensiondata,0,maxpacksize); + Clear(); + error = BuildPacket(payloadtype,payloaddata,payloadlen,seqnr,timestamp,ssrc,gotmarker,numcsrcs, + csrcs,gotextension,extensionid,extensionlen_numwords,extensiondata,0,maxpacksize); } RTPPacket::RTPPacket(uint8_t payloadtype,const void *payloaddata,size_t payloadlen,uint16_t seqnr, - uint32_t timestamp,uint32_t ssrc,bool gotmarker,uint8_t numcsrcs,const uint32_t *csrcs, - bool gotextension,uint16_t extensionid,uint16_t extensionlen_numwords,const void *extensiondata, - void *buffer,size_t buffersize, RTPMemoryManager *mgr) : RTPMemoryObject(mgr),receivetime(0,0) + uint32_t timestamp,uint32_t ssrc,bool gotmarker,uint8_t numcsrcs,const uint32_t *csrcs, + bool gotextension,uint16_t extensionid,uint16_t extensionlen_numwords,const void *extensiondata, + void *buffer,size_t buffersize, RTPMemoryManager *mgr) : RTPMemoryObject(mgr),receivetime(0,0) { - Clear(); - if (buffer == 0) - error = ERR_RTP_PACKET_EXTERNALBUFFERNULL; - else if (buffersize <= 0) - error = ERR_RTP_PACKET_ILLEGALBUFFERSIZE; - else - error = BuildPacket(payloadtype,payloaddata,payloadlen,seqnr,timestamp,ssrc,gotmarker,numcsrcs, - csrcs,gotextension,extensionid,extensionlen_numwords,extensiondata,buffer,buffersize); + Clear(); + if (buffer == 0) + error = ERR_RTP_PACKET_EXTERNALBUFFERNULL; + else if (buffersize <= 0) + error = ERR_RTP_PACKET_ILLEGALBUFFERSIZE; + else + error = BuildPacket(payloadtype,payloaddata,payloadlen,seqnr,timestamp,ssrc,gotmarker,numcsrcs, + csrcs,gotextension,extensionid,extensionlen_numwords,extensiondata,buffer,buffersize); } RTPPacket::~RTPPacket() { - if (packet && !externalbuffer) - { - RTPDeleteByteArray(packet,GetMemoryManager()); - } + if (packet && !externalbuffer) + { + RTPDeleteByteArray(packet,GetMemoryManager()); + } } int RTPPacket::ParseRawPacket(RTPRawPacket &rawpack) { - uint8_t *packetbytes; - size_t packetlen; - uint8_t payloadtype; - RTPHeader *rtpheader; - bool marker; - int csrccount; - bool hasextension; - int payloadoffset,payloadlength; - int numpadbytes; - RTPExtensionHeader *rtpextheader; - uint16_t exthdrlen; - - if (!rawpack.IsRTP()) // If we didn't receive it on the RTP port, we'll ignore it - return ERR_RTP_PACKET_INVALIDPACKET; - - // The length should be at least the size of the RTP header - packetlen = rawpack.GetDataLength(); - if (packetlen < sizeof(RTPHeader)) - return ERR_RTP_PACKET_INVALIDPACKET; + uint8_t *packetbytes; + size_t packetlen; + uint8_t payloadtype; + RTPHeader *rtpheader; + bool marker; + int csrccount; + bool hasextension; + int payloadoffset,payloadlength; + int numpadbytes; + RTPExtensionHeader *rtpextheader; + uint16_t exthdrlen; - packetbytes = (uint8_t *)rawpack.GetData(); - rtpheader = (RTPHeader *)packetbytes; - - // The version number should be correct - if (rtpheader->version != RTP_VERSION) - return ERR_RTP_PACKET_INVALIDPACKET; - - // We'll check if this is possibly a RTCP packet. For this to be possible - // the marker bit and payload type combined should be either an SR or RR - // identifier - marker = (rtpheader->marker == 0)?false:true; - payloadtype = rtpheader->payloadtype; - if (marker) - { - if (payloadtype == (RTP_RTCPTYPE_SR & 127)) // don't check high bit (this was the marker!!) - return ERR_RTP_PACKET_INVALIDPACKET; - if (payloadtype == (RTP_RTCPTYPE_RR & 127)) - return ERR_RTP_PACKET_INVALIDPACKET; - } + if (!rawpack.IsRTP()) // If we didn't receive it on the RTP port, we'll ignore it + return ERR_RTP_PACKET_INVALIDPACKET; - csrccount = rtpheader->csrccount; - payloadoffset = sizeof(RTPHeader)+(int)(csrccount*sizeof(uint32_t)); - - if (rtpheader->padding) // adjust payload length to take padding into account - { - numpadbytes = (int)packetbytes[packetlen-1]; // last byte contains number of padding bytes - if (numpadbytes <= 0) - return ERR_RTP_PACKET_INVALIDPACKET; - } - else - numpadbytes = 0; + // The length should be at least the size of the RTP header + packetlen = rawpack.GetDataLength(); + if (packetlen < sizeof(RTPHeader)) + return ERR_RTP_PACKET_INVALIDPACKET; - hasextension = (rtpheader->extension == 0)?false:true; - if (hasextension) // got header extension - { - rtpextheader = (RTPExtensionHeader *)(packetbytes+payloadoffset); - payloadoffset += sizeof(RTPExtensionHeader); - exthdrlen = ntohs(rtpextheader->length); - payloadoffset += ((int)exthdrlen)*sizeof(uint32_t); - } - else - { - rtpextheader = 0; - exthdrlen = 0; - } - - payloadlength = packetlen-numpadbytes-payloadoffset; - if (payloadlength < 0) - return ERR_RTP_PACKET_INVALIDPACKET; + packetbytes = (uint8_t *)rawpack.GetData(); + rtpheader = (RTPHeader *)packetbytes; - // Now, we've got a valid packet, so we can create a new instance of RTPPacket - // and fill in the members - - RTPPacket::hasextension = hasextension; - if (hasextension) - { - RTPPacket::extid = ntohs(rtpextheader->extid); - RTPPacket::extensionlength = ((int)ntohs(rtpextheader->length))*sizeof(uint32_t); - RTPPacket::extension = ((uint8_t *)rtpextheader)+sizeof(RTPExtensionHeader); - } + // The version number should be correct + if (rtpheader->version != RTP_VERSION) + return ERR_RTP_PACKET_INVALIDPACKET; - RTPPacket::hasmarker = marker; - RTPPacket::numcsrcs = csrccount; - RTPPacket::payloadtype = payloadtype; - - // Note: we don't fill in the EXTENDED sequence number here, since we - // don't have information about the source here. We just fill in the low - // 16 bits - RTPPacket::extseqnr = (uint32_t)ntohs(rtpheader->sequencenumber); + // We'll check if this is possibly a RTCP packet. For this to be possible + // the marker bit and payload type combined should be either an SR or RR + // identifier + marker = (rtpheader->marker == 0)?false:true; + payloadtype = rtpheader->payloadtype; + if (marker) + { + if (payloadtype == (RTP_RTCPTYPE_SR & 127)) // don't check high bit (this was the marker!!) + return ERR_RTP_PACKET_INVALIDPACKET; + if (payloadtype == (RTP_RTCPTYPE_RR & 127)) + return ERR_RTP_PACKET_INVALIDPACKET; + } - RTPPacket::timestamp = ntohl(rtpheader->timestamp); - RTPPacket::ssrc = ntohl(rtpheader->ssrc); - RTPPacket::packet = packetbytes; - RTPPacket::payload = packetbytes+payloadoffset; - RTPPacket::packetlength = packetlen; - RTPPacket::payloadlength = payloadlength; + csrccount = rtpheader->csrccount; + payloadoffset = sizeof(RTPHeader)+(int)(csrccount*sizeof(uint32_t)); + if ((size_t)payloadoffset > packetlen) + return ERR_RTP_PACKET_INVALIDPACKET; - // We'll zero the data of the raw packet, since we're using it here now! - rawpack.ZeroData(); + if (rtpheader->padding) // adjust payload length to take padding into account + { + numpadbytes = (int)packetbytes[packetlen-1]; // last byte contains number of padding bytes + if (numpadbytes <= 0) + return ERR_RTP_PACKET_INVALIDPACKET; + } + else + numpadbytes = 0; - return 0; + hasextension = (rtpheader->extension == 0)?false:true; + if (hasextension) // got header extension + { + rtpextheader = (RTPExtensionHeader *)(packetbytes+payloadoffset); + payloadoffset += sizeof(RTPExtensionHeader); + if ((size_t)payloadoffset > packetlen) + return ERR_RTP_PACKET_INVALIDPACKET; + exthdrlen = ntohs(rtpextheader->length); + payloadoffset += ((int)exthdrlen)*sizeof(uint32_t); + } + else + { + rtpextheader = 0; + exthdrlen = 0; + } + + payloadlength = packetlen-numpadbytes-payloadoffset; + if (payloadlength < 0) + return ERR_RTP_PACKET_INVALIDPACKET; + + // Now, we've got a valid packet, so we can create a new instance of RTPPacket + // and fill in the members + + RTPPacket::hasextension = hasextension; + if (hasextension) + { + RTPPacket::extid = ntohs(rtpextheader->extid); + RTPPacket::extensionlength = ((int)ntohs(rtpextheader->length))*sizeof(uint32_t); + RTPPacket::extension = ((uint8_t *)rtpextheader)+sizeof(RTPExtensionHeader); + } + + RTPPacket::hasmarker = marker; + RTPPacket::numcsrcs = csrccount; + RTPPacket::payloadtype = payloadtype; + + // Note: we don't fill in the EXTENDED sequence number here, since we + // don't have information about the source here. We just fill in the low + // 16 bits + RTPPacket::extseqnr = (uint32_t)ntohs(rtpheader->sequencenumber); + + RTPPacket::timestamp = ntohl(rtpheader->timestamp); + RTPPacket::ssrc = ntohl(rtpheader->ssrc); + RTPPacket::packet = packetbytes; + RTPPacket::payload = packetbytes+payloadoffset; + RTPPacket::packetlength = packetlen; + RTPPacket::payloadlength = payloadlength; + + // We'll zero the data of the raw packet, since we're using it here now! + rawpack.ZeroData(); + + return 0; } uint32_t RTPPacket::GetCSRC(int num) const { - if (num >= numcsrcs) - return 0; + if (num >= numcsrcs) + return 0; - uint8_t *csrcpos; - uint32_t *csrcval_nbo; - uint32_t csrcval_hbo; - - csrcpos = packet+sizeof(RTPHeader)+num*sizeof(uint32_t); - csrcval_nbo = (uint32_t *)csrcpos; - csrcval_hbo = ntohl(*csrcval_nbo); - return csrcval_hbo; + uint8_t *csrcpos; + uint32_t *csrcval_nbo; + uint32_t csrcval_hbo; + + csrcpos = packet+sizeof(RTPHeader)+num*sizeof(uint32_t); + csrcval_nbo = (uint32_t *)csrcpos; + csrcval_hbo = ntohl(*csrcval_nbo); + return csrcval_hbo; } int RTPPacket::BuildPacket(uint8_t payloadtype,const void *payloaddata,size_t payloadlen,uint16_t seqnr, - uint32_t timestamp,uint32_t ssrc,bool gotmarker,uint8_t numcsrcs,const uint32_t *csrcs, - bool gotextension,uint16_t extensionid,uint16_t extensionlen_numwords,const void *extensiondata, - void *buffer,size_t maxsize) + uint32_t timestamp,uint32_t ssrc,bool gotmarker,uint8_t numcsrcs,const uint32_t *csrcs, + bool gotextension,uint16_t extensionid,uint16_t extensionlen_numwords,const void *extensiondata, + void *buffer,size_t maxsize) { - if (numcsrcs > RTP_MAXCSRCS) - return ERR_RTP_PACKET_TOOMANYCSRCS; + if (numcsrcs > RTP_MAXCSRCS) + return ERR_RTP_PACKET_TOOMANYCSRCS; - if (payloadtype > 127) // high bit should not be used - return ERR_RTP_PACKET_BADPAYLOADTYPE; - if (payloadtype == 72 || payloadtype == 73) // could cause confusion with rtcp types - return ERR_RTP_PACKET_BADPAYLOADTYPE; - - packetlength = sizeof(RTPHeader); - packetlength += sizeof(uint32_t)*((size_t)numcsrcs); - if (gotextension) - { - packetlength += sizeof(RTPExtensionHeader); - packetlength += sizeof(uint32_t)*((size_t)extensionlen_numwords); - } - packetlength += payloadlen; + if (payloadtype > 127) // high bit should not be used + return ERR_RTP_PACKET_BADPAYLOADTYPE; + if (payloadtype == 72 || payloadtype == 73) // could cause confusion with rtcp types + return ERR_RTP_PACKET_BADPAYLOADTYPE; - if (maxsize > 0 && packetlength > maxsize) - { - packetlength = 0; - return ERR_RTP_PACKET_DATAEXCEEDSMAXSIZE; - } + packetlength = sizeof(RTPHeader); + packetlength += sizeof(uint32_t)*((size_t)numcsrcs); + if (gotextension) + { + packetlength += sizeof(RTPExtensionHeader); + packetlength += sizeof(uint32_t)*((size_t)extensionlen_numwords); + } + packetlength += payloadlen; - // Ok, now we'll just fill in... - - RTPHeader *rtphdr; - - if (buffer == 0) - { - packet = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTPPACKET) uint8_t [packetlength]; - if (packet == 0) - { - packetlength = 0; - return ERR_RTP_OUTOFMEM; - } - externalbuffer = false; - } - else - { - packet = (uint8_t *)buffer; - externalbuffer = true; - } - - RTPPacket::hasmarker = gotmarker; - RTPPacket::hasextension = gotextension; - RTPPacket::numcsrcs = numcsrcs; - RTPPacket::payloadtype = payloadtype; - RTPPacket::extseqnr = (uint32_t)seqnr; - RTPPacket::timestamp = timestamp; - RTPPacket::ssrc = ssrc; - RTPPacket::payloadlength = payloadlen; - RTPPacket::extid = extensionid; - RTPPacket::extensionlength = ((size_t)extensionlen_numwords)*sizeof(uint32_t); - - rtphdr = (RTPHeader *)packet; - rtphdr->version = RTP_VERSION; - rtphdr->padding = 0; - if (gotmarker) - rtphdr->marker = 1; - else - rtphdr->marker = 0; - if (gotextension) - rtphdr->extension = 1; - else - rtphdr->extension = 0; - rtphdr->csrccount = numcsrcs; - rtphdr->payloadtype = payloadtype&127; // make sure high bit isn't set - rtphdr->sequencenumber = htons(seqnr); - rtphdr->timestamp = htonl(timestamp); - rtphdr->ssrc = htonl(ssrc); - - uint32_t *curcsrc; - int i; + if (maxsize > 0 && packetlength > maxsize) + { + packetlength = 0; + return ERR_RTP_PACKET_DATAEXCEEDSMAXSIZE; + } - curcsrc = (uint32_t *)(packet+sizeof(RTPHeader)); - for (i = 0 ; i < numcsrcs ; i++,curcsrc++) - *curcsrc = htonl(csrcs[i]); + // Ok, now we'll just fill in... - payload = packet+sizeof(RTPHeader)+((size_t)numcsrcs)*sizeof(uint32_t); - if (gotextension) - { - RTPExtensionHeader *rtpexthdr = (RTPExtensionHeader *)payload; + RTPHeader *rtphdr; - rtpexthdr->extid = htons(extensionid); - rtpexthdr->length = htons((uint16_t)extensionlen_numwords); - - payload += sizeof(RTPExtensionHeader); - memcpy(payload,extensiondata,RTPPacket::extensionlength); - - payload += RTPPacket::extensionlength; - } - memcpy(payload,payloaddata,payloadlen); - return 0; + if (buffer == 0) + { + packet = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTPPACKET) uint8_t [packetlength]; + if (packet == 0) + { + packetlength = 0; + return ERR_RTP_OUTOFMEM; + } + externalbuffer = false; + } + else + { + packet = (uint8_t *)buffer; + externalbuffer = true; + } + + RTPPacket::hasmarker = gotmarker; + RTPPacket::hasextension = gotextension; + RTPPacket::numcsrcs = numcsrcs; + RTPPacket::payloadtype = payloadtype; + RTPPacket::extseqnr = (uint32_t)seqnr; + RTPPacket::timestamp = timestamp; + RTPPacket::ssrc = ssrc; + RTPPacket::payloadlength = payloadlen; + RTPPacket::extid = extensionid; + RTPPacket::extensionlength = ((size_t)extensionlen_numwords)*sizeof(uint32_t); + + rtphdr = (RTPHeader *)packet; + rtphdr->version = RTP_VERSION; + rtphdr->padding = 0; + if (gotmarker) + rtphdr->marker = 1; + else + rtphdr->marker = 0; + if (gotextension) + rtphdr->extension = 1; + else + rtphdr->extension = 0; + rtphdr->csrccount = numcsrcs; + rtphdr->payloadtype = payloadtype&127; // make sure high bit isn't set + rtphdr->sequencenumber = htons(seqnr); + rtphdr->timestamp = htonl(timestamp); + rtphdr->ssrc = htonl(ssrc); + + uint32_t *curcsrc; + int i; + + curcsrc = (uint32_t *)(packet+sizeof(RTPHeader)); + for (i = 0 ; i < numcsrcs ; i++,curcsrc++) + *curcsrc = htonl(csrcs[i]); + + payload = packet+sizeof(RTPHeader)+((size_t)numcsrcs)*sizeof(uint32_t); + if (gotextension) + { + RTPExtensionHeader *rtpexthdr = (RTPExtensionHeader *)payload; + + rtpexthdr->extid = htons(extensionid); + rtpexthdr->length = htons((uint16_t)extensionlen_numwords); + + payload += sizeof(RTPExtensionHeader); + memcpy(payload,extensiondata,RTPPacket::extensionlength); + + payload += RTPPacket::extensionlength; + } + memcpy(payload,payloaddata,payloadlen); + return 0; } #ifdef RTPDEBUG void RTPPacket::Dump() { - int i; - - printf("Payload type: %d\n",(int)GetPayloadType()); - printf("Extended sequence number: 0x%08x\n",GetExtendedSequenceNumber()); - printf("Timestamp: 0x%08x\n",GetTimestamp()); - printf("SSRC: 0x%08x\n",GetSSRC()); - printf("Marker: %s\n",HasMarker()?"yes":"no"); - printf("CSRC count: %d\n",GetCSRCCount()); - for (i = 0 ; i < GetCSRCCount() ; i++) - printf(" CSRC[%02d]: 0x%08x\n",i,GetCSRC(i)); - printf("Payload: %s\n",GetPayloadData()); - printf("Payload length: %d\n",GetPayloadLength()); - printf("Packet length: %d\n",GetPacketLength()); - printf("Extension: %s\n",HasExtension()?"yes":"no"); - if (HasExtension()) - { - printf(" Extension ID: 0x%04x\n",GetExtensionID()); - printf(" Extension data: %s\n",GetExtensionData()); - printf(" Extension length: %d\n",GetExtensionLength()); - } + int i; + + printf("Payload type: %d\n",(int)GetPayloadType()); + printf("Extended sequence number: 0x%08x\n",GetExtendedSequenceNumber()); + printf("Timestamp: 0x%08x\n",GetTimestamp()); + printf("SSRC: 0x%08x\n",GetSSRC()); + printf("Marker: %s\n",HasMarker()?"yes":"no"); + printf("CSRC count: %d\n",GetCSRCCount()); + for (i = 0 ; i < GetCSRCCount() ; i++) + printf(" CSRC[%02d]: 0x%08x\n",i,GetCSRC(i)); + printf("Payload: %s\n",GetPayloadData()); + printf("Payload length: %d\n",GetPayloadLength()); + printf("Packet length: %d\n",GetPacketLength()); + printf("Extension: %s\n",HasExtension()?"yes":"no"); + if (HasExtension()) + { + printf(" Extension ID: 0x%04x\n",GetExtensionID()); + printf(" Extension data: %s\n",GetExtensionData()); + printf(" Extension length: %d\n",GetExtensionLength()); + } } #endif // RTPDEBUG