00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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 <rtp/rtp.h>
00042
00043 #include <opal/buildopts.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
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;
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