コード例 #1
0
RTPReceptionStats::RTPReceptionStats(unsigned int SSRC,unsigned short initialSeq):m_SSRC(0),m_numPacketsReceivedSinceLastReset(0),
	m_totalNumPacketsReceived(0),m_totalBytesReceived_hi(0),m_totalBytesReceived_lo(0),
	m_haveSeenInitialSequenceNumber(0),m_baseExtSeqNumReceived(0),m_lastResetExtSeqNumReceived(0),
	m_highestExtSeqNumReceived(0),m_lastTransit(0),m_previousPacketRTPTimestamp(0),
	m_jitter(0),m_lastReceivedSR_NTPmsw(0),m_lastReceivedSR_NTPlsw(0),
	m_minInterPacketGapUS(0),m_maxInterPacketGapUS(0),m_hasBeenSynchronized(0)
{
	gethostname(m_CNAME,100);
	m_CNAME_length=strlen(m_CNAME);
	initSeqNum(initialSeq);
	initStats(SSRC);
}
コード例 #2
0
ファイル: RTPSource.cpp プロジェクト: Christof0113/rtsp-tools
void RTPReceptionStats
::noteIncomingPacket(u_int16_t seqNum, u_int32_t rtpTimestamp,
		     unsigned timestampFrequency,
		     Boolean useForJitterCalculation,
		     struct timeval& resultPresentationTime,
		     Boolean& resultHasBeenSyncedUsingRTCP,
		     unsigned packetSize) {
  if (!fHaveSeenInitialSequenceNumber) initSeqNum(seqNum);

  ++fNumPacketsReceivedSinceLastReset;
  ++fTotNumPacketsReceived;
  u_int32_t prevTotBytesReceived_lo = fTotBytesReceived_lo;
  fTotBytesReceived_lo += packetSize;
  if (fTotBytesReceived_lo < prevTotBytesReceived_lo) { // wrap-around
    ++fTotBytesReceived_hi;
  }

  // Check whether the new sequence number is the highest yet seen:
  unsigned oldSeqNum = (fHighestExtSeqNumReceived&0xFFFF);
  unsigned seqNumCycle = (fHighestExtSeqNumReceived&0xFFFF0000);
  unsigned seqNumDifference = (unsigned)((int)seqNum-(int)oldSeqNum);
  unsigned newSeqNum = 0;
  if (seqNumLT((u_int16_t)oldSeqNum, seqNum)) {
    // This packet was not an old packet received out of order, so check it:
    
    if (seqNumDifference >= 0x8000) {
      // The sequence number wrapped around, so start a new cycle:
      seqNumCycle += 0x10000;
    }
    
    newSeqNum = seqNumCycle|seqNum;
    if (newSeqNum > fHighestExtSeqNumReceived) {
      fHighestExtSeqNumReceived = newSeqNum;
    }
  } else if (fTotNumPacketsReceived > 1) {
    // This packet was an old packet received out of order
    
    if ((int)seqNumDifference >= 0x8000) {
      // The sequence number wrapped around, so switch to an old cycle:
      seqNumCycle -= 0x10000;
    }
    
    newSeqNum = seqNumCycle|seqNum;
    if (newSeqNum < fBaseExtSeqNumReceived) {
      fBaseExtSeqNumReceived = newSeqNum;
    }
  }

  // Record the inter-packet delay
  struct timeval timeNow;
  gettimeofday(&timeNow, NULL);
  if (fLastPacketReceptionTime.tv_sec != 0
      || fLastPacketReceptionTime.tv_usec != 0) {
    unsigned gap
      = (timeNow.tv_sec - fLastPacketReceptionTime.tv_sec)*MILLION
      + timeNow.tv_usec - fLastPacketReceptionTime.tv_usec; 
    if (gap > fMaxInterPacketGapUS) {
      fMaxInterPacketGapUS = gap;
    }
    if (gap < fMinInterPacketGapUS) {
      fMinInterPacketGapUS = gap;
    }
    fTotalInterPacketGaps.tv_usec += gap;
    if (fTotalInterPacketGaps.tv_usec >= MILLION) {
      ++fTotalInterPacketGaps.tv_sec;
      fTotalInterPacketGaps.tv_usec -= MILLION;
    }
  }
  fLastPacketReceptionTime = timeNow;

  // Compute the current 'jitter' using the received packet's RTP timestamp,
  // and the RTP timestamp that would correspond to the current time.
  // (Use the code from appendix A.8 in the RTP spec.)
  // Note, however, that we don't use this packet if its timestamp is
  // the same as that of the previous packet (this indicates a multi-packet
  // fragment), or if we've been explicitly told not to use this packet.
  if (useForJitterCalculation
      && rtpTimestamp != fPreviousPacketRTPTimestamp) {
    unsigned arrival = (timestampFrequency*timeNow.tv_sec);
    arrival += (unsigned)
      ((2.0*timestampFrequency*timeNow.tv_usec + 1000000.0)/2000000);
            // note: rounding
    int transit = arrival - rtpTimestamp;
    if (fLastTransit == (~0)) fLastTransit = transit; // hack for first time
    int d = transit - fLastTransit;
    fLastTransit = transit;
    if (d < 0) d = -d;
    fJitter += (1.0/16.0) * ((double)d - fJitter);
  }

  // Return the 'presentation time' that corresponds to "rtpTimestamp":
  if (fSyncTime.tv_sec == 0 && fSyncTime.tv_usec == 0) {
    // This is the first timestamp that we've seen, so use the current
    // 'wall clock' time as the synchronization time.  (This will be
    // corrected later when we receive RTCP SRs.)
    fSyncTimestamp = rtpTimestamp;
    fSyncTime = timeNow;
  }

  int timestampDiff = rtpTimestamp - fSyncTimestamp;
      // Note: This works even if the timestamp wraps around
      // (as long as "int" is 32 bits)

  // Divide this by the timestamp frequency to get real time:
  double timeDiff = timestampDiff/(double)timestampFrequency;

  // Add this to the 'sync time' to get our result:
  unsigned const million = 1000000;
  unsigned seconds, uSeconds;
  if (timeDiff >= 0.0) {
    seconds = fSyncTime.tv_sec + (unsigned)(timeDiff);
    uSeconds = fSyncTime.tv_usec
      + (unsigned)((timeDiff - (unsigned)timeDiff)*million);
    if (uSeconds >= million) {
      uSeconds -= million;
      ++seconds;
    }
  } else {
    timeDiff = -timeDiff;
    seconds = fSyncTime.tv_sec - (unsigned)(timeDiff);
    uSeconds = fSyncTime.tv_usec
      - (unsigned)((timeDiff - (unsigned)timeDiff)*million);
    if ((int)uSeconds < 0) {
      uSeconds += million;
      --seconds;
    }
  }
  resultPresentationTime.tv_sec = seconds;
  resultPresentationTime.tv_usec = uSeconds;
  resultHasBeenSyncedUsingRTCP = fHasBeenSynchronized;

  // Save these as the new synchronization timestamp & time:
  fSyncTimestamp = rtpTimestamp;
  fSyncTime = resultPresentationTime;

  fPreviousPacketRTPTimestamp = rtpTimestamp;
}
コード例 #3
0
ファイル: RTPSource.cpp プロジェクト: Christof0113/rtsp-tools
RTPReceptionStats::RTPReceptionStats(u_int32_t SSRC, u_int16_t initialSeqNum) {
  initSeqNum(initialSeqNum);
  init(SSRC);
}
コード例 #4
0
void			RTPReceptionStats::noteIncomingPacket(
	unsigned short	seqNum,
	unsigned int	rtpTimestamp,unsigned int	timestampFrequency,
	bool		useForJitterCalculation,
	timeval&	resultPresentationTime,
	bool&		resultHasBeenSyncedUsingRTCP,
	unsigned int	packetSize)
{
	if (!m_haveSeenInitialSequenceNumber)
	{
		initSeqNum(seqNum);
	}
	m_numPacketsReceivedSinceLastReset++;
	m_totalNumPacketsReceived++;
	unsigned int lastTotalBytesReceived_Io=m_totalBytesReceived_lo;
	m_totalBytesReceived_lo+=packetSize;
	if (m_totalBytesReceived_lo<lastTotalBytesReceived_Io)
	{
		m_totalBytesReceived_hi++;
	}
	unsigned int oldSeqNum=(m_highestExtSeqNumReceived&0xffff);
	unsigned int seqNumCycle=(m_highestExtSeqNumReceived&0xffff0000);
	unsigned int seqNumDifference=(unsigned int)((int)seqNum-(int)oldSeqNum);
	//32bit contains cycle seqNum;
	unsigned int newSeqNum=0;

	if (seqNumLT((unsigned short)oldSeqNum,seqNum))
	{
		//newSeq<oldSeq,uint<0,seqNumDifference>>0,进入新的循环;
		if (seqNumDifference>0x8000)
		{
			seqNumCycle+=0x10000;
		}

		newSeqNum=seqNumCycle|seqNum;
		if (newSeqNum>m_highestExtSeqNumReceived)
		{
			m_highestExtSeqNumReceived=newSeqNum;
		}
	}else if(m_totalNumPacketsReceived>1)
	{
		//newSeq>>oldSeq回到上一个循环;
		if ((int)seqNumDifference>0x8000)
		{
			seqNumCycle-=0x10000;
		}
		newSeqNum=seqNumCycle|seqNum;
		if (m_baseExtSeqNumReceived>newSeqNum)
		{
			m_baseExtSeqNumReceived=newSeqNum;
		}
	}
	//记录包延时;
	timeval timeNow;
	gettimeofday(&timeNow,0);
	if (m_lastPacketReceptionTime.tv_sec!=0&&
		m_lastPacketReceptionTime.tv_usec!=0)
	{
		unsigned int gapUsec=(timeNow.tv_sec-m_lastPacketReceptionTime.tv_sec)*1000000+
			(timeNow.tv_usec-m_lastPacketReceptionTime.tv_usec);
		if (gapUsec>m_maxInterPacketGapUS)
		{
			m_maxInterPacketGapUS=gapUsec;
		}
		if (gapUsec<m_minInterPacketGapUS)
		{
			m_minInterPacketGapUS=gapUsec;
		}
		m_totalInterPacketGaps.tv_usec+=gapUsec;
		while (m_totalInterPacketGaps.tv_usec>1000000)
		{
			m_totalInterPacketGaps.tv_sec++;
			m_totalInterPacketGaps.tv_usec-=1000000;
		}
	}
	m_lastPacketReceptionTime=timeNow;
	//rtp jitter:时间抖动;
	//Si:RTP 时间戳;
	//Ri:RTP 接收到时的时间戳;
	//D(i,j)=(Rj-Ri)-(Sj-Si)=(Rj-Sj)-(Ri-Si);
	//J=J+(|D(i-1,i)|-J)/16;
	//RFC 1889 A.8
	if (useForJitterCalculation&&
		rtpTimestamp!=m_previousPacketRTPTimestamp)
	{
		unsigned int arrival=(timestampFrequency*timeNow.tv_sec);
		arrival+=(unsigned int)((2.0*timestampFrequency*timeNow.tv_usec+1000000.0)/2000000.0);

		int	transit=arrival-rtpTimestamp;
		if (m_lastTransit==~0)
		{
			m_lastTransit=transit;
		}
		int d=transit-m_lastTransit;
		m_lastTransit=transit;
		if (d<0)
		{
			d=-d;
		}
		m_jitter+=(1.0/16.0)*((double)d-m_jitter);
	}
	if (m_syncTime.tv_usec==0&&m_syncTime.tv_sec==0)
	{
		m_syncTime=timeNow;
		m_syncTimestamp=rtpTimestamp;
	}
	//时间戳间距;
	int timestampDiff=rtpTimestamp-m_syncTimestamp;
	//乘以采样率,获得真实时间差;
	double	timeDiff=timestampDiff/(double)timestampFrequency;

	unsigned int seconds=0,useconds=0;
	if (timeDiff>=0.0)
	{
		seconds=m_syncTime.tv_sec+(unsigned int)timeDiff;
		useconds=m_syncTime.tv_usec+
			(unsigned int)((timeDiff-(unsigned int)timeDiff)*UMILLION);
		if (useconds>=UMILLION)
		{
			seconds++;
			useconds-=UMILLION;
		}
	}else
	{
		timeDiff=-timeDiff;
		seconds=m_syncTime.tv_sec-(unsigned int)timeDiff;
		useconds=m_syncTime.tv_usec-
			(unsigned int)((timeDiff-(unsigned int)timeDiff)*UMILLION);
		if ((int)useconds<0)
		{
			useconds+=UMILLION;
			--seconds;
		}
	}
	resultPresentationTime.tv_sec=seconds;
	resultPresentationTime.tv_usec=useconds;
	resultHasBeenSyncedUsingRTCP=m_hasBeenSynchronized;
	//保存这一包的信息;
	m_syncTimestamp=rtpTimestamp;
	m_syncTime=resultPresentationTime;
	m_previousPacketRTPTimestamp=rtpTimestamp;
}