123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500 |
- /*
- This file is a part of JRTPLIB
- Copyright (c) 1999-2011 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 "rtpsourcedata.h"
- #include "rtpdefines.h"
- #include "rtpaddress.h"
- #include "rtpmemorymanager.h"
- #if ! (defined(WIN32) || defined(_WIN32_WCE))
- #include <netinet/in.h>
- #endif // WIN32
- #ifdef RTPDEBUG
- #include <iostream>
- #include <string>
- #endif // RTPDEBUG
- #include "rtpdebug.h"
- #define ACCEPTPACKETCODE \
- *accept = true; \
- \
- sentdata = true; \
- packetsreceived++; \
- numnewpackets++; \
- \
- if (pack->GetExtendedSequenceNumber() == 0) \
- { \
- baseseqnr = 0x0000FFFF; \
- numcycles = 0x00010000; \
- } \
- else \
- baseseqnr = pack->GetExtendedSequenceNumber() - 1; \
- \
- exthighseqnr = baseseqnr + 1; \
- prevpacktime = receivetime; \
- prevexthighseqnr = baseseqnr; \
- savedextseqnr = baseseqnr; \
- \
- pack->SetExtendedSequenceNumber(exthighseqnr); \
- \
- prevtimestamp = pack->GetTimestamp(); \
- lastmsgtime = prevpacktime; \
- if (!ownpacket) /* for own packet, this value is set on an outgoing packet */ \
- lastrtptime = prevpacktime;
- namespace jrtplib
- {
- void RTPSourceStats::ProcessPacket(RTPPacket *pack,const RTPTime &receivetime,double tsunit,
- bool ownpacket,bool *accept,bool applyprobation,bool *onprobation)
- {
- // Note that the sequence number in the RTP packet is still just the
- // 16 bit number contained in the RTP header
- *onprobation = false;
-
- if (!sentdata) // no valid packets received yet
- {
- #ifdef RTP_SUPPORT_PROBATION
- if (applyprobation)
- {
- bool acceptpack = false;
- if (probation)
- {
- uint16_t pseq;
- uint32_t pseq2;
-
- pseq = prevseqnr;
- pseq++;
- pseq2 = (uint32_t)pseq;
- if (pseq2 == pack->GetExtendedSequenceNumber()) // ok, its the next expected packet
- {
- prevseqnr = (uint16_t)pack->GetExtendedSequenceNumber();
- probation--;
- if (probation == 0) // probation over
- acceptpack = true;
- else
- *onprobation = true;
- }
- else // not next packet
- {
- probation = RTP_PROBATIONCOUNT;
- prevseqnr = (uint16_t)pack->GetExtendedSequenceNumber();
- *onprobation = true;
- }
- }
- else // first packet received with this SSRC ID, start probation
- {
- probation = RTP_PROBATIONCOUNT;
- prevseqnr = (uint16_t)pack->GetExtendedSequenceNumber();
- *onprobation = true;
- }
-
- if (acceptpack)
- {
- ACCEPTPACKETCODE
- }
- else
- {
- *accept = false;
- lastmsgtime = receivetime;
- }
- }
- else // No probation
- {
- ACCEPTPACKETCODE
- }
- #else // No compiled-in probation support
- ACCEPTPACKETCODE
- #endif // RTP_SUPPORT_PROBATION
- }
- else // already got packets
- {
- uint16_t maxseq16;
- uint32_t extseqnr;
- // Adjust max extended sequence number and set extende seq nr of packet
- *accept = true;
- packetsreceived++;
- numnewpackets++;
- maxseq16 = (uint16_t)(exthighseqnr&0x0000FFFF);
- if (pack->GetExtendedSequenceNumber() >= maxseq16)
- {
- extseqnr = numcycles+pack->GetExtendedSequenceNumber();
- exthighseqnr = extseqnr;
- }
- else
- {
- uint16_t dif1,dif2;
- dif1 = ((uint16_t)pack->GetExtendedSequenceNumber());
- dif1 -= maxseq16;
- dif2 = maxseq16;
- dif2 -= ((uint16_t)pack->GetExtendedSequenceNumber());
- if (dif1 < dif2)
- {
- numcycles += 0x00010000;
- extseqnr = numcycles+pack->GetExtendedSequenceNumber();
- exthighseqnr = extseqnr;
- }
- else
- extseqnr = numcycles+pack->GetExtendedSequenceNumber();
- }
- pack->SetExtendedSequenceNumber(extseqnr);
- // Calculate jitter
- if (tsunit > 0)
- {
- #if 0
- RTPTime curtime = receivetime;
- double diffts1,diffts2,diff;
- curtime -= prevpacktime;
- diffts1 = curtime.GetDouble()/tsunit;
- diffts2 = (double)pack->GetTimestamp() - (double)prevtimestamp;
- diff = diffts1 - diffts2;
- if (diff < 0)
- diff = -diff;
- diff -= djitter;
- diff /= 16.0;
- djitter += diff;
- jitter = (uint32_t)djitter;
- #else
- RTPTime curtime = receivetime;
- double diffts1,diffts2,diff;
- uint32_t curts = pack->GetTimestamp();
- curtime -= prevpacktime;
- diffts1 = curtime.GetDouble()/tsunit;
- if (curts > prevtimestamp)
- {
- uint32_t unsigneddiff = curts - prevtimestamp;
- if (unsigneddiff < 0x10000000) // okay, curts realy is larger than prevtimestamp
- diffts2 = (double)unsigneddiff;
- else
- {
- // wraparound occurred and curts is actually smaller than prevtimestamp
- unsigneddiff = -unsigneddiff; // to get the actual difference (in absolute value)
- diffts2 = -((double)unsigneddiff);
- }
- }
- else if (curts < prevtimestamp)
- {
- uint32_t unsigneddiff = prevtimestamp - curts;
- if (unsigneddiff < 0x10000000) // okay, curts really is smaller than prevtimestamp
- diffts2 = -((double)unsigneddiff); // negative since we actually need curts-prevtimestamp
- else
- {
- // wraparound occurred and curts is actually larger than prevtimestamp
- unsigneddiff = -unsigneddiff; // to get the actual difference (in absolute value)
- diffts2 = (double)unsigneddiff;
- }
- }
- else
- diffts2 = 0;
- diff = diffts1 - diffts2;
- if (diff < 0)
- diff = -diff;
- diff -= djitter;
- diff /= 16.0;
- djitter += diff;
- jitter = (uint32_t)djitter;
- #endif
- }
- else
- {
- djitter = 0;
- jitter = 0;
- }
- prevpacktime = receivetime;
- prevtimestamp = pack->GetTimestamp();
- lastmsgtime = prevpacktime;
- if (!ownpacket) // for own packet, this value is set on an outgoing packet
- lastrtptime = prevpacktime;
- }
- }
- RTPSourceData::RTPSourceData(uint32_t s, RTPMemoryManager *mgr) : RTPMemoryObject(mgr),SDESinf(mgr),byetime(0,0)
- {
- ssrc = s;
- issender = false;
- iscsrc = false;
- timestampunit = -1;
- receivedbye = false;
- byereason = 0;
- byereasonlen = 0;
- rtpaddr = 0;
- rtcpaddr = 0;
- ownssrc = false;
- validated = false;
- processedinrtcp = false;
- isrtpaddrset = false;
- isrtcpaddrset = false;
- }
- RTPSourceData::~RTPSourceData()
- {
- FlushPackets();
- if (byereason)
- RTPDeleteByteArray(byereason,GetMemoryManager());
- if (rtpaddr)
- RTPDelete(rtpaddr,GetMemoryManager());
- if (rtcpaddr)
- RTPDelete(rtcpaddr,GetMemoryManager());
- }
- double RTPSourceData::INF_GetEstimatedTimestampUnit() const
- {
- if (!SRprevinf.HasInfo())
- return -1.0;
-
- RTPTime t1 = RTPTime(SRinf.GetNTPTimestamp());
- RTPTime t2 = RTPTime(SRprevinf.GetNTPTimestamp());
- if ((t1.GetSeconds() == 0 && t1.GetMicroSeconds() == 0) ||
- (t2.GetSeconds() == 0 && t2.GetMicroSeconds() == 0)) // one of the times couldn't be calculated
- return -1.0;
- if (t1 <= t2)
- return -1.0;
- t1 -= t2; // get the time difference
-
- uint32_t tsdiff = SRinf.GetRTPTimestamp()-SRprevinf.GetRTPTimestamp();
-
- return (t1.GetDouble()/((double)tsdiff));
- }
- RTPTime RTPSourceData::INF_GetRoundtripTime() const
- {
- if (!RRinf.HasInfo())
- return RTPTime(0,0);
- if (RRinf.GetDelaySinceLastSR() == 0 && RRinf.GetLastSRTimestamp() == 0)
- return RTPTime(0,0);
- RTPNTPTime recvtime = RRinf.GetReceiveTime().GetNTPTime();
- uint32_t rtt = ((recvtime.GetMSW()&0xFFFF)<<16)|((recvtime.GetLSW()>>16)&0xFFFF);
- rtt -= RRinf.GetLastSRTimestamp();
- rtt -= RRinf.GetDelaySinceLastSR();
- double drtt = (((double)rtt)/65536.0);
- return RTPTime(drtt);
- }
- #ifdef RTPDEBUG
- void RTPSourceData::Dump()
- {
- std::cout << "Source data for SSRC: " << ssrc << std::endl;
- std::cout << " Active: " << ((IsActive())?"Yes":"No") << std::endl;
- std::cout << " Sender: " << ((issender)?"Yes":"No") << std::endl;
- std::cout << " CSRC: " << ((iscsrc)?"Yes":"No") << std::endl;
- std::cout << " Received bye: " << ((receivedbye)?"Yes":"No") << std::endl;
- std::cout << " ProcessedInRTCP: " << ((processedinrtcp)?"Yes":"No") << std::endl;
- std::cout << " Timestamp unit: " << timestampunit << std::endl;
- std::cout << " RTP address: ";
- if (!isrtpaddrset)
- std::cout << "Not set" << std::endl;
- else
- {
- if (rtpaddr == 0)
- std::cout << "Own session" << std::endl;
- else
- std::cout << rtpaddr->GetAddressString() << std::endl;
- }
- std::cout << " RTCP address: ";
- if (!isrtcpaddrset)
- std::cout << "Not set" << std::endl;
- else
- {
- if (rtcpaddr == 0)
- std::cout << "Own session" << std::endl;
- else
- std::cout << rtcpaddr->GetAddressString() << std::endl;
- }
- if (SRinf.HasInfo())
- {
- if (!SRprevinf.HasInfo())
- {
- std::cout << " SR Info:" << std::endl;
- std::cout << " NTP timestamp: " << SRinf.GetNTPTimestamp().GetMSW() << ":" << SRinf.GetNTPTimestamp().GetLSW() << std::endl;
- std::cout << " RTP timestamp: " << SRinf.GetRTPTimestamp() << std::endl;
- std::cout << " Packet count: " << SRinf.GetPacketCount() << std::endl;
- std::cout << " Octet count: " << SRinf.GetByteCount() << std::endl;
- std::cout << " Receive time: " << SRinf.GetReceiveTime().GetSeconds() << std::endl;
- }
- else
- {
- std::cout << " SR Info:" << std::endl;
- std::cout << " NTP timestamp: " << SRinf.GetNTPTimestamp().GetMSW() << ":" << SRinf.GetNTPTimestamp().GetLSW()
- << " (" << SRprevinf.GetNTPTimestamp().GetMSW() << ":" << SRprevinf.GetNTPTimestamp().GetLSW() << ")" << std::endl;
- std::cout << " RTP timestamp: " << SRinf.GetRTPTimestamp()
- << " (" << SRprevinf.GetRTPTimestamp() << ")" << std::endl;
- std::cout << " Packet count: " << SRinf.GetPacketCount()
- << " (" << SRprevinf.GetPacketCount() << ")" << std::endl;
- std::cout << " Octet count: " << SRinf.GetByteCount()
- << " (" << SRprevinf.GetByteCount() <<")" << std::endl;
- std::cout << " Receive time: " << SRinf.GetReceiveTime().GetSeconds()
- << " (" << SRprevinf.GetReceiveTime().GetSeconds() << ")" << std::endl;
- }
- }
- if (RRinf.HasInfo())
- {
- if (!RRprevinf.HasInfo())
- {
- std::cout << " RR Info:" << std::endl;
- std::cout << " Fraction lost: " << RRinf.GetFractionLost() << std::endl;
- std::cout << " Packets lost: " << RRinf.GetPacketsLost() << std::endl;
- std::cout << " Ext.High.Seq: " << RRinf.GetExtendedHighestSequenceNumber() << std::endl;
- std::cout << " Jitter: " << RRinf.GetJitter() << std::endl;
- std::cout << " LSR: " << RRinf.GetLastSRTimestamp() << std::endl;
- std::cout << " DLSR: " << RRinf.GetDelaySinceLastSR() << std::endl;
- std::cout << " Receive time: " << RRinf.GetReceiveTime().GetSeconds() << std::endl;
- }
- else
- {
- std::cout << " RR Info:" << std::endl;
- std::cout << " Fraction lost: " << RRinf.GetFractionLost()
- << " (" << RRprevinf.GetFractionLost() << ")" << std::endl;
- std::cout << " Packets lost: " << RRinf.GetPacketsLost()
- << " (" << RRprevinf.GetPacketsLost() << ")" << std::endl;
- std::cout << " Ext.High.Seq: " << RRinf.GetExtendedHighestSequenceNumber()
- << " (" << RRprevinf.GetExtendedHighestSequenceNumber() << ")" << std::endl;
- std::cout << " Jitter: " << RRinf.GetJitter()
- << " (" << RRprevinf.GetJitter() << ")" << std::endl;
- std::cout << " LSR: " << RRinf.GetLastSRTimestamp()
- << " (" << RRprevinf.GetLastSRTimestamp() << ")" << std::endl;
- std::cout << " DLSR: " << RRinf.GetDelaySinceLastSR()
- << " (" << RRprevinf.GetDelaySinceLastSR() << ")" << std::endl;
- std::cout << " Receive time: " << RRinf.GetReceiveTime().GetSeconds()
- << " (" << RRprevinf.GetReceiveTime().GetSeconds() <<")" << std::endl;
- }
- }
- std::cout << " Stats:" << std::endl;
- std::cout << " Sent data: " << ((stats.HasSentData())?"Yes":"No") << std::endl;
- std::cout << " Packets received: " << stats.GetNumPacketsReceived() << std::endl;
- std::cout << " Seq. base: " << stats.GetBaseSequenceNumber() << std::endl;
- std::cout << " Ext.High.Seq: " << stats.GetExtendedHighestSequenceNumber() << std::endl;
- std::cout << " Jitter: " << stats.GetJitter() << std::endl;
- std::cout << " New packets: " << stats.GetNumPacketsReceivedInInterval() << std::endl;
- std::cout << " Saved seq. nr.: " << stats.GetSavedExtendedSequenceNumber() << std::endl;
- std::cout << " RTT: " << INF_GetRoundtripTime().GetDouble() << " seconds" << std::endl;
- if (INF_GetEstimatedTimestampUnit() > 0)
- std::cout << " Estimated: " << (1.0/INF_GetEstimatedTimestampUnit()) << " samples per second" << std::endl;
- std::cout << " SDES Info:" << std::endl;
- size_t len;
- char str[1024];
- uint8_t *val;
-
- if ((val = SDESinf.GetCNAME(&len)) != 0)
- {
- memcpy(str,val,len);
- str[len] = 0;
- std::cout << " CNAME: " << std::string(str) << std::endl;
- }
- if ((val = SDESinf.GetName(&len)) != 0)
- {
- memcpy(str,val,len);
- str[len] = 0;
- std::cout << " Name: " << std::string(str) << std::endl;
- }
- if ((val = SDESinf.GetEMail(&len)) != 0)
- {
- memcpy(str,val,len);
- str[len] = 0;
- std::cout << " EMail: " << std::string(str) << std::endl;
- }
- if ((val = SDESinf.GetPhone(&len)) != 0)
- {
- memcpy(str,val,len);
- str[len] = 0;
- std::cout << " phone: " << std::string(str) << std::endl;
- }
- if ((val = SDESinf.GetLocation(&len)) != 0)
- {
- memcpy(str,val,len);
- str[len] = 0;
- std::cout << " Location: " << std::string(str) << std::endl;
- }
- if ((val = SDESinf.GetTool(&len)) != 0)
- {
- memcpy(str,val,len);
- str[len] = 0;
- std::cout << " Tool: " << std::string(str) << std::endl;
- }
- if ((val = SDESinf.GetNote(&len)) != 0)
- {
- memcpy(str,val,len);
- str[len] = 0;
- std::cout << " Note: " << std::string(str) << std::endl;
- }
- #ifdef RTP_SUPPORT_SDESPRIV
- SDESinf.GotoFirstPrivateValue();
- uint8_t *pref;
- size_t preflen;
- while (SDESinf.GetNextPrivateValue(&pref,&preflen,&val,&len))
- {
- char prefstr[1024];
- memcpy(prefstr,pref,preflen);
- memcpy(str,val,len);
- prefstr[preflen] = 0;
- str[len] = 0;
- std::cout << " Private: " << std::string(prefstr) << ":" << std::string(str) << std::endl;
- }
- #endif // RTP_SUPPORT_SDESPRIV
- if (byereason)
- {
- memcpy(str,byereason,byereasonlen);
- str[byereasonlen] = 0;
- std::cout << " BYE Reason: " << std::string(str) << std::endl;
- }
- }
- #endif // RTPDEBUG
- } // end namespace
|