// Check for the 12-byte RTP header:
if (bPacket->dataSize() < 12) break;
unsigned rtpHdr = ntohl(*(unsigned*)(bPacket->data())); ADVANCE(4);
Boolean rtpMarkerBit = (rtpHdr&0x00800000) >> 23;
unsigned rtpTimestamp = ntohl(*(unsigned*)(bPacket->data()));ADVANCE(4);
unsigned rtpSSRC = ntohl(*(unsigned*)(bPacket->data())); ADVANCE(4);
// Check the RTP version number (it should be 2):
if ((rtpHdr&0xC0000000) != 0x80000000) break;
// Skip over any CSRC identifiers in the header:
unsigned cc = (rtpHdr>>24)&0xF;
if (bPacket->dataSize() < cc) break;
ADVANCE(cc*4);
// Check for (& ignore) any RTP header extension
if (rtpHdr&0x10000000) {
if (bPacket->dataSize() < 4) break;
unsigned extHdr = ntohl(*(unsigned*)(bPacket->data())); ADVANCE(4);
unsigned remExtSize = 4*(extHdr&0xFFFF);
if (bPacket->dataSize() < remExtSize) break;
ADVANCE(remExtSize);
}
// Discard any padding bytes:
if (rtpHdr&0x20000000) {
if (bPacket->dataSize() == 0) break;
unsigned numPaddingBytes
= (unsigned)(bPacket->data())[bPacket->dataSize()-1];
if (bPacket->dataSize() < numPaddingBytes) break;
bPacket->removePadding(numPaddingBytes);
}
// Check the Payload Type.
if ((unsigned char)((rtpHdr&0x007F0000)>>16)
!= source->rtpPayloadFormat()) {
break;
}
// The rest of the packet is the usable data. Record and save it:
source->fLastReceivedSSRC = rtpSSRC;
unsigned short rtpSeqNo = (unsigned short)(rtpHdr&0xFFFF);
Boolean usableInJitterCalculation
= source->packetIsUsableInJitterCalculation((bPacket->data()),
bPacket->dataSize());
struct timeval presentationTime; // computed by:
Boolean hasBeenSyncedUsingRTCP; // computed by:
source->receptionStatsDB()
.noteIncomingPacket(rtpSSRC, rtpSeqNo, rtpTimestamp,
source->timestampFrequency(),
usableInJitterCalculation, presentationTime,
hasBeenSyncedUsingRTCP, bPacket->dataSize());
// Fill in the rest of the packet descriptor, and store it:
struct timeval timeNow;
gettimeofday(&timeNow, NULL);
bPacket->assignMiscParams(rtpSeqNo, rtpTimestamp, presentationTime,
hasBeenSyncedUsingRTCP, rtpMarkerBit,
timeNow);
if (!source->fReorderingBuffer->storePacket(bPacket)) break;
readSuccess = True;
BufferedPacket* ReorderingPacketBuffer
::getNextCompletedPacket(Boolean& packetLossPreceded) {
if (fHeadPacket == NULL) return NULL;
关于丢包的处理:
// Check whether the next packet we want is already at the head
// of the queue:检查接受包中的序列号是否是所希望的序列号
if (fHeadPacket->rtpSeqNo() == fNextExpectedSeqNo) {
packetLossPreceded = fHeadPacket->isFirstPacket();
// (The very first packet is treated as if there was packet loss beforehand.)
return fHeadPacket;
}
// We're still waiting for our desired packet to arrive. However, if
// our time threshold has been exceeded, then forget it, and return
// the head packet instead:等待所希望的包的到来,一段时间后丢弃
struct timeval timeNow;
gettimeofday(&timeNow, NULL);
unsigned uSecondsSinceReceived
= (timeNow.tv_sec - fHeadPacket->timeReceived().tv_sec)*1000000
+ (timeNow.tv_usec - fHeadPacket->timeReceived().tv_usec);
if (uSecondsSinceReceived > fThresholdTime) {
fNextExpectedSeqNo = fHeadPacket->rtpSeqNo();
// we've given up on earlier packets now
packetLossPreceded = True;
return fHeadPacket;
}
// Otherwise, keep waiting for our desired packet to arrive:
return NULL;
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/rachel2968/archive/2010/07/22/5755447.aspx