jitter.h

Go to the documentation of this file.
00001 /*
00002  * jitter.h
00003  *
00004  * Jitter buffer support
00005  *
00006  * Open H323 Library
00007  *
00008  * Copyright (c) 1999-2001 Equivalence Pty. Ltd.
00009  *
00010  * The contents of this file are subject to the Mozilla Public License
00011  * Version 1.0 (the "License"); you may not use this file except in
00012  * compliance with the License. You may obtain a copy of the License at
00013  * http://www.mozilla.org/MPL/
00014  *
00015  * Software distributed under the License is distributed on an "AS IS"
00016  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
00017  * the License for the specific language governing rights and limitations
00018  * under the License.
00019  *
00020  * The Original Code is Open H323 Library.
00021  *
00022  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
00023  *
00024  * Portions of this code were written with the assisance of funding from
00025  * Vovida Networks, Inc. http://www.vovida.com.
00026  *
00027  * Contributor(s): ______________________________________.
00028  *
00029  * $Revision: 22553 $
00030  * $Author: csoutheren $
00031  * $Date: 2009-05-07 08:56:06 +0000 (Thu, 07 May 2009) $
00032  */
00033 
00034 #ifndef OPAL_RTP_JITTER_H
00035 #define OPAL_RTP_JITTER_H
00036 
00037 #ifdef P_USE_PRAGMA
00038 #pragma interface
00039 #endif
00040 
00041 #include <opal/buildopts.h>
00042 
00043 #include <rtp/rtp.h>
00044 
00045 
00046 class RTP_JitterBuffer;
00047 class RTP_JitterBufferAnalyser;
00048 
00049 
00051 
00055 class OpalJitterBuffer : public PSafeObject
00056 {
00057   PCLASSINFO(OpalJitterBuffer, PSafeObject);
00058 
00059   public:
00062     OpalJitterBuffer(
00063       unsigned minJitterDelay, 
00064       unsigned maxJitterDelay, 
00065       unsigned timeUnits = 8,  
00066       PINDEX stackSize = 30000 
00067     );
00068     
00070     virtual ~OpalJitterBuffer();
00071 
00073     void PrintOn(ostream & strm  ) const;
00074 
00080     virtual PBoolean OnReadPacket    (
00081       RTP_DataFrame & frame,  
00082       PBoolean loop               
00083     ) = 0;
00084 
00085 //    PINDEX GetSize() const { return bufferSize; }
00088     void SetDelay(
00089       unsigned minJitterDelay, 
00090       unsigned maxJitterDelay  
00091     );
00092 
00093     void UseImmediateReduction(PBoolean state) { doJitterReductionImmediately = state; }
00094 
00100     virtual PBoolean ReadData(
00101       RTP_DataFrame & frame   
00102     );
00103 
00106     DWORD GetJitterTime() const { return currentJitterTime; }
00107 
00110     unsigned GetTimeUnits() const { return timeUnits; }
00111     
00114     DWORD GetPacketsTooLate() const { return packetsTooLate; }
00115 
00118     DWORD GetBufferOverruns() const { return bufferOverruns; }
00119 
00122     DWORD GetMaxConsecutiveMarkerBits() const { return maxConsecutiveMarkerBits; }
00123 
00126     void SetMaxConsecutiveMarkerBits(DWORD max) { maxConsecutiveMarkerBits = max; }
00127 
00130     virtual void Resume();
00131 
00132     PDECLARE_NOTIFIER(PThread, OpalJitterBuffer, JitterThreadMain);
00133 
00134     PBoolean WaitForTermination(const PTimeInterval & t)
00135     { 
00136       if (jitterThread == NULL) 
00137         return PTrue;
00138       shuttingDown = true;
00139       return jitterThread->WaitForTermination(t); 
00140     }
00141 
00142     bool IsEmpty() { return jitterBuffer.size() == 0; }
00143 
00144   protected:
00145     void Start(unsigned _minJitterTime, unsigned _maxJitterTime);
00146 
00147     PINDEX        bufferSize;
00148     DWORD         minJitterTime;
00149     DWORD         maxJitterTime;
00150     DWORD         maxConsecutiveMarkerBits;
00151 
00152     unsigned      timeUnits;
00153     DWORD         currentJitterTime;
00154     DWORD         packetsTooLate;
00155     unsigned      bufferOverruns;
00156     unsigned      consecutiveBufferOverruns;
00157     DWORD         consecutiveMarkerBits;
00158     PTimeInterval consecutiveEarlyPacketStartTime;
00159     DWORD         lastWriteTimestamp;
00160     PTimeInterval lastWriteTick;
00161     DWORD         jitterCalc;
00162     DWORD         targetJitterTime;
00163     unsigned      jitterCalcPacketCount;
00164     bool          doJitterReductionImmediately;
00165 
00166     class Entry : public RTP_DataFrame
00167     {
00168       public:
00169         Entry() : RTP_DataFrame(0, 512) { } // Allocate enough for 250ms of L16 audio, zero payload size
00170         PTimeInterval tick;
00171     };
00172 
00173     class FrameQueue : public std::deque<Entry *>
00174     {
00175       public:
00176         void resize(size_type _Newsize)
00177         { 
00178           while (size() < (size_t)_Newsize)
00179             push_back(new Entry);
00180           while (size() > (size_t)_Newsize) {
00181             delete front();
00182             pop_front();
00183           }
00184         }
00185 
00186         ~FrameQueue()
00187         { resize(0); }
00188     };
00189 
00190     FrameQueue freeFrames;
00191     FrameQueue jitterBuffer;
00192     inline Entry * GetNewest(bool pop) { Entry * e = jitterBuffer.back(); if (pop) jitterBuffer.pop_back(); return e; }
00193     inline Entry * GetOldest(bool pop) { Entry * e = jitterBuffer.front(); if (pop) jitterBuffer.pop_front(); return e; }
00194 
00195     Entry * currentFrame;    // storage of current frame
00196 
00197     PMutex bufferMutex;
00198     bool   shuttingDown;
00199     bool   preBuffering;
00200     bool   firstReadData;
00201 
00202     RTP_JitterBufferAnalyser * analyser;
00203 
00204     PThread * jitterThread;
00205     PINDEX    jitterStackSize;
00206 
00207     PBoolean Init(Entry * & currentReadFrame, PBoolean & markerWarning);
00208     PBoolean PreRead(Entry * & currentReadFrame, PBoolean & markerWarning);
00209     PBoolean OnRead(Entry * & currentReadFrame, PBoolean & markerWarning, PBoolean loop);
00210     void DeInit(Entry * & currentReadFrame, PBoolean & markerWarning);
00211 };
00212 
00214 
00216 class RTP_JitterBuffer : public OpalJitterBuffer
00217 {
00218     PCLASSINFO(RTP_JitterBuffer, OpalJitterBuffer);
00219 
00220  public:
00221     RTP_JitterBuffer(
00222       RTP_Session & session,   
00223       unsigned minJitterDelay, 
00224       unsigned maxJitterDelay, 
00225       unsigned timeUnits = 8,  
00226       PINDEX stackSize = 30000 
00227     );
00228 
00233     virtual PBoolean OnReadPacket(
00234       RTP_DataFrame & frame,  
00235       PBoolean loop           
00236     );
00237 
00238  protected:
00240    RTP_Session & session;
00241 };
00242 
00243 #endif // OPAL_RTP_JITTER_H
00244 
00245 

Generated on Mon Feb 1 00:25:49 2010 for OPAL by  doxygen 1.5.1