mirror of https://github.com/f4exb/sdrangel.git
qrtplib: new RTPUDPTransmitter
This commit is contained in:
parent
503c6093b9
commit
afe3fbabd3
|
@ -42,6 +42,7 @@ set (qrtplib_HEADERS
|
|||
rtptransmitter.h
|
||||
rtptypes_win.h
|
||||
rtptypes.h
|
||||
rtpudpransmitter.h
|
||||
# rtpudpv4transmitter.h
|
||||
# rtpudpv4transmitternobind.h
|
||||
# rtpexternaltransmitter.h
|
||||
|
@ -82,6 +83,7 @@ set(qrtplib_SOURCES
|
|||
rtpsourcedata.cpp
|
||||
rtpsources.cpp
|
||||
rtptimeutilities.cpp
|
||||
rtpudptransmitter.cpp
|
||||
# rtpudpv4transmitter.cpp
|
||||
# rtpudpv4transmitternobind.cpp
|
||||
# rtpexternaltransmitter.cpp
|
||||
|
|
|
@ -61,30 +61,30 @@ RTCPCompoundPacket::RTCPCompoundPacket(RTPRawPacket &rawpack)
|
|||
std::size_t datalen = rawpack.GetDataLength();
|
||||
|
||||
error = ParseData(data, datalen);
|
||||
if (error < 0)
|
||||
|
||||
if (error < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
compoundpacket = rawpack.GetData();
|
||||
compoundpacketlength = rawpack.GetDataLength();
|
||||
deletepacket = true;
|
||||
|
||||
rawpack.ZeroData();
|
||||
|
||||
rtcppackit = rtcppacklist.begin();
|
||||
}
|
||||
|
||||
RTCPCompoundPacket::RTCPCompoundPacket(uint8_t *packet, std::size_t packetlen, bool deletedata)
|
||||
RTCPCompoundPacket::RTCPCompoundPacket(uint8_t *packet, std::size_t packetlen)
|
||||
{
|
||||
compoundpacket = 0;
|
||||
compoundpacketlength = 0;
|
||||
|
||||
error = ParseData(packet, packetlen);
|
||||
if (error < 0)
|
||||
|
||||
if (error < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
compoundpacket = packet;
|
||||
compoundpacketlength = packetlen;
|
||||
deletepacket = deletedata;
|
||||
|
||||
rtcppackit = rtcppacklist.begin();
|
||||
}
|
||||
|
@ -94,7 +94,6 @@ RTCPCompoundPacket::RTCPCompoundPacket()
|
|||
compoundpacket = 0;
|
||||
compoundpacketlength = 0;
|
||||
error = 0;
|
||||
deletepacket = true;
|
||||
}
|
||||
|
||||
int RTCPCompoundPacket::ParseData(uint8_t *data, std::size_t datalen)
|
||||
|
@ -195,16 +194,16 @@ int RTCPCompoundPacket::ParseData(uint8_t *data, std::size_t datalen)
|
|||
RTCPCompoundPacket::~RTCPCompoundPacket()
|
||||
{
|
||||
ClearPacketList();
|
||||
if (compoundpacket && deletepacket)
|
||||
delete[] compoundpacket;
|
||||
}
|
||||
|
||||
void RTCPCompoundPacket::ClearPacketList()
|
||||
{
|
||||
std::list<RTCPPacket *>::const_iterator it;
|
||||
|
||||
for (it = rtcppacklist.begin(); it != rtcppacklist.end(); it++)
|
||||
for (it = rtcppacklist.begin(); it != rtcppacklist.end(); it++) {
|
||||
delete *it;
|
||||
}
|
||||
|
||||
rtcppacklist.clear();
|
||||
rtcppackit = rtcppacklist.begin();
|
||||
}
|
||||
|
|
|
@ -58,12 +58,8 @@ public:
|
|||
/** Creates an RTCPCompoundPacket instance from the data in \c rawpack, installing a memory manager if specified. */
|
||||
RTCPCompoundPacket(RTPRawPacket &rawpack);
|
||||
|
||||
/** 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, std::size_t len, bool deletedata = true);
|
||||
/** Creates an RTCPCompoundPacket instance from the data in \c packet}, with size \c len. */
|
||||
RTCPCompoundPacket(uint8_t *packet, std::size_t len);
|
||||
protected:
|
||||
RTCPCompoundPacket(); // this is for the compoundpacket builder
|
||||
public:
|
||||
|
@ -118,7 +114,6 @@ protected:
|
|||
|
||||
uint8_t *compoundpacket;
|
||||
std::size_t compoundpacketlength;
|
||||
bool deletepacket;
|
||||
|
||||
std::list<RTCPPacket *> rtcppacklist;
|
||||
std::list<RTCPPacket *>::const_iterator rtcppackit;
|
||||
|
|
|
@ -77,4 +77,9 @@ bool RTPAddress::IsFromSameHost(const RTPAddress *addr) const
|
|||
return addr->address == address;
|
||||
}
|
||||
|
||||
bool RTPAddress::operator==(const RTPAddress& otherAddress)
|
||||
{
|
||||
return IsSameAddress(&otherAddress);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -82,6 +82,9 @@ public:
|
|||
*/
|
||||
bool IsFromSameHost(const RTPAddress *addr) const;
|
||||
|
||||
/** Equality */
|
||||
bool operator==(const RTPAddress& otherAddress);
|
||||
|
||||
/** Get host address */
|
||||
const QHostAddress& getAddress() const
|
||||
{
|
||||
|
|
|
@ -49,11 +49,5 @@
|
|||
#define RTP_SNPRINTF snprintf
|
||||
#endif
|
||||
|
||||
#ifdef RTP_HAVE_STRNCPY_S
|
||||
#define RTP_STRNCPY(dest, src, len) strncpy_s((dest), (len), (src), _TRUNCATE)
|
||||
#else
|
||||
#define RTP_STRNCPY(dest, src, len) strncpy((dest), (src), (len))
|
||||
#endif // RTP_HAVE_STRNCPY_S
|
||||
|
||||
#endif // RTPINTERNALUTILS_H
|
||||
|
||||
|
|
|
@ -67,17 +67,58 @@ RTPPacket::RTPPacket(RTPRawPacket &rawpack) :
|
|||
error = ParseRawPacket(rawpack);
|
||||
}
|
||||
|
||||
RTPPacket::RTPPacket(uint8_t payloadtype, const void *payloaddata, std::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, std::size_t maxpacksize) :
|
||||
RTPPacket::RTPPacket(
|
||||
uint8_t payloadtype,
|
||||
const void *payloaddata,
|
||||
std::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,
|
||||
std::size_t maxpacksize) :
|
||||
receivetime(0, 0)
|
||||
{
|
||||
Clear();
|
||||
error = BuildPacket(payloadtype, payloaddata, payloadlen, seqnr, timestamp, ssrc, gotmarker, numcsrcs, csrcs, gotextension, extensionid, extensionlen_numwords, extensiondata,
|
||||
0, maxpacksize);
|
||||
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, std::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, std::size_t buffersize) :
|
||||
RTPPacket::RTPPacket(
|
||||
uint8_t payloadtype,
|
||||
const void *payloaddata,
|
||||
std::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,
|
||||
std::size_t buffersize) :
|
||||
receivetime(0, 0)
|
||||
{
|
||||
Clear();
|
||||
|
@ -86,8 +127,22 @@ RTPPacket::RTPPacket(uint8_t payloadtype, const void *payloaddata, std::size_t p
|
|||
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);
|
||||
error = BuildPacket(
|
||||
payloadtype,
|
||||
payloaddata,
|
||||
payloadlen,
|
||||
seqnr,
|
||||
timestamp,
|
||||
ssrc,
|
||||
gotmarker,
|
||||
numcsrcs,
|
||||
csrcs,
|
||||
gotextension,
|
||||
extensionid,
|
||||
extensionlen_numwords,
|
||||
extensiondata,
|
||||
buffer,
|
||||
buffersize);
|
||||
}
|
||||
|
||||
int RTPPacket::ParseRawPacket(RTPRawPacket &rawpack)
|
||||
|
@ -188,9 +243,6 @@ int RTPPacket::ParseRawPacket(RTPRawPacket &rawpack)
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -209,8 +261,22 @@ uint32_t RTPPacket::GetCSRC(int num) const
|
|||
return csrcval_hbo;
|
||||
}
|
||||
|
||||
int RTPPacket::BuildPacket(uint8_t payloadtype, const void *payloaddata, std::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, std::size_t maxsize)
|
||||
int RTPPacket::BuildPacket(
|
||||
uint8_t payloadtype,
|
||||
const void *payloaddata,
|
||||
std::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,
|
||||
std::size_t maxsize)
|
||||
{
|
||||
if (numcsrcs > RTP_MAXCSRCS)
|
||||
return ERR_RTP_PACKET_TOOMANYCSRCS;
|
||||
|
|
|
@ -57,7 +57,7 @@ public:
|
|||
* The flag which indicates whether this data is RTP or RTCP data is set to \c rtp. A memory
|
||||
* manager can be installed as well.
|
||||
*/
|
||||
RTPRawPacket(uint8_t *data, std::size_t datalen, RTPAddress *address, RTPTime &recvtime, bool rtp);
|
||||
RTPRawPacket(const uint8_t *data, std::size_t datalen, const RTPAddress& address, RTPTime &recvtime, bool rtp);
|
||||
~RTPRawPacket();
|
||||
|
||||
/** Returns the pointer to the data which is contained in this packet. */
|
||||
|
@ -79,7 +79,7 @@ public:
|
|||
}
|
||||
|
||||
/** Returns the address stored in this packet. */
|
||||
const RTPAddress *GetSenderAddress() const
|
||||
const RTPAddress& GetSenderAddress() const
|
||||
{
|
||||
return senderaddress;
|
||||
}
|
||||
|
@ -90,45 +90,28 @@ public:
|
|||
return isrtp;
|
||||
}
|
||||
|
||||
/** Sets the pointer to the data stored in this packet to zero.
|
||||
* Sets the pointer to the data stored in this packet to zero. This will prevent
|
||||
* a \c delete call for the actual data when the destructor of RTPRawPacket is called.
|
||||
* This function is used by the RTPPacket and RTCPCompoundPacket classes to obtain
|
||||
* the packet data (without having to copy it) and to make sure the data isn't deleted
|
||||
* when the destructor of RTPRawPacket is called.
|
||||
*/
|
||||
void ZeroData()
|
||||
{
|
||||
packetdata = 0;
|
||||
packetdatalength = 0;
|
||||
}
|
||||
|
||||
/** Allocates a number of bytes for RTP or RTCP data using the memory manager that
|
||||
* was used for this raw packet instance, can be useful if the RTPRawPacket::SetData
|
||||
* function will be used. */
|
||||
uint8_t *AllocateBytes(int recvlen) const;
|
||||
|
||||
/** Deallocates the previously stored data and replaces it with the data that's
|
||||
* specified, can be useful when e.g. decrypting data in RTPSession::OnChangeIncomingData */
|
||||
void SetData(uint8_t *data, std::size_t datalen);
|
||||
void SetData(const uint8_t *data, std::size_t datalen);
|
||||
|
||||
/** Deallocates the currently stored RTPAddress instance and replaces it
|
||||
* with the one that's specified (you probably don't need this function). */
|
||||
void SetSenderAddress(RTPAddress *address);
|
||||
void SetSenderAddress(const RTPAddress& address);
|
||||
private:
|
||||
void DeleteData();
|
||||
|
||||
uint8_t *packetdata;
|
||||
std::size_t packetdatalength;
|
||||
RTPTime receivetime;
|
||||
RTPAddress *senderaddress;
|
||||
RTPAddress senderaddress;
|
||||
bool isrtp;
|
||||
};
|
||||
|
||||
inline RTPRawPacket::RTPRawPacket(uint8_t *data, std::size_t datalen, RTPAddress *address, RTPTime &recvtime, bool rtp) :
|
||||
inline RTPRawPacket::RTPRawPacket(const uint8_t *data, std::size_t datalen, const RTPAddress& address, RTPTime &recvtime, bool rtp) :
|
||||
receivetime(recvtime)
|
||||
{
|
||||
packetdata = data;
|
||||
packetdata = new uint8_t[datalen];
|
||||
memcpy(packetdata, data, datalen);
|
||||
packetdatalength = datalen;
|
||||
senderaddress = address;
|
||||
isrtp = rtp;
|
||||
|
@ -142,33 +125,25 @@ inline RTPRawPacket::~RTPRawPacket()
|
|||
inline void RTPRawPacket::DeleteData()
|
||||
{
|
||||
if (packetdata)
|
||||
{
|
||||
delete[] packetdata;
|
||||
if (senderaddress)
|
||||
delete senderaddress;
|
||||
|
||||
packetdata = 0;
|
||||
senderaddress = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline uint8_t *RTPRawPacket::AllocateBytes(int recvlen) const
|
||||
inline void RTPRawPacket::SetData(const uint8_t *data, std::size_t datalen)
|
||||
{
|
||||
return new uint8_t[recvlen];
|
||||
}
|
||||
|
||||
inline void RTPRawPacket::SetData(uint8_t *data, std::size_t datalen)
|
||||
{
|
||||
if (packetdata)
|
||||
if (packetdata) {
|
||||
delete[] packetdata;
|
||||
}
|
||||
|
||||
packetdata = data;
|
||||
packetdata = new uint8_t[datalen];
|
||||
memcpy(packetdata, data, datalen);
|
||||
packetdatalength = datalen;
|
||||
}
|
||||
|
||||
inline void RTPRawPacket::SetSenderAddress(RTPAddress *address)
|
||||
inline void RTPRawPacket::SetSenderAddress(const RTPAddress& address)
|
||||
{
|
||||
if (senderaddress)
|
||||
delete senderaddress;
|
||||
|
||||
senderaddress = address;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,20 +55,16 @@
|
|||
#include <winbase.h>
|
||||
#endif // WIN32
|
||||
|
||||
#define SOURCES_LOCK
|
||||
#define SOURCES_UNLOCK
|
||||
#define BUILDER_LOCK
|
||||
#define BUILDER_UNLOCK
|
||||
#define SCHED_LOCK
|
||||
#define SCHED_UNLOCK
|
||||
#define PACKSENT_LOCK
|
||||
#define PACKSENT_UNLOCK
|
||||
|
||||
namespace qrtplib
|
||||
{
|
||||
|
||||
RTPSession::RTPSession(RTPRandom *r) :
|
||||
rtprnd(GetRandomNumberGenerator(r)), sources(*this), packetbuilder(*rtprnd), rtcpsched(sources, *rtprnd), rtcpbuilder(sources, packetbuilder)
|
||||
rtprnd(GetRandomNumberGenerator(r)),
|
||||
sources(*this),
|
||||
packetbuilder(*rtprnd),
|
||||
rtcpsched(sources, *rtprnd),
|
||||
rtcpbuilder(sources, packetbuilder)
|
||||
{
|
||||
// We're not going to set these flags in Create, so that the constructor of a derived class
|
||||
// can already change them
|
||||
|
@ -97,9 +93,6 @@ int RTPSession::Create(const RTPSessionParams &sessparams, const RTPTransmission
|
|||
return ERR_RTP_SESSION_ALREADYCREATED;
|
||||
|
||||
usingpollthread = sessparams.IsUsingPollThread();
|
||||
needthreadsafety = sessparams.NeedThreadSafety();
|
||||
if (usingpollthread && !needthreadsafety)
|
||||
return ERR_RTP_SESSION_THREADSAFETYCONFLICT;
|
||||
|
||||
useSR_BYEifpossible = sessparams.GetSenderReportForBYE();
|
||||
sentpackets = false;
|
||||
|
@ -135,7 +128,7 @@ int RTPSession::Create(const RTPSessionParams &sessparams, const RTPTransmission
|
|||
|
||||
if (rtptrans == 0)
|
||||
return ERR_RTP_OUTOFMEM;
|
||||
if ((status = rtptrans->Init(needthreadsafety)) < 0)
|
||||
if ((status = rtptrans->Init()) < 0)
|
||||
{
|
||||
delete rtptrans;
|
||||
return status;
|
||||
|
@ -158,9 +151,6 @@ int RTPSession::Create(const RTPSessionParams &sessparams, RTPTransmitter *trans
|
|||
return ERR_RTP_SESSION_ALREADYCREATED;
|
||||
|
||||
usingpollthread = sessparams.IsUsingPollThread();
|
||||
needthreadsafety = sessparams.NeedThreadSafety();
|
||||
if (usingpollthread && !needthreadsafety)
|
||||
return ERR_RTP_SESSION_THREADSAFETYCONFLICT;
|
||||
|
||||
useSR_BYEifpossible = sessparams.GetSenderReportForBYE();
|
||||
sentpackets = false;
|
||||
|
@ -236,7 +226,7 @@ int RTPSession::InternalCreate(const RTPSessionParams &sessparams)
|
|||
}
|
||||
else
|
||||
{
|
||||
RTP_STRNCPY((char * )buf, forcedcname.c_str(), buflen);
|
||||
strncpy((char * )buf, forcedcname.c_str(), buflen);
|
||||
buf[buflen - 1] = 0;
|
||||
buflen = strlen((char *) buf);
|
||||
}
|
||||
|
@ -419,9 +409,7 @@ uint32_t RTPSession::GetLocalSSRC()
|
|||
|
||||
uint32_t ssrc;
|
||||
|
||||
BUILDER_LOCK
|
||||
ssrc = packetbuilder.GetSSRC();
|
||||
BUILDER_UNLOCK
|
||||
return ssrc;
|
||||
}
|
||||
|
||||
|
@ -467,13 +455,6 @@ int RTPSession::LeaveMulticastGroup(const RTPAddress &addr)
|
|||
return rtptrans->LeaveMulticastGroup(addr);
|
||||
}
|
||||
|
||||
void RTPSession::LeaveAllMulticastGroups()
|
||||
{
|
||||
if (!created)
|
||||
return;
|
||||
rtptrans->LeaveAllMulticastGroups();
|
||||
}
|
||||
|
||||
int RTPSession::SendPacket(const void *data, std::size_t len)
|
||||
{
|
||||
int status;
|
||||
|
@ -481,25 +462,17 @@ int RTPSession::SendPacket(const void *data, std::size_t len)
|
|||
if (!created)
|
||||
return ERR_RTP_SESSION_NOTCREATED;
|
||||
|
||||
BUILDER_LOCK
|
||||
if ((status = packetbuilder.BuildPacket(data, len)) < 0)
|
||||
{
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
if ((status = SendRTPData(packetbuilder.GetPacket(), packetbuilder.GetPacketLength())) < 0)
|
||||
{
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
BUILDER_UNLOCK
|
||||
|
||||
SOURCES_LOCK
|
||||
sources.SentRTPPacket();
|
||||
SOURCES_UNLOCK
|
||||
PACKSENT_LOCK
|
||||
sentpackets = true;
|
||||
PACKSENT_UNLOCK
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -510,25 +483,17 @@ int RTPSession::SendPacket(const void *data, std::size_t len, uint8_t pt, bool m
|
|||
if (!created)
|
||||
return ERR_RTP_SESSION_NOTCREATED;
|
||||
|
||||
BUILDER_LOCK
|
||||
if ((status = packetbuilder.BuildPacket(data, len, pt, mark, timestampinc)) < 0)
|
||||
{
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
if ((status = SendRTPData(packetbuilder.GetPacket(), packetbuilder.GetPacketLength())) < 0)
|
||||
{
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
BUILDER_UNLOCK
|
||||
|
||||
SOURCES_LOCK
|
||||
sources.SentRTPPacket();
|
||||
SOURCES_UNLOCK
|
||||
PACKSENT_LOCK
|
||||
sentpackets = true;
|
||||
PACKSENT_UNLOCK
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -539,25 +504,17 @@ int RTPSession::SendPacketEx(const void *data, std::size_t len, uint16_t hdrextI
|
|||
if (!created)
|
||||
return ERR_RTP_SESSION_NOTCREATED;
|
||||
|
||||
BUILDER_LOCK
|
||||
if ((status = packetbuilder.BuildPacketEx(data, len, hdrextID, hdrextdata, numhdrextwords)) < 0)
|
||||
{
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
if ((status = SendRTPData(packetbuilder.GetPacket(), packetbuilder.GetPacketLength())) < 0)
|
||||
{
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
BUILDER_UNLOCK
|
||||
|
||||
SOURCES_LOCK
|
||||
sources.SentRTPPacket();
|
||||
SOURCES_UNLOCK
|
||||
PACKSENT_LOCK
|
||||
sentpackets = true;
|
||||
PACKSENT_UNLOCK
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -568,25 +525,17 @@ int RTPSession::SendPacketEx(const void *data, std::size_t len, uint8_t pt, bool
|
|||
if (!created)
|
||||
return ERR_RTP_SESSION_NOTCREATED;
|
||||
|
||||
BUILDER_LOCK
|
||||
if ((status = packetbuilder.BuildPacketEx(data, len, pt, mark, timestampinc, hdrextID, hdrextdata, numhdrextwords)) < 0)
|
||||
{
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
if ((status = SendRTPData(packetbuilder.GetPacket(), packetbuilder.GetPacketLength())) < 0)
|
||||
{
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
BUILDER_UNLOCK
|
||||
|
||||
SOURCES_LOCK
|
||||
sources.SentRTPPacket();
|
||||
SOURCES_UNLOCK
|
||||
PACKSENT_LOCK
|
||||
sentpackets = true;
|
||||
PACKSENT_UNLOCK
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -599,9 +548,7 @@ int RTPSession::SendRTCPAPPPacket(uint8_t subtype, const uint8_t name[4], const
|
|||
if (!created)
|
||||
return ERR_RTP_SESSION_NOTCREATED;
|
||||
|
||||
BUILDER_LOCK
|
||||
uint32_t ssrc = packetbuilder.GetSSRC();
|
||||
BUILDER_UNLOCK
|
||||
|
||||
RTCPCompoundPacketBuilder pb;
|
||||
|
||||
|
@ -618,16 +565,13 @@ int RTPSession::SendRTCPAPPPacket(uint8_t subtype, const uint8_t name[4], const
|
|||
if ((status = pb.AddSDESSource(ssrc)) < 0)
|
||||
return status;
|
||||
|
||||
BUILDER_LOCK
|
||||
std::size_t owncnamelen = 0;
|
||||
uint8_t *owncname = rtcpbuilder.GetLocalCNAME(&owncnamelen);
|
||||
|
||||
if ((status = pb.AddSDESNormalItem(RTCPSDESPacket::CNAME, owncname, owncnamelen)) < 0)
|
||||
{
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
BUILDER_UNLOCK
|
||||
|
||||
//add our application specific packet
|
||||
if ((status = pb.AddAPPPacket(subtype, ssrc, name, appdata, appdatalen)) < 0)
|
||||
|
@ -641,9 +585,7 @@ int RTPSession::SendRTCPAPPPacket(uint8_t subtype, const uint8_t name[4], const
|
|||
if (status < 0)
|
||||
return status;
|
||||
|
||||
PACKSENT_LOCK
|
||||
sentpackets = true;
|
||||
PACKSENT_UNLOCK
|
||||
|
||||
return pb.GetCompoundPacketLength();
|
||||
}
|
||||
|
@ -671,9 +613,7 @@ int RTPSession::SetDefaultPayloadType(uint8_t pt)
|
|||
|
||||
int status;
|
||||
|
||||
BUILDER_LOCK
|
||||
status = packetbuilder.SetDefaultPayloadType(pt);
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -684,9 +624,7 @@ int RTPSession::SetDefaultMark(bool m)
|
|||
|
||||
int status;
|
||||
|
||||
BUILDER_LOCK
|
||||
status = packetbuilder.SetDefaultMark(m);
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -697,9 +635,7 @@ int RTPSession::SetDefaultTimestampIncrement(uint32_t timestampinc)
|
|||
|
||||
int status;
|
||||
|
||||
BUILDER_LOCK
|
||||
status = packetbuilder.SetDefaultTimestampIncrement(timestampinc);
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -710,9 +646,7 @@ int RTPSession::IncrementTimestamp(uint32_t inc)
|
|||
|
||||
int status;
|
||||
|
||||
BUILDER_LOCK
|
||||
status = packetbuilder.IncrementTimestamp(inc);
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -723,9 +657,7 @@ int RTPSession::IncrementTimestampDefault()
|
|||
|
||||
int status;
|
||||
|
||||
BUILDER_LOCK
|
||||
status = packetbuilder.IncrementTimestampDefault();
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -736,9 +668,7 @@ int RTPSession::SetPreTransmissionDelay(const RTPTime &delay)
|
|||
|
||||
int status;
|
||||
|
||||
BUILDER_LOCK
|
||||
status = rtcpbuilder.SetPreTransmissionDelay(delay);
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -756,37 +686,6 @@ void RTPSession::DeleteTransmissionInfo(RTPTransmissionInfo *inf)
|
|||
rtptrans->DeleteTransmissionInfo(inf);
|
||||
}
|
||||
|
||||
int RTPSession::Poll()
|
||||
{
|
||||
int status;
|
||||
|
||||
if (!created)
|
||||
return ERR_RTP_SESSION_NOTCREATED;
|
||||
if (usingpollthread)
|
||||
return ERR_RTP_SESSION_USINGPOLLTHREAD;
|
||||
if ((status = rtptrans->Poll()) < 0)
|
||||
return status;
|
||||
return ProcessPolledData();
|
||||
}
|
||||
|
||||
int RTPSession::WaitForIncomingData(const RTPTime &delay, bool *dataavailable)
|
||||
{
|
||||
if (!created)
|
||||
return ERR_RTP_SESSION_NOTCREATED;
|
||||
if (usingpollthread)
|
||||
return ERR_RTP_SESSION_USINGPOLLTHREAD;
|
||||
return rtptrans->WaitForIncomingData(delay, dataavailable);
|
||||
}
|
||||
|
||||
int RTPSession::AbortWait()
|
||||
{
|
||||
if (!created)
|
||||
return ERR_RTP_SESSION_NOTCREATED;
|
||||
if (usingpollthread)
|
||||
return ERR_RTP_SESSION_USINGPOLLTHREAD;
|
||||
return rtptrans->AbortWait();
|
||||
}
|
||||
|
||||
RTPTime RTPSession::GetRTCPDelay()
|
||||
{
|
||||
if (!created)
|
||||
|
@ -794,11 +693,7 @@ RTPTime RTPSession::GetRTCPDelay()
|
|||
if (usingpollthread)
|
||||
return RTPTime(0, 0);
|
||||
|
||||
SOURCES_LOCK
|
||||
SCHED_LOCK
|
||||
RTPTime t = rtcpsched.GetTransmissionDelay();
|
||||
SCHED_UNLOCK
|
||||
SOURCES_UNLOCK
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -806,7 +701,6 @@ int RTPSession::BeginDataAccess()
|
|||
{
|
||||
if (!created)
|
||||
return ERR_RTP_SESSION_NOTCREATED;
|
||||
SOURCES_LOCK
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -887,7 +781,6 @@ int RTPSession::EndDataAccess()
|
|||
{
|
||||
if (!created)
|
||||
return ERR_RTP_SESSION_NOTCREATED;
|
||||
SOURCES_UNLOCK
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -953,10 +846,8 @@ int RTPSession::SetMaximumPacketSize(std::size_t s)
|
|||
if ((status = rtptrans->SetMaximumPacketSize(s)) < 0)
|
||||
return status;
|
||||
|
||||
BUILDER_LOCK
|
||||
if ((status = packetbuilder.SetMaximumPacketSize(s)) < 0)
|
||||
{
|
||||
BUILDER_UNLOCK
|
||||
// restore previous max packet size
|
||||
rtptrans->SetMaximumPacketSize(maxpacksize);
|
||||
return status;
|
||||
|
@ -965,11 +856,9 @@ int RTPSession::SetMaximumPacketSize(std::size_t s)
|
|||
{
|
||||
// restore previous max packet size
|
||||
packetbuilder.SetMaximumPacketSize(maxpacksize);
|
||||
BUILDER_UNLOCK
|
||||
rtptrans->SetMaximumPacketSize(maxpacksize);
|
||||
return status;
|
||||
}
|
||||
BUILDER_UNLOCK
|
||||
maxpacksize = s;
|
||||
return 0;
|
||||
}
|
||||
|
@ -980,7 +869,6 @@ int RTPSession::SetSessionBandwidth(double bw)
|
|||
return ERR_RTP_SESSION_NOTCREATED;
|
||||
|
||||
int status;
|
||||
SCHED_LOCK
|
||||
RTCPSchedulerParams p = rtcpsched.GetParameters();
|
||||
status = p.SetRTCPBandwidth(bw * controlfragment);
|
||||
if (status >= 0)
|
||||
|
@ -988,7 +876,6 @@ int RTPSession::SetSessionBandwidth(double bw)
|
|||
rtcpsched.SetParameters(p);
|
||||
sessionbandwidth = bw;
|
||||
}
|
||||
SCHED_UNLOCK
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -999,9 +886,7 @@ int RTPSession::SetTimestampUnit(double u)
|
|||
|
||||
int status;
|
||||
|
||||
BUILDER_LOCK
|
||||
status = rtcpbuilder.SetTimestampUnit(u);
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1009,54 +894,42 @@ void RTPSession::SetNameInterval(int count)
|
|||
{
|
||||
if (!created)
|
||||
return;
|
||||
BUILDER_LOCK
|
||||
rtcpbuilder.SetNameInterval(count);
|
||||
BUILDER_UNLOCK
|
||||
}
|
||||
|
||||
void RTPSession::SetEMailInterval(int count)
|
||||
{
|
||||
if (!created)
|
||||
return;
|
||||
BUILDER_LOCK
|
||||
rtcpbuilder.SetEMailInterval(count);
|
||||
BUILDER_UNLOCK
|
||||
}
|
||||
|
||||
void RTPSession::SetLocationInterval(int count)
|
||||
{
|
||||
if (!created)
|
||||
return;
|
||||
BUILDER_LOCK
|
||||
rtcpbuilder.SetLocationInterval(count);
|
||||
BUILDER_UNLOCK
|
||||
}
|
||||
|
||||
void RTPSession::SetPhoneInterval(int count)
|
||||
{
|
||||
if (!created)
|
||||
return;
|
||||
BUILDER_LOCK
|
||||
rtcpbuilder.SetPhoneInterval(count);
|
||||
BUILDER_UNLOCK
|
||||
}
|
||||
|
||||
void RTPSession::SetToolInterval(int count)
|
||||
{
|
||||
if (!created)
|
||||
return;
|
||||
BUILDER_LOCK
|
||||
rtcpbuilder.SetToolInterval(count);
|
||||
BUILDER_UNLOCK
|
||||
}
|
||||
|
||||
void RTPSession::SetNoteInterval(int count)
|
||||
{
|
||||
if (!created)
|
||||
return;
|
||||
BUILDER_LOCK
|
||||
rtcpbuilder.SetNoteInterval(count);
|
||||
BUILDER_UNLOCK
|
||||
}
|
||||
|
||||
int RTPSession::SetLocalName(const void *s, std::size_t len)
|
||||
|
@ -1065,9 +938,7 @@ if (!created)
|
|||
return ERR_RTP_SESSION_NOTCREATED;
|
||||
|
||||
int status;
|
||||
BUILDER_LOCK
|
||||
status = rtcpbuilder.SetLocalName(s, len);
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1077,9 +948,7 @@ if (!created)
|
|||
return ERR_RTP_SESSION_NOTCREATED;
|
||||
|
||||
int status;
|
||||
BUILDER_LOCK
|
||||
status = rtcpbuilder.SetLocalEMail(s, len);
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1089,9 +958,7 @@ if (!created)
|
|||
return ERR_RTP_SESSION_NOTCREATED;
|
||||
|
||||
int status;
|
||||
BUILDER_LOCK
|
||||
status = rtcpbuilder.SetLocalLocation(s, len);
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1101,9 +968,7 @@ if (!created)
|
|||
return ERR_RTP_SESSION_NOTCREATED;
|
||||
|
||||
int status;
|
||||
BUILDER_LOCK
|
||||
status = rtcpbuilder.SetLocalPhone(s, len);
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1113,9 +978,7 @@ if (!created)
|
|||
return ERR_RTP_SESSION_NOTCREATED;
|
||||
|
||||
int status;
|
||||
BUILDER_LOCK
|
||||
status = rtcpbuilder.SetLocalTool(s, len);
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1125,9 +988,7 @@ if (!created)
|
|||
return ERR_RTP_SESSION_NOTCREATED;
|
||||
|
||||
int status;
|
||||
BUILDER_LOCK
|
||||
status = rtcpbuilder.SetLocalNote(s, len);
|
||||
BUILDER_UNLOCK
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1136,7 +997,6 @@ int RTPSession::ProcessPolledData()
|
|||
RTPRawPacket *rawpack;
|
||||
int status;
|
||||
|
||||
SOURCES_LOCK
|
||||
while ((rawpack = rtptrans->GetNextPacket()) != 0)
|
||||
{
|
||||
if (m_changeIncomingData)
|
||||
|
@ -1153,32 +1013,25 @@ sources.ClearOwnCollisionFlag();
|
|||
|
||||
// since our sources instance also uses the scheduler (analysis of incoming packets)
|
||||
// we'll lock it
|
||||
SCHED_LOCK
|
||||
if ((status = sources.ProcessRawPacket(rawpack, rtptrans, acceptownpackets)) < 0)
|
||||
{
|
||||
SCHED_UNLOCK
|
||||
SOURCES_UNLOCK
|
||||
delete rawpack;
|
||||
return status;
|
||||
}
|
||||
SCHED_UNLOCK
|
||||
|
||||
if (sources.DetectedOwnCollision()) // collision handling!
|
||||
{
|
||||
bool created;
|
||||
|
||||
if ((status = collisionlist.UpdateAddress(rawpack->GetSenderAddress(), rawpack->GetReceiveTime(), &created)) < 0)
|
||||
if ((status = collisionlist.UpdateAddress(&rawpack->GetSenderAddress(), rawpack->GetReceiveTime(), &created)) < 0)
|
||||
{
|
||||
SOURCES_UNLOCK
|
||||
delete rawpack;
|
||||
return status;
|
||||
}
|
||||
|
||||
if (created) // first time we've encountered this address, send bye packet and
|
||||
{ // change our own SSRC
|
||||
PACKSENT_LOCK
|
||||
bool hassentpackets = sentpackets;
|
||||
PACKSENT_UNLOCK
|
||||
|
||||
if (hassentpackets)
|
||||
{
|
||||
|
@ -1187,46 +1040,34 @@ if (hassentpackets)
|
|||
|
||||
RTCPCompoundPacket *rtcpcomppack;
|
||||
|
||||
BUILDER_LOCK
|
||||
if ((status = rtcpbuilder.BuildBYEPacket(&rtcpcomppack, 0, 0, useSR_BYEifpossible)) < 0)
|
||||
{
|
||||
BUILDER_UNLOCK
|
||||
SOURCES_UNLOCK
|
||||
delete rawpack;
|
||||
return status;
|
||||
}
|
||||
BUILDER_UNLOCK
|
||||
|
||||
byepackets.push_back(rtcpcomppack);
|
||||
if (byepackets.size() == 1) // was the first packet, schedule a BYE packet (otherwise there's already one scheduled)
|
||||
{
|
||||
SCHED_LOCK
|
||||
rtcpsched.ScheduleBYEPacket(rtcpcomppack->GetCompoundPacketLength());
|
||||
SCHED_UNLOCK
|
||||
}
|
||||
}
|
||||
// bye packet is built and scheduled, now change our SSRC
|
||||
// and reset the packet count in the transmitter
|
||||
|
||||
BUILDER_LOCK
|
||||
uint32_t newssrc = packetbuilder.CreateNewSSRC(sources);
|
||||
BUILDER_UNLOCK
|
||||
|
||||
PACKSENT_LOCK
|
||||
sentpackets = false;
|
||||
PACKSENT_UNLOCK
|
||||
|
||||
// remove old entry in source table and add new one
|
||||
|
||||
if ((status = sources.DeleteOwnSSRC()) < 0)
|
||||
{
|
||||
SOURCES_UNLOCK
|
||||
delete rawpack;
|
||||
return status;
|
||||
}
|
||||
if ((status = sources.CreateOwnSSRC(newssrc)) < 0)
|
||||
{
|
||||
SOURCES_UNLOCK
|
||||
delete rawpack;
|
||||
return status;
|
||||
}
|
||||
|
@ -1235,9 +1076,7 @@ return status;
|
|||
delete rawpack;
|
||||
}
|
||||
|
||||
SCHED_LOCK
|
||||
RTPTime d = rtcpsched.CalculateDeterministicInterval(false);
|
||||
SCHED_UNLOCK
|
||||
|
||||
RTPTime t = RTPTime::CurrentTime();
|
||||
double Td = d.GetDouble();
|
||||
|
@ -1252,9 +1091,7 @@ collisionlist.Timeout(t, colltimeout);
|
|||
|
||||
// We'll check if it's time for RTCP stuff
|
||||
|
||||
SCHED_LOCK
|
||||
bool istime = rtcpsched.IsTime();
|
||||
SCHED_UNLOCK
|
||||
|
||||
if (istime)
|
||||
{
|
||||
|
@ -1264,24 +1101,17 @@ RTCPCompoundPacket *pack;
|
|||
|
||||
if (byepackets.empty())
|
||||
{
|
||||
BUILDER_LOCK
|
||||
if ((status = rtcpbuilder.BuildNextPacket(&pack)) < 0)
|
||||
{
|
||||
BUILDER_UNLOCK
|
||||
SOURCES_UNLOCK
|
||||
return status;
|
||||
}
|
||||
BUILDER_UNLOCK
|
||||
if ((status = SendRTCPData(pack->GetCompoundPacketData(), pack->GetCompoundPacketLength())) < 0)
|
||||
{
|
||||
SOURCES_UNLOCK
|
||||
delete pack;
|
||||
return status;
|
||||
}
|
||||
|
||||
PACKSENT_LOCK
|
||||
sentpackets = true;
|
||||
PACKSENT_UNLOCK
|
||||
|
||||
OnSendRTCPCompoundPacket(pack); // we'll place this after the actual send to avoid tampering
|
||||
}
|
||||
|
@ -1292,36 +1122,28 @@ byepackets.pop_front();
|
|||
|
||||
if ((status = SendRTCPData(pack->GetCompoundPacketData(), pack->GetCompoundPacketLength())) < 0)
|
||||
{
|
||||
SOURCES_UNLOCK
|
||||
delete pack;
|
||||
return status;
|
||||
}
|
||||
|
||||
PACKSENT_LOCK
|
||||
sentpackets = true;
|
||||
PACKSENT_UNLOCK
|
||||
|
||||
OnSendRTCPCompoundPacket(pack); // we'll place this after the actual send to avoid tampering
|
||||
|
||||
if (!byepackets.empty()) // more bye packets to send, schedule them
|
||||
{
|
||||
SCHED_LOCK
|
||||
rtcpsched.ScheduleBYEPacket((*(byepackets.begin()))->GetCompoundPacketLength());
|
||||
SCHED_UNLOCK
|
||||
}
|
||||
}
|
||||
|
||||
SCHED_LOCK
|
||||
rtcpsched.AnalyseOutgoing(*pack);
|
||||
SCHED_UNLOCK
|
||||
|
||||
delete pack;
|
||||
}
|
||||
SOURCES_UNLOCK
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RTPSession::CreateCNAME(uint8_t *buffer, std::size_t *bufferlength, bool resolve)
|
||||
int RTPSession::CreateCNAME(uint8_t *buffer, std::size_t *bufferlength, bool resolve __attribute__((unused)))
|
||||
{
|
||||
#ifndef WIN32
|
||||
bool gotlogin = true;
|
||||
|
@ -1362,9 +1184,9 @@ strncpy((char *) buffer, logname, *bufferlength);
|
|||
#ifndef _WIN32_WCE
|
||||
DWORD len = *bufferlength;
|
||||
if (!GetUserName((LPTSTR)buffer,&len))
|
||||
RTP_STRNCPY((char *)buffer,"unknown",*bufferlength);
|
||||
strncpy((char *)buffer,"unknown",*bufferlength);
|
||||
#else
|
||||
RTP_STRNCPY((char *)buffer,"unknown",*bufferlength);
|
||||
strncpy((char *)buffer,"unknown",*bufferlength);
|
||||
#endif // _WIN32_WCE
|
||||
|
||||
#endif // WIN32
|
||||
|
@ -1376,25 +1198,15 @@ buffer[offset] = (uint8_t) '@';
|
|||
offset++;
|
||||
|
||||
std::size_t buflen2 = *bufferlength - offset;
|
||||
int status;
|
||||
|
||||
if (resolve)
|
||||
{
|
||||
if ((status = rtptrans->GetLocalHostName(buffer + offset, &buflen2)) < 0)
|
||||
return status;
|
||||
*bufferlength = buflen2 + offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
char hostname[1024];
|
||||
|
||||
RTP_STRNCPY(hostname, "localhost", 1024); // just in case gethostname fails
|
||||
strncpy(hostname, "localhost", 1024); // just in case gethostname fails
|
||||
|
||||
gethostname(hostname, 1024);
|
||||
RTP_STRNCPY((char * )(buffer + offset), hostname, buflen2);
|
||||
strncpy((char * )(buffer + offset), hostname, buflen2);
|
||||
|
||||
*bufferlength = offset + strlen(hostname);
|
||||
}
|
||||
if (*bufferlength > RTCP_SDES_MAXITEMLENGTH)
|
||||
*bufferlength = RTCP_SDES_MAXITEMLENGTH;
|
||||
return 0;
|
||||
|
|
|
@ -140,9 +140,6 @@ public:
|
|||
/** Leaves the multicast group specified by \c addr. */
|
||||
int LeaveMulticastGroup(const RTPAddress &addr);
|
||||
|
||||
/** Leaves all multicast groups. */
|
||||
void LeaveAllMulticastGroups();
|
||||
|
||||
/** Sends the RTP packet with payload \c data which has length \c len.
|
||||
* Sends the RTP packet with payload \c data which has length \c len.
|
||||
* The used payload type, marker and timestamp increment will be those that have been set
|
||||
|
@ -233,23 +230,6 @@ public:
|
|||
/** Frees the memory used by the transmission information \c inf. */
|
||||
void DeleteTransmissionInfo(RTPTransmissionInfo *inf);
|
||||
|
||||
/** If you're not using the poll thread, this function must be called regularly to process incoming data
|
||||
* and to send RTCP data when necessary.
|
||||
*/
|
||||
int Poll();
|
||||
|
||||
/** Waits at most a time \c delay until incoming data has been detected.
|
||||
* Waits at most a time \c delay until incoming data has been detected. Only works when you're not
|
||||
* using the poll thread. If \c dataavailable is not \c NULL, it should be set to \c true if data
|
||||
* was actually read and to \c false otherwise.
|
||||
*/
|
||||
int WaitForIncomingData(const RTPTime &delay, bool *dataavailable = 0);
|
||||
|
||||
/** If the previous function has been called, this one aborts the waiting (only works when you're not
|
||||
* using the poll thread).
|
||||
*/
|
||||
int AbortWait();
|
||||
|
||||
/** Returns the time interval after which an RTCP compound packet may have to be sent (only works when
|
||||
* you're not using the poll thread.
|
||||
*/
|
||||
|
@ -574,7 +554,7 @@ private:
|
|||
RTPTransmitter *rtptrans;
|
||||
bool created;
|
||||
bool deletetransmitter;
|
||||
bool usingpollthread, needthreadsafety;
|
||||
bool usingpollthread;
|
||||
bool acceptownpackets;
|
||||
bool useSR_BYEifpossible;
|
||||
std::size_t maxpacksize;
|
||||
|
|
|
@ -191,7 +191,7 @@ int RTPSources::ProcessRawPacket(RTPRawPacket *rawpack, RTPTransmitter *rtptrans
|
|||
bool stored = false;
|
||||
bool ownpacket = false;
|
||||
int i;
|
||||
const RTPAddress *senderaddress = rawpack->GetSenderAddress();
|
||||
const RTPAddress& senderaddress = rawpack->GetSenderAddress();
|
||||
|
||||
for (i = 0; !ownpacket && i < numtrans; i++)
|
||||
{
|
||||
|
@ -217,7 +217,7 @@ int RTPSources::ProcessRawPacket(RTPRawPacket *rawpack, RTPTransmitter *rtptrans
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((status = ProcessRTPPacket(rtppack, rawpack->GetReceiveTime(), senderaddress, &stored)) < 0)
|
||||
if ((status = ProcessRTPPacket(rtppack, rawpack->GetReceiveTime(), &senderaddress, &stored)) < 0)
|
||||
{
|
||||
if (!stored)
|
||||
delete rtppack;
|
||||
|
@ -245,7 +245,7 @@ int RTPSources::ProcessRawPacket(RTPRawPacket *rawpack, RTPTransmitter *rtptrans
|
|||
{
|
||||
bool ownpacket = false;
|
||||
int i;
|
||||
const RTPAddress *senderaddress = rawpack->GetSenderAddress();
|
||||
const RTPAddress& senderaddress = rawpack->GetSenderAddress();
|
||||
|
||||
for (i = 0; !ownpacket && i < numtrans; i++)
|
||||
{
|
||||
|
@ -266,7 +266,7 @@ int RTPSources::ProcessRawPacket(RTPRawPacket *rawpack, RTPTransmitter *rtptrans
|
|||
}
|
||||
else // not our own packet
|
||||
{
|
||||
status = ProcessRTCPCompoundPacket(&rtcpcomppack, rawpack->GetReceiveTime(), rawpack->GetSenderAddress());
|
||||
status = ProcessRTCPCompoundPacket(&rtcpcomppack, rawpack->GetReceiveTime(), &rawpack->GetSenderAddress());
|
||||
if (status < 0)
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -94,11 +94,8 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
/** This function must be called before the transmission component can be used.
|
||||
* This function must be called before the transmission component can be used. Depending on
|
||||
* the value of \c threadsafe, the component will be created for thread-safe usage or not.
|
||||
*/
|
||||
virtual int Init(bool threadsafe) = 0;
|
||||
/** This function must be called before the transmission component can be used. */
|
||||
virtual int Init() = 0;
|
||||
|
||||
/** Prepares the component to be used.
|
||||
* Prepares the component to be used. The parameter \c maxpacksize specifies the maximum size
|
||||
|
@ -110,6 +107,9 @@ public:
|
|||
*/
|
||||
virtual int Create(std::size_t maxpacksize, const RTPTransmissionParams *transparams) = 0;
|
||||
|
||||
/** Bind the RTP and RTCP sockets to ports that were set at creation time */
|
||||
virtual int BindSockets() = 0;
|
||||
|
||||
/** By calling this function, buffers are cleared and the component cannot be used anymore.
|
||||
* By calling this function, buffers are cleared and the component cannot be used anymore.
|
||||
* Only when the Create function is called again can the component be used again. */
|
||||
|
@ -129,36 +129,13 @@ public:
|
|||
*/
|
||||
virtual void DeleteTransmissionInfo(RTPTransmissionInfo *inf) = 0;
|
||||
|
||||
/** Looks up the local host name.
|
||||
* Looks up the local host name based upon internal information about the local host's
|
||||
* addresses. This function might take some time since a DNS query might be done. \c bufferlength
|
||||
* should initially contain the number of bytes that may be stored in \c buffer. If the function
|
||||
* succeeds, \c bufferlength is set to the number of bytes stored in \c buffer. Note that the data
|
||||
* in \c buffer is not NULL-terminated. If the function fails because the buffer isn't large enough,
|
||||
* it returns \c ERR_RTP_TRANS_BUFFERLENGTHTOOSMALL and stores the number of bytes needed in
|
||||
* \c bufferlength.
|
||||
*/
|
||||
virtual int GetLocalHostName(uint8_t *buffer, std::size_t *bufferlength) = 0;
|
||||
|
||||
/** Returns \c true if the address specified by \c addr is one of the addresses of the transmitter. */
|
||||
virtual bool ComesFromThisTransmitter(const RTPAddress *addr) = 0;
|
||||
virtual bool ComesFromThisTransmitter(const RTPAddress& addr) = 0;
|
||||
|
||||
/** Returns the amount of bytes that will be added to the RTP packet by the underlying layers (excluding
|
||||
* the link layer). */
|
||||
virtual std::size_t GetHeaderOverhead() = 0;
|
||||
|
||||
/** Checks for incoming data and stores it. */
|
||||
virtual int Poll() = 0;
|
||||
|
||||
/** Waits until incoming data is detected.
|
||||
* Waits at most a time \c delay until incoming data has been detected. If \c dataavailable is not NULL,
|
||||
* it should be set to \c true if data was actually read and to \c false otherwise.
|
||||
*/
|
||||
virtual int WaitForIncomingData(const RTPTime &delay, bool *dataavailable = 0) = 0;
|
||||
|
||||
/** If the previous function has been called, this one aborts the waiting. */
|
||||
virtual int AbortWait() = 0;
|
||||
|
||||
/** Send a packet with length \c len containing \c data to all RTP addresses of the current destination list. */
|
||||
virtual int SendRTPData(const void *data, std::size_t len) = 0;
|
||||
|
||||
|
@ -183,9 +160,6 @@ public:
|
|||
/** Leaves the multicast group specified by \c addr. */
|
||||
virtual int LeaveMulticastGroup(const RTPAddress &addr) = 0;
|
||||
|
||||
/** Leaves all the multicast groups that have been joined. */
|
||||
virtual void LeaveAllMulticastGroups() = 0;
|
||||
|
||||
/** Sets the receive mode.
|
||||
* Sets the receive mode to \c m, which is one of the following: RTPTransmitter::AcceptAll,
|
||||
* RTPTransmitter::AcceptSome or RTPTransmitter::IgnoreSome. Note that if the receive
|
||||
|
@ -214,10 +188,7 @@ public:
|
|||
/** Sets the maximum packet size which the transmitter should allow to \c s. */
|
||||
virtual int SetMaximumPacketSize(std::size_t s) = 0;
|
||||
|
||||
/** Returns \c true if packets can be obtained using the GetNextPacket member function. */
|
||||
virtual bool NewDataAvailable() = 0;
|
||||
|
||||
/** Returns the raw data of a received RTP packet (received during the Poll function)
|
||||
/** Returns the raw data of a received RTP packet
|
||||
* in an RTPRawPacket instance. */
|
||||
virtual RTPRawPacket *GetNextPacket() = 0;
|
||||
};
|
||||
|
|
|
@ -32,13 +32,17 @@
|
|||
|
||||
#include "rtpudptransmitter.h"
|
||||
#include "rtperrors.h"
|
||||
#include "rtpaddress.h"
|
||||
#include "rtpstructs.h"
|
||||
#include "rtprawpacket.h"
|
||||
|
||||
#define RTPUDPTRANS_MAXPACKSIZE 65535
|
||||
#include <QUdpSocket>
|
||||
|
||||
namespace qrtplib
|
||||
{
|
||||
|
||||
RTPUDPTransmitter::RTPUDPTransmitter()
|
||||
RTPUDPTransmitter::RTPUDPTransmitter() :
|
||||
m_rawPacketQueueLock(QMutex::Recursive)
|
||||
{
|
||||
m_created = false;
|
||||
m_init = false;
|
||||
|
@ -48,9 +52,7 @@ RTPUDPTransmitter::RTPUDPTransmitter()
|
|||
m_closesocketswhendone = false;
|
||||
m_rtcpPort = 0;
|
||||
m_rtpPort = 0;
|
||||
m_supportsmulticasting = false;
|
||||
m_receivemode = RTPTransmitter::AcceptAll;
|
||||
m_localhostname = 0;
|
||||
}
|
||||
|
||||
RTPUDPTransmitter::~RTPUDPTransmitter()
|
||||
|
@ -71,11 +73,9 @@ int RTPUDPTransmitter::Init()
|
|||
int RTPUDPTransmitter::Create(std::size_t maximumpacketsize, const RTPTransmissionParams *transparams)
|
||||
{
|
||||
const RTPUDPTransmissionParams *params, defaultparams;
|
||||
struct sockaddr_in addr;
|
||||
qint64 size;
|
||||
int status;
|
||||
|
||||
if (maximumpacketsize > RTPUDPTRANS_MAXPACKSIZE) {
|
||||
if (maximumpacketsize > m_absoluteMaxPackSize) {
|
||||
return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG;
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ int RTPUDPTransmitter::Create(std::size_t maximumpacketsize, const RTPTransmissi
|
|||
{
|
||||
return ERR_RTP_UDPV4TRANS_ILLEGALPARAMETERS;
|
||||
}
|
||||
params = (const RTPUDPv4TransmissionParams *) transparams;
|
||||
params = (const RTPUDPTransmissionParams *) transparams;
|
||||
}
|
||||
|
||||
// Determine the port numbers
|
||||
|
@ -155,18 +155,35 @@ int RTPUDPTransmitter::Create(std::size_t maximumpacketsize, const RTPTransmissi
|
|||
}
|
||||
|
||||
m_maxpacksize = maximumpacketsize;
|
||||
m_mcastifaceIP = params->GetMulticastInterfaceIP();
|
||||
m_multicastInterface = params->GetMulticastInterface();
|
||||
m_receivemode = RTPTransmitter::AcceptAll;
|
||||
|
||||
m_localhostname = 0;
|
||||
m_localhostnamelength = 0;
|
||||
|
||||
m_waitingfordata = false;
|
||||
m_created = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RTPUDPTransmitter::BindSockets()
|
||||
{
|
||||
if (!m_rtpsock->bind(m_localIP, m_rtpPort)) {
|
||||
return ERR_RTP_UDPV4TRANS_CANTBINDRTPSOCKET;
|
||||
}
|
||||
|
||||
connect(m_rtpsock, SIGNAL(readyRead()), this, SLOT(readRTPPendingDatagrams()));
|
||||
|
||||
if (m_rtpsock != m_rtcpsock)
|
||||
{
|
||||
if (!m_rtcpsock->bind(m_localIP, m_rtcpPort)) {
|
||||
return ERR_RTP_UDPV4TRANS_CANTBINDRTCPSOCKET;
|
||||
}
|
||||
|
||||
connect(m_rtcpsock, SIGNAL(readyRead()), this, SLOT(readRTCPPendingDatagrams()));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RTPUDPTransmitter::Destroy()
|
||||
{
|
||||
if (!m_init) {
|
||||
|
@ -178,16 +195,6 @@ void RTPUDPTransmitter::Destroy()
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_localhostname)
|
||||
{
|
||||
delete[] m_localhostname;
|
||||
m_localhostname = 0;
|
||||
m_localhostnamelength = 0;
|
||||
}
|
||||
|
||||
FlushPackets();
|
||||
ClearAcceptIgnoreInfo();
|
||||
|
||||
if (m_closesocketswhendone)
|
||||
{
|
||||
if (m_rtpsock != m_rtcpsock) {
|
||||
|
@ -206,8 +213,7 @@ RTPTransmissionInfo *RTPUDPTransmitter::GetTransmissionInfo()
|
|||
return 0;
|
||||
}
|
||||
|
||||
RTPTransmissionInfo *tinf = new RTPUDPv4TransmissionNoBindInfo(
|
||||
m_localIP, m_rtpsock, m_rtcpsock, m_rtpPort, m_rtcpPort);
|
||||
RTPTransmissionInfo *tinf = new RTPUDPTransmissionInfo(m_localIP, m_rtpsock, m_rtcpsock, m_rtpPort, m_rtcpPort);
|
||||
|
||||
return tinf;
|
||||
}
|
||||
|
@ -221,13 +227,326 @@ void RTPUDPTransmitter::DeleteTransmissionInfo(RTPTransmissionInfo *inf)
|
|||
delete inf;
|
||||
}
|
||||
|
||||
bool RTPUDPTransmitter::ComesFromThisTransmitter(const RTPAddress *addr)
|
||||
bool RTPUDPTransmitter::ComesFromThisTransmitter(const RTPAddress& addr)
|
||||
{
|
||||
if (addr->getAddress() != m_localIP) {
|
||||
if (addr.getAddress() != m_localIP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (addr->getPort() == m_rtpPort) && (addr->getRtcpsendport() == m_rtcpPort);
|
||||
return (addr.getPort() == m_rtpPort) && (addr.getRtcpsendport() == m_rtcpPort);
|
||||
}
|
||||
|
||||
int RTPUDPTransmitter::SendRTPData(const void *data, std::size_t len)
|
||||
{
|
||||
if (!m_init) {
|
||||
return ERR_RTP_UDPV4TRANS_NOTINIT;
|
||||
}
|
||||
|
||||
if (!m_created) {
|
||||
return ERR_RTP_UDPV4TRANS_NOTCREATED;
|
||||
}
|
||||
|
||||
if (len > m_maxpacksize)
|
||||
{
|
||||
return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG;
|
||||
}
|
||||
|
||||
std::list<RTPAddress>::const_iterator it = m_destinations.begin();
|
||||
|
||||
for (; it != m_destinations.end(); ++it)
|
||||
{
|
||||
m_rtpsock->writeDatagram((const char*) data, (qint64) len, it->getAddress(), it->getPort());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RTPUDPTransmitter::SendRTCPData(const void *data, std::size_t len)
|
||||
{
|
||||
if (!m_init) {
|
||||
return ERR_RTP_UDPV4TRANS_NOTINIT;
|
||||
}
|
||||
|
||||
if (!m_created) {
|
||||
return ERR_RTP_UDPV4TRANS_NOTCREATED;
|
||||
}
|
||||
|
||||
if (len > m_maxpacksize) {
|
||||
return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG;
|
||||
}
|
||||
|
||||
std::list<RTPAddress>::const_iterator it = m_destinations.begin();
|
||||
|
||||
for (; it != m_destinations.end(); ++it)
|
||||
{
|
||||
m_rtcpsock->writeDatagram((const char*) data, (qint64) len, it->getAddress(), it->getRtcpsendport());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RTPUDPTransmitter::AddDestination(const RTPAddress &addr)
|
||||
{
|
||||
m_destinations.push_back(addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RTPUDPTransmitter::DeleteDestination(const RTPAddress &addr)
|
||||
{
|
||||
m_destinations.remove(addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RTPUDPTransmitter::ClearDestinations()
|
||||
{
|
||||
m_destinations.clear();
|
||||
}
|
||||
|
||||
bool RTPUDPTransmitter::SupportsMulticasting()
|
||||
{
|
||||
QNetworkInterface::InterfaceFlags flags = m_multicastInterface.flags();
|
||||
QAbstractSocket::SocketState rtpSocketState = m_rtpsock->state();
|
||||
QAbstractSocket::SocketState rtcpSocketState = m_rtcpsock->state();
|
||||
return m_multicastInterface.isValid()
|
||||
&& (rtpSocketState & QAbstractSocket::BoundState)
|
||||
&& (rtcpSocketState & QAbstractSocket::BoundState)
|
||||
&& (flags & QNetworkInterface::CanMulticast)
|
||||
&& (flags & QNetworkInterface::IsRunning)
|
||||
&& !(flags & QNetworkInterface::IsLoopBack);
|
||||
}
|
||||
|
||||
int RTPUDPTransmitter::JoinMulticastGroup(const RTPAddress &addr)
|
||||
{
|
||||
if (!m_init) {
|
||||
return ERR_RTP_UDPV4TRANS_NOTINIT;
|
||||
}
|
||||
|
||||
if (!m_created) {
|
||||
return ERR_RTP_UDPV4TRANS_NOTCREATED;
|
||||
}
|
||||
|
||||
if (!SupportsMulticasting()) {
|
||||
return ERR_RTP_UDPV6TRANS_NOMULTICASTSUPPORT;
|
||||
}
|
||||
|
||||
if (m_rtpsock->joinMulticastGroup(addr.getAddress(), m_multicastInterface))
|
||||
{
|
||||
if (m_rtpsock != m_rtcpsock)
|
||||
{
|
||||
if (!m_rtcpsock->joinMulticastGroup(addr.getAddress(), m_multicastInterface)) {
|
||||
return ERR_RTP_UDPV4TRANS_COULDNTJOINMULTICASTGROUP;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERR_RTP_UDPV4TRANS_COULDNTJOINMULTICASTGROUP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RTPUDPTransmitter::LeaveMulticastGroup(const RTPAddress &addr)
|
||||
{
|
||||
if (!m_init) {
|
||||
return ERR_RTP_UDPV4TRANS_NOTINIT;
|
||||
}
|
||||
|
||||
if (!m_created) {
|
||||
return ERR_RTP_UDPV4TRANS_NOTCREATED;
|
||||
}
|
||||
|
||||
if (!SupportsMulticasting()) {
|
||||
return ERR_RTP_UDPV6TRANS_NOMULTICASTSUPPORT;
|
||||
}
|
||||
|
||||
m_rtpsock->leaveMulticastGroup(addr.getAddress());
|
||||
|
||||
if (m_rtpsock != m_rtcpsock)
|
||||
{
|
||||
m_rtcpsock->leaveMulticastGroup(addr.getAddress());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RTPUDPTransmitter::SetReceiveMode(RTPTransmitter::ReceiveMode m)
|
||||
{
|
||||
if (!m_init) {
|
||||
return ERR_RTP_UDPV4TRANS_NOTINIT;
|
||||
}
|
||||
|
||||
if (!m_created) {
|
||||
return ERR_RTP_UDPV4TRANS_NOTCREATED;
|
||||
}
|
||||
|
||||
if (m != m_receivemode) {
|
||||
m_receivemode = m;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RTPUDPTransmitter::AddToIgnoreList(const RTPAddress &addr)
|
||||
{
|
||||
m_ignoreList.push_back(addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RTPUDPTransmitter::DeleteFromIgnoreList(const RTPAddress &addr)
|
||||
{
|
||||
m_ignoreList.remove(addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RTPUDPTransmitter::ClearIgnoreList()
|
||||
{
|
||||
m_ignoreList.clear();
|
||||
}
|
||||
|
||||
int RTPUDPTransmitter::AddToAcceptList(const RTPAddress &addr)
|
||||
{
|
||||
m_acceptList.push_back(addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RTPUDPTransmitter::DeleteFromAcceptList(const RTPAddress &addr)
|
||||
{
|
||||
m_acceptList.remove(addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RTPUDPTransmitter::ClearAcceptList()
|
||||
{
|
||||
m_acceptList.clear();
|
||||
}
|
||||
|
||||
int RTPUDPTransmitter::SetMaximumPacketSize(std::size_t s)
|
||||
{
|
||||
if (!m_init) {
|
||||
return ERR_RTP_UDPV4TRANS_NOTINIT;
|
||||
}
|
||||
|
||||
if (!m_created) {
|
||||
return ERR_RTP_UDPV4TRANS_NOTCREATED;
|
||||
}
|
||||
|
||||
if (s > m_absoluteMaxPackSize) {
|
||||
return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG;
|
||||
}
|
||||
|
||||
m_maxpacksize = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
RTPRawPacket *RTPUDPTransmitter::GetNextPacket()
|
||||
{
|
||||
QMutexLocker locker(&m_rawPacketQueueLock);
|
||||
|
||||
if (m_rawPacketQueue.isEmpty()) {
|
||||
return 0;
|
||||
} else {
|
||||
return m_rawPacketQueue.takeFirst();
|
||||
}
|
||||
}
|
||||
|
||||
void RTPUDPTransmitter::readRTPPendingDatagrams()
|
||||
{
|
||||
while (m_rtpsock->hasPendingDatagrams())
|
||||
{
|
||||
RTPTime curtime = RTPTime::CurrentTime();
|
||||
QHostAddress remoteAddress;
|
||||
quint16 remotePort;
|
||||
qint64 pendingDataSize = m_rtpsock->pendingDatagramSize();
|
||||
qint64 bytesRead = m_rtpsock->readDatagram(m_rtpBuffer, pendingDataSize, &remoteAddress, &remotePort);
|
||||
qDebug("RTPUDPTransmitter::readRTPPendingDatagrams: %lld bytes read from %s:%d",
|
||||
bytesRead,
|
||||
qPrintable(remoteAddress.toString()),
|
||||
remotePort);
|
||||
|
||||
RTPAddress rtpAddress;
|
||||
rtpAddress.setAddress(remoteAddress);
|
||||
rtpAddress.setPort(remotePort);
|
||||
|
||||
if (ShouldAcceptData(rtpAddress))
|
||||
{
|
||||
bool isrtp = true;
|
||||
|
||||
if (m_rtpsock == m_rtcpsock) // check payload type when multiplexing
|
||||
{
|
||||
if ((std::size_t) bytesRead > sizeof(RTCPCommonHeader))
|
||||
{
|
||||
RTCPCommonHeader *rtcpheader = (RTCPCommonHeader *) m_rtpBuffer;
|
||||
uint8_t packettype = rtcpheader->packettype;
|
||||
|
||||
if (packettype >= 200 && packettype <= 204) {
|
||||
isrtp = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RTPRawPacket *pack = new RTPRawPacket((uint8_t *) m_rtpBuffer, bytesRead, rtpAddress, curtime, isrtp);
|
||||
|
||||
m_rawPacketQueueLock.lock();
|
||||
m_rawPacketQueue.append(pack);
|
||||
m_rawPacketQueueLock.unlock();
|
||||
|
||||
emit NewDataAvailable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RTPUDPTransmitter::readRTCPPendingDatagrams()
|
||||
{
|
||||
while (m_rtcpsock->hasPendingDatagrams())
|
||||
{
|
||||
RTPTime curtime = RTPTime::CurrentTime();
|
||||
QHostAddress remoteAddress;
|
||||
quint16 remotePort;
|
||||
qint64 pendingDataSize = m_rtcpsock->pendingDatagramSize();
|
||||
qint64 bytesRead = m_rtcpsock->readDatagram(m_rtcpBuffer, pendingDataSize, &remoteAddress, &remotePort);
|
||||
qDebug("RTPUDPTransmitter::readRTCPPendingDatagrams: %lld bytes read from %s:%d",
|
||||
bytesRead,
|
||||
qPrintable(remoteAddress.toString()),
|
||||
remotePort);
|
||||
|
||||
RTPAddress rtpAddress;
|
||||
rtpAddress.setAddress(remoteAddress);
|
||||
rtpAddress.setPort(remotePort);
|
||||
|
||||
if (ShouldAcceptData(rtpAddress))
|
||||
{
|
||||
RTPRawPacket *pack = new RTPRawPacket((uint8_t *) m_rtcpBuffer, bytesRead, rtpAddress, curtime, false);
|
||||
|
||||
m_rawPacketQueueLock.lock();
|
||||
m_rawPacketQueue.append(pack);
|
||||
m_rawPacketQueueLock.unlock();
|
||||
|
||||
emit NewDataAvailable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool RTPUDPTransmitter::ShouldAcceptData(const RTPAddress& rtpAddress)
|
||||
{
|
||||
if (m_receivemode == RTPTransmitter::AcceptAll)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (m_receivemode == RTPTransmitter::AcceptSome)
|
||||
{
|
||||
std::list<RTPAddress>::iterator findIt = std::find(m_acceptList.begin(), m_acceptList.end(), rtpAddress);
|
||||
return findIt != m_acceptList.end();
|
||||
}
|
||||
else if (m_receivemode == RTPTransmitter::IgnoreSome)
|
||||
{
|
||||
std::list<RTPAddress>::iterator findIt = std::find(m_ignoreList.begin(), m_ignoreList.end(), rtpAddress);
|
||||
return findIt == m_ignoreList.end();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -34,12 +34,17 @@
|
|||
#define QRTPLIB_RTPUDPTRANSMITTER_H_
|
||||
|
||||
#include "rtptransmitter.h"
|
||||
#include "util/export.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QHostAddress>
|
||||
#include <QNetworkInterface>
|
||||
#include <QQueue>
|
||||
#include <QMutex>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <list>
|
||||
|
||||
#include "util/export.h"
|
||||
|
||||
#define RTPUDPV4TRANS_HASHSIZE 8317
|
||||
#define RTPUDPV4TRANS_DEFAULTPORTBASE 5000
|
||||
#define RTPUDPV4TRANS_RTPRECEIVEBUFFER 32768
|
||||
|
@ -64,8 +69,8 @@ public:
|
|||
}
|
||||
|
||||
/** Sets the multicast interface IP address. */
|
||||
void SetMulticastInterfaceIP(const QHostAddress& mcastGroupAddress) {
|
||||
m_mcastGroupAddress = mcastGroupAddress;
|
||||
void SetMulticastInterface(const QNetworkInterface& mcastInterface) {
|
||||
m_mcastInterface = mcastInterface;
|
||||
}
|
||||
|
||||
/** Sets the RTP portbase to \c pbase, which has to be an even number
|
||||
|
@ -76,21 +81,6 @@ public:
|
|||
m_portbase = pbase;
|
||||
}
|
||||
|
||||
/** Passes a list of IP addresses which will be used as the local IP addresses. */
|
||||
void SetLocalIPList(const std::list<QHostAddress>& iplist)
|
||||
{
|
||||
m_localIPs = iplist;
|
||||
}
|
||||
|
||||
/** Clears the list of local IP addresses.
|
||||
* Clears the list of local IP addresses. An empty list will make the transmission
|
||||
* component itself determine the local IP addresses.
|
||||
*/
|
||||
void ClearLocalIPList()
|
||||
{
|
||||
m_localIPs.clear();
|
||||
}
|
||||
|
||||
/** Returns the IP address which will be used to bind the sockets. */
|
||||
QHostAddress GetBindIP() const
|
||||
{
|
||||
|
@ -98,9 +88,9 @@ public:
|
|||
}
|
||||
|
||||
/** Returns the multicast interface IP address. */
|
||||
QHostAddress GetMulticastInterfaceIP() const
|
||||
QNetworkInterface GetMulticastInterface() const
|
||||
{
|
||||
return m_mcastGroupAddress;
|
||||
return m_mcastInterface;
|
||||
}
|
||||
|
||||
/** Returns the RTP portbase which will be used (default is 5000). */
|
||||
|
@ -109,12 +99,6 @@ public:
|
|||
return m_portbase;
|
||||
}
|
||||
|
||||
/** Returns the list of local IP addresses. */
|
||||
const std::list<QHostAddress> &GetLocalIPList() const
|
||||
{
|
||||
return m_localIPs;
|
||||
}
|
||||
|
||||
/** Sets the RTP socket's send buffer size. */
|
||||
void SetRTPSendBufferSize(int s)
|
||||
{
|
||||
|
@ -225,9 +209,8 @@ public:
|
|||
|
||||
private:
|
||||
QHostAddress m_bindAddress;
|
||||
QHostAddress m_mcastGroupAddress;
|
||||
QNetworkInterface m_mcastInterface;
|
||||
uint16_t m_portbase;
|
||||
std::list<QHostAddress> m_localIPs;
|
||||
int m_rtpsendbufsz, m_rtprecvbufsz;
|
||||
int m_rtcpsendbufsz, m_rtcprecvbufsz;
|
||||
bool m_rtcpmux;
|
||||
|
@ -258,10 +241,15 @@ inline RTPUDPTransmissionParams::RTPUDPTransmissionParams() :
|
|||
class QRTPLIB_API RTPUDPTransmissionInfo: public RTPTransmissionInfo
|
||||
{
|
||||
public:
|
||||
RTPUDPTransmissionInfo(const std::list<QHostAddress>& iplist, QUdpSocket *rtpsock, QUdpSocket *rtcpsock, uint16_t rtpport, uint16_t rtcpport) :
|
||||
RTPUDPTransmissionInfo(
|
||||
QHostAddress localIP,
|
||||
QUdpSocket *rtpsock,
|
||||
QUdpSocket *rtcpsock,
|
||||
uint16_t rtpport,
|
||||
uint16_t rtcpport) :
|
||||
RTPTransmissionInfo(RTPTransmitter::IPv4UDPProto)
|
||||
{
|
||||
m_localIPlist = iplist;
|
||||
m_localIP = localIP;
|
||||
m_rtpsocket = rtpsock;
|
||||
m_rtcpsocket = rtcpsock;
|
||||
m_rtpPort = rtpport;
|
||||
|
@ -272,12 +260,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
/** Returns the list of IPv4 addresses the transmitter considers to be the local IP addresses. */
|
||||
std::list<uint32_t> GetLocalIPList() const
|
||||
{
|
||||
return m_localIPlist;
|
||||
}
|
||||
|
||||
/** Returns the socket descriptor used for receiving and transmitting RTP packets. */
|
||||
QUdpSocket *GetRTPSocket() const
|
||||
{
|
||||
|
@ -302,7 +284,7 @@ public:
|
|||
return m_rtcpPort;
|
||||
}
|
||||
private:
|
||||
std::list<QHostAddress> m_localIPlist;
|
||||
QHostAddress m_localIP;
|
||||
QUdpSocket *m_rtpsocket, *m_rtcpsocket;
|
||||
uint16_t m_rtpPort, m_rtcpPort;
|
||||
};
|
||||
|
@ -315,81 +297,79 @@ private:
|
|||
* are described by the class RTPUDPTransmissionParams. The GetTransmissionInfo member function
|
||||
* returns an instance of type RTPUDPTransmissionInfo.
|
||||
*/
|
||||
class QRTPLIB_API RTPUDPTransmitter: public RTPTransmitter
|
||||
class QRTPLIB_API RTPUDPTransmitter: public QObject, public RTPTransmitter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RTPUDPTransmitter();
|
||||
~RTPUDPTransmitter();
|
||||
virtual ~RTPUDPTransmitter();
|
||||
|
||||
int Init();
|
||||
int Create(std::size_t maxpacksize, const RTPTransmissionParams *transparams);
|
||||
void Destroy();
|
||||
RTPTransmissionInfo *GetTransmissionInfo();
|
||||
void DeleteTransmissionInfo(RTPTransmissionInfo *inf);
|
||||
virtual int Init();
|
||||
virtual int Create(std::size_t maxpacksize, const RTPTransmissionParams *transparams);
|
||||
virtual int BindSockets();
|
||||
virtual void Destroy();
|
||||
virtual RTPTransmissionInfo *GetTransmissionInfo();
|
||||
virtual void DeleteTransmissionInfo(RTPTransmissionInfo *inf);
|
||||
|
||||
bool ComesFromThisTransmitter(const RTPAddress *addr);
|
||||
std::size_t GetHeaderOverhead()
|
||||
virtual bool ComesFromThisTransmitter(const RTPAddress& addr);
|
||||
virtual std::size_t GetHeaderOverhead()
|
||||
{
|
||||
return RTPUDPTRANS_HEADERSIZE;
|
||||
}
|
||||
|
||||
int Poll();
|
||||
int WaitForIncomingData(const RTPTime &delay, bool *dataavailable = 0);
|
||||
int AbortWait();
|
||||
virtual int SendRTPData(const void *data, std::size_t len);
|
||||
virtual int SendRTCPData(const void *data, std::size_t len);
|
||||
|
||||
int SendRTPData(const void *data, std::size_t len);
|
||||
int SendRTCPData(const void *data, std::size_t len);
|
||||
virtual int AddDestination(const RTPAddress &addr);
|
||||
virtual int DeleteDestination(const RTPAddress &addr);
|
||||
virtual void ClearDestinations();
|
||||
|
||||
int AddDestination(const RTPAddress &addr);
|
||||
int DeleteDestination(const RTPAddress &addr);
|
||||
void ClearDestinations();
|
||||
virtual bool SupportsMulticasting();
|
||||
virtual int JoinMulticastGroup(const RTPAddress &addr);
|
||||
virtual int LeaveMulticastGroup(const RTPAddress &addr);
|
||||
|
||||
bool SupportsMulticasting();
|
||||
int JoinMulticastGroup(const RTPAddress &addr);
|
||||
int LeaveMulticastGroup(const RTPAddress &addr);
|
||||
void LeaveAllMulticastGroups();
|
||||
virtual int SetReceiveMode(RTPTransmitter::ReceiveMode m);
|
||||
virtual int AddToIgnoreList(const RTPAddress &addr);
|
||||
virtual int DeleteFromIgnoreList(const RTPAddress &addr);
|
||||
virtual void ClearIgnoreList();
|
||||
virtual int AddToAcceptList(const RTPAddress &addr);
|
||||
virtual int DeleteFromAcceptList(const RTPAddress &addr);
|
||||
virtual void ClearAcceptList();
|
||||
virtual int SetMaximumPacketSize(std::size_t s);
|
||||
|
||||
int SetReceiveMode(RTPTransmitter::ReceiveMode m);
|
||||
int AddToIgnoreList(const RTPAddress &addr);
|
||||
int DeleteFromIgnoreList(const RTPAddress &addr);
|
||||
void ClearIgnoreList();
|
||||
int AddToAcceptList(const RTPAddress &addr);
|
||||
int DeleteFromAcceptList(const RTPAddress &addr);
|
||||
void ClearAcceptList();
|
||||
int SetMaximumPacketSize(std::size_t s);
|
||||
|
||||
bool NewDataAvailable(); // TODO: emit signal instead
|
||||
RTPRawPacket *GetNextPacket(); // TODO: use a queue
|
||||
virtual RTPRawPacket *GetNextPacket();
|
||||
|
||||
private:
|
||||
int CreateLocalIPList();
|
||||
bool GetLocalIPList_Interfaces();
|
||||
void GetLocalIPList_DNS();
|
||||
void AddLoopbackAddress();
|
||||
void FlushPackets();
|
||||
int ProcessAddAcceptIgnoreEntry(uint32_t ip, uint16_t port);
|
||||
int ProcessDeleteAcceptIgnoreEntry(uint32_t ip, uint16_t port);
|
||||
bool ShouldAcceptData(uint32_t srcip, uint16_t srcport);
|
||||
void ClearAcceptIgnoreInfo();
|
||||
|
||||
bool m_init;
|
||||
bool m_created;
|
||||
bool m_waitingfordata;
|
||||
QUdpSocket *m_rtpsock, *m_rtcpsock;
|
||||
QHostAddress m_mcastifaceIP;
|
||||
QHostAddress m_localIP;
|
||||
QHostAddress m_localIP; //!< from parameters bind IP
|
||||
QNetworkInterface m_multicastInterface; //!< from parameters multicast interface
|
||||
uint16_t m_rtpPort, m_rtcpPort;
|
||||
RTPTransmitter::ReceiveMode m_receivemode;
|
||||
|
||||
uint8_t *m_localhostname;
|
||||
std::size_t m_localhostnamelength;
|
||||
|
||||
std::list<RTPRawPacket*> m_rawpacketlist;
|
||||
|
||||
bool m_supportsmulticasting;
|
||||
std::size_t m_maxpacksize;
|
||||
static const std::size_t m_absoluteMaxPackSize = 65535;
|
||||
char m_rtpBuffer[m_absoluteMaxPackSize];
|
||||
char m_rtcpBuffer[m_absoluteMaxPackSize];
|
||||
|
||||
std::list<RTPAddress> m_destinations;
|
||||
std::list<RTPAddress> m_acceptList;
|
||||
std::list<RTPAddress> m_ignoreList;
|
||||
QQueue<RTPRawPacket*> m_rawPacketQueue;
|
||||
QMutex m_rawPacketQueueLock;
|
||||
|
||||
bool m_closesocketswhendone;
|
||||
|
||||
bool ShouldAcceptData(const RTPAddress& address);
|
||||
|
||||
private slots:
|
||||
void readRTPPendingDatagrams();
|
||||
void readRTCPPendingDatagrams();
|
||||
|
||||
signals:
|
||||
void NewDataAvailable();
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue