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 #include <ptlib/safecoll.h>
00045
00046
00047 class RTP_JitterBuffer;
00048 class RTP_JitterBufferAnalyser;
00049 class OpalRTPSession;
00050
00051
00053
00057 class OpalJitterBuffer : public PSafeObject
00058 {
00059 PCLASSINFO(OpalJitterBuffer, PSafeObject);
00060
00061 public:
00063 struct Init {
00064 Init(unsigned minDelay = 0, unsigned maxDelay = 0)
00065 : m_minJitterDelay(minDelay)
00066 , m_maxJitterDelay(maxDelay != 0 ? maxDelay : minDelay)
00067 , m_timeUnits(8)
00068 , m_packetSize(2048)
00069 { }
00070
00071 unsigned m_minJitterDelay;
00072 unsigned m_maxJitterDelay;
00073 unsigned m_timeUnits;
00074 PINDEX m_packetSize;
00075 };
00076
00082 OpalJitterBuffer(
00083 const Init & init
00084 );
00085
00088 virtual ~OpalJitterBuffer();
00090
00094 void PrintOn(
00095 ostream & strm
00096 ) const;
00098
00101
00102 virtual void Start() { }
00103
00106 void SetDelay(
00107 const Init & init
00108 );
00109
00112 void Reset();
00113
00116 virtual PBoolean WriteData(
00117 const RTP_DataFrame & frame,
00118 const PTimeInterval & tick = 0
00119 );
00120
00125 virtual PBoolean ReadData(
00126 RTP_DataFrame & frame,
00127 const PTimeInterval & tick = 0
00128 );
00129
00132 DWORD GetCurrentJitterDelay() const { return m_currentJitterDelay; }
00133
00136 DWORD GetMinJitterDelay() const { return m_minJitterDelay; }
00137
00140 DWORD GetMaxJitterDelay() const { return m_maxJitterDelay; }
00141
00144 unsigned GetTimeUnits() const { return m_timeUnits; }
00145
00148 DWORD GetPacketsTooLate() const { return m_packetsTooLate; }
00149
00152 DWORD GetBufferOverruns() const { return m_bufferOverruns; }
00153
00156 DWORD GetMaxConsecutiveMarkerBits() const { return m_maxConsecutiveMarkerBits; }
00157
00160 void SetMaxConsecutiveMarkerBits(DWORD max) { m_maxConsecutiveMarkerBits = max; }
00162
00163 protected:
00164 DWORD CalculateRequiredTimestamp(DWORD playOutTimestamp) const;
00165 bool AdjustCurrentJitterDelay(int delta);
00166
00167 unsigned m_timeUnits;
00168 PINDEX m_packetSize;
00169 DWORD m_minJitterDelay;
00170 DWORD m_maxJitterDelay;
00171 int m_jitterGrowTime;
00172 DWORD m_jitterShrinkPeriod;
00173
00174 int m_jitterShrinkTime;
00175 DWORD m_silenceShrinkPeriod;
00176 int m_silenceShrinkTime;
00177 DWORD m_jitterDriftPeriod;
00178
00179 int m_currentJitterDelay;
00180 DWORD m_packetsTooLate;
00181 DWORD m_bufferOverruns;
00182 DWORD m_consecutiveMarkerBits;
00183 DWORD m_maxConsecutiveMarkerBits;
00184 DWORD m_consecutiveLatePackets;
00185
00186 unsigned m_frameTimeCount;
00187 DWORD m_incomingFrameTime;
00188 int m_lastFrameTime[2];
00189 DWORD m_lastSequenceNum;
00190 DWORD m_lastTimestamp;
00191 DWORD m_lastSyncSource;
00192 DWORD m_bufferFilledTime;
00193 DWORD m_bufferLowTime;
00194 DWORD m_bufferEmptiedTime;
00195 int m_timestampDelta;
00196
00197 enum {
00198 e_SynchronisationStart,
00199 e_SynchronisationFill,
00200 e_SynchronisationShrink,
00201 e_SynchronisationDone
00202 } m_synchronisationState;
00203
00204 typedef std::map<DWORD, RTP_DataFrame> FrameMap;
00205 FrameMap m_frames;
00206 PMutex m_bufferMutex;
00207
00208 RTP_JitterBufferAnalyser * m_analyser;
00209 };
00210
00211
00215 class OpalJitterBufferThread : public OpalJitterBuffer
00216 {
00217 PCLASSINFO(OpalJitterBufferThread, OpalJitterBuffer);
00218 public:
00219 OpalJitterBufferThread(
00220 const Init & init
00221 );
00222 ~OpalJitterBufferThread();
00223
00225 virtual void Start();
00226
00233 virtual PBoolean ReadData(
00234 RTP_DataFrame & frame,
00235 const PTimeInterval & tick = 0
00236 );
00237
00242 virtual PBoolean OnReadPacket(
00243 RTP_DataFrame & frame
00244 ) = 0;
00245
00246 protected:
00247 PDECLARE_NOTIFIER(PThread, OpalJitterBufferThread, JitterThreadMain);
00248
00250 void WaitForThreadTermination();
00251
00252 PThread * m_jitterThread;
00253 bool m_running;
00254 };
00255
00256
00257 #endif // OPAL_RTP_JITTER_H
00258
00259