コード例 #1
0
Boolean ReorderingPacketBuffer::storePacket(BufferedPacket* bPacket) {
  unsigned short rtpSeqNo = bPacket->rtpSeqNo();

  if (!fHaveSeenFirstPacket) {
    fNextExpectedSeqNo = rtpSeqNo; // initialization
    bPacket->isFirstPacket() = True;
    fHaveSeenFirstPacket = True;
  }

  // Ignore this packet if its sequence number is less than the one
  // that we're looking for (in this case, it's been excessively delayed).
  if (seqNumLT(rtpSeqNo, fNextExpectedSeqNo)) return False;

  if (fTailPacket == NULL) {
    // Common case: There are no packets in the queue; this will be the first one:
    bPacket->nextPacket() = NULL;
    fHeadPacket = fTailPacket = bPacket;
    return True;
  }

  if (seqNumLT(fTailPacket->rtpSeqNo(), rtpSeqNo)) {
    // The next-most common case: There are packets already in the queue; this packet arrived in order => put it at the tail:
    bPacket->nextPacket() = NULL;
    fTailPacket->nextPacket() = bPacket;
    fTailPacket = bPacket;
    return True;
  }

  if (rtpSeqNo == fTailPacket->rtpSeqNo()) {
    // This is a duplicate packet - ignore it
    return False;
  }

  // Rare case: This packet is out-of-order.  Run through the list (from the head), to figure out where it belongs:
  BufferedPacket* beforePtr = NULL;
  BufferedPacket* afterPtr = fHeadPacket;
  while (afterPtr != NULL) {
    if (seqNumLT(rtpSeqNo, afterPtr->rtpSeqNo())) break; // it comes here
    if (rtpSeqNo == afterPtr->rtpSeqNo()) {
      // This is a duplicate packet - ignore it
      return False;
    }

    beforePtr = afterPtr;
    afterPtr = afterPtr->nextPacket();
  }

  // Link our new packet between "beforePtr" and "afterPtr":
  bPacket->nextPacket() = afterPtr;
  if (beforePtr == NULL) {
    fHeadPacket = bPacket;
  } else {
    beforePtr->nextPacket() = bPacket;
  }

  return True;
}
コード例 #2
0
ファイル: MediaSession.cpp プロジェクト: hatboyzero/live456
double MediaSubsession::getNormalPlayTime(struct timeval const& presentationTime) {
  if (rtpSource() == NULL || rtpSource()->timestampFrequency() == 0) return 0.0; // no RTP source, or bad freq!

  // First, check whether our "RTPSource" object has already been synchronized using RTCP.
  // If it hasn't, then - as a special case - we need to use the RTP timestamp to compute the NPT.
  if (!rtpSource()->hasBeenSynchronizedUsingRTCP()) {
    if (!rtpInfo.infoIsNew) return 0.0; // the "rtpInfo" structure has not been filled in
    u_int32_t timestampOffset = rtpSource()->curPacketRTPTimestamp() - rtpInfo.timestamp;
    double nptOffset = (timestampOffset/(double)(rtpSource()->timestampFrequency()))*scale();
    double npt = playStartTime() + nptOffset;

    return npt;
  } else {
    // Common case: We have been synchronized using RTCP.  This means that the "presentationTime" parameter
    // will be accurate, and so we should use this to compute the NPT.
    double ptsDouble = (double)(presentationTime.tv_sec + presentationTime.tv_usec/1000000.0);

    if (rtpInfo.infoIsNew) {
      // This is the first time we've been called with a synchronized presentation time since the "rtpInfo"
      // structure was last filled in.  Use this "presentationTime" to compute "fNPT_PTS_Offset":
      if (seqNumLT(rtpSource()->curPacketRTPSeqNum(), rtpInfo.seqNum)) return -0.1; // sanity check; ignore old packets
      u_int32_t timestampOffset = rtpSource()->curPacketRTPTimestamp() - rtpInfo.timestamp;
      double nptOffset = (timestampOffset/(double)(rtpSource()->timestampFrequency()))*scale();
      double npt = playStartTime() + nptOffset;
      fNPT_PTS_Offset = npt - ptsDouble*scale();
      rtpInfo.infoIsNew = False; // for next time

      return npt;
    } else {
      // Use the precomputed "fNPT_PTS_Offset" to compute the NPT from the PTS:
      if (fNPT_PTS_Offset == 0.0) return 0.0; // error: The "rtpInfo" structure was apparently never filled in
      return (double)(ptsDouble*scale() + fNPT_PTS_Offset);
    }
  }
}
コード例 #3
0
void QCELPDeinterleavingBuffer
::deliverIncomingFrame(unsigned frameSize,
		       unsigned char interleaveL,
		       unsigned char interleaveN,
		       unsigned char frameIndex,
		       unsigned short packetSeqNum,
		       struct timeval presentationTime) {
  // First perform a sanity check on the parameters:
  // (This is overkill, as the source should have already done this.)
  if (frameSize > QCELP_MAX_FRAME_SIZE
      || interleaveL > QCELP_MAX_INTERLEAVE_L || interleaveN > interleaveL
      || frameIndex == 0 || frameIndex > QCELP_MAX_FRAMES_PER_PACKET) {
#ifdef DEBUG
    fprintf(stderr, "QCELPDeinterleavingBuffer::deliverIncomingFrame() param sanity check failed (%d,%d,%d,%d)\n", frameSize, interleaveL, interleaveN, frameIndex);
#endif
    abort();
  }

  // The input "presentationTime" was that of the first frame in this
  // packet.  Update it for the current frame:
  unsigned uSecIncrement = (frameIndex-1)*(interleaveL+1)*uSecsPerFrame;
  presentationTime.tv_usec += uSecIncrement;
  presentationTime.tv_sec += presentationTime.tv_usec/1000000;
  presentationTime.tv_usec = presentationTime.tv_usec%1000000;

  // Next, check whether this packet is part of a new interleave group
  if (!fHaveSeenPackets
      || seqNumLT(fLastPacketSeqNumForGroup, packetSeqNum)) {
    // We've moved to a new interleave group
    fHaveSeenPackets = True;
    fLastPacketSeqNumForGroup = packetSeqNum + interleaveL - interleaveN;

    // Switch the incoming and outgoing banks:
    fIncomingBankId ^= 1;
    unsigned char tmp = fIncomingBinMax;
    fIncomingBinMax = fOutgoingBinMax;
    fOutgoingBinMax = tmp;
    fNextOutgoingBin = 0;
  }

  // Now move the incoming frame into the appropriate bin:
  unsigned const binNumber
    = interleaveN + (frameIndex-1)*(interleaveL+1);
  FrameDescriptor& inBin = fFrames[binNumber][fIncomingBankId];
  unsigned char* curBuffer = inBin.frameData;
  inBin.frameData = fInputBuffer;
  inBin.frameSize = frameSize;
  inBin.presentationTime = presentationTime;

  if (curBuffer == NULL) curBuffer = new unsigned char[QCELP_MAX_FRAME_SIZE];
  fInputBuffer = curBuffer;

  if (binNumber >= fIncomingBinMax) {
    fIncomingBinMax = binNumber + 1;
  }
}
コード例 #4
0
void AMRDeinterleavingBuffer
::deliverIncomingFrame(unsigned frameSize, RawAMRRTPSource* source,
		       struct timeval presentationTime) {
  fILL = source->ILL();
  unsigned char const ILP = source->ILP();
  unsigned frameIndex = source->frameIndex();
  unsigned short packetSeqNum = source->curPacketRTPSeqNum();

  // First perform a sanity check on the parameters:
  // (This is overkill, as the source should have already done this.)
  if (ILP > fILL || frameIndex == 0) {
#ifdef DEBUG
    fprintf(stderr, "AMRDeinterleavingBuffer::deliverIncomingFrame() param sanity check failed (%d,%d,%d,%d)\n", frameSize, fILL, ILP, frameIndex);
#endif
    source->envir().internalError();
  }

  --frameIndex; // because it was incremented by the source when this frame was read
  u_int8_t frameHeader;
  if (frameIndex >= source->TOCSize()) { // sanity check
    frameHeader = FT_NO_DATA<<3;
  } else {
    frameHeader = source->TOC()[frameIndex];
  }

  unsigned frameBlockIndex = frameIndex/fNumChannels;
  unsigned frameWithinFrameBlock = frameIndex%fNumChannels;

  // The input "presentationTime" was that of the first frame-block in this
  // packet.  Update it for the current frame:
  unsigned uSecIncrement = frameBlockIndex*(fILL+1)*uSecsPerFrame;
  presentationTime.tv_usec += uSecIncrement;
  presentationTime.tv_sec += presentationTime.tv_usec/1000000;
  presentationTime.tv_usec = presentationTime.tv_usec%1000000;

  // Next, check whether this packet is part of a new interleave group
  if (!fHaveSeenPackets
      || seqNumLT(fLastPacketSeqNumForGroup, packetSeqNum + frameBlockIndex)) {
    // We've moved to a new interleave group
#ifdef DEBUG
    fprintf(stderr, "AMRDeinterleavingBuffer::deliverIncomingFrame(): new interleave group\n");
#endif
    fHaveSeenPackets = True;
    fLastPacketSeqNumForGroup = packetSeqNum + fILL - ILP;

    // Switch the incoming and outgoing banks:
    fIncomingBankId ^= 1;
    unsigned char tmp = fIncomingBinMax;
    fIncomingBinMax = fOutgoingBinMax;
    fOutgoingBinMax = tmp;
    fNextOutgoingBin = 0;
  }

  // Now move the incoming frame into the appropriate bin:
  unsigned const binNumber
    = ((ILP + frameBlockIndex*(fILL+1))*fNumChannels + frameWithinFrameBlock)
      % fMaxInterleaveGroupSize; // the % is for sanity
#ifdef DEBUG
  fprintf(stderr, "AMRDeinterleavingBuffer::deliverIncomingFrame(): frameIndex %d (%d,%d) put in bank %d, bin %d (%d): size %d, header 0x%02x, presentationTime %lu.%06ld\n", frameIndex, frameBlockIndex, frameWithinFrameBlock, fIncomingBankId, binNumber, fMaxInterleaveGroupSize, frameSize, frameHeader, presentationTime.tv_sec, presentationTime.tv_usec);
#endif
  FrameDescriptor& inBin = fFrames[fIncomingBankId][binNumber];
  unsigned char* curBuffer = inBin.frameData;
  inBin.frameData = fInputBuffer;
  inBin.frameSize = frameSize;
  inBin.frameHeader = frameHeader;
  inBin.presentationTime = presentationTime;
  inBin.fIsSynchronized = ((RTPSource*)source)->RTPSource::hasBeenSynchronizedUsingRTCP();

  if (curBuffer == NULL) curBuffer = createNewBuffer();
  fInputBuffer = curBuffer;

  if (binNumber >= fIncomingBinMax) {
    fIncomingBinMax = binNumber + 1;
  }
}
コード例 #5
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;
}
コード例 #6
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;
}