rtptimeutilities.h
Go to the documentation of this file.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
00037 #ifndef RTPTIMEUTILITIES_H
00038
00039 #define RTPTIMEUTILITIES_H
00040
00041 #include "rtpconfig.h"
00042 #include "rtptypes.h"
00043 #ifndef WIN32
00044 #include <sys/time.h>
00045 #include <time.h>
00046 #else
00047 #ifndef _WIN32_WCE
00048 #include <sys/timeb.h>
00049 #endif // _WIN32_WINCE
00050 #endif // WIN32
00051
00052 #define RTP_NTPTIMEOFFSET 2208988800UL
00053
00058 class RTPNTPTime
00059 {
00060 public:
00062 RTPNTPTime(uint32_t m,uint32_t l) { msw = m ; lsw = l; }
00063
00065 uint32_t GetMSW() const { return msw; }
00066
00068 uint32_t GetLSW() const { return lsw; }
00069 private:
00070 uint32_t msw,lsw;
00071 };
00072
00077 class RTPTime
00078 {
00079 public:
00084 static RTPTime CurrentTime();
00085
00087 static void Wait(const RTPTime &delay);
00088
00090 RTPTime(double t);
00091
00097 RTPTime(RTPNTPTime ntptime);
00098
00100 RTPTime(uint32_t seconds,uint32_t microseconds) { sec = seconds; microsec = microseconds; }
00101
00103 uint32_t GetSeconds() const { return sec; }
00104
00106 uint32_t GetMicroSeconds() const { return microsec; }
00107
00109 double GetDouble() const { return (((double)sec)+(((double)microsec)/1000000.0)); }
00110
00112 RTPNTPTime GetNTPTime() const;
00113
00114 RTPTime &operator-=(const RTPTime &t);
00115 RTPTime &operator+=(const RTPTime &t);
00116 bool operator<(const RTPTime &t) const;
00117 bool operator>(const RTPTime &t) const;
00118 bool operator<=(const RTPTime &t) const;
00119 bool operator>=(const RTPTime &t) const;
00120 private:
00121 #if (defined(WIN32) || defined(_WIN32_WCE))
00122 static inline unsigned __int64 CalculateMicroseconds(unsigned __int64 performancecount,unsigned __int64 performancefrequency);
00123 #endif // WIN32 || _WIN32_WCE
00124
00125 uint32_t sec,microsec;
00126 };
00127
00128 inline RTPTime::RTPTime(double t)
00129 {
00130 sec = (uint32_t)t;
00131
00132 double t2 = t-((double)sec);
00133 t2 *= 1000000.0;
00134 microsec = (uint32_t)t2;
00135 }
00136
00137 inline RTPTime::RTPTime(RTPNTPTime ntptime)
00138 {
00139 if (ntptime.GetMSW() < RTP_NTPTIMEOFFSET)
00140 {
00141 sec = 0;
00142 microsec = 0;
00143 }
00144 else
00145 {
00146 sec = ntptime.GetMSW() - RTP_NTPTIMEOFFSET;
00147
00148 double x = (double)ntptime.GetLSW();
00149 x /= (65536.0*65536.0);
00150 x *= 1000000.0;
00151 microsec = (uint32_t)x;
00152 }
00153 }
00154
00155 #if (defined(WIN32) || defined(_WIN32_WCE))
00156
00157 inline unsigned __int64 RTPTime::CalculateMicroseconds(unsigned __int64 performancecount,unsigned __int64 performancefrequency)
00158 {
00159 unsigned __int64 f = performancefrequency;
00160 unsigned __int64 a = performancecount;
00161 unsigned __int64 b = a/f;
00162 unsigned __int64 c = a%f;
00163
00164 return b*1000000ui64+(c*1000000ui64)/f;
00165 }
00166
00167 inline RTPTime RTPTime::CurrentTime()
00168 {
00169 static int inited = 0;
00170 static unsigned __int64 microseconds, initmicroseconds;
00171 static LARGE_INTEGER performancefrequency;
00172
00173 unsigned __int64 emulate_microseconds, microdiff;
00174 SYSTEMTIME systemtime;
00175 FILETIME filetime;
00176
00177 LARGE_INTEGER performancecount;
00178
00179 QueryPerformanceCounter(&performancecount);
00180
00181 if(!inited){
00182 inited = 1;
00183 QueryPerformanceFrequency(&performancefrequency);
00184 GetSystemTime(&systemtime);
00185 SystemTimeToFileTime(&systemtime,&filetime);
00186 microseconds = ( ((unsigned __int64)(filetime.dwHighDateTime) << 32) + (unsigned __int64)(filetime.dwLowDateTime) ) / 10ui64;
00187 microseconds-= 11644473600000000ui64;
00188 initmicroseconds = CalculateMicroseconds(performancecount.QuadPart, performancefrequency.QuadPart);
00189 }
00190
00191 emulate_microseconds = CalculateMicroseconds(performancecount.QuadPart, performancefrequency.QuadPart);
00192
00193 microdiff = emulate_microseconds - initmicroseconds;
00194
00195 return RTPTime((uint32_t)((microseconds + microdiff) / 1000000ui64),((uint32_t)((microseconds + microdiff) % 1000000ui64)));
00196 }
00197
00198 inline void RTPTime::Wait(const RTPTime &delay)
00199 {
00200 DWORD t;
00201
00202 t = ((DWORD)delay.GetSeconds())*1000+(((DWORD)delay.GetMicroSeconds())/1000);
00203 Sleep(t);
00204 }
00205
00206 class RTPTimeInitializer
00207 {
00208 public:
00209 RTPTimeInitializer();
00210 void Dummy() { dummy++; }
00211 private:
00212 int dummy;
00213 };
00214
00215 extern RTPTimeInitializer timeinit;
00216
00217 #else // unix style
00218
00219 inline RTPTime RTPTime::CurrentTime()
00220 {
00221 struct timeval tv;
00222
00223 gettimeofday(&tv,0);
00224 return RTPTime((uint32_t)tv.tv_sec,(uint32_t)tv.tv_usec);
00225 }
00226
00227 inline void RTPTime::Wait(const RTPTime &delay)
00228 {
00229 struct timespec req,rem;
00230
00231 req.tv_sec = (time_t)delay.sec;
00232 req.tv_nsec = ((long)delay.microsec)*1000;
00233 nanosleep(&req,&rem);
00234 }
00235
00236 #endif // WIN32
00237
00238 inline RTPTime &RTPTime::operator-=(const RTPTime &t)
00239 {
00240 sec -= t.sec;
00241 if (t.microsec > microsec)
00242 {
00243 sec--;
00244 microsec += 1000000;
00245 }
00246 microsec -= t.microsec;
00247 return *this;
00248 }
00249
00250 inline RTPTime &RTPTime::operator+=(const RTPTime &t)
00251 {
00252 sec += t.sec;
00253 microsec += t.microsec;
00254 if (microsec >= 1000000)
00255 {
00256 sec++;
00257 microsec -= 1000000;
00258 }
00259 return *this;
00260 }
00261
00262 inline RTPNTPTime RTPTime::GetNTPTime() const
00263 {
00264 uint32_t msw = sec+RTP_NTPTIMEOFFSET;
00265 uint32_t lsw;
00266 double x;
00267
00268 x = microsec/1000000.0;
00269 x *= (65536.0*65536.0);
00270 lsw = (uint32_t)x;
00271
00272 return RTPNTPTime(msw,lsw);
00273 }
00274
00275 inline bool RTPTime::operator<(const RTPTime &t) const
00276 {
00277 if (sec < t.sec)
00278 return true;
00279 if (sec > t.sec)
00280 return false;
00281 if (microsec < t.microsec)
00282 return true;
00283 return false;
00284 }
00285
00286 inline bool RTPTime::operator>(const RTPTime &t) const
00287 {
00288 if (sec > t.sec)
00289 return true;
00290 if (sec < t.sec)
00291 return false;
00292 if (microsec > t.microsec)
00293 return true;
00294 return false;
00295 }
00296
00297 inline bool RTPTime::operator<=(const RTPTime &t) const
00298 {
00299 if (sec < t.sec)
00300 return true;
00301 if (sec > t.sec)
00302 return false;
00303 if (microsec <= t.microsec)
00304 return true;
00305 return false;
00306 }
00307
00308 inline bool RTPTime::operator>=(const RTPTime &t) const
00309 {
00310 if (sec > t.sec)
00311 return true;
00312 if (sec < t.sec)
00313 return false;
00314 if (microsec >= t.microsec)
00315 return true;
00316 return false;
00317 }
00318 #endif // RTPTIMEUTILITIES_H
00319