1 /* 2 * jitter.h 3 * 4 * Jitter buffer support 5 * 6 * Open H323 Library 7 * 8 * Copyright (c) 1999-2001 Equivalence Pty. Ltd. 9 * 10 * The contents of this file are subject to the Mozilla Public License 11 * Version 1.0 (the "License"); you may not use this file except in 12 * compliance with the License. You may obtain a copy of the License at 13 * http://www.mozilla.org/MPL/ 14 * 15 * Software distributed under the License is distributed on an "AS IS" 16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 17 * the License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * The Original Code is Open H323 Library. 21 * 22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd. 23 * 24 * Portions of this code were written with the assisance of funding from 25 * Vovida Networks, Inc. http://www.vovida.com. 26 * 27 * Contributor(s): ______________________________________. 28 * 29 * $Revision: 28053 $ 30 * $Author: rjongbloed $ 31 * $Date: 2012-07-18 02:50:22 -0500 (Wed, 18 Jul 2012) $ 32 */ 33 34 #ifndef OPAL_RTP_JITTER_H 35 #define OPAL_RTP_JITTER_H 36 37 #ifdef P_USE_PRAGMA 38 #pragma interface 39 #endif 40 41 #include <opal/buildopts.h> 42 43 #include <rtp/rtp.h> 44 45 46 class RTP_JitterBuffer; 47 class RTP_JitterBufferAnalyser; 48 49 50 /////////////////////////////////////////////////////////////////////////////// 51 /**This is an Abstract jitter buffer, which can be used simply in any 52 application. The user is required to use a descendant of this class, and 53 provide a "OnReadPacket" method, so that network packets can be placed in 54 this class instance */ 55 class OpalJitterBuffer : public PSafeObject 56 { 57 PCLASSINFO(OpalJitterBuffer, PSafeObject); 58 59 public: 60 /**@name Construction */ 61 //@{ 62 /**Constructor for this jitter buffer. The size of this buffer can be 63 altered later with the SetDelay method 64 */ 65 OpalJitterBuffer( 66 unsigned minJitterDelay, ///< Minimum delay in RTP timestamp units 67 unsigned maxJitterDelay, ///< Maximum delay in RTP timestamp units 68 unsigned timeUnits = 8, ///< Time units, usually 8 or 16 69 PINDEX packetSize = 2048 ///< Max RTP packet size 70 ); 71 72 /** Destructor, which closes this down and deletes the internal list of frames 73 */ 74 virtual ~OpalJitterBuffer(); 75 //@} 76 77 /**@name Overrides from PObject */ 78 //@{ 79 /**Report the statistics for this jitter instance */ 80 void PrintOn( 81 ostream & strm 82 ) const; 83 //@} 84 85 /**@name Operations */ 86 //@{ 87 /**Set the maximum delay the jitter buffer will operate to. 88 */ 89 void SetDelay( 90 unsigned minJitterDelay, ///< Minimum delay in RTP timestamp units 91 unsigned maxJitterDelay, ///< Maximum delay in RTP timestamp units 92 PINDEX packetSize = 2048 ///< Max RTP packet size 93 ); 94 95 /**Reset jitter buffer. 96 */ 97 void Reset(); 98 99 /**Write data frame from the RTP channel. 100 */ 101 virtual PBoolean WriteData( 102 const RTP_DataFrame & frame, ///< Frame to feed into jitter buffer 103 const PTimeInterval & tick = 0 ///< Real time tick for packet arrival 104 ); 105 106 /**Read a data frame from the jitter buffer. 107 This function never blocks. If no data is available, an RTP packet 108 with zero payload size is returned. 109 */ 110 virtual PBoolean ReadData( 111 RTP_DataFrame & frame, ///< Frame to extract from jitter buffer 112 const PTimeInterval & tick = 0 ///< Real time tick for packet removal 113 ); 114 115 /**Get current delay for jitter buffer. 116 */ GetCurrentJitterDelay()117 DWORD GetCurrentJitterDelay() const { return m_currentJitterDelay; } 118 119 /**Get minimum delay for jitter buffer. 120 */ GetMinJitterDelay()121 DWORD GetMinJitterDelay() const { return m_minJitterDelay; } 122 123 /**Get maximum delay for jitter buffer. 124 */ GetMaxJitterDelay()125 DWORD GetMaxJitterDelay() const { return m_maxJitterDelay; } 126 127 /**Get time units. 128 */ GetTimeUnits()129 unsigned GetTimeUnits() const { return m_timeUnits; } 130 131 /**Get total number received packets too late to go into jitter buffer. 132 */ GetPacketsTooLate()133 DWORD GetPacketsTooLate() const { return m_packetsTooLate; } 134 135 /**Get total number received packets that overran the jitter buffer. 136 */ GetBufferOverruns()137 DWORD GetBufferOverruns() const { return m_bufferOverruns; } 138 139 /**Get maximum consecutive marker bits before buffer starts to ignore them. 140 */ GetMaxConsecutiveMarkerBits()141 DWORD GetMaxConsecutiveMarkerBits() const { return m_maxConsecutiveMarkerBits; } 142 143 /**Set maximum consecutive marker bits before buffer starts to ignore them. 144 */ SetMaxConsecutiveMarkerBits(DWORD max)145 void SetMaxConsecutiveMarkerBits(DWORD max) { m_maxConsecutiveMarkerBits = max; } 146 //@} 147 148 protected: 149 DWORD CalculateRequiredTimestamp(DWORD playOutTimestamp) const; 150 bool AdjustCurrentJitterDelay(int delta); 151 152 unsigned m_timeUnits; 153 PINDEX m_packetSize; 154 DWORD m_minJitterDelay; ///< Minimum jitter delay in timestamp units 155 DWORD m_maxJitterDelay; ///< Maximum jitter delay in timestamp units 156 int m_jitterGrowTime; ///< Amaint to increase jitter delay by when get "late" packet 157 DWORD m_jitterShrinkPeriod; ///< Period (in timestamp units) over which buffer is 158 ///< consistently filled before shrinking 159 int m_jitterShrinkTime; ///< Amount to shrink jitter delay by if consistently filled 160 DWORD m_silenceShrinkPeriod; ///< Reduce jitter delay is silent for this long 161 int m_silenceShrinkTime; ///< Amount to shrink jitter delay by if consistently silent 162 DWORD m_jitterDriftPeriod; 163 164 int m_currentJitterDelay; 165 DWORD m_packetsTooLate; 166 DWORD m_bufferOverruns; 167 DWORD m_consecutiveMarkerBits; 168 DWORD m_maxConsecutiveMarkerBits; 169 DWORD m_consecutiveLatePackets; 170 171 DWORD m_averageFrameTime; 172 DWORD m_lastTimestamp; 173 DWORD m_lastSyncSource; 174 DWORD m_bufferFilledTime; 175 DWORD m_bufferLowTime; 176 DWORD m_bufferEmptiedTime; 177 int m_timestampDelta; 178 179 enum { 180 e_SynchronisationStart, 181 e_SynchronisationFill, 182 e_SynchronisationShrink, 183 e_SynchronisationDone 184 } m_synchronisationState; 185 186 typedef std::map<DWORD, RTP_DataFrame> FrameMap; 187 FrameMap m_frames; 188 PMutex m_bufferMutex; 189 190 RTP_JitterBufferAnalyser * m_analyser; 191 }; 192 193 194 /**A descendant of the OpalJitterBuffer that starts a thread to read 195 from something continuously and feed it into the jitter buffer. 196 */ 197 class OpalJitterBufferThread : public OpalJitterBuffer 198 { 199 PCLASSINFO(OpalJitterBufferThread, OpalJitterBuffer); 200 public: 201 OpalJitterBufferThread( 202 unsigned minJitterDelay, ///< Minimum delay in RTP timestamp units 203 unsigned maxJitterDelay, ///< Maximum delay in RTP timestamp units 204 unsigned timeUnits = 8, ///< Time units, usually 8 or 16 205 PINDEX packetSize = 2048 ///< Max RTP packet size 206 ); 207 ~OpalJitterBufferThread(); 208 209 /**Read a data frame from the jitter buffer. 210 This function never blocks. If no data is available, an RTP packet 211 with zero payload size is returned. 212 213 Override of base class so can terminate caller when shutting down. 214 */ 215 virtual PBoolean ReadData( 216 RTP_DataFrame & frame ///< Frame to extract from jitter buffer 217 ); 218 219 /**This class instance collects data from the outside world in this 220 method. 221 222 @return true on successful read, false on faulty read. */ 223 virtual PBoolean OnReadPacket( 224 RTP_DataFrame & frame ///< Frame read from the RTP session 225 ) = 0; 226 227 void StartThread(); 228 229 protected: 230 PDECLARE_NOTIFIER(PThread, OpalJitterBufferThread, JitterThreadMain); 231 232 /// Internal function to be called from derived class destructor 233 void WaitForThreadTermination(); 234 235 PThread * m_jitterThread; 236 bool m_running; 237 }; 238 239 240 ///////////////////////////////////////////////////////////////////////////// 241 /**A descendant of the OpalJitterBuffer that reads RTP_DataFrame instances 242 from the RTP_Sessions 243 */ 244 class RTP_JitterBuffer : public OpalJitterBufferThread 245 { 246 PCLASSINFO(RTP_JitterBuffer, OpalJitterBufferThread); 247 public: 248 RTP_JitterBuffer( 249 RTP_Session & session, ///< Associated RTP session tor ead data from 250 unsigned minJitterDelay, ///< Minimum delay in RTP timestamp units 251 unsigned maxJitterDelay, ///< Maximum delay in RTP timestamp units 252 unsigned timeUnits = 8, ///< Time units, usually 8 or 16 253 PINDEX packetSize = 2048 ///< Max RTP packet size 254 ); 255 ~RTP_JitterBuffer(); 256 257 /**This class instance collects data from the outside world in this 258 method. 259 260 @return true on successful read, false on faulty read. */ 261 virtual PBoolean OnReadPacket( 262 RTP_DataFrame & frame ///< Frame read from the RTP session 263 ); 264 265 protected: 266 /**This class extracts data from the outside world by reading from this session variable */ 267 RTP_Session & m_session; 268 }; 269 270 #endif // OPAL_RTP_JITTER_H 271 272 273 ///////////////////////////////////////////////////////////////////////////// 274