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 uint32_t sec,microsec;
00122 };
00123
00124 inline RTPTime::RTPTime(double t)
00125 {
00126 sec = (uint32_t)t;
00127
00128 double t2 = t-((double)sec);
00129 t2 *= 1000000.0;
00130 microsec = (uint32_t)t2;
00131 }
00132
00133 inline RTPTime::RTPTime(RTPNTPTime ntptime)
00134 {
00135 if (ntptime.GetMSW() < RTP_NTPTIMEOFFSET)
00136 {
00137 sec = 0;
00138 microsec = 0;
00139 }
00140 else
00141 {
00142 sec = ntptime.GetMSW() - RTP_NTPTIMEOFFSET;
00143
00144 double x = (double)ntptime.GetLSW();
00145 x /= (65536.0*65536.0);
00146 x *= 1000000.0;
00147 microsec = (uint32_t)x;
00148 }
00149 }
00150
00151 #if (defined(WIN32) || defined(_WIN32_WCE))
00152
00153 inline RTPTime RTPTime::CurrentTime()
00154 {
00155 static int inited = 0;
00156 static unsigned __int64 microseconds, initmicroseconds;
00157 static LARGE_INTEGER performancefrequency;
00158
00159 unsigned __int64 emulate_microseconds, microdiff;
00160 SYSTEMTIME systemtime;
00161 FILETIME filetime;
00162
00163 LARGE_INTEGER performancecount;
00164
00165 QueryPerformanceCounter(&performancecount);
00166
00167 if(!inited){
00168 inited = 1;
00169 QueryPerformanceFrequency(&performancefrequency);
00170 GetSystemTime(&systemtime);
00171 SystemTimeToFileTime(&systemtime,&filetime);
00172 microseconds = ( ((unsigned __int64)(filetime.dwHighDateTime) << 32) + (unsigned __int64)(filetime.dwLowDateTime) ) / 10ui64;
00173 microseconds-= 11644473600000000ui64;
00174 initmicroseconds = ( ( performancecount.QuadPart * 1000000ui64 ) / performancefrequency.QuadPart );
00175 }
00176
00177 emulate_microseconds = ( ( performancecount.QuadPart * 1000000ui64 ) / performancefrequency.QuadPart );
00178
00179 microdiff = emulate_microseconds - initmicroseconds;
00180
00181 return RTPTime((uint32_t)((microseconds + microdiff) / 1000000ui64),((uint32_t)((microseconds + microdiff) % 1000000ui64)));
00182 }
00183
00184 inline void RTPTime::Wait(const RTPTime &delay)
00185 {
00186 DWORD t;
00187
00188 t = ((DWORD)delay.GetSeconds())*1000+(((DWORD)delay.GetMicroSeconds())/1000);
00189 Sleep(t);
00190 }
00191
00192 class RTPTimeInitializer
00193 {
00194 public:
00195 RTPTimeInitializer();
00196 void Dummy() { dummy++; }
00197 private:
00198 int dummy;
00199 };
00200
00201 extern RTPTimeInitializer timeinit;
00202
00203 #else // unix style
00204
00205 inline RTPTime RTPTime::CurrentTime()
00206 {
00207 struct timeval tv;
00208
00209 gettimeofday(&tv,0);
00210 return RTPTime((uint32_t)tv.tv_sec,(uint32_t)tv.tv_usec);
00211 }
00212
00213 inline void RTPTime::Wait(const RTPTime &delay)
00214 {
00215 struct timespec req,rem;
00216
00217 req.tv_sec = (time_t)delay.sec;
00218 req.tv_nsec = ((long)delay.microsec)*1000;
00219 nanosleep(&req,&rem);
00220 }
00221
00222 #endif // WIN32
00223
00224 inline RTPTime &RTPTime::operator-=(const RTPTime &t)
00225 {
00226 sec -= t.sec;
00227 if (t.microsec > microsec)
00228 {
00229 sec--;
00230 microsec += 1000000;
00231 }
00232 microsec -= t.microsec;
00233 return *this;
00234 }
00235
00236 inline RTPTime &RTPTime::operator+=(const RTPTime &t)
00237 {
00238 sec += t.sec;
00239 microsec += t.microsec;
00240 if (microsec >= 1000000)
00241 {
00242 sec++;
00243 microsec -= 1000000;
00244 }
00245 return *this;
00246 }
00247
00248 inline RTPNTPTime RTPTime::GetNTPTime() const
00249 {
00250 uint32_t msw = sec+RTP_NTPTIMEOFFSET;
00251 uint32_t lsw;
00252 double x;
00253
00254 x = microsec/1000000.0;
00255 x *= (65536.0*65536.0);
00256 lsw = (uint32_t)x;
00257
00258 return RTPNTPTime(msw,lsw);
00259 }
00260
00261 inline bool RTPTime::operator<(const RTPTime &t) const
00262 {
00263 if (sec < t.sec)
00264 return true;
00265 if (sec > t.sec)
00266 return false;
00267 if (microsec < t.microsec)
00268 return true;
00269 return false;
00270 }
00271
00272 inline bool RTPTime::operator>(const RTPTime &t) const
00273 {
00274 if (sec > t.sec)
00275 return true;
00276 if (sec < t.sec)
00277 return false;
00278 if (microsec > t.microsec)
00279 return true;
00280 return false;
00281 }
00282
00283 inline bool RTPTime::operator<=(const RTPTime &t) const
00284 {
00285 if (sec < t.sec)
00286 return true;
00287 if (sec > t.sec)
00288 return false;
00289 if (microsec <= t.microsec)
00290 return true;
00291 return false;
00292 }
00293
00294 inline bool RTPTime::operator>=(const RTPTime &t) const
00295 {
00296 if (sec > t.sec)
00297 return true;
00298 if (sec < t.sec)
00299 return false;
00300 if (microsec >= t.microsec)
00301 return true;
00302 return false;
00303 }
00304 #endif // RTPTIMEUTILITIES_H
00305