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

📄 qcelpaudiortpsource.cpp

📁 流媒体传输协议的实现代码,非常有用.可以支持rtsp mms等流媒体传输协议
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}///////// QCELPDeinterleavingBuffer /////////// (used to implement QCELPDeinterleaver)#define QCELP_MAX_FRAME_SIZE 35#define QCELP_MAX_INTERLEAVE_L 5#define QCELP_MAX_FRAMES_PER_PACKET 10#define QCELP_MAX_INTERLEAVE_GROUP_SIZE \    ((QCELP_MAX_INTERLEAVE_L+1)*QCELP_MAX_FRAMES_PER_PACKET)class QCELPDeinterleavingBuffer {public:  QCELPDeinterleavingBuffer();  virtual ~QCELPDeinterleavingBuffer();  void deliverIncomingFrame(unsigned frameSize,			    unsigned char interleaveL,			    unsigned char interleaveN,			    unsigned char frameIndex,			    unsigned short packetSeqNum,			    struct timeval presentationTime);  Boolean retrieveFrame(unsigned char* to, unsigned maxSize,			unsigned& resultFrameSize, unsigned& resultNumTruncatedBytes,			struct timeval& resultPresentationTime);  unsigned char* inputBuffer() { return fInputBuffer; }  unsigned inputBufferSize() const { return QCELP_MAX_FRAME_SIZE; }private:  class FrameDescriptor {  public:    FrameDescriptor();    virtual ~FrameDescriptor();    unsigned frameSize;    unsigned char* frameData;    struct timeval presentationTime;  };  // Use two banks of descriptors - one for incoming, one for outgoing  FrameDescriptor fFrames[QCELP_MAX_INTERLEAVE_GROUP_SIZE][2];  unsigned char fIncomingBankId; // toggles between 0 and 1  unsigned char fIncomingBinMax; // in the incoming bank  unsigned char fOutgoingBinMax; // in the outgoing bank  unsigned char fNextOutgoingBin;  Boolean fHaveSeenPackets;  u_int16_t fLastPacketSeqNumForGroup;  unsigned char* fInputBuffer;  struct timeval fLastRetrievedPresentationTime;};////////// QCELPDeinterleaver implementation /////////QCELPDeinterleaver*QCELPDeinterleaver::createNew(UsageEnvironment& env,			      RawQCELPRTPSource* inputSource) {  return new QCELPDeinterleaver(env, inputSource);}QCELPDeinterleaver::QCELPDeinterleaver(UsageEnvironment& env,				       RawQCELPRTPSource* inputSource)  : FramedFilter(env, inputSource),    fNeedAFrame(False) {  fDeinterleavingBuffer = new QCELPDeinterleavingBuffer();}QCELPDeinterleaver::~QCELPDeinterleaver() {  delete fDeinterleavingBuffer;}static unsigned const uSecsPerFrame = 20000; // 20 msvoid QCELPDeinterleaver::doGetNextFrame() {  // First, try getting a frame from the deinterleaving buffer:  if (fDeinterleavingBuffer->retrieveFrame(fTo, fMaxSize,					   fFrameSize, fNumTruncatedBytes,					   fPresentationTime)) {    // Success!    fNeedAFrame = False;    fDurationInMicroseconds = uSecsPerFrame;    // Call our own 'after getting' function.  Because we're not a 'leaf'    // source, we can call this directly, without risking    // infinite recursion    afterGetting(this);    return;  }  // No luck, so ask our source for help:  fNeedAFrame = True;  if (!fInputSource->isCurrentlyAwaitingData()) {    fInputSource->getNextFrame(fDeinterleavingBuffer->inputBuffer(),			       fDeinterleavingBuffer->inputBufferSize(),			       afterGettingFrame, this,			       FramedSource::handleClosure, this);  }}void QCELPDeinterleaver::afterGettingFrame(void* clientData, unsigned frameSize,		    unsigned /*numTruncatedBytes*/,		    struct timeval presentationTime,		    unsigned /*durationInMicroseconds*/) {  QCELPDeinterleaver* deinterleaver = (QCELPDeinterleaver*)clientData;  deinterleaver->afterGettingFrame1(frameSize, presentationTime);}void QCELPDeinterleaver::afterGettingFrame1(unsigned frameSize, struct timeval presentationTime) {  RawQCELPRTPSource* source = (RawQCELPRTPSource*)fInputSource;    // First, put the frame into our deinterleaving buffer:  fDeinterleavingBuffer    ->deliverIncomingFrame(frameSize, source->interleaveL(),			   source->interleaveN(), source->frameIndex(),			   source->curPacketRTPSeqNum(),			   presentationTime);    // Then, try delivering a frame to the client (if he wants one):  if (fNeedAFrame) doGetNextFrame();}////////// QCELPDeinterleavingBuffer implementation /////////QCELPDeinterleavingBuffer::QCELPDeinterleavingBuffer()  : fIncomingBankId(0), fIncomingBinMax(0),    fOutgoingBinMax(0), fNextOutgoingBin(0),    fHaveSeenPackets(False) {  fInputBuffer = new unsigned char[QCELP_MAX_FRAME_SIZE];}QCELPDeinterleavingBuffer::~QCELPDeinterleavingBuffer() {  delete[] fInputBuffer;}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    exit(1);  }  // 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;  }}Boolean QCELPDeinterleavingBuffer::retrieveFrame(unsigned char* to, unsigned maxSize,		unsigned& resultFrameSize, unsigned& resultNumTruncatedBytes,		struct timeval& resultPresentationTime) {  if (fNextOutgoingBin >= fOutgoingBinMax) return False; // none left  FrameDescriptor& outBin = fFrames[fNextOutgoingBin][fIncomingBankId^1];  unsigned char* fromPtr;  unsigned char fromSize = outBin.frameSize;  outBin.frameSize = 0; // for the next time this bin is used  // Check whether this frame is missing; if so, return an 'erasure' frame:  unsigned char erasure = 14;  if (fromSize == 0) {    fromPtr = &erasure;    fromSize = 1;    // Compute this erasure frame's presentation time via extrapolation:    resultPresentationTime = fLastRetrievedPresentationTime;    resultPresentationTime.tv_usec += uSecsPerFrame;    if (resultPresentationTime.tv_usec >= 1000000) {      ++resultPresentationTime.tv_sec;      resultPresentationTime.tv_usec -= 1000000;    }  } else {    // Normal case - a frame exists:    fromPtr = outBin.frameData;    resultPresentationTime = outBin.presentationTime;  }  fLastRetrievedPresentationTime = resultPresentationTime;  if (fromSize > maxSize) {    resultNumTruncatedBytes = fromSize - maxSize;    resultFrameSize = maxSize;  } else {    resultNumTruncatedBytes = 0;    resultFrameSize = fromSize;  }  memmove(to, fromPtr, resultFrameSize);  ++fNextOutgoingBin;  return True;}QCELPDeinterleavingBuffer::FrameDescriptor::FrameDescriptor()  : frameSize(0), frameData(NULL) {}QCELPDeinterleavingBuffer::FrameDescriptor::~FrameDescriptor() {  delete[] frameData;}

⌨️ 快捷键说明

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