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 struct FrameQueue : public PList<Entry>
00170 {
00171 FrameQueue() { DisallowDeleteObjects(); }
00172 ~FrameQueue() { AllowDeleteObjects(); }
00173 };
00174 FrameQueue freeFrames;
00175 FrameQueue jitterBuffer;
00176 Entry * GetNewest(bool pop);
00177 Entry * GetOldest(bool pop);
00178
00179 Entry * currentFrame;
00180
00181 PMutex bufferMutex;
00182 bool preBuffering;
00183 bool firstReadData;
00184
00185 RTP_JitterBufferAnalyser * analyser;
00186 };
00187
00188
00192 class OpalJitterBufferThread : public OpalJitterBuffer
00193 {
00194 PCLASSINFO(OpalJitterBufferThread, OpalJitterBuffer);
00195 public:
00196 OpalJitterBufferThread(
00197 unsigned minJitterDelay,
00198 unsigned maxJitterDelay,
00199 unsigned timeUnits = 8,
00200 PINDEX packetSize = 2048
00201 );
00202 ~OpalJitterBufferThread();
00203
00210 virtual PBoolean ReadData(
00211 RTP_DataFrame & frame
00212 );
00213
00218 virtual PBoolean OnReadPacket(
00219 RTP_DataFrame & frame,
00220 PBoolean loop
00221 ) = 0;
00222
00223 protected:
00224 PDECLARE_NOTIFIER(PThread, OpalJitterBufferThread, JitterThreadMain);
00225
00227 void StartThread();
00228
00230 void WaitForThreadTermination();
00231
00232 PThread * m_jitterThread;
00233 bool m_running;
00234 };
00235
00236
00238
00241 class RTP_JitterBuffer : public OpalJitterBufferThread
00242 {
00243 PCLASSINFO(RTP_JitterBuffer, OpalJitterBufferThread);
00244 public:
00245 RTP_JitterBuffer(
00246 RTP_Session & session,
00247 unsigned minJitterDelay,
00248 unsigned maxJitterDelay,
00249 unsigned timeUnits = 8,
00250 PINDEX packetSize = 2048
00251 );
00252 ~RTP_JitterBuffer();
00253
00258 virtual PBoolean OnReadPacket(
00259 RTP_DataFrame & frame,
00260 PBoolean loop
00261 );
00262
00263 protected:
00265 RTP_Session & session;
00266 };
00267
00268 #endif // OPAL_RTP_JITTER_H
00269
00270