Compare commits

..

No commits in common. "e342abe2f57646bcdb287a8dba23b9f200261639" and "c3c59ddf03b60a2a09657b7b0a5e2b85f0d51171" have entirely different histories.

12 changed files with 403 additions and 322 deletions

View File

@ -184,3 +184,80 @@ void RtpDump::flush()
}
#endif
// -------------- MediaStreamId --------------------
bool MediaStreamId::operator < (const MediaStreamId& right) const
{
if (mSsrcIsId)
return std::tie(mSSRC, mSource, mDestination) < std::tie(right.mSSRC, right.mSource, right.mDestination);
else
return std::tie(mSource, mDestination) < std::tie(right.mSource, right.mDestination);
}
bool MediaStreamId::operator == (const MediaStreamId& right) const
{
if (mSsrcIsId)
return std::tie(mSSRC, mSource, mDestination) == std::tie(right.mSSRC, right.mSource, right.mDestination);
else
return std::tie(mSource, mDestination) == std::tie(right.mSource, right.mDestination);
}
std::string MediaStreamId::toString() const
{
std::ostringstream oss;
oss << "src: " << mSource.toStdString() <<
" dst: " << mDestination.toStdString() <<
" ssrc: " << StringHelper::toHex(mSSRC);
return oss.str();
}
void writeToJson(const MediaStreamId& id, std::ostringstream& oss)
{
oss << " \"src\": \"" << id.mSource.toStdString() << "\"," << std::endl
<< " \"dst\": \"" << id.mDestination.toStdString() << "\"," << std::endl
<< " \"ssrc\": \"" << StringHelper::toHex(id.mSSRC) << "\"," << std::endl
#if !defined(USE_NULL_UUID)
<< " \"link_id\": \"" << id.mLinkId.toString() << "\"" << std::endl
#endif
;
}
std::string MediaStreamId::getDetectDescription() const
{
std::ostringstream oss;
oss << "{\"event\": \"stream_detected\"," << std::endl;
writeToJson(*this, oss);
oss << "}";
return oss.str();
}
std::string MediaStreamId::getFinishDescription() const
{
std::ostringstream oss;
oss << "{" << std::endl
<< " \"event\": \"stream_finished\", " << std::endl;
writeToJson(*this, oss);
oss << "}";
return oss.str();
}
MediaStreamId& MediaStreamId::operator = (const MediaStreamId& src)
{
this->mDestination = src.mDestination;
this->mSource = src.mSource;
this->mLinkId = src.mLinkId;
this->mSSRC = src.mSSRC;
this->mSsrcIsId = src.mSsrcIsId;
return *this;
}
std::ostream& operator << (std::ostream& output, const MediaStreamId& id)
{
return (output << id.toString());
}

View File

@ -72,4 +72,22 @@ public:
};
#endif
struct MediaStreamId
{
InternetAddress mSource;
InternetAddress mDestination;
uint32_t mSSRC = 0;
bool mSsrcIsId = true;
Uuid mLinkId;
bool operator < (const MediaStreamId& s2) const;
bool operator == (const MediaStreamId& right) const;
std::string toString() const;
std::string getDetectDescription() const;
std::string getFinishDescription() const;
MediaStreamId& operator = (const MediaStreamId& src);
};
std::ostream& operator << (std::ostream& output, const MediaStreamId& id);
#endif

View File

