mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-23 01:55:48 -05:00
qrtplib: draft (2)
This commit is contained in:
parent
96014f0efb
commit
b8147ffacc
@ -1,22 +1,25 @@
|
|||||||
project(qrtplib)
|
project(qrtplib)
|
||||||
|
|
||||||
set(qrtplib_SOURCES
|
set(qrtplib_SOURCES
|
||||||
rtptimeutilities.cpp
|
|
||||||
rtprandomurandom.cpp
|
|
||||||
rtprandomrand48.cpp
|
|
||||||
rtprandom.cpp
|
|
||||||
rtperrors.cpp
|
rtperrors.cpp
|
||||||
|
rtppacket.cpp
|
||||||
|
rtprandom.cpp
|
||||||
|
rtprandomrand48.cpp
|
||||||
|
rtprandomurandom.cpp
|
||||||
|
rtptimeutilities.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(qrtplib_HEADERS
|
set(qrtplib_HEADERS
|
||||||
rtptimeutilities.h
|
|
||||||
rtprandom.h
|
|
||||||
rtprandomurandom.h
|
|
||||||
rtprandomrand48.h
|
|
||||||
rtprandom.h
|
|
||||||
rtpinternalutils.h
|
|
||||||
rtperrors.h
|
rtperrors.h
|
||||||
rtpdefines.h
|
rtpdefines.h
|
||||||
|
rtpinternalutils.h
|
||||||
|
rtppacket.h
|
||||||
|
rtprandom.h
|
||||||
|
rtprandomrand48.h
|
||||||
|
rtprandomurandom.h
|
||||||
|
rtprawpacket.h
|
||||||
|
rtpstructs.h
|
||||||
|
rtptimeutilities.h
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
|
441
qrtplib/rtppacket.cpp
Normal file
441
qrtplib/rtppacket.cpp
Normal file
@ -0,0 +1,441 @@
|
|||||||
|
/*
|
||||||
|
Rewritten to fit into the Qt Network framework
|
||||||
|
Copyright (c) 2018 Edouard Griffiths, F4EXB
|
||||||
|
|
||||||
|
This file is a part of JRTPLIB
|
||||||
|
Copyright (c) 1999-2017 Jori Liesenborgs
|
||||||
|
|
||||||
|
Contact: jori.liesenborgs@gmail.com
|
||||||
|
|
||||||
|
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
|
||||||
|
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included
|
||||||
|
in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
IN THE SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rtppacket.h"
|
||||||
|
#include "rtpstructs.h"
|
||||||
|
#include "rtpdefines.h"
|
||||||
|
#include "rtperrors.h"
|
||||||
|
#include "rtprawpacket.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef RTPDEBUG
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif // RTPDEBUG
|
||||||
|
|
||||||
|
//#include "rtpdebug.h"
|
||||||
|
|
||||||
|
namespace qrtplib
|
||||||
|
{
|
||||||
|
|
||||||
|
void RTPPacket::Clear()
|
||||||
|
{
|
||||||
|
hasextension = false;
|
||||||
|
hasmarker = false;
|
||||||
|
numcsrcs = 0;
|
||||||
|
payloadtype = 0;
|
||||||
|
extseqnr = 0;
|
||||||
|
timestamp = 0;
|
||||||
|
ssrc = 0;
|
||||||
|
packet = 0;
|
||||||
|
payload = 0;
|
||||||
|
packetlength = 0;
|
||||||
|
payloadlength = 0;
|
||||||
|
extid = 0;
|
||||||
|
extension = 0;
|
||||||
|
extensionlength = 0;
|
||||||
|
error = 0;
|
||||||
|
externalbuffer = false;
|
||||||
|
|
||||||
|
uint32_t endianTest32 = 1;
|
||||||
|
uint8_t *ptr = (uint8_t*) &endianTest32;
|
||||||
|
m_littleEndian = (*ptr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
RTPPacket::RTPPacket(RTPRawPacket &rawpack) : receivetime(rawpack.GetReceiveTime())
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
|
||||||
|
error = BuildPacket(
|
||||||
|
payloadtype,
|
||||||
|
payloaddata,
|
||||||
|
payloadlen,
|
||||||
|
seqnr,
|
||||||
|
timestamp,
|
||||||
|
ssrc,
|
||||||
|
gotmarker,
|
||||||
|
numcsrcs,
|
||||||
|
csrcs,
|
||||||
|
gotextension,
|
||||||
|
extensionid,
|
||||||
|
extensionlen_numwords,
|
||||||
|
extensiondata,
|
||||||
|
0,
|
||||||
|
maxpacksize);
|
||||||
|
}
|
||||||
|
|
||||||
|
RTPPacket::RTPPacket(
|
||||||
|
uint8_t payloadtype,
|
||||||
|
const void *payloaddata,
|
||||||
|
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) {
|
||||||
|
error = ERR_RTP_PACKET_EXTERNALBUFFERNULL;
|
||||||
|
} else if (buffersize <= 0) {
|
||||||
|
error = ERR_RTP_PACKET_ILLEGALBUFFERSIZE;
|
||||||
|
} else {
|
||||||
|
error = BuildPacket(
|
||||||
|
payloadtype,
|
||||||
|
payloaddata,
|
||||||
|
payloadlen,
|
||||||
|
seqnr,
|
||||||
|
timestamp,
|
||||||
|
ssrc,
|
||||||
|
gotmarker,
|
||||||
|
numcsrcs,
|
||||||
|
csrcs,
|
||||||
|
gotextension,
|
||||||
|
extensionid,
|
||||||
|
extensionlen_numwords,
|
||||||
|
extensiondata,
|
||||||
|
buffer,
|
||||||
|
buffersize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int RTPPacket::ParseRawPacket(RTPRawPacket &rawpack)
|
||||||
|
{
|
||||||
|
uint8_t *packetbytes;
|
||||||
|
std::size_t packetlen;
|
||||||
|
uint8_t payloadtype;
|
||||||
|
RTPHeader *rtpheader;
|
||||||
|
bool marker;
|
||||||
|
int csrccount;
|
||||||
|
bool hasextension;
|
||||||
|
int payloadoffset,payloadlength;
|
||||||
|
int numpadbytes;
|
||||||
|
RTPExtensionHeader *rtpextheader;
|
||||||
|
|
||||||
|
if (!rawpack.IsRTP()) { // If we didn't receive it on the RTP port, we'll ignore it
|
||||||
|
return ERR_RTP_PACKET_INVALIDPACKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The length should be at least the size of the RTP header
|
||||||
|
packetlen = rawpack.GetDataLength();
|
||||||
|
|
||||||
|
if (packetlen < sizeof(RTPHeader)) {
|
||||||
|
return ERR_RTP_PACKET_INVALIDPACKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
packetbytes = (uint8_t *)rawpack.GetData();
|
||||||
|
rtpheader = (RTPHeader *)packetbytes;
|
||||||
|
|
||||||
|
// The version number should be correct
|
||||||
|
if (rtpheader->version != RTP_VERSION) {
|
||||||
|
return ERR_RTP_PACKET_INVALIDPACKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We'll check if this is possibly a RTCP packet. For this to be possible
|
||||||
|
// the marker bit and payload type combined should be either an SR or RR
|
||||||
|
// identifier
|
||||||
|
marker = (rtpheader->marker == 0)?false:true;
|
||||||
|
payloadtype = rtpheader->payloadtype;
|
||||||
|
|
||||||
|
if (marker)
|
||||||
|
{
|
||||||
|
if (payloadtype == (RTP_RTCPTYPE_SR & 127)) { // don't check high bit (this was the marker!!)
|
||||||
|
return ERR_RTP_PACKET_INVALIDPACKET;
|
||||||
|
}
|
||||||
|
if (payloadtype == (RTP_RTCPTYPE_RR & 127)) {
|
||||||
|
return ERR_RTP_PACKET_INVALIDPACKET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
csrccount = rtpheader->csrccount;
|
||||||
|
payloadoffset = sizeof(RTPHeader)+(int)(csrccount*sizeof(uint32_t));
|
||||||
|
|
||||||
|
if (rtpheader->padding) // adjust payload length to take padding into account
|
||||||
|
{
|
||||||
|
numpadbytes = (int)packetbytes[packetlen-1]; // last byte contains number of padding bytes
|
||||||
|
if (numpadbytes <= 0) {
|
||||||
|
return ERR_RTP_PACKET_INVALIDPACKET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
numpadbytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasextension = (rtpheader->extension != 0);
|
||||||
|
|
||||||
|
if (hasextension) // got header extension
|
||||||
|
{
|
||||||
|
rtpextheader = (RTPExtensionHeader *)(packetbytes+payloadoffset);
|
||||||
|
payloadoffset += sizeof(RTPExtensionHeader);
|
||||||
|
|
||||||
|
uint16_t exthdrlen = qToHost(rtpextheader->length); // ntohs(rtpextheader->length);
|
||||||
|
payloadoffset += ((int)exthdrlen)*sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rtpextheader = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
payloadlength = packetlen-numpadbytes-payloadoffset;
|
||||||
|
|
||||||
|
if (payloadlength < 0) {
|
||||||
|
return ERR_RTP_PACKET_INVALIDPACKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, we've got a valid packet, so we can create a new instance of RTPPacket
|
||||||
|
// and fill in the members
|
||||||
|
|
||||||
|
RTPPacket::hasextension = hasextension;
|
||||||
|
|
||||||
|
if (hasextension)
|
||||||
|
{
|
||||||
|
RTPPacket::extid = qToHost(rtpextheader->extid); // ntohs(rtpextheader->extid);
|
||||||
|
RTPPacket::extensionlength = ((int)qToHost(rtpextheader->length))*sizeof(uint32_t); // ((int)ntohs(rtpextheader->length))*sizeof(uint32_t);
|
||||||
|
RTPPacket::extension = ((uint8_t *)rtpextheader)+sizeof(RTPExtensionHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
RTPPacket::hasmarker = marker;
|
||||||
|
RTPPacket::numcsrcs = csrccount;
|
||||||
|
RTPPacket::payloadtype = payloadtype;
|
||||||
|
|
||||||
|
// Note: we don't fill in the EXTENDED sequence number here, since we
|
||||||
|
// don't have information about the source here. We just fill in the low
|
||||||
|
// 16 bits
|
||||||
|
RTPPacket::extseqnr = (uint32_t) qToHost(rtpheader->sequencenumber); // ntohs(rtpheader->sequencenumber);
|
||||||
|
|
||||||
|
RTPPacket::timestamp = qToHost(rtpheader->timestamp); // ntohl(rtpheader->timestamp);
|
||||||
|
RTPPacket::ssrc = qToHost(rtpheader->ssrc); // ntohl(rtpheader->ssrc);
|
||||||
|
RTPPacket::packet = packetbytes;
|
||||||
|
RTPPacket::payload = packetbytes+payloadoffset;
|
||||||
|
RTPPacket::packetlength = packetlen;
|
||||||
|
RTPPacket::payloadlength = payloadlength;
|
||||||
|
|
||||||
|
// We'll zero the data of the raw packet, since we're using it here now!
|
||||||
|
rawpack.ZeroData();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RTPPacket::GetCSRC(int num) const
|
||||||
|
{
|
||||||
|
if (num >= numcsrcs) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *csrcpos;
|
||||||
|
uint32_t *csrcval_nbo;
|
||||||
|
uint32_t csrcval_hbo;
|
||||||
|
|
||||||
|
csrcpos = packet+sizeof(RTPHeader)+num*sizeof(uint32_t);
|
||||||
|
csrcval_nbo = (uint32_t *)csrcpos;
|
||||||
|
csrcval_hbo = qToHost(*csrcval_nbo); // ntohl(*csrcval_nbo);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (numcsrcs > RTP_MAXCSRCS) {
|
||||||
|
return ERR_RTP_PACKET_TOOMANYCSRCS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payloadtype > 127) { // high bit should not be used
|
||||||
|
return ERR_RTP_PACKET_BADPAYLOADTYPE;
|
||||||
|
}
|
||||||
|
if (payloadtype == 72 || payloadtype == 73) { // could cause confusion with rtcp types
|
||||||
|
return ERR_RTP_PACKET_BADPAYLOADTYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
packetlength = sizeof(RTPHeader);
|
||||||
|
packetlength += sizeof(uint32_t)*((std::size_t)numcsrcs);
|
||||||
|
|
||||||
|
if (gotextension)
|
||||||
|
{
|
||||||
|
packetlength += sizeof(RTPExtensionHeader);
|
||||||
|
packetlength += sizeof(uint32_t)*((size_t)extensionlen_numwords);
|
||||||
|
}
|
||||||
|
|
||||||
|
packetlength += payloadlen;
|
||||||
|
|
||||||
|
if (maxsize > 0 && packetlength > maxsize)
|
||||||
|
{
|
||||||
|
packetlength = 0;
|
||||||
|
return ERR_RTP_PACKET_DATAEXCEEDSMAXSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ok, now we'll just fill in...
|
||||||
|
|
||||||
|
RTPHeader *rtphdr;
|
||||||
|
|
||||||
|
if (buffer == 0)
|
||||||
|
{
|
||||||
|
packet = new uint8_t[packetlength];
|
||||||
|
if (packet == 0)
|
||||||
|
{
|
||||||
|
packetlength = 0;
|
||||||
|
return ERR_RTP_OUTOFMEM;
|
||||||
|
}
|
||||||
|
externalbuffer = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
packet = (uint8_t *)buffer;
|
||||||
|
externalbuffer = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RTPPacket::hasmarker = gotmarker;
|
||||||
|
RTPPacket::hasextension = gotextension;
|
||||||
|
RTPPacket::numcsrcs = numcsrcs;
|
||||||
|
RTPPacket::payloadtype = payloadtype;
|
||||||
|
RTPPacket::extseqnr = (uint32_t)seqnr;
|
||||||
|
RTPPacket::timestamp = timestamp;
|
||||||
|
RTPPacket::ssrc = ssrc;
|
||||||
|
RTPPacket::payloadlength = payloadlen;
|
||||||
|
RTPPacket::extid = extensionid;
|
||||||
|
RTPPacket::extensionlength = ((std::size_t)extensionlen_numwords)*sizeof(uint32_t);
|
||||||
|
|
||||||
|
rtphdr = (RTPHeader *)packet;
|
||||||
|
rtphdr->version = RTP_VERSION;
|
||||||
|
rtphdr->padding = 0;
|
||||||
|
if (gotmarker)
|
||||||
|
rtphdr->marker = 1;
|
||||||
|
else
|
||||||
|
rtphdr->marker = 0;
|
||||||
|
if (gotextension)
|
||||||
|
rtphdr->extension = 1;
|
||||||
|
else
|
||||||
|
rtphdr->extension = 0;
|
||||||
|
rtphdr->csrccount = numcsrcs;
|
||||||
|
rtphdr->payloadtype = payloadtype&127; // make sure high bit isn't set
|
||||||
|
rtphdr->sequencenumber = qToBigEndian(seqnr); // htons(seqnr);
|
||||||
|
rtphdr->timestamp = qToBigEndian(timestamp); // htonl(timestamp);
|
||||||
|
rtphdr->ssrc = qToBigEndian(ssrc); // htonl(ssrc);
|
||||||
|
|
||||||
|
uint32_t *curcsrc;
|
||||||
|
int i;
|
||||||
|
curcsrc = (uint32_t *)(packet+sizeof(RTPHeader));
|
||||||
|
|
||||||
|
for (i = 0 ; i < numcsrcs ; i++,curcsrc++) {
|
||||||
|
*curcsrc = qToBigEndian(csrcs[i]); // htonl(csrcs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = packet+sizeof(RTPHeader)+((std::size_t)numcsrcs)*sizeof(uint32_t);
|
||||||
|
|
||||||
|
if (gotextension)
|
||||||
|
{
|
||||||
|
RTPExtensionHeader *rtpexthdr = (RTPExtensionHeader *)payload;
|
||||||
|
|
||||||
|
rtpexthdr->extid = qToBigEndian(extensionid); // htons(extensionid);
|
||||||
|
rtpexthdr->length = qToBigEndian((uint16_t)extensionlen_numwords); // htons((uint16_t)extensionlen_numwords);
|
||||||
|
|
||||||
|
payload += sizeof(RTPExtensionHeader);
|
||||||
|
memcpy(payload,extensiondata,RTPPacket::extensionlength);
|
||||||
|
|
||||||
|
payload += RTPPacket::extensionlength;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(payload,payloaddata,payloadlen);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RTPDEBUG
|
||||||
|
void RTPPacket::Dump()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
printf("Payload type: %d\n",(int)GetPayloadType());
|
||||||
|
printf("Extended sequence number: 0x%08x\n",GetExtendedSequenceNumber());
|
||||||
|
printf("Timestamp: 0x%08x\n",GetTimestamp());
|
||||||
|
printf("SSRC: 0x%08x\n",GetSSRC());
|
||||||
|
printf("Marker: %s\n",HasMarker()?"yes":"no");
|
||||||
|
printf("CSRC count: %d\n",GetCSRCCount());
|
||||||
|
for (i = 0 ; i < GetCSRCCount() ; i++)
|
||||||
|
printf(" CSRC[%02d]: 0x%08x\n",i,GetCSRC(i));
|
||||||
|
printf("Payload: %s\n",GetPayloadData());
|
||||||
|
printf("Payload length: %d\n",GetPayloadLength());
|
||||||
|
printf("Packet length: %d\n",GetPacketLength());
|
||||||
|
printf("Extension: %s\n",HasExtension()?"yes":"no");
|
||||||
|
if (HasExtension())
|
||||||
|
{
|
||||||
|
printf(" Extension ID: 0x%04x\n",GetExtensionID());
|
||||||
|
printf(" Extension data: %s\n",GetExtensionData());
|
||||||
|
printf(" Extension length: %d\n",GetExtensionLength());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // RTPDEBUG
|
||||||
|
|
||||||
|
} // end namespace
|
||||||
|
|
288
qrtplib/rtppacket.h
Normal file
288
qrtplib/rtppacket.h
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
/*
|
||||||
|
Rewritten to fit into the Qt Network framework
|
||||||
|
Copyright (c) 2018 Edouard Griffiths, F4EXB
|
||||||
|
|
||||||
|
This file is a part of JRTPLIB
|
||||||
|
Copyright (c) 1999-2017 Jori Liesenborgs
|
||||||
|
|
||||||
|
Contact: jori.liesenborgs@gmail.com
|
||||||
|
|
||||||
|
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
|
||||||
|
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included
|
||||||
|
in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
IN THE SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file rtppacket.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RTPPACKET_H
|
||||||
|
|
||||||
|
#define RTPPACKET_H
|
||||||
|
|
||||||
|
//#include "rtpconfig.h"
|
||||||
|
//#include "rtptypes.h"
|
||||||
|
#include "rtptimeutilities.h"
|
||||||
|
//#include "rtpmemoryobject.h"
|
||||||
|
#include <cstddef>
|
||||||
|
#include <QtEndian>
|
||||||
|
|
||||||
|
namespace qrtplib
|
||||||
|
{
|
||||||
|
|
||||||
|
class RTPRawPacket;
|
||||||
|
|
||||||
|
/** Represents an RTP Packet.
|
||||||
|
* The RTPPacket class can be used to parse a RTPRawPacket instance if it represents RTP data.
|
||||||
|
* The class can also be used to create a new RTP packet according to the parameters specified by
|
||||||
|
* the user.
|
||||||
|
*/
|
||||||
|
class RTPPacket
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Creates an RTPPacket instance based upon the data in \c rawpack.
|
||||||
|
* Creates an RTPPacket instance based upon the data in \c rawpack.
|
||||||
|
* If successful, the data is moved from the raw packet to the RTPPacket instance.
|
||||||
|
*/
|
||||||
|
RTPPacket(RTPRawPacket &rawpack);
|
||||||
|
|
||||||
|
/** Creates a new buffer for an RTP packet and fills in the fields according to the specified parameters.
|
||||||
|
* Creates a new buffer for an RTP packet and fills in the fields according to the specified parameters.
|
||||||
|
* If \c maxpacksize is not equal to zero, an error is generated if the total packet size would exceed
|
||||||
|
* \c maxpacksize. The arguments of the constructor are self-explanatory. Note that the size of a header
|
||||||
|
* extension is specified in a number of 32-bit words.
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
|
/** This constructor is similar to the other constructor, but here data is stored in an external buffer
|
||||||
|
* \c buffer with size \c buffersize. */
|
||||||
|
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);
|
||||||
|
|
||||||
|
virtual ~RTPPacket()
|
||||||
|
{
|
||||||
|
if (packet && !externalbuffer){
|
||||||
|
delete[] packet;
|
||||||
|
//RTPDeleteByteArray(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** If an error occurred in one of the constructors, this function returns the error code. */
|
||||||
|
int GetCreationError() const
|
||||||
|
{
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns \c true if the RTP packet has a header extension and \c false otherwise. */
|
||||||
|
bool HasExtension() const
|
||||||
|
{
|
||||||
|
return hasextension;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns \c true if the marker bit was set and \c false otherwise. */
|
||||||
|
bool HasMarker() const
|
||||||
|
{
|
||||||
|
return hasmarker;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the number of CSRCs contained in this packet. */
|
||||||
|
int GetCSRCCount() const
|
||||||
|
{
|
||||||
|
return numcsrcs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a specific CSRC identifier.
|
||||||
|
* Returns a specific CSRC identifier. The parameter \c num can go from 0 to GetCSRCCount()-1.
|
||||||
|
*/
|
||||||
|
uint32_t GetCSRC(int num) const;
|
||||||
|
|
||||||
|
/** Returns the payload type of the packet. */
|
||||||
|
uint8_t GetPayloadType() const
|
||||||
|
{
|
||||||
|
return payloadtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the extended sequence number of the packet.
|
||||||
|
* Returns the extended sequence number of the packet. When the packet is just received,
|
||||||
|
* only the low $16$ bits will be set. The high 16 bits can be filled in later.
|
||||||
|
*/
|
||||||
|
uint32_t GetExtendedSequenceNumber() const
|
||||||
|
{
|
||||||
|
return extseqnr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the sequence number of this packet. */
|
||||||
|
uint16_t GetSequenceNumber() const
|
||||||
|
{
|
||||||
|
return (uint16_t)(extseqnr&0x0000FFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the extended sequence number of this packet to \c seq. */
|
||||||
|
void SetExtendedSequenceNumber(uint32_t seq)
|
||||||
|
{
|
||||||
|
extseqnr = seq;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the timestamp of this packet. */
|
||||||
|
uint32_t GetTimestamp() const
|
||||||
|
{
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the SSRC identifier stored in this packet. */
|
||||||
|
uint32_t GetSSRC() const
|
||||||
|
{
|
||||||
|
return ssrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a pointer to the data of the entire packet. */
|
||||||
|
uint8_t *GetPacketData() const
|
||||||
|
{
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a pointer to the actual payload data. */
|
||||||
|
uint8_t *GetPayloadData() const
|
||||||
|
{
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the length of the entire packet. */
|
||||||
|
std::size_t GetPacketLength() const
|
||||||
|
{
|
||||||
|
return packetlength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the payload length. */
|
||||||
|
std::size_t GetPayloadLength() const
|
||||||
|
{
|
||||||
|
return payloadlength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** If a header extension is present, this function returns the extension identifier. */
|
||||||
|
uint16_t GetExtensionID() const
|
||||||
|
{
|
||||||
|
return extid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the length of the header extension data. */
|
||||||
|
uint8_t *GetExtensionData() const
|
||||||
|
{
|
||||||
|
return extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the length of the header extension data. */
|
||||||
|
std::size_t GetExtensionLength() const
|
||||||
|
{
|
||||||
|
return extensionlength;
|
||||||
|
}
|
||||||
|
#ifdef RTPDEBUG
|
||||||
|
void Dump();
|
||||||
|
#endif // RTPDEBUG
|
||||||
|
|
||||||
|
/** Returns the time at which this packet was received.
|
||||||
|
* When an RTPPacket instance is created from an RTPRawPacket instance, the raw packet's
|
||||||
|
* reception time is stored in the RTPPacket instance. This function then retrieves that
|
||||||
|
* time.
|
||||||
|
*/
|
||||||
|
RTPTime GetReceiveTime() const
|
||||||
|
{
|
||||||
|
return receivetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Clear();
|
||||||
|
int ParseRawPacket(RTPRawPacket &rawpack);
|
||||||
|
int 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);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T qToHost(const T& x) const {
|
||||||
|
return m_littleEndian ? qToLittleEndian(x) : qToBigEndian(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
int error;
|
||||||
|
bool m_littleEndian;
|
||||||
|
|
||||||
|
bool hasextension,hasmarker;
|
||||||
|
int numcsrcs;
|
||||||
|
|
||||||
|
uint8_t payloadtype;
|
||||||
|
uint32_t extseqnr,timestamp,ssrc;
|
||||||
|
uint8_t *packet,*payload;
|
||||||
|
std::size_t packetlength,payloadlength;
|
||||||
|
|
||||||
|
uint16_t extid;
|
||||||
|
uint8_t *extension;
|
||||||
|
std::size_t extensionlength;
|
||||||
|
|
||||||
|
bool externalbuffer;
|
||||||
|
|
||||||
|
RTPTime receivetime;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace
|
||||||
|
|
||||||
|
#endif // RTPPACKET_H
|
||||||
|
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
This library was developed at the Expertise Centre for Digital Media
|
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.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).
|
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
@ -46,6 +46,21 @@ namespace qrtplib
|
|||||||
RTPPacketBuilder::RTPPacketBuilder(RTPRandom &r) : rtprnd(r), lastwallclocktime(0,0)
|
RTPPacketBuilder::RTPPacketBuilder(RTPRandom &r) : rtprnd(r), lastwallclocktime(0,0)
|
||||||
{
|
{
|
||||||
init = false;
|
init = false;
|
||||||
|
deftsset = false;
|
||||||
|
defaultpayloadtype = 0;
|
||||||
|
lastrtptimestamp = 0;
|
||||||
|
ssrc = 0;
|
||||||
|
numcsrcs = 0;
|
||||||
|
defmarkset = false;
|
||||||
|
defaultmark = false;
|
||||||
|
defaulttimestampinc = 0;
|
||||||
|
timestamp = 0;
|
||||||
|
buffer = 0;
|
||||||
|
numpackets = 0;
|
||||||
|
seqnr = 0;
|
||||||
|
numpayloadbytes = 0;
|
||||||
|
prevrtptimestamp = 0;
|
||||||
|
defptset = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RTPPacketBuilder::~RTPPacketBuilder()
|
RTPPacketBuilder::~RTPPacketBuilder()
|
||||||
@ -62,22 +77,22 @@ int RTPPacketBuilder::Init(std::size_t max)
|
|||||||
if (max <= 0) {
|
if (max <= 0) {
|
||||||
return ERR_RTP_PACKBUILD_INVALIDMAXPACKETSIZE;
|
return ERR_RTP_PACKBUILD_INVALIDMAXPACKETSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
maxpacksize = max;
|
maxpacksize = max;
|
||||||
buffer = new uint8_t[max];
|
buffer = new uint8_t[max];
|
||||||
if (buffer == 0) {
|
if (buffer == 0) {
|
||||||
return ERR_RTP_OUTOFMEM;
|
return ERR_RTP_OUTOFMEM;
|
||||||
}
|
}
|
||||||
packetlength = 0;
|
packetlength = 0;
|
||||||
|
|
||||||
CreateNewSSRC();
|
CreateNewSSRC();
|
||||||
|
|
||||||
deftsset = false;
|
deftsset = false;
|
||||||
defptset = false;
|
defptset = false;
|
||||||
defmarkset = false;
|
defmarkset = false;
|
||||||
|
|
||||||
numcsrcs = 0;
|
numcsrcs = 0;
|
||||||
|
|
||||||
init = true;
|
init = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -102,7 +117,7 @@ int RTPPacketBuilder::SetMaximumPacketSize(std::size_t max)
|
|||||||
if (newbuf == 0) {
|
if (newbuf == 0) {
|
||||||
return ERR_RTP_OUTOFMEM;
|
return ERR_RTP_OUTOFMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
buffer = newbuf;
|
buffer = newbuf;
|
||||||
maxpacksize = max;
|
maxpacksize = max;
|
||||||
@ -135,7 +150,7 @@ int RTPPacketBuilder::DeleteCSRC(uint32_t csrc)
|
|||||||
if (!init) {
|
if (!init) {
|
||||||
return ERR_RTP_PACKBUILD_NOTINIT;
|
return ERR_RTP_PACKBUILD_NOTINIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
@ -151,7 +166,7 @@ int RTPPacketBuilder::DeleteCSRC(uint32_t csrc)
|
|||||||
if (!found) {
|
if (!found) {
|
||||||
return ERR_RTP_PACKBUILD_CSRCNOTINLIST;
|
return ERR_RTP_PACKBUILD_CSRCNOTINLIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
// move the last csrc in the place of the deleted one
|
// move the last csrc in the place of the deleted one
|
||||||
numcsrcs--;
|
numcsrcs--;
|
||||||
if (numcsrcs > 0 && numcsrcs != i) {
|
if (numcsrcs > 0 && numcsrcs != i) {
|
||||||
@ -184,13 +199,13 @@ uint32_t RTPPacketBuilder::CreateNewSSRC()
|
|||||||
uint32_t RTPPacketBuilder::CreateNewSSRC(RTPSources &sources)
|
uint32_t RTPPacketBuilder::CreateNewSSRC(RTPSources &sources)
|
||||||
{
|
{
|
||||||
bool found;
|
bool found;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ssrc = rtprnd.GetRandom32();
|
ssrc = rtprnd.GetRandom32();
|
||||||
found = sources.GotEntry(ssrc);
|
found = sources.GotEntry(ssrc);
|
||||||
} while (found);
|
} while (found);
|
||||||
|
|
||||||
timestamp = rtprnd.GetRandom32();
|
timestamp = rtprnd.GetRandom32();
|
||||||
seqnr = rtprnd.GetRandom16();
|
seqnr = rtprnd.GetRandom16();
|
||||||
|
|
||||||
@ -273,7 +288,7 @@ int RTPPacketBuilder::PrivateBuildPacket(const void *data, std::size_t len,
|
|||||||
lastrtptimestamp = timestamp;
|
lastrtptimestamp = timestamp;
|
||||||
prevrtptimestamp = timestamp;
|
prevrtptimestamp = timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
numpayloadbytes += (uint32_t)p.GetPayloadLength();
|
numpayloadbytes += (uint32_t)p.GetPayloadLength();
|
||||||
numpackets++;
|
numpackets++;
|
||||||
timestamp += timestampinc;
|
timestamp += timestampinc;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
This library was developed at the Expertise Centre for Digital Media
|
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.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).
|
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
@ -35,13 +35,11 @@
|
|||||||
#include "rtprandom.h"
|
#include "rtprandom.h"
|
||||||
#include "rtprandomurandom.h"
|
#include "rtprandomurandom.h"
|
||||||
#include "rtprandomrand48.h"
|
#include "rtprandomrand48.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#ifndef WIN32
|
#include <unistd.h>
|
||||||
#include <unistd.h>
|
|
||||||
#else
|
#include <QDateTime>
|
||||||
#include <process.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#endif // WIN32
|
|
||||||
|
|
||||||
//#include "rtpdebug.h"
|
//#include "rtpdebug.h"
|
||||||
|
|
||||||
@ -51,24 +49,15 @@ namespace qrtplib
|
|||||||
uint32_t RTPRandom::PickSeed()
|
uint32_t RTPRandom::PickSeed()
|
||||||
{
|
{
|
||||||
uint32_t x;
|
uint32_t x;
|
||||||
// TODO: do it for MinGW see sdrbase/util/uid.h,cpp
|
x = (uint32_t) getpid();
|
||||||
|
QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||||
|
x += currentDateTime.toTime_t();
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
x = (uint32_t)GetCurrentProcessId();
|
x += QDateTime::currentMSecsSinceEpoch() % 1000;
|
||||||
|
|
||||||
FILETIME ft;
|
|
||||||
SYSTEMTIME st;
|
|
||||||
|
|
||||||
GetSystemTime(&st);
|
|
||||||
SystemTimeToFileTime(&st,&ft);
|
|
||||||
|
|
||||||
x += ft.dwLowDateTime;
|
|
||||||
x ^= (uint32_t)((uint8_t *)this - (uint8_t *)0);
|
|
||||||
#else
|
#else
|
||||||
x = (uint32_t)getpid();
|
|
||||||
x += (uint32_t)time(0);
|
|
||||||
x += (uint32_t)clock();
|
x += (uint32_t)clock();
|
||||||
x ^= (uint32_t)((uint8_t *)this - (uint8_t *)0);
|
|
||||||
#endif
|
#endif
|
||||||
|
x ^= (uint32_t)((uint8_t *)this - (uint8_t *)0);
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +71,7 @@ RTPRandom *RTPRandom::CreateDefaultRandomNumberGenerator()
|
|||||||
delete r;
|
delete r;
|
||||||
rRet = new RTPRandomRand48();
|
rRet = new RTPRandomRand48();
|
||||||
}
|
}
|
||||||
|
|
||||||
return rRet;
|
return rRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
183
qrtplib/rtprawpacket.h
Normal file
183
qrtplib/rtprawpacket.h
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
/*
|
||||||
|
Rewritten to fit into the Qt Network framework
|
||||||
|
Copyright (c) 2018 Edouard Griffiths, F4EXB
|
||||||
|
|
||||||
|
This file is a part of JRTPLIB
|
||||||
|
Copyright (c) 1999-2017 Jori Liesenborgs
|
||||||
|
|
||||||
|
Contact: jori.liesenborgs@gmail.com
|
||||||
|
|
||||||
|
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
|
||||||
|
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included
|
||||||
|
in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
IN THE SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file rtprawpacket.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RTPRAWPACKET_H
|
||||||
|
|
||||||
|
#define RTPRAWPACKET_H
|
||||||
|
|
||||||
|
//#include "rtpconfig.h"
|
||||||
|
#include "rtptimeutilities.h"
|
||||||
|
//#include "rtpaddress.h"
|
||||||
|
//#include "rtptypes.h"
|
||||||
|
//#include "rtpmemoryobject.h"
|
||||||
|
#include <cstddef>
|
||||||
|
#include <QHostAddress>
|
||||||
|
|
||||||
|
namespace qrtplib
|
||||||
|
{
|
||||||
|
|
||||||
|
/** This class is used by the transmission component to store the incoming RTP and RTCP data in. */
|
||||||
|
class RTPRawPacket
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Creates an instance which stores data from \c data with length \c datalen.
|
||||||
|
* Creates an instance which stores data from \c data with length \c datalen. Only the pointer
|
||||||
|
* to the data is stored, no actual copy is made! The address from which this packet originated
|
||||||
|
* is set to \c address and the time at which the packet was received is set to \c recvtime.
|
||||||
|
* 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, QHostAddress *address, RTPTime &recvtime, bool rtp);
|
||||||
|
~RTPRawPacket();
|
||||||
|
|
||||||
|
/** Returns the pointer to the data which is contained in this packet. */
|
||||||
|
uint8_t *GetData()
|
||||||
|
{
|
||||||
|
return packetdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the length of the packet described by this instance. */
|
||||||
|
std::size_t GetDataLength() const
|
||||||
|
{
|
||||||
|
return packetdatalength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the time at which this packet was received. */
|
||||||
|
RTPTime GetReceiveTime() const
|
||||||
|
{
|
||||||
|
return receivetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the address stored in this packet. */
|
||||||
|
const QHostAddress *GetSenderAddress() const
|
||||||
|
{
|
||||||
|
return senderaddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns \c true if this data is RTP data, \c false if it is RTCP data. */
|
||||||
|
bool IsRTP() const
|
||||||
|
{
|
||||||
|
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(bool isrtp, 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);
|
||||||
|
|
||||||
|
/** Deallocates the currently stored RTPAddress instance and replaces it
|
||||||
|
* with the one that's specified (you probably don't need this function). */
|
||||||
|
void SetSenderAddress(QHostAddress *address);
|
||||||
|
private:
|
||||||
|
void DeleteData();
|
||||||
|
|
||||||
|
uint8_t *packetdata;
|
||||||
|
std::size_t packetdatalength;
|
||||||
|
RTPTime receivetime;
|
||||||
|
QHostAddress *senderaddress;
|
||||||
|
bool isrtp;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline RTPRawPacket::RTPRawPacket(
|
||||||
|
uint8_t *data,
|
||||||
|
std::size_t datalen,
|
||||||
|
QHostAddress *address,
|
||||||
|
RTPTime &recvtime,
|
||||||
|
bool rtp): receivetime(recvtime)
|
||||||
|
{
|
||||||
|
packetdata = data;
|
||||||
|
packetdatalength = datalen;
|
||||||
|
senderaddress = address;
|
||||||
|
isrtp = rtp;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline RTPRawPacket::~RTPRawPacket()
|
||||||
|
{
|
||||||
|
DeleteData();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RTPRawPacket::DeleteData()
|
||||||
|
{
|
||||||
|
if (packetdata) {
|
||||||
|
delete[] packetdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
packetdata = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint8_t *RTPRawPacket::AllocateBytes(bool isrtp __attribute__((unused)), int recvlen) const
|
||||||
|
{
|
||||||
|
return new uint8_t[recvlen];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RTPRawPacket::SetData(uint8_t *data, std::size_t datalen)
|
||||||
|
{
|
||||||
|
if (packetdata) {
|
||||||
|
delete[] packetdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
packetdata = data;
|
||||||
|
packetdatalength = datalen;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RTPRawPacket::SetSenderAddress(QHostAddress *address)
|
||||||
|
{
|
||||||
|
senderaddress = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace
|
||||||
|
|
||||||
|
#endif // RTPRAWPACKET_H
|
||||||
|
|
130
qrtplib/rtpstructs.h
Normal file
130
qrtplib/rtpstructs.h
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
Rewritten to fit into the Qt Network framework
|
||||||
|
Copyright (c) 2018 Edouard Griffiths, F4EXB
|
||||||
|
|
||||||
|
This file is a part of JRTPLIB
|
||||||
|
Copyright (c) 1999-2017 Jori Liesenborgs
|
||||||
|
|
||||||
|
Contact: jori.liesenborgs@gmail.com
|
||||||
|
|
||||||
|
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
|
||||||
|
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included
|
||||||
|
in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
IN THE SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file rtpstructs.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RTPSTRUCTS_H
|
||||||
|
|
||||||
|
#define RTPSTRUCTS_H
|
||||||
|
|
||||||
|
//#include "rtpconfig.h"
|
||||||
|
//#include "rtptypes.h"
|
||||||
|
|
||||||
|
namespace qrtplib
|
||||||
|
{
|
||||||
|
|
||||||
|
struct RTPHeader
|
||||||
|
{
|
||||||
|
#ifdef RTP_BIG_ENDIAN
|
||||||
|
uint8_t version:2;
|
||||||
|
uint8_t padding:1;
|
||||||
|
uint8_t extension:1;
|
||||||
|
uint8_t csrccount:4;
|
||||||
|
|
||||||
|
uint8_t marker:1;
|
||||||
|
uint8_t payloadtype:7;
|
||||||
|
#else // little endian
|
||||||
|
uint8_t csrccount:4;
|
||||||
|
uint8_t extension:1;
|
||||||
|
uint8_t padding:1;
|
||||||
|
uint8_t version:2;
|
||||||
|
|
||||||
|
uint8_t payloadtype:7;
|
||||||
|
uint8_t marker:1;
|
||||||
|
#endif // RTP_BIG_ENDIAN
|
||||||
|
|
||||||
|
uint16_t sequencenumber;
|
||||||
|
uint32_t timestamp;
|
||||||
|
uint32_t ssrc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RTPExtensionHeader
|
||||||
|
{
|
||||||
|
uint16_t extid;
|
||||||
|
uint16_t length;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RTPSourceIdentifier
|
||||||
|
{
|
||||||
|
uint32_t ssrc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RTCPCommonHeader
|
||||||
|
{
|
||||||
|
#ifdef RTP_BIG_ENDIAN
|
||||||
|
uint8_t version:2;
|
||||||
|
uint8_t padding:1;
|
||||||
|
uint8_t count:5;
|
||||||
|
#else // little endian
|
||||||
|
uint8_t count:5;
|
||||||
|
uint8_t padding:1;
|
||||||
|
uint8_t version:2;
|
||||||
|
#endif // RTP_BIG_ENDIAN
|
||||||
|
|
||||||
|
uint8_t packettype;
|
||||||
|
uint16_t length;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RTCPSenderReport
|
||||||
|
{
|
||||||
|
uint32_t ntptime_msw;
|
||||||
|
uint32_t ntptime_lsw;
|
||||||
|
uint32_t rtptimestamp;
|
||||||
|
uint32_t packetcount;
|
||||||
|
uint32_t octetcount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RTCPReceiverReport
|
||||||
|
{
|
||||||
|
uint32_t ssrc; // Identifies about which SSRC's data this report is...
|
||||||
|
uint8_t fractionlost;
|
||||||
|
uint8_t packetslost[3];
|
||||||
|
uint32_t exthighseqnr;
|
||||||
|
uint32_t jitter;
|
||||||
|
uint32_t lsr;
|
||||||
|
uint32_t dlsr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RTCPSDESHeader
|
||||||
|
{
|
||||||
|
uint8_t sdesid;
|
||||||
|
uint8_t length;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace
|
||||||
|
|
||||||
|
#endif // RTPSTRUCTS
|
||||||
|
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
This library was developed at the Expertise Centre for Digital Media
|
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.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).
|
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
@ -35,7 +35,7 @@
|
|||||||
//#include "rtpconfig.h"
|
//#include "rtpconfig.h"
|
||||||
#include "rtptimeutilities.h"
|
#include "rtptimeutilities.h"
|
||||||
|
|
||||||
namespace jrtplib
|
namespace qrtplib
|
||||||
{
|
{
|
||||||
|
|
||||||
RTPTimeInitializerObject::RTPTimeInitializerObject()
|
RTPTimeInitializerObject::RTPTimeInitializerObject()
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
This library was developed at the Expertise Centre for Digital Media
|
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.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).
|
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
@ -51,11 +51,11 @@
|
|||||||
#define C1000000 1000000ULL
|
#define C1000000 1000000ULL
|
||||||
#define CEPOCH 11644473600000000ULL
|
#define CEPOCH 11644473600000000ULL
|
||||||
|
|
||||||
namespace jrtplib
|
namespace qrtplib
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a simple wrapper for the most significant word (MSW) and least
|
* This is a simple wrapper for the most significant word (MSW) and least
|
||||||
* significant word (LSW) of an NTP timestamp.
|
* significant word (LSW) of an NTP timestamp.
|
||||||
*/
|
*/
|
||||||
class RTPNTPTime
|
class RTPNTPTime
|
||||||
@ -74,25 +74,25 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** This class is used to specify wallclock time, delay intervals etc.
|
/** This class is used to specify wallclock time, delay intervals etc.
|
||||||
* This class is used to specify wallclock time, delay intervals etc.
|
* This class is used to specify wallclock time, delay intervals etc.
|
||||||
* It stores a number of seconds and a number of microseconds.
|
* It stores a number of seconds and a number of microseconds.
|
||||||
*/
|
*/
|
||||||
class RTPTime
|
class RTPTime
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Returns an RTPTime instance representing the current wallclock time.
|
/** Returns an RTPTime instance representing the current wallclock time.
|
||||||
* Returns an RTPTime instance representing the current wallclock time. This is expressed
|
* Returns an RTPTime instance representing the current wallclock time. This is expressed
|
||||||
* as a number of seconds since 00:00:00 UTC, January 1, 1970.
|
* as a number of seconds since 00:00:00 UTC, January 1, 1970.
|
||||||
*/
|
*/
|
||||||
static RTPTime CurrentTime();
|
static RTPTime CurrentTime();
|
||||||
|
|
||||||
/** This function waits the amount of time specified in \c delay. */
|
/** This function waits the amount of time specified in \c delay. */
|
||||||
static void Wait(const RTPTime &delay);
|
static void Wait(const RTPTime &delay);
|
||||||
|
|
||||||
/** Creates an RTPTime instance representing \c t, which is expressed in units of seconds. */
|
/** Creates an RTPTime instance representing \c t, which is expressed in units of seconds. */
|
||||||
RTPTime(double t);
|
RTPTime(double t);
|
||||||
|
|
||||||
/** Creates an instance that corresponds to \c ntptime.
|
/** Creates an instance that corresponds to \c ntptime.
|
||||||
* Creates an instance that corresponds to \c ntptime. If
|
* Creates an instance that corresponds to \c ntptime. If
|
||||||
* the conversion cannot be made, both the seconds and the
|
* the conversion cannot be made, both the seconds and the
|
||||||
* microseconds are set to zero.
|
* microseconds are set to zero.
|
||||||
@ -155,7 +155,7 @@ inline RTPTime::RTPTime(RTPNTPTime ntptime)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint32_t sec = ntptime.GetMSW() - RTP_NTPTIMEOFFSET;
|
uint32_t sec = ntptime.GetMSW() - RTP_NTPTIMEOFFSET;
|
||||||
|
|
||||||
double x = (double)ntptime.GetLSW();
|
double x = (double)ntptime.GetLSW();
|
||||||
x /= (65536.0*65536.0);
|
x /= (65536.0*65536.0);
|
||||||
x *= 1000000.0;
|
x *= 1000000.0;
|
||||||
@ -233,7 +233,7 @@ inline RTPTime RTPTime::CurrentTime()
|
|||||||
inline RTPTime RTPTime::CurrentTime()
|
inline RTPTime RTPTime::CurrentTime()
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
gettimeofday(&tv,0);
|
gettimeofday(&tv,0);
|
||||||
return RTPTime((uint64_t)tv.tv_sec,(uint32_t)tv.tv_usec);
|
return RTPTime((uint64_t)tv.tv_sec,(uint32_t)tv.tv_usec);
|
||||||
}
|
}
|
||||||
@ -260,13 +260,13 @@ inline void RTPTime::Wait(const RTPTime &delay)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline RTPTime &RTPTime::operator-=(const RTPTime &t)
|
inline RTPTime &RTPTime::operator-=(const RTPTime &t)
|
||||||
{
|
{
|
||||||
m_t -= t.m_t;
|
m_t -= t.m_t;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline RTPTime &RTPTime::operator+=(const RTPTime &t)
|
inline RTPTime &RTPTime::operator+=(const RTPTime &t)
|
||||||
{
|
{
|
||||||
m_t += t.m_t;
|
m_t += t.m_t;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -279,7 +279,7 @@ inline RTPNTPTime RTPTime::GetNTPTime() const
|
|||||||
uint32_t msw = sec+RTP_NTPTIMEOFFSET;
|
uint32_t msw = sec+RTP_NTPTIMEOFFSET;
|
||||||
uint32_t lsw;
|
uint32_t lsw;
|
||||||
double x;
|
double x;
|
||||||
|
|
||||||
x = microsec/1000000.0;
|
x = microsec/1000000.0;
|
||||||
x *= (65536.0*65536.0);
|
x *= (65536.0*65536.0);
|
||||||
lsw = (uint32_t)x;
|
lsw = (uint32_t)x;
|
||||||
|
Loading…
Reference in New Issue
Block a user