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_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:
00065 OpalJitterBuffer(
00066 unsigned minJitterDelay,
00067 unsigned maxJitterDelay,
00068 unsigned timeUnits = 8,
00069 PINDEX packetSize = 2048
00070 );
00071
00074 virtual ~OpalJitterBuffer();
00076
00080 void PrintOn(
00081 ostream & strm
00082 ) const;
00084
00089 void SetDelay(
00090 unsigned minJitterDelay,
00091 unsigned maxJitterDelay,
00092 PINDEX packetSize = 2048
00093 );
00094
00098 void Reset() { m_resetJitterBufferNow = true; }
00099
00102 virtual PBoolean WriteData(
00103 const RTP_DataFrame & frame
00104 );
00105
00110 virtual PBoolean ReadData(
00111 RTP_DataFrame & frame
00112 );
00113
00116 DWORD GetJitterTime() const { return currentJitterTime; }
00117
00120 unsigned GetTimeUnits() const { return timeUnits; }
00121
00124 DWORD GetPacketsTooLate() const { return packetsTooLate; }
00125
00128 DWORD GetBufferOverruns() const { return bufferOverruns; }
00129
00132 DWORD GetMaxConsecutiveMarkerBits() const { return maxConsecutiveMarkerBits; }
00133
00136 void SetMaxConsecutiveMarkerBits(DWORD max) { maxConsecutiveMarkerBits = max; }
00138
00139 protected:
00140 class Entry : public RTP_DataFrame
00141 {
00142 public:
00143 Entry(PINDEX sz) : RTP_DataFrame(0, sz) { }
00144 PTimeInterval tick;
00145 };
00146 OpalJitterBuffer::Entry * GetAvailableEntry();
00147 void InternalWriteData(OpalJitterBuffer::Entry * availableEntry);
00148
00149 DWORD minJitterTime;
00150 DWORD maxJitterTime;
00151 unsigned timeUnits;
00152 PINDEX bufferSize;
00153 DWORD maxConsecutiveMarkerBits;
00154
00155 DWORD currentJitterTime;
00156 DWORD packetsTooLate;
00157 unsigned bufferOverruns;
00158 unsigned consecutiveBufferOverruns;
00159 DWORD consecutiveMarkerBits;
00160 bool markerWarning;
00161 PTimeInterval consecutiveEarlyPacketStartTime;
00162 DWORD lastWriteTimestamp;
00163 PTimeInterval lastWriteTick;
00164 DWORD jitterCalc;
00165 DWORD targetJitterTime;
00166 unsigned jitterCalcPacketCount;
00167 bool m_resetJitterBufferNow;
00168
00169 class FrameQueue : public std::deque<Entry *>
00170 {
00171 public:
00172 void resize(size_type _Newsize, PINDEX packetSize)
00173 {
00174 while (size() < (size_t)_Newsize)
00175 push_back(new Entry(packetSize));
00176 while (size() > (size_t)_Newsize) {
00177 delete front();
00178 pop_front();
00179 }
00180 }
00181
00182 ~FrameQueue()
00183 { resize(0, 0); }
00184 };
00185
00186 FrameQueue freeFrames;
00187 FrameQueue jitterBuffer;
00188 inline Entry * GetNewest(bool pop) { Entry * e = jitterBuffer.back(); if (pop) jitterBuffer.pop_back(); return e; }
00189 inline Entry * GetOldest(bool pop) { Entry * e = jitterBuffer.front(); if (pop) jitterBuffer.pop_front(); return e; }
00190
00191 Entry * currentFrame;
00192
00193 PMutex bufferMutex;
00194 bool shuttingDown;
00195 bool preBuffering;
00196 bool firstReadData;
00197
00198 RTP_JitterBufferAnalyser * analyser;
00199 };
00200
00201
00205 class OpalJitterBufferThread : public OpalJitterBuffer
00206 {
00207 PCLASSINFO(OpalJitterBufferThread, OpalJitterBuffer);
00208 public:
00209 OpalJitterBufferThread(
00210 unsigned minJitterDelay,
00211 unsigned maxJitterDelay,
00212 unsigned timeUnits = 8,
00213 PINDEX packetSize = 2048
00214 );
00215 ~OpalJitterBufferThread();
00216
00217 virtual void Resume();
00218
00219 virtual PBoolean OnReadPacket(RTP_DataFrame & frame, PBoolean loop) = 0;
00220
00221 protected:
00222 PDECLARE_NOTIFIER(PThread, OpalJitterBufferThread, JitterThreadMain);
00223
00224 PThread * jitterThread;
00225 };
00226
00227
00229
00232 class RTP_JitterBuffer : public OpalJitterBufferThread
00233 {
00234 PCLASSINFO(RTP_JitterBuffer, OpalJitterBufferThread);
00235 public:
00236 RTP_JitterBuffer(
00237 RTP_Session & session,
00238 unsigned minJitterDelay,
00239 unsigned maxJitterDelay,
00240 unsigned timeUnits = 8,
00241 PINDEX packetSize = 2048
00242 );
00243
00248 virtual PBoolean OnReadPacket(
00249 RTP_DataFrame & frame,
00250 PBoolean loop
00251 );
00252
00253 protected:
00255 RTP_Session & session;
00256 };
00257
00258 #endif // OPAL_RTP_JITTER_H
00259
00260