# 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: 21004 $
    00030  * $Author: rjongbloed $
    00031  * $Date: 2008-09-16 07:08:56 +0000 (Tue, 16 Sep 2008) $
    00032  */
    00033
    00034 #ifndef __OPAL_JITTER_H
    00035 #define __OPAL_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 PObject
    00056 {
    00057   PCLASSINFO(OpalJitterBuffer, PObject);
    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(PHandleAggregator * aggregator = NULL);
    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         PTimeInterval tick;
    00170     };
    00171
    00172     class FrameQueue : public std::deque<Entry *>
    00173     {
    00174       public:
    00175         void resize(size_type _Newsize)
    00176         {
    00177           while (size() < (size_t)_Newsize)
    00178             push_back(new Entry);
    00179           while (size() > (size_t)_Newsize) {
    00180             delete front();
    00181             pop_front();
    00182           }
    00183         }
    00184
    00185         ~FrameQueue()
    00186         { resize(0); }
    00187     };
    00188
    00189     FrameQueue freeFrames;
    00190     FrameQueue jitterBuffer;
    00191     inline Entry * GetNewest(bool pop) { Entry * e = jitterBuffer.back(); if (pop) jitterBuffer.pop_back(); return e; }
    00192     inline Entry * GetOldest(bool pop) { Entry * e = jitterBuffer.front(); if (pop) jitterBuffer.pop_front(); return e; }
    00193
    00194     Entry * currentFrame;    // storage of current frame
    00195
    00196     PMutex bufferMutex;
    00197     bool   shuttingDown;
    00198     bool   preBuffering;
    00199     bool   firstReadData;
    00200
    00201     RTP_JitterBufferAnalyser * analyser;
    00202
    00203     PThread * jitterThread;
    00204     PINDEX    jitterStackSize;
    00205
    00206     PBoolean Init(Entry * & currentReadFrame, PBoolean & markerWarning);
    00207     PBoolean PreRead(Entry * & currentReadFrame, PBoolean & markerWarning);
    00208     PBoolean OnRead(Entry * & currentReadFrame, PBoolean & markerWarning, PBoolean loop);
    00209     void DeInit(Entry * & currentReadFrame, PBoolean & markerWarning);
    00210 };
    00211
    00213
    00215 class RTP_JitterBuffer : public OpalJitterBuffer
    00216 {
    00217     PCLASSINFO(RTP_JitterBuffer, OpalJitterBuffer);
    00218
    00219  public:
    00220     RTP_JitterBuffer(
    00221             RTP_Session & session,
    00222             unsigned minJitterDelay,
    00223             unsigned maxJitterDelay,
    00224             unsigned timeUnits = 8,
    00225             PINDEX stackSize = 30000
    00226             );
    00227
    00232     virtual PBoolean OnReadPacket    (
    00233       RTP_DataFrame & frame,
    00234       PBoolean loop
    00235         ) ;
    00236
    00237  protected:
    00239    RTP_Session & session;
    00240 };
    00241
    00242 #endif // __OPAL_JITTER_H
    00243
    00244