mirror of
https://github.com/f4exb/sdrangel.git
synced 2026-06-01 21:54:55 -04:00
qrtplib: removed debug
This commit is contained in:
@@ -0,0 +1,737 @@
|
||||
/*
|
||||
|
||||
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 "rtcppacketbuilder.h"
|
||||
#include "rtpsources.h"
|
||||
#include "rtppacketbuilder.h"
|
||||
#include "rtcpscheduler.h"
|
||||
#include "rtpsourcedata.h"
|
||||
#include "rtcpcompoundpacketbuilder.h"
|
||||
#include "rtpmemorymanager.h"
|
||||
|
||||
namespace qrtplib
|
||||
{
|
||||
|
||||
RTCPPacketBuilder::RTCPPacketBuilder(RTPSources &s,RTPPacketBuilder &pb,RTPMemoryManager *mgr)
|
||||
: RTPMemoryObject(mgr),sources(s),rtppacketbuilder(pb),prevbuildtime(0,0),transmissiondelay(0,0),ownsdesinfo(mgr)
|
||||
{
|
||||
init = false;
|
||||
timeinit.Dummy();
|
||||
}
|
||||
|
||||
RTCPPacketBuilder::~RTCPPacketBuilder()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
int RTCPPacketBuilder::Init(size_t maxpacksize,double tsunit,const void *cname,size_t cnamelen)
|
||||
{
|
||||
if (init)
|
||||
return ERR_RTP_RTCPPACKETBUILDER_ALREADYINIT;
|
||||
if (maxpacksize < RTP_MINPACKETSIZE)
|
||||
return ERR_RTP_RTCPPACKETBUILDER_ILLEGALMAXPACKSIZE;
|
||||
if (tsunit < 0.0)
|
||||
return ERR_RTP_RTCPPACKETBUILDER_ILLEGALTIMESTAMPUNIT;
|
||||
|
||||
if (cnamelen>255)
|
||||
cnamelen = 255;
|
||||
|
||||
maxpacketsize = maxpacksize;
|
||||
timestampunit = tsunit;
|
||||
|
||||
int status;
|
||||
|
||||
if ((status = ownsdesinfo.SetCNAME((const uint8_t *)cname,cnamelen)) < 0)
|
||||
return status;
|
||||
|
||||
ClearAllSourceFlags();
|
||||
|
||||
interval_name = -1;
|
||||
interval_email = -1;
|
||||
interval_location = -1;
|
||||
interval_phone = -1;
|
||||
interval_tool = -1;
|
||||
interval_note = -1;
|
||||
|
||||
sdesbuildcount = 0;
|
||||
transmissiondelay = RTPTime(0,0);
|
||||
|
||||
firstpacket = true;
|
||||
processingsdes = false;
|
||||
init = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RTCPPacketBuilder::Destroy()
|
||||
{
|
||||
if (!init)
|
||||
return;
|
||||
ownsdesinfo.Clear();
|
||||
init = false;
|
||||
}
|
||||
|
||||
int RTCPPacketBuilder::BuildNextPacket(RTCPCompoundPacket **pack)
|
||||
{
|
||||
if (!init)
|
||||
return ERR_RTP_RTCPPACKETBUILDER_NOTINIT;
|
||||
|
||||
RTCPCompoundPacketBuilder *rtcpcomppack;
|
||||
int status;
|
||||
bool sender = false;
|
||||
RTPSourceData *srcdat;
|
||||
|
||||
*pack = 0;
|
||||
|
||||
rtcpcomppack = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPCOMPOUNDPACKETBUILDER) RTCPCompoundPacketBuilder(GetMemoryManager());
|
||||
if (rtcpcomppack == 0)
|
||||
return ERR_RTP_OUTOFMEM;
|
||||
|
||||
if ((status = rtcpcomppack->InitBuild(maxpacketsize)) < 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
return status;
|
||||
}
|
||||
|
||||
if ((srcdat = sources.GetOwnSourceInfo()) != 0)
|
||||
{
|
||||
if (srcdat->IsSender())
|
||||
sender = true;
|
||||
}
|
||||
|
||||
uint32_t ssrc = rtppacketbuilder.GetSSRC();
|
||||
RTPTime curtime = RTPTime::CurrentTime();
|
||||
|
||||
if (sender)
|
||||
{
|
||||
RTPTime rtppacktime = rtppacketbuilder.GetPacketTime();
|
||||
uint32_t rtppacktimestamp = rtppacketbuilder.GetPacketTimestamp();
|
||||
uint32_t packcount = rtppacketbuilder.GetPacketCount();
|
||||
uint32_t octetcount = rtppacketbuilder.GetPayloadOctetCount();
|
||||
RTPTime diff = curtime;
|
||||
diff -= rtppacktime;
|
||||
diff += transmissiondelay; // the sample being sampled at this very instant will need a larger timestamp
|
||||
|
||||
uint32_t tsdiff = (uint32_t)((diff.GetDouble()/timestampunit)+0.5);
|
||||
uint32_t rtptimestamp = rtppacktimestamp+tsdiff;
|
||||
RTPNTPTime ntptimestamp = curtime.GetNTPTime();
|
||||
|
||||
if ((status = rtcpcomppack->StartSenderReport(ssrc,ntptimestamp,rtptimestamp,packcount,octetcount)) < 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT)
|
||||
return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((status = rtcpcomppack->StartReceiverReport(ssrc)) < 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT)
|
||||
return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *owncname;
|
||||
size_t owncnamelen;
|
||||
|
||||
owncname = ownsdesinfo.GetCNAME(&owncnamelen);
|
||||
|
||||
if ((status = rtcpcomppack->AddSDESSource(ssrc)) < 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT)
|
||||
return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON;
|
||||
return status;
|
||||
}
|
||||
if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::CNAME,owncname,owncnamelen)) < 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT)
|
||||
return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON;
|
||||
return status;
|
||||
}
|
||||
|
||||
if (!processingsdes)
|
||||
{
|
||||
int added,skipped;
|
||||
bool full,atendoflist;
|
||||
|
||||
if ((status = FillInReportBlocks(rtcpcomppack,curtime,sources.GetTotalCount(),&full,&added,&skipped,&atendoflist)) < 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
return status;
|
||||
}
|
||||
|
||||
if (full && added == 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON;
|
||||
}
|
||||
|
||||
if (!full)
|
||||
{
|
||||
processingsdes = true;
|
||||
sdesbuildcount++;
|
||||
|
||||
ClearAllSourceFlags();
|
||||
|
||||
doname = false;
|
||||
doemail = false;
|
||||
doloc = false;
|
||||
dophone = false;
|
||||
dotool = false;
|
||||
donote = false;
|
||||
if (interval_name > 0 && ((sdesbuildcount%interval_name) == 0)) doname = true;
|
||||
if (interval_email > 0 && ((sdesbuildcount%interval_email) == 0)) doemail = true;
|
||||
if (interval_location > 0 && ((sdesbuildcount%interval_location) == 0)) doloc = true;
|
||||
if (interval_phone > 0 && ((sdesbuildcount%interval_phone) == 0)) dophone = true;
|
||||
if (interval_tool > 0 && ((sdesbuildcount%interval_tool) == 0)) dotool = true;
|
||||
if (interval_note > 0 && ((sdesbuildcount%interval_note) == 0)) donote = true;
|
||||
|
||||
bool processedall;
|
||||
int itemcount;
|
||||
|
||||
if ((status = FillInSDES(rtcpcomppack,&full,&processedall,&itemcount)) < 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
return status;
|
||||
}
|
||||
|
||||
if (processedall)
|
||||
{
|
||||
processingsdes = false;
|
||||
ClearAllSDESFlags();
|
||||
if (!full && skipped > 0)
|
||||
{
|
||||
// if the packet isn't full and we skipped some
|
||||
// sources that we already got in a previous packet,
|
||||
// we can add some of them now
|
||||
|
||||
bool atendoflist;
|
||||
|
||||
if ((status = FillInReportBlocks(rtcpcomppack,curtime,skipped,&full,&added,&skipped,&atendoflist)) < 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // previous sdes processing wasn't finished
|
||||
{
|
||||
bool processedall;
|
||||
int itemcount;
|
||||
bool full;
|
||||
|
||||
if ((status = FillInSDES(rtcpcomppack,&full,&processedall,&itemcount)) < 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
return status;
|
||||
}
|
||||
|
||||
if (itemcount == 0) // Big problem: packet size is too small to let any progress happen
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON;
|
||||
}
|
||||
|
||||
if (processedall)
|
||||
{
|
||||
processingsdes = false;
|
||||
ClearAllSDESFlags();
|
||||
if (!full)
|
||||
{
|
||||
// if the packet isn't full and we skipped some
|
||||
// we can add some report blocks
|
||||
|
||||
int added,skipped;
|
||||
bool atendoflist;
|
||||
|
||||
if ((status = FillInReportBlocks(rtcpcomppack,curtime,sources.GetTotalCount(),&full,&added,&skipped,&atendoflist)) < 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
return status;
|
||||
}
|
||||
if (atendoflist) // filled in all possible sources
|
||||
ClearAllSourceFlags();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((status = rtcpcomppack->EndBuild()) < 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
return status;
|
||||
}
|
||||
|
||||
*pack = rtcpcomppack;
|
||||
firstpacket = false;
|
||||
prevbuildtime = curtime;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RTCPPacketBuilder::ClearAllSourceFlags()
|
||||
{
|
||||
if (sources.GotoFirstSource())
|
||||
{
|
||||
do
|
||||
{
|
||||
RTPSourceData *srcdat = sources.GetCurrentSourceInfo();
|
||||
srcdat->SetProcessedInRTCP(false);
|
||||
} while (sources.GotoNextSource());
|
||||
}
|
||||
}
|
||||
|
||||
int RTCPPacketBuilder::FillInReportBlocks(RTCPCompoundPacketBuilder *rtcpcomppack,const RTPTime &curtime,int maxcount,bool *full,int *added,int *skipped,bool *atendoflist)
|
||||
{
|
||||
RTPSourceData *srcdat;
|
||||
int addedcount = 0;
|
||||
int skippedcount = 0;
|
||||
bool done = false;
|
||||
bool filled = false;
|
||||
bool atend = false;
|
||||
int status;
|
||||
|
||||
if (sources.GotoFirstSource())
|
||||
{
|
||||
do
|
||||
{
|
||||
bool shouldprocess = false;
|
||||
|
||||
srcdat = sources.GetCurrentSourceInfo();
|
||||
if (!srcdat->IsOwnSSRC()) // don't send to ourselves
|
||||
{
|
||||
if (!srcdat->IsCSRC()) // p 35: no reports should go to CSRCs
|
||||
{
|
||||
if (srcdat->INF_HasSentData()) // if this isn't true, INF_GetLastRTPPacketTime() won't make any sense
|
||||
{
|
||||
if (firstpacket)
|
||||
shouldprocess = true;
|
||||
else
|
||||
{
|
||||
// p 35: only if rtp packets were received since the last RTP packet, a report block
|
||||
// should be added
|
||||
|
||||
RTPTime lastrtptime = srcdat->INF_GetLastRTPPacketTime();
|
||||
|
||||
if (lastrtptime > prevbuildtime)
|
||||
shouldprocess = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldprocess)
|
||||
{
|
||||
if (srcdat->IsProcessedInRTCP()) // already covered this one
|
||||
{
|
||||
skippedcount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t rr_ssrc = srcdat->GetSSRC();
|
||||
uint32_t num = srcdat->INF_GetNumPacketsReceivedInInterval();
|
||||
uint32_t prevseq = srcdat->INF_GetSavedExtendedSequenceNumber();
|
||||
uint32_t curseq = srcdat->INF_GetExtendedHighestSequenceNumber();
|
||||
uint32_t expected = curseq-prevseq;
|
||||
uint8_t fraclost;
|
||||
|
||||
if (expected < num) // got duplicates
|
||||
fraclost = 0;
|
||||
else
|
||||
{
|
||||
double lost = (double)(expected-num);
|
||||
double frac = lost/((double)expected);
|
||||
fraclost = (uint8_t)(frac*256.0);
|
||||
}
|
||||
|
||||
expected = curseq-srcdat->INF_GetBaseSequenceNumber();
|
||||
num = srcdat->INF_GetNumPacketsReceived();
|
||||
|
||||
uint32_t diff = expected-num;
|
||||
int32_t *packlost = (int32_t *)&diff;
|
||||
|
||||
uint32_t jitter = srcdat->INF_GetJitter();
|
||||
uint32_t lsr;
|
||||
uint32_t dlsr;
|
||||
|
||||
if (!srcdat->SR_HasInfo())
|
||||
{
|
||||
lsr = 0;
|
||||
dlsr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
RTPNTPTime srtime = srcdat->SR_GetNTPTimestamp();
|
||||
uint32_t m = (srtime.GetMSW()&0xFFFF);
|
||||
uint32_t l = ((srtime.GetLSW()>>16)&0xFFFF);
|
||||
lsr = ((m<<16)|l);
|
||||
|
||||
RTPTime diff = curtime;
|
||||
diff -= srcdat->SR_GetReceiveTime();
|
||||
double diff2 = diff.GetDouble();
|
||||
diff2 *= 65536.0;
|
||||
dlsr = (uint32_t)diff2;
|
||||
}
|
||||
|
||||
status = rtcpcomppack->AddReportBlock(rr_ssrc,fraclost,*packlost,curseq,jitter,lsr,dlsr);
|
||||
if (status < 0)
|
||||
{
|
||||
if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT)
|
||||
{
|
||||
done = true;
|
||||
filled = true;
|
||||
}
|
||||
else
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
addedcount++;
|
||||
if (addedcount >= maxcount)
|
||||
{
|
||||
done = true;
|
||||
if (!sources.GotoNextSource())
|
||||
atend = true;
|
||||
}
|
||||
srcdat->INF_StartNewInterval();
|
||||
srcdat->SetProcessedInRTCP(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (!sources.GotoNextSource())
|
||||
{
|
||||
atend = true;
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
} while (!done);
|
||||
}
|
||||
|
||||
*added = addedcount;
|
||||
*skipped = skippedcount;
|
||||
*full = filled;
|
||||
|
||||
if (!atend) // search for available sources
|
||||
{
|
||||
bool shouldprocess = false;
|
||||
|
||||
do
|
||||
{
|
||||
srcdat = sources.GetCurrentSourceInfo();
|
||||
if (!srcdat->IsOwnSSRC()) // don't send to ourselves
|
||||
{
|
||||
if (!srcdat->IsCSRC()) // p 35: no reports should go to CSRCs
|
||||
{
|
||||
if (srcdat->INF_HasSentData()) // if this isn't true, INF_GetLastRTPPacketTime() won't make any sense
|
||||
{
|
||||
if (firstpacket)
|
||||
shouldprocess = true;
|
||||
else
|
||||
{
|
||||
// p 35: only if rtp packets were received since the last RTP packet, a report block
|
||||
// should be added
|
||||
|
||||
RTPTime lastrtptime = srcdat->INF_GetLastRTPPacketTime();
|
||||
|
||||
if (lastrtptime > prevbuildtime)
|
||||
shouldprocess = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldprocess)
|
||||
{
|
||||
if (srcdat->IsProcessedInRTCP())
|
||||
shouldprocess = false;
|
||||
}
|
||||
|
||||
if (!shouldprocess)
|
||||
{
|
||||
if (!sources.GotoNextSource())
|
||||
atend = true;
|
||||
}
|
||||
|
||||
} while (!atend && !shouldprocess);
|
||||
}
|
||||
|
||||
*atendoflist = atend;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RTCPPacketBuilder::FillInSDES(RTCPCompoundPacketBuilder *rtcpcomppack,bool *full,bool *processedall,int *added)
|
||||
{
|
||||
int status;
|
||||
uint8_t *data;
|
||||
size_t datalen;
|
||||
|
||||
*full = false;
|
||||
*processedall = false;
|
||||
*added = 0;
|
||||
|
||||
// We don't need to add a SSRC for our own data, this is still set
|
||||
// from adding the CNAME
|
||||
if (doname)
|
||||
{
|
||||
if (!ownsdesinfo.ProcessedName())
|
||||
{
|
||||
data = ownsdesinfo.GetName(&datalen);
|
||||
if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::NAME,data,datalen)) < 0)
|
||||
{
|
||||
if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT)
|
||||
{
|
||||
*full = true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
(*added)++;
|
||||
ownsdesinfo.SetProcessedName(true);
|
||||
}
|
||||
}
|
||||
if (doemail)
|
||||
{
|
||||
if (!ownsdesinfo.ProcessedEMail())
|
||||
{
|
||||
data = ownsdesinfo.GetEMail(&datalen);
|
||||
if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::EMAIL,data,datalen)) < 0)
|
||||
{
|
||||
if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT)
|
||||
{
|
||||
*full = true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
(*added)++;
|
||||
ownsdesinfo.SetProcessedEMail(true);
|
||||
}
|
||||
}
|
||||
if (doloc)
|
||||
{
|
||||
if (!ownsdesinfo.ProcessedLocation())
|
||||
{
|
||||
data = ownsdesinfo.GetLocation(&datalen);
|
||||
if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::LOC,data,datalen)) < 0)
|
||||
{
|
||||
if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT)
|
||||
{
|
||||
*full = true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
(*added)++;
|
||||
ownsdesinfo.SetProcessedLocation(true);
|
||||
}
|
||||
}
|
||||
if (dophone)
|
||||
{
|
||||
if (!ownsdesinfo.ProcessedPhone())
|
||||
{
|
||||
data = ownsdesinfo.GetPhone(&datalen);
|
||||
if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::PHONE,data,datalen)) < 0)
|
||||
{
|
||||
if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT)
|
||||
{
|
||||
*full = true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
(*added)++;
|
||||
ownsdesinfo.SetProcessedPhone(true);
|
||||
}
|
||||
}
|
||||
if (dotool)
|
||||
{
|
||||
if (!ownsdesinfo.ProcessedTool())
|
||||
{
|
||||
data = ownsdesinfo.GetTool(&datalen);
|
||||
if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::TOOL,data,datalen)) < 0)
|
||||
{
|
||||
if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT)
|
||||
{
|
||||
*full = true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
(*added)++;
|
||||
ownsdesinfo.SetProcessedTool(true);
|
||||
}
|
||||
}
|
||||
if (donote)
|
||||
{
|
||||
if (!ownsdesinfo.ProcessedNote())
|
||||
{
|
||||
data = ownsdesinfo.GetNote(&datalen);
|
||||
if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::NOTE,data,datalen)) < 0)
|
||||
{
|
||||
if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT)
|
||||
{
|
||||
*full = true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
(*added)++;
|
||||
ownsdesinfo.SetProcessedNote(true);
|
||||
}
|
||||
}
|
||||
|
||||
*processedall = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RTCPPacketBuilder::ClearAllSDESFlags()
|
||||
{
|
||||
ownsdesinfo.ClearFlags();
|
||||
}
|
||||
|
||||
int RTCPPacketBuilder::BuildBYEPacket(RTCPCompoundPacket **pack,const void *reason,size_t reasonlength,bool useSRifpossible)
|
||||
{
|
||||
if (!init)
|
||||
return ERR_RTP_RTCPPACKETBUILDER_NOTINIT;
|
||||
|
||||
RTCPCompoundPacketBuilder *rtcpcomppack;
|
||||
int status;
|
||||
|
||||
if (reasonlength > 255)
|
||||
reasonlength = 255;
|
||||
|
||||
*pack = 0;
|
||||
|
||||
rtcpcomppack = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPCOMPOUNDPACKETBUILDER) RTCPCompoundPacketBuilder(GetMemoryManager());
|
||||
if (rtcpcomppack == 0)
|
||||
return ERR_RTP_OUTOFMEM;
|
||||
|
||||
if ((status = rtcpcomppack->InitBuild(maxpacketsize)) < 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
return status;
|
||||
}
|
||||
|
||||
uint32_t ssrc = rtppacketbuilder.GetSSRC();
|
||||
bool useSR = false;
|
||||
|
||||
if (useSRifpossible)
|
||||
{
|
||||
RTPSourceData *srcdat;
|
||||
|
||||
if ((srcdat = sources.GetOwnSourceInfo()) != 0)
|
||||
{
|
||||
if (srcdat->IsSender())
|
||||
useSR = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (useSR)
|
||||
{
|
||||
RTPTime curtime = RTPTime::CurrentTime();
|
||||
RTPTime rtppacktime = rtppacketbuilder.GetPacketTime();
|
||||
uint32_t rtppacktimestamp = rtppacketbuilder.GetPacketTimestamp();
|
||||
uint32_t packcount = rtppacketbuilder.GetPacketCount();
|
||||
uint32_t octetcount = rtppacketbuilder.GetPayloadOctetCount();
|
||||
RTPTime diff = curtime;
|
||||
diff -= rtppacktime;
|
||||
|
||||
uint32_t tsdiff = (uint32_t)((diff.GetDouble()/timestampunit)+0.5);
|
||||
uint32_t rtptimestamp = rtppacktimestamp+tsdiff;
|
||||
RTPNTPTime ntptimestamp = curtime.GetNTPTime();
|
||||
|
||||
if ((status = rtcpcomppack->StartSenderReport(ssrc,ntptimestamp,rtptimestamp,packcount,octetcount)) < 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT)
|
||||
return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((status = rtcpcomppack->StartReceiverReport(ssrc)) < 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT)
|
||||
return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *owncname;
|
||||
size_t owncnamelen;
|
||||
|
||||
owncname = ownsdesinfo.GetCNAME(&owncnamelen);
|
||||
|
||||
if ((status = rtcpcomppack->AddSDESSource(ssrc)) < 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT)
|
||||
return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON;
|
||||
return status;
|
||||
}
|
||||
if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::CNAME,owncname,owncnamelen)) < 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT)
|
||||
return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON;
|
||||
return status;
|
||||
}
|
||||
|
||||
uint32_t ssrcs[1];
|
||||
|
||||
ssrcs[0] = ssrc;
|
||||
|
||||
if ((status = rtcpcomppack->AddBYEPacket(ssrcs,1,(const uint8_t *)reason,reasonlength)) < 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT)
|
||||
return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON;
|
||||
return status;
|
||||
}
|
||||
|
||||
if ((status = rtcpcomppack->EndBuild()) < 0)
|
||||
{
|
||||
RTPDelete(rtcpcomppack,GetMemoryManager());
|
||||
return status;
|
||||
}
|
||||
|
||||
*pack = rtcpcomppack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
||||
Reference in New Issue
Block a user