📄 jitter.cxx
字号:
/* * jitter.cxx * * Jitter buffer support * * Open H323 Library * * Copyright (c) 1998-2000 Equivalence Pty. Ltd. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Open H323 Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Portions of this code were written with the assisance of funding from * Vovida Networks, Inc. http://www.vovida.com. * * Contributor(s): ______________________________________. * * $Log: jitter.cxx,v $ * Revision 1.17 2000/05/30 06:53:04 robertj * Fixed bug where jitter buffer needs to be restarted, eg Cisco double use of session. * * Revision 1.16 2000/05/25 02:26:12 robertj * Added ignore of marker bits on broken clients that sets it on every RTP packet. * * Revision 1.15 2000/05/25 00:35:37 robertj * Fixed rare crashing bug in jitter buffer caused by our of order packet. * * Revision 1.14 2000/05/16 07:37:41 robertj * Initialised preBuffering flag just in case sender does not set RTP marker bit. * * Revision 1.13 2000/05/08 14:05:58 robertj * Increased log level of big jitter debug output to level 5. * * Revision 1.12 2000/05/05 02:54:15 robertj * Fixed memory leak just introduced in jitter buffer. * * Revision 1.11 2000/05/04 11:52:35 robertj * Added Packets Too Late statistics, requiring major rearrangement of jitter * buffer code, not also changes semantics of codec Write() function slightly. * * Revision 1.10 2000/05/02 04:32:27 robertj * Fixed copyright notice comment. * * Revision 1.9 2000/05/01 09:11:04 robertj * Fixed removal of analysis code on No Trace version. * * Revision 1.8 2000/05/01 06:04:33 robertj * More jitter buffer debugging. * * Revision 1.7 2000/04/10 18:55:46 robertj * Changed RTP data receive tp be more forgiving, will process packet even if payload type is wrong. * * Revision 1.6 2000/03/31 20:10:43 robertj * Fixed problem with insufficient jitter buffer frames being allocated. * Fixed "center in frame" change in previous version. * * Revision 1.5 2000/03/23 03:08:52 robertj * Changed jitter buffer so asumes output double buffering and centers output in time frames. * * Revision 1.4 2000/03/21 03:06:50 robertj * Changes to make RTP TX of exact numbers of frames in some codecs. * * Revision 1.3 2000/03/20 20:51:47 robertj * Fixed possible buffer overrun problem in RTP_DataFrames * * Revision 1.2 1999/12/29 01:18:07 craigs * Fixed problem with codecs other than G.711 not working after reorganisation * * Revision 1.1 1999/12/23 23:02:36 robertj * File reorganision for separating RTP from H.323 and creation of LID for VPB support. * */#include <ptlib.h>#include "jitter.h"#if PTRACINGclass RTP_JitterBufferAnalyser : public PObject{ PCLASSINFO(RTP_JitterBufferAnalyser, PObject); public: RTP_JitterBufferAnalyser(); void In(DWORD time, unsigned depth, const char * extra); void Out(DWORD time, unsigned depth, const char * extra); void PrintOn(ostream & strm) const; struct Info { Info() { } DWORD time; PTimeInterval tick; int depth; const char * extra; } in[1000], out[1000]; PINDEX inPos, outPos;};#endif#define new PNEW/////////////////////////////////////////////////////////////////////////////RTP_JitterBuffer::RTP_JitterBuffer(RTP_Session & sess, unsigned jitterDelay) : PThread(30000, NoAutoDeleteThread), session(sess){ // Jitter buffer is a queue of frames waiting for playback, a list of // free frames, and a couple of place holders for the frame that is // currently beeing read from the RTP transport or written to the codec. oldestFrame = newestFrame = currentWriteFrame = NULL; // Calculate the maximum amount of timestamp units for the jitter buffer maxJitterTime = jitterDelay; // Calculate number of frames to allocate, we make the assumption that the // smallest packet we can possibly get is 5ms long (assuming audio 8kHz unit). bufferSize = jitterDelay/40+1; // Nothing in the buffer so far currentDepth = 0; packetsTooLate = 0; maxConsecutiveMarkerBits = 10; consecutiveMarkerBits = 0; shuttingDown = FALSE; preBuffering = TRUE; // Allocate the frames and put them all into the free list freeFrames = new Entry; freeFrames->next = freeFrames->prev = NULL; for (PINDEX i = 0; i < bufferSize; i++) { Entry * frame = new Entry; frame->prev = NULL; frame->next = freeFrames; freeFrames->prev = frame; freeFrames = frame; } PTRACE(2, "RTP\tJitter buffer created:" " size=" << bufferSize << " delay=" << maxJitterTime);#if PTRACING analyser = new RTP_JitterBufferAnalyser;#else analyser = NULL;#endif // Start reading data from RTP session Resume();}RTP_JitterBuffer::~RTP_JitterBuffer(){ PTRACE(3, "RTP\tRemoving jitter buffer"); shuttingDown = TRUE; WaitForTermination(); bufferMutex.Wait(); // Free up all the memory allocated while (oldestFrame != NULL) { Entry * frame = oldestFrame; oldestFrame = oldestFrame->next; delete frame; } while (freeFrames != NULL) { Entry * frame = freeFrames; freeFrames = freeFrames->next; delete frame; } delete currentWriteFrame; bufferMutex.Signal();#if PTRACING PTRACE(5, "Jitter buffer analysis: size=" << bufferSize << " time=" << maxJitterTime << '\n' << *analyser); delete analyser;#endif}void RTP_JitterBuffer::SetDelay( unsigned delay){ bufferMutex.Wait(); if (shuttingDown) WaitForTermination(); maxJitterTime = delay; PINDEX newBufferSize = maxJitterTime/40+1; while (bufferSize < newBufferSize) { Entry * frame = new Entry; frame->prev = NULL; frame->next = freeFrames; freeFrames->prev = frame; freeFrames = frame; bufferSize++; } if (IsTerminated()) { packetsTooLate = 0; consecutiveMarkerBits = 0; shuttingDown = FALSE; preBuffering = TRUE; PTRACE(2, "RTP\tJitter buffer restarted:" " size=" << bufferSize << " delay=" << maxJitterTime); Restart(); } bufferMutex.Signal();}void RTP_JitterBuffer::Main(){ PTRACE(3, "RTP\tJitter RTP receive thread started"); bufferMutex.Wait(); for (;;) { // Get the next free frame available for use for reading from the RTP // transport. Place it into a parking spot. Entry * currentReadFrame; if (freeFrames != NULL) { // Take the next free frame and make it the current for reading currentReadFrame = freeFrames; freeFrames = freeFrames->next; if (freeFrames != NULL) freeFrames->prev = NULL; } else { // We have a full jitter buffer, need a new frame so take the oldest one currentReadFrame = oldestFrame; oldestFrame = oldestFrame->next; if (oldestFrame != NULL) oldestFrame->prev = NULL; currentDepth--; packetsTooLate++; } currentReadFrame->next = NULL; bufferMutex.Signal(); // Keep reading from the RTP transport frames if (!session.ReadData(*currentReadFrame)) { delete currentReadFrame; // Destructor won't delete this one, so do it here. shuttingDown = TRUE; // Flag to stop the reading side thread PTRACE(3, "RTP\tJitter RTP receive thread ended");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -