mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-02-03 09:44:01 -05:00
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
|
||||
{
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
This library was developed at the Expertise Centre for Digital Media
|
||||
(http://www.edm.uhasselt.be), a research center of the Hasselt University
|
||||
(http://www.uhasselt.be). The library is based upon work done for
|
||||
(http://www.uhasselt.be). The library is based upon work done for
|
||||
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@ -47,13 +47,7 @@
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#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
|
||||
|
||||
#endif // RTPINTERNALUTILS_H
|
||||
|
||||
|
@ -67,18 +67,59 @@ 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) :
|
||||
receivetime(0, 0)
|
||||
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) :
|
||||
receivetime(0, 0)
|
||||
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();
|
||||
if (buffer == 0)
|
||||
@ -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;
|
||||
packetdata = 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;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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) :
|
||||
RTPTransmissionInfo(RTPTransmitter::IPv4UDPProto)
|
||||
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
Block a user