@ -80,8 +80,6 @@ if (CMAKE_SYSTEM MATCHES "Windows*")
endif()
add_library(media_lib ${SOURCES})
# Depending on ice stack library to provide bit level operations
target_link_libraries(media_lib PUBLIC ice_stack)
target_include_directories(media_lib
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../libs/

View File

@ -67,7 +67,7 @@ void JitterStatistics::process(jrtplib::RTPPacket* packet, int rate)
Statistics::Statistics()
:mReceived(0), mSent(0), mReceivedRtp(0), mSentRtp(0),
mReceivedRtcp(0), mSentRtcp(0), mDuplicatedRtp(0), mOldRtp(0), mIllegalRtp(0),
mPacketLoss(0), mJitter(0.0), mAudioTime(0), mSsrc(0), mPacketDropped(0), mDecodedAudio(0)
mPacketLoss(0), mJitter(0.0), mAudioTime(0), mSsrc(0), mPacketDropped(0)
{
mBitrateSwitchCounter = 0;
memset(mLoss, 0, sizeof mLoss);
@ -95,7 +95,7 @@ void Statistics::reset()
mJitter = 0.0;
mAudioTime = 0;
mPacketDropped = 0;
mDecodedAudio = 0;
memset(mLoss, 0, sizeof mLoss);
}
@ -179,7 +179,7 @@ Statistics& Statistics::operator += (const Statistics& src)
mPacketLoss += src.mPacketLoss;
mPacketDropped += src.mPacketDropped;
mAudioTime += src.mAudioTime;
mDecodedAudio += src.mDecodedAudio;
for (auto codecStat: src.mCodecCount)
{
@ -230,7 +230,6 @@ Statistics& Statistics::operator -= (const Statistics& src)
mOldRtp -= src.mOldRtp;
mPacketLoss -= src.mPacketLoss;
mPacketDropped -= src.mPacketDropped;
mDecodedAudio -= src.mDecodedAudio;
mAudioTime -= src.mAudioTime;
for (auto codecStat: src.mCodecCount)

View File

@ -63,8 +63,6 @@ public:
mPacketDropped, // Number of dropped packets (due to time unsync when playing)б
mIllegalRtp; // Number of rtp packets with bad payload type
size_t mDecodedAudio; // Size of decoded audio bytes
TestResult<float> mDecodingInterval, // Average interval on call to packet decode
mDecodeRequested, // Average amount of requested audio frames to play
mPacketInterval; // Average interval between packet adding to jitter buffer
@ -100,10 +98,10 @@ public:
Statistics& operator -= (const Statistics& src);
float mNetworkMos = 0.0;
// #if defined(USE_PVQA_LIBRARY) && !defined(PVQA_SERVER)
// float mPvqaMos = 0.0;
//std::string mPvqaReport;
// #endif
#if defined(USE_PVQA_LIBRARY) && !defined(PVQA_SERVER)
float mPvqaMos = 0.0;
std::string mPvqaReport;
#endif
std::string toString() const;
};

View File

@ -201,6 +201,7 @@ void Logger::beginLine(LogLevel level, const char* filename, int linenumber, con
void
Logger::endLine()
{
*mStream << std::endl;
*mStream << std::flush;
mStream->flush();
@ -212,7 +213,7 @@ Logger::endLine()
result << time_buffer << ":" << (unix_timestamp_ms.count() % 1000 ) << "\t" << " | " << std::setw(8) << ThreadInfo::currentThread() << " | " << std::setw(30)
<< mFilename.c_str() << " | " << std::setw(4) << mLine << " | " << std::setw(12) << mSubsystem.c_str() << " | "
<< mStream->str().c_str() << std::endl;
<< mStream->str().c_str();
std::string t = result.str();
if (mUseDebugWindow) {

View File

@ -86,14 +86,8 @@ protected:
class LogLock
{
public:
LogLock(LogGuard& g) :mGuard(g)
{
mGuard.Lock();
}
~LogLock()
{
mGuard.Unlock();
}
LogLock(LogGuard& g) :mGuard(g) { mGuard.Lock(); }
~LogLock() { mGuard.Unlock(); }
protected:
LogGuard& mGuard;

View File

@ -91,4 +91,4 @@ set(JRTPLIB_SOURCES
rtpexternaltransmitter.cpp)
add_library(jrtplib STATIC ${JRTPLIB_SOURCES})
target_include_directories(jrtplib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

View File

@ -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);
void ClearPacketList();
int ParseData(uint8_t *packet, size_t len);
int error;
int error;
const uint8_t *compoundpacket;
size_t compoundpacketlength;
bool deletepacket;
const uint8_t *compoundpacket;
size_t compoundpacketlength;
bool deletepacket;
std::list<RTCPPacket *> rtcppacklist;
std::list<RTCPPacket *>::const_iterator rtcppackit;
std::list<RTCPPacket *> rtcppacklist;
std::list<RTCPPacket *>::const_iterator rtcppackit;
};
} // end namespace

View File

@ -36,12 +36,12 @@
#include "rtperrors.h"
#include "rtprawpacket.h"
#if ! (defined(WIN32) || defined(_WIN32_WCE))
#include <netinet/in.h>
#include <string.h>
#include <netinet/in.h>
#include <string.h>
#endif // WIN32
#ifdef RTPDEBUG
#include <stdio.h>
#include <stdio.h>
#endif // RTPDEBUG
#include "rtpdebug.h"
@ -51,310 +51,306 @@ 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;
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;
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;
// The length should be at least the size of the RTP header
packetlen = rawpack.GetDataLength();
if (packetlen < sizeof(RTPHeader))
return ERR_RTP_PACKET_INVALIDPACKET;
packetbytes = (uint8_t *)rawpack.GetData();
rtpheader = (RTPHeader *)packetbytes;
packetbytes = (uint8_t *)rawpack.GetData();
rtpheader = (RTPHeader *)packetbytes;
// The version number should be correct
if (rtpheader->version != RTP_VERSION)
return ERR_RTP_PACKET_INVALIDPACKET;
// 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;
}
// 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;
}
csrccount = rtpheader->csrccount;
payloadoffset = sizeof(RTPHeader)+(int)(csrccount*sizeof(uint32_t));
if ((size_t)payloadoffset > packetlen)
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;
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;
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;
}
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;
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
// 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::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;
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);
// 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;
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();
// We'll zero the data of the raw packet, since we're using it here now!
rawpack.ZeroData();
return 0;
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;
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;
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;
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;
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 (maxsize > 0 && packetlength > maxsize)
{
packetlength = 0;
return ERR_RTP_PACKET_DATAEXCEEDSMAXSIZE;
}
if (maxsize > 0 && packetlength > maxsize)
{
packetlength = 0;
return ERR_RTP_PACKET_DATAEXCEEDSMAXSIZE;
}
// Ok, now we'll just fill in...
// Ok, now we'll just fill in...
RTPHeader *rtphdr;
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;
}
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);
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);
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;
uint32_t *curcsrc;
int i;
curcsrc = (uint32_t *)(packet+sizeof(RTPHeader));
for (i = 0 ; i < numcsrcs ; i++,curcsrc++)
*curcsrc = htonl(csrcs[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;
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);
rtpexthdr->extid = htons(extensionid);
rtpexthdr->length = htons((uint16_t)extensionlen_numwords);
payload += sizeof(RTPExtensionHeader);
memcpy(payload,extensiondata,RTPPacket::extensionlength);
payload += sizeof(RTPExtensionHeader);
memcpy(payload,extensiondata,RTPPacket::extensionlength);
payload += RTPPacket::extensionlength;
}
memcpy(payload,payloaddata,payloadlen);
return 0;
payload += RTPPacket::extensionlength;
}
memcpy(payload,payloaddata,payloadlen);
return 0;
}
#ifdef RTPDEBUG
void RTPPacket::Dump()
{
int i;
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());
}
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

View File

@ -131,7 +131,7 @@ public:
/** Returns the payload length. */
size_t GetPayloadLength() const { return payloadlength; }
void SetPayloadLength(size_t l) { payloadlength = l; }
void SetPayloadLength(size_t l) { payloadlength = l; }
/** If a header extension is present, this function returns the extension identifier. */
uint16_t GetExtensionID() const { return extid; }

View File

@ -20,7 +20,7 @@ set (SPEEXDSP_SOURCES
)
add_library(speexdsp ${SPEEXDSP_SOURCES})
target_compile_definitions(speexdsp PUBLIC -DUSE_KISS_FFT -DFLOATING_POINT -DHAVE_STDINT_H)
target_compile_definitions(speexdsp PUBLIC -DUSE_KISS_FFT -DFIXED_POINT -DHAVE_STDINT_H)
target_include_directories(speexdsp PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/libspeexdsp