| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  This file is a part of JRTPLIB | 
					
						
							|  |  |  |  Copyright (c) 1999-2017 Jori Liesenborgs | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  Contact: jori.liesenborgs@gmail.com | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  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). | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  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: | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  The above copyright notice and this permission notice shall be included | 
					
						
							|  |  |  |  in all copies or substantial portions of the Software. | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  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. | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "rtpsourcedata.h"
 | 
					
						
							|  |  |  | #include "rtpdefines.h"
 | 
					
						
							|  |  |  | #include "rtpaddress.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 qrtplib | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:54:23 +01:00
										 |  |  | void RTPSourceStats::ProcessPacket( | 
					
						
							|  |  |  |         RTPPacket *pack, | 
					
						
							|  |  |  |         const RTPTime &receivetime, | 
					
						
							|  |  |  |         double tsunit, | 
					
						
							|  |  |  |         bool ownpacket, | 
					
						
							|  |  |  |         bool *accept) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     // Note that the sequence number in the RTP packet is still just the
 | 
					
						
							|  |  |  |     // 16 bit number contained in the RTP header
 | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (!sentdata) // no valid packets received yet
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ACCEPTPACKETCODE | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     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) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |             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; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |             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; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         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; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | RTPSourceData::RTPSourceData(uint32_t s) : | 
					
						
							|  |  |  |         byetime(0, 0) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     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; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RTPSourceData::~RTPSourceData() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     FlushPackets(); | 
					
						
							|  |  |  |     if (byereason) | 
					
						
							|  |  |  |         delete[] byereason; | 
					
						
							|  |  |  |     if (rtpaddr) | 
					
						
							|  |  |  |         delete rtpaddr; | 
					
						
							|  |  |  |     if (rtcpaddr) | 
					
						
							|  |  |  |         delete rtcpaddr; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | double RTPSourceData::INF_GetEstimatedTimestampUnit() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (!SRprevinf.HasInfo()) | 
					
						
							|  |  |  |         return -1.0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     RTPTime t1 = RTPTime(SRinf.GetNTPTimestamp()); | 
					
						
							|  |  |  |     RTPTime t2 = RTPTime(SRprevinf.GetNTPTimestamp()); | 
					
						
							|  |  |  |     if (t1.IsZero() || t2.IsZero()) // one of the times couldn't be calculated
 | 
					
						
							|  |  |  |         return -1.0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (t1 <= t2) | 
					
						
							|  |  |  |         return -1.0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     t1 -= t2; // get the time difference
 | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     uint32_t tsdiff = SRinf.GetRTPTimestamp() - SRprevinf.GetRTPTimestamp(); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     return (t1.GetDouble() / ((double) tsdiff)); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RTPTime RTPSourceData::INF_GetRoundtripTime() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     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); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // end namespace
 | 
					
						
							|  |  |  | 
 |