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

📄 jitter.cxx

📁 mgcp协议源代码。支持多种编码:g711
💻 CXX
📖 第 1 页 / 共 2 页
字号:
      return;    }    if (currentReadFrame->GetMarker()) {      // See if remote appears to be setting marker bit on EVERY packet.      consecutiveMarkerBits++;      if (consecutiveMarkerBits < maxConsecutiveMarkerBits) {        PTRACE(3, "RTP\tReceived start of talk burst: " << currentReadFrame->GetTimestamp());        preBuffering = TRUE;      }      if (consecutiveMarkerBits == maxConsecutiveMarkerBits) {        PTRACE(3, "RTP\tEvery packet has Marker bit, ignoring them from this client!");      }    }    else      consecutiveMarkerBits = 0;#if PTRACING    analyser->In(currentReadFrame->GetTimestamp(), currentDepth, preBuffering ? "PreBuf" : "");#endif    // Queue the frame for playing by the thread at other end of jitter buffer    bufferMutex.Wait();    // Have been reading a frame, put it into the queue now, at correct position    if (newestFrame == NULL)      oldestFrame = newestFrame = currentReadFrame; // Was empty    else {      DWORD time = currentReadFrame->GetTimestamp();      if (time > newestFrame->GetTimestamp()) {        // Is newer than newst, put at that end of queue        currentReadFrame->prev = newestFrame;        newestFrame->next = currentReadFrame;        newestFrame = currentReadFrame;      }      else if (time <= oldestFrame->GetTimestamp()) {        // Is older than the oldest, put at that end of queue        currentReadFrame->next = oldestFrame;        oldestFrame->prev = currentReadFrame;        oldestFrame = currentReadFrame;      }      else {        // Somewhere in between, locate its position        Entry * frame = newestFrame->prev;        while (time < frame->GetTimestamp())          frame = frame->prev;        currentReadFrame->prev = frame;        currentReadFrame->next = frame->next;        frame->next = currentReadFrame;        frame->next->prev = currentReadFrame;      }    }    currentDepth++;  }}BOOL RTP_JitterBuffer::ReadData(DWORD timestamp, RTP_DataFrame & frame){  if (shuttingDown)    return FALSE;  /*Free the frame just written to codec, putting it back into    the free list and clearing the parking spot for it.   */  if (currentWriteFrame != NULL) {    bufferMutex.Wait();    // Move frame from current to free list    currentWriteFrame->next = freeFrames;    if (freeFrames != NULL)      freeFrames->prev = currentWriteFrame;    freeFrames = currentWriteFrame;    currentWriteFrame = NULL;    bufferMutex.Signal();  }  // Default response is an empty frame, ie silence  frame.SetPayloadSize(0);  /*Get the next frame to write to the codec. Takes it from the oldest    position in the queue, if it is time to do so, and parks it in the    special member so can unlock the mutex while the writer thread has its    way with the buffer.   */  if (oldestFrame == NULL) {    /*No data to play! We ran the buffer down to empty, restart buffer by      setting flag that will fill it again before returning any data.     */    preBuffering = TRUE;#if PTRACING    analyser->Out(0, currentDepth, "Empty");#endif    return TRUE;  }  PWaitAndSignal mutex(bufferMutex);  /* See if time for this packet, if our oldest frame is older than the     required age, then use it. If it is not time yet, make sure that the     writer thread isn't falling behind (not enough MIPS). If the time     between the oldest and the newest entries in the jitter buffer is     greater than the size specified for the buffer, then return the oldest     entry regardless, making the writer thread catch up.  */  DWORD oldestTimestamp = oldestFrame->GetTimestamp();  DWORD newestTimestamp = newestFrame->GetTimestamp();  if (preBuffering && (newestTimestamp - oldestTimestamp) > maxJitterTime/2)    preBuffering = FALSE;  if (preBuffering) {    // Are filling the buffer, don't return anything yet#if PTRACING    analyser->Out(oldestTimestamp, currentDepth, "PreBuf");#endif    return TRUE;  }  if (timestamp < oldestTimestamp && timestamp > (newestTimestamp - maxJitterTime)) {    // It is not yet time for something in the buffer#if PTRACING    analyser->Out(oldestTimestamp, currentDepth, "Wait");#endif    return TRUE;  }  // Detatch oldest packet from the list, put into parking space  currentDepth--;#if PTRACING  analyser->Out(oldestTimestamp, currentDepth, timestamp >= oldestTimestamp ? "" : "Late");#endif  currentWriteFrame = oldestFrame;  oldestFrame = currentWriteFrame->next;  currentWriteFrame->next = NULL;  if (oldestFrame == NULL)    newestFrame = NULL;  else {    oldestFrame->prev = NULL;    // See if exceeded maximum jitter buffer time delay, waste them if so    while ((newestTimestamp - oldestFrame->GetTimestamp()) > maxJitterTime) {      // Throw away the oldest entry      Entry * wastedFrame = oldestFrame;      oldestFrame = oldestFrame->next;      oldestFrame->prev = NULL;      currentDepth--;      // Put thrown away frame on free list      wastedFrame->next = freeFrames;      if (freeFrames != NULL)        freeFrames->prev = wastedFrame;      freeFrames = wastedFrame;      packetsTooLate++;    }  }  frame = *currentWriteFrame;  return TRUE;}#if PTRACINGRTP_JitterBufferAnalyser::RTP_JitterBufferAnalyser(){  inPos = outPos = 1;  in[0].time = out[0].time = 0;  in[0].tick = out[0].tick = PTimer::Tick();  in[0].depth = out[0].depth = 0;}void RTP_JitterBufferAnalyser::In(DWORD time, unsigned depth, const char * extra){  if (inPos < PARRAYSIZE(in)) {    in[inPos].tick = PTimer::Tick();    in[inPos].time = time;    in[inPos].depth = depth;    in[inPos++].extra = extra;  }}void RTP_JitterBufferAnalyser::Out(DWORD time, unsigned depth, const char * extra){  if (outPos < PARRAYSIZE(out)) {    out[outPos].tick = PTimer::Tick();    if (time == 0 && outPos > 0)      out[outPos].time = out[outPos-1].time;    else      out[outPos].time = time;    out[outPos].depth = depth;    out[outPos++].extra = extra;  }}void RTP_JitterBufferAnalyser::PrintOn(ostream & strm) const{  strm << "Input samples: " << inPos << " Output samples: " << outPos << "\n"          "Dir\tRTPTime\tInDiff\tOutDiff\tInMode\tOutMode\t"          "InDepth\tOutDep\tInTick\tInDelay\tOutTick\tOutDel\tIODelay\n";  PINDEX ix = 1;  PINDEX ox = 1;  while (ix < inPos || ox < outPos) {    while (ix < inPos && (ox >= outPos || in[ix].time < out[ox].time)) {      strm << "In\t"           << in[ix].time << '\t'           << (in[ix].time - in[ix-1].time) << "\t"              "\t"           << in[ix].extra << "\t"              "\t"           << in[ix].depth << "\t"              "\t"           << (in[ix].tick - in[0].tick) << '\t'           << (in[ix].tick - in[ix-1].tick) << "\t"              "\t"              "\t"              "\n";      ix++;    }    while (ox < outPos && (ix >= inPos || out[ox].time < in[ix].time)) {      strm << "Out\t"           << out[ox].time << "\t"              "\t"           << (out[ox].time - out[ox-1].time) << "\t"              "\t"           << out[ox].extra << "\t"              "\t"           << out[ox].depth << "\t"              "\t"              "\t"           << (out[ox].tick - out[0].tick) << '\t'           << (out[ox].tick - out[ox-1].tick) << "\t"              "\n";      ox++;    }    while (ix < inPos && ox < outPos && in[ix].time == out[ox].time) {      strm << "I/O\t"           << in[ix].time << '\t'           << (in[ix].time - in[ix-1].time) << '\t'           << (out[ox].time - out[ox-1].time) << '\t'           << in[ix].extra << '\t'           << out[ox].extra << '\t'           << in[ix].depth << '\t'           << out[ox].depth << '\t'           << (in[ix].tick - in[0].tick) << '\t'           << (in[ix].tick - in[ix-1].tick) << '\t'           << (out[ox].tick - out[0].tick) << '\t'           << (out[ox].tick - out[ox-1].tick) << '\t'           << (out[ox].tick - in[ix].tick)           << '\n';      ox++;      ix++;    }  }}#endif/////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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