summaryrefslogtreecommitdiffstats
path: root/src/rtppacketbuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rtppacketbuilder.cpp')
-rw-r--r--src/rtppacketbuilder.cpp268
1 files changed, 268 insertions, 0 deletions
diff --git a/src/rtppacketbuilder.cpp b/src/rtppacketbuilder.cpp
new file mode 100644
index 0000000..76dca01
--- /dev/null
+++ b/src/rtppacketbuilder.cpp
@@ -0,0 +1,268 @@
+/*
+
+ This file is a part of JRTPLIB
+ Copyright (c) 1999-2007 Jori Liesenborgs
+
+ Contact: jori.liesenborgs@gmail.com
+
+ This library was developed at the "Expertisecentrum Digitale 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 "rtppacketbuilder.h"
+#include "rtperrors.h"
+#include "rtppacket.h"
+#include "rtpsources.h"
+#include <time.h>
+#include <stdlib.h>
+#ifdef RTPDEBUG
+ #include <iostream>
+#endif // RTPDEBUG
+
+#include "rtpdebug.h"
+
+RTPPacketBuilder::RTPPacketBuilder(RTPMemoryManager *mgr) : RTPMemoryObject(mgr),lastwallclocktime(0,0)
+{
+ init = false;
+#if (defined(WIN32) || defined(_WIN32_WCE))
+ timeinit.Dummy();
+#endif // WIN32 || _WIN32_WCE
+}
+
+RTPPacketBuilder::~RTPPacketBuilder()
+{
+ Destroy();
+}
+
+int RTPPacketBuilder::Init(size_t max)
+{
+ if (init)
+ return ERR_RTP_PACKBUILD_ALREADYINIT;
+ if (max <= 0)
+ return ERR_RTP_PACKBUILD_INVALIDMAXPACKETSIZE;
+
+ maxpacksize = max;
+ buffer = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTPPACKETBUILDERBUFFER) uint8_t [max];
+ if (buffer == 0)
+ return ERR_RTP_OUTOFMEM;
+ packetlength = 0;
+
+ CreateNewSSRC();
+
+ deftsset = false;
+ defptset = false;
+ defmarkset = false;
+
+ numcsrcs = 0;
+
+ init = true;
+ return 0;
+}
+
+void RTPPacketBuilder::Destroy()
+{
+ if (!init)
+ return;
+ RTPDeleteByteArray(buffer,GetMemoryManager());
+ init = false;
+}
+
+int RTPPacketBuilder::SetMaximumPacketSize(size_t max)
+{
+ uint8_t *newbuf;
+
+ if (max <= 0)
+ return ERR_RTP_PACKBUILD_INVALIDMAXPACKETSIZE;
+ newbuf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTPPACKETBUILDERBUFFER) uint8_t[max];
+ if (newbuf == 0)
+ return ERR_RTP_OUTOFMEM;
+
+ RTPDeleteByteArray(buffer,GetMemoryManager());
+ buffer = newbuf;
+ maxpacksize = max;
+ return 0;
+}
+
+int RTPPacketBuilder::AddCSRC(uint32_t csrc)
+{
+ if (!init)
+ return ERR_RTP_PACKBUILD_NOTINIT;
+ if (numcsrcs >= RTP_MAXCSRCS)
+ return ERR_RTP_PACKBUILD_CSRCLISTFULL;
+
+ int i;
+
+ for (i = 0 ; i < numcsrcs ; i++)
+ {
+ if (csrcs[i] == csrc)
+ return ERR_RTP_PACKBUILD_CSRCALREADYINLIST;
+ }
+ csrcs[numcsrcs] = csrc;
+ numcsrcs++;
+ return 0;
+}
+
+int RTPPacketBuilder::DeleteCSRC(uint32_t csrc)
+{
+ if (!init)
+ return ERR_RTP_PACKBUILD_NOTINIT;
+
+ int i = 0;
+ bool found = false;
+
+ while (!found && i < numcsrcs)
+ {
+ if (csrcs[i] == csrc)
+ found = true;
+ else
+ i++;
+ }
+
+ if (!found)
+ return ERR_RTP_PACKBUILD_CSRCNOTINLIST;
+
+ // move the last csrc in the place of the deleted one
+ numcsrcs--;
+ if (numcsrcs > 0 && numcsrcs != i)
+ csrcs[i] = csrcs[numcsrcs];
+ return 0;
+}
+
+void RTPPacketBuilder::ClearCSRCList()
+{
+ if (!init)
+ return;
+ numcsrcs = 0;
+}
+
+uint32_t RTPPacketBuilder::CreateNewSSRC()
+{
+ ssrc = rtprnd.GetRandom32();
+ timestamp = rtprnd.GetRandom32();
+ seqnr = rtprnd.GetRandom16();
+
+ // p 38: the count SHOULD be reset if the sender changes its SSRC identifier
+ numpayloadbytes = 0;
+ numpackets = 0;
+ return ssrc;
+}
+
+uint32_t RTPPacketBuilder::CreateNewSSRC(RTPSources &sources)
+{
+ bool found;
+
+ do
+ {
+ ssrc = rtprnd.GetRandom32();
+ found = sources.GotEntry(ssrc);
+ } while (found);
+
+ timestamp = rtprnd.GetRandom32();
+ seqnr = rtprnd.GetRandom16();
+
+ // p 38: the count SHOULD be reset if the sender changes its SSRC identifier
+ numpayloadbytes = 0;
+ numpackets = 0;
+ return ssrc;
+}
+
+int RTPPacketBuilder::BuildPacket(const void *data,size_t len)
+{
+ if (!init)
+ return ERR_RTP_PACKBUILD_NOTINIT;
+ if (!defptset)
+ return ERR_RTP_PACKBUILD_DEFAULTPAYLOADTYPENOTSET;
+ if (!defmarkset)
+ return ERR_RTP_PACKBUILD_DEFAULTMARKNOTSET;
+ if (!deftsset)
+ return ERR_RTP_PACKBUILD_DEFAULTTSINCNOTSET;
+ return PrivateBuildPacket(data,len,defaultpayloadtype,defaultmark,defaulttimestampinc,false);
+}
+
+int RTPPacketBuilder::BuildPacket(const void *data,size_t len,
+ uint8_t pt,bool mark,uint32_t timestampinc)
+{
+ if (!init)
+ return ERR_RTP_PACKBUILD_NOTINIT;
+ return PrivateBuildPacket(data,len,pt,mark,timestampinc,false);
+}
+
+int RTPPacketBuilder::BuildPacketEx(const void *data,size_t len,
+ uint16_t hdrextID,const void *hdrextdata,size_t numhdrextwords)
+{
+ if (!init)
+ return ERR_RTP_PACKBUILD_NOTINIT;
+ if (!defptset)
+ return ERR_RTP_PACKBUILD_DEFAULTPAYLOADTYPENOTSET;
+ if (!defmarkset)
+ return ERR_RTP_PACKBUILD_DEFAULTMARKNOTSET;
+ if (!deftsset)
+ return ERR_RTP_PACKBUILD_DEFAULTTSINCNOTSET;
+ return PrivateBuildPacket(data,len,defaultpayloadtype,defaultmark,defaulttimestampinc,true,hdrextID,hdrextdata,numhdrextwords);
+}
+
+int RTPPacketBuilder::BuildPacketEx(const void *data,size_t len,
+ uint8_t pt,bool mark,uint32_t timestampinc,
+ uint16_t hdrextID,const void *hdrextdata,size_t numhdrextwords)
+{
+ if (!init)
+ return ERR_RTP_PACKBUILD_NOTINIT;
+ return PrivateBuildPacket(data,len,pt,mark,timestampinc,true,hdrextID,hdrextdata,numhdrextwords);
+
+}
+
+int RTPPacketBuilder::PrivateBuildPacket(const void *data,size_t len,
+ uint8_t pt,bool mark,uint32_t timestampinc,bool gotextension,
+ uint16_t hdrextID,const void *hdrextdata,size_t numhdrextwords)
+{
+ RTPPacket p(pt,data,len,seqnr,timestamp,ssrc,mark,numcsrcs,csrcs,gotextension,hdrextID,
+ (uint16_t)numhdrextwords,hdrextdata,buffer,maxpacksize,GetMemoryManager());
+ int status = p.GetCreationError();
+
+ if (status < 0)
+ return status;
+ packetlength = p.GetPacketLength();
+
+ if (numpackets == 0) // first packet
+ {
+ lastwallclocktime = RTPTime::CurrentTime();
+ lastrtptimestamp = timestamp;
+ prevrtptimestamp = timestamp;
+ }
+ else if (timestamp != prevrtptimestamp)
+ {
+ lastwallclocktime = RTPTime::CurrentTime();
+ lastrtptimestamp = timestamp;
+ prevrtptimestamp = timestamp;
+ }
+
+ numpayloadbytes += (uint32_t)p.GetPayloadLength();
+ numpackets++;
+ timestamp += timestampinc;
+ seqnr++;
+
+ return 0;
+}
+
+