jrtplib
3.7.1
|
00001 /* 00002 00003 This file is a part of JRTPLIB 00004 Copyright (c) 1999-2007 Jori Liesenborgs 00005 00006 Contact: jori.liesenborgs@gmail.com 00007 00008 This library was developed at the "Expertisecentrum Digitale Media" 00009 (http://www.edm.uhasselt.be), a research center of the Hasselt University 00010 (http://www.uhasselt.be). The library is based upon work done for 00011 my thesis at the School for Knowledge Technology (Belgium/The Netherlands). 00012 00013 Permission is hereby granted, free of charge, to any person obtaining a 00014 copy of this software and associated documentation files (the "Software"), 00015 to deal in the Software without restriction, including without limitation 00016 the rights to use, copy, modify, merge, publish, distribute, sublicense, 00017 and/or sell copies of the Software, and to permit persons to whom the 00018 Software is furnished to do so, subject to the following conditions: 00019 00020 The above copyright notice and this permission notice shall be included 00021 in all copies or substantial portions of the Software. 00022 00023 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00024 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00025 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00026 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00027 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00028 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 00029 IN THE SOFTWARE. 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; // a = b*f+c => (a*1000000)/f = b*1000000+(c*1000000)/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; // EPOCH 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