⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 multiframedrtpsource.cpp

📁 流媒体传输协议的实现代码,非常有用.可以支持rtsp mms等流媒体传输协议
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    gettimeofday(&timeNow, NULL);    bPacket->assignMiscParams(rtpSeqNo, rtpTimestamp, presentationTime,			      hasBeenSyncedUsingRTCP, rtpMarkerBit,			      timeNow);    source->fReorderingBuffer->storePacket(bPacket);    readSuccess = True;  } while (0);  if (!readSuccess) source->fReorderingBuffer->freePacket(bPacket);  source->doGetNextFrame1();  // If we didn't get proper data this time, we'll get another chance}////////// BufferedPacket and BufferedPacketFactory implementation /////#define MAX_PACKET_SIZE 10000BufferedPacket::BufferedPacket()  : fPacketSize(MAX_PACKET_SIZE),    fBuf(new unsigned char[MAX_PACKET_SIZE]),    fNextPacket(NULL) {}BufferedPacket::~BufferedPacket() {  delete fNextPacket;  delete[] fBuf;}void BufferedPacket::reset() {  fHead = fTail = 0;  fUseCount = 0;}// The following function has been deprecated:unsigned BufferedPacket::nextEnclosedFrameSize(unsigned char*& /*framePtr*/, unsigned dataSize) {  // By default, use the entire buffered data, even though it may consist  // of more than one frame, on the assumption that the client doesn't  // care.  (This is more efficient than delivering a frame at a time)  return dataSize;}void BufferedPacket::getNextEnclosedFrameParameters(unsigned char*& framePtr, unsigned dataSize,				 unsigned& frameSize,				 unsigned& frameDurationInMicroseconds) {  // By default, use the entire buffered data, even though it may consist  // of more than one frame, on the assumption that the client doesn't  // care.  (This is more efficient than delivering a frame at a time)  // For backwards-compatibilty with existing uses of (the now deprecated)  // "nextEnclosedFrameSize()", call that function to implement this one:  frameSize = nextEnclosedFrameSize(framePtr, dataSize);  frameDurationInMicroseconds = 0; // by default.  Subclasses should correct this.  }Boolean BufferedPacket::fillInData(RTPInterface& rtpInterface) {  reset();  unsigned numBytesRead;  struct sockaddr_in fromAddress;  if (!rtpInterface.handleRead(&fBuf[fTail], fPacketSize-fTail, numBytesRead,			       fromAddress)) {    return False;  }  fTail += numBytesRead;  return True;}void BufferedPacket::assignMiscParams(unsigned short rtpSeqNo, unsigned rtpTimestamp,		   struct timeval presentationTime,		   Boolean hasBeenSyncedUsingRTCP, Boolean rtpMarkerBit,		   struct timeval timeReceived) {  fRTPSeqNo = rtpSeqNo;  fRTPTimestamp = rtpTimestamp;  fPresentationTime = presentationTime;  fHasBeenSyncedUsingRTCP = hasBeenSyncedUsingRTCP;  fRTPMarkerBit = rtpMarkerBit;  fTimeReceived = timeReceived;}void BufferedPacket::skip(unsigned numBytes) {  fHead += numBytes;  if (fHead > fTail) fHead = fTail;}void BufferedPacket::removePadding(unsigned numBytes) {  if (numBytes > fTail-fHead) numBytes = fTail-fHead;  fTail -= numBytes;}void BufferedPacket::appendData(unsigned char* newData, unsigned numBytes) {  if (numBytes > fPacketSize-fTail) numBytes = fPacketSize - fTail;  memmove(&fBuf[fTail], newData, numBytes);   fTail += numBytes;}void BufferedPacket::use(unsigned char* to, unsigned toSize,			 unsigned& bytesUsed, unsigned& bytesTruncated,			 unsigned short& rtpSeqNo, unsigned& rtpTimestamp,			 struct timeval& presentationTime,			 Boolean& hasBeenSyncedUsingRTCP,			 Boolean& rtpMarkerBit) {  unsigned char* origFramePtr = &fBuf[fHead];  unsigned char* newFramePtr = origFramePtr; // may change in the call below  unsigned frameSize, frameDurationInMicroseconds;  getNextEnclosedFrameParameters(newFramePtr, fTail - fHead,				 frameSize, frameDurationInMicroseconds);  if (frameSize > toSize) {    bytesTruncated = frameSize - toSize;    bytesUsed = toSize;  } else {    bytesTruncated = 0;    bytesUsed = frameSize;  }  memmove(to, newFramePtr, bytesUsed);  fHead += (newFramePtr - origFramePtr) + frameSize;  ++fUseCount;  rtpSeqNo = fRTPSeqNo;  rtpTimestamp = fRTPTimestamp;  presentationTime = fPresentationTime;  hasBeenSyncedUsingRTCP = fHasBeenSyncedUsingRTCP;  rtpMarkerBit = fRTPMarkerBit;  // Update "fPresentationTime" for the next enclosed frame (if any):  fPresentationTime.tv_usec += frameDurationInMicroseconds;  if (fPresentationTime.tv_usec >= 1000000) {    fPresentationTime.tv_sec += fPresentationTime.tv_usec/1000000;    fPresentationTime.tv_usec = fPresentationTime.tv_usec%1000000;  }}BufferedPacketFactory::BufferedPacketFactory() {}BufferedPacketFactory::~BufferedPacketFactory() {}BufferedPacket* BufferedPacketFactory::createNewPacket(MultiFramedRTPSource* /*ourSource*/) {  return new BufferedPacket;}////////// ReorderingPacketBuffer definition //////////ReorderingPacketBuffer::ReorderingPacketBuffer(BufferedPacketFactory* packetFactory)  : fThresholdTime(100000) /* default reordering threshold: 100 ms */,    fHaveSeenFirstPacket(False), fHeadPacket(NULL), fSavedPacket(NULL) {  fPacketFactory = (packetFactory == NULL)    ? (new BufferedPacketFactory)    : packetFactory;}ReorderingPacketBuffer::~ReorderingPacketBuffer() {  if (fHeadPacket == NULL) {    delete fSavedPacket;  } else {    delete fHeadPacket; // will also delete fSavedPacket, because it's on the list  }  delete fPacketFactory;}BufferedPacket* ReorderingPacketBuffer::getFreePacket(MultiFramedRTPSource* ourSource) {  if (fSavedPacket == NULL) { // we're being called for the first time    fSavedPacket = fPacketFactory->createNewPacket(ourSource);  }  return fHeadPacket == NULL    ? fSavedPacket    : fPacketFactory->createNewPacket(ourSource);}void ReorderingPacketBuffer::storePacket(BufferedPacket* bPacket) {  unsigned short rtpSeqNo = bPacket->rtpSeqNo();  if (!fHaveSeenFirstPacket) {    fNextExpectedSeqNo = rtpSeqNo; // initialization    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).  // (But (sanity check) if the new packet's sequence number is a *lot*  // less, then accept it anyway.)  unsigned short const seqNoThreshold = 100;  if (seqNumLT(rtpSeqNo, fNextExpectedSeqNo)      && seqNumLT(fNextExpectedSeqNo, rtpSeqNo+seqNoThreshold)) {    return;  }    // Figure out where the new packet will be stored in the queue:  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;    }        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;  }}void ReorderingPacketBuffer::releaseUsedPacket(BufferedPacket* packet) {  // ASSERT: packet == fHeadPacket  // ASSERT: fNextExpectedSeqNo == packet->rtpSeqNo()  ++fNextExpectedSeqNo; // because we're finished with this packet now  fHeadPacket = fHeadPacket->nextPacket();  packet->nextPacket() = NULL;  freePacket(packet);}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:  // ASSERT: fHeadPacket->rtpSeqNo() >= fNextExpectedSeqNo  if (fHeadPacket->rtpSeqNo() == fNextExpectedSeqNo) {    packetLossPreceded = False;    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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -