JRTPLIB  3.9.0
rtptimeutilities.h
Go to the documentation of this file.
1 /*
2 
3  This file is a part of JRTPLIB
4  Copyright (c) 1999-2011 Jori Liesenborgs
5 
6  Contact: jori.liesenborgs@gmail.com
7 
8  This library was developed at the Expertise Centre for Digital Media
9  (http://www.edm.uhasselt.be), a research center of the Hasselt University
10  (http://www.uhasselt.be). The library is based upon work done for
11  my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
12 
13  Permission is hereby granted, free of charge, to any person obtaining a
14  copy of this software and associated documentation files (the "Software"),
15  to deal in the Software without restriction, including without limitation
16  the rights to use, copy, modify, merge, publish, distribute, sublicense,
17  and/or sell copies of the Software, and to permit persons to whom the
18  Software is furnished to do so, subject to the following conditions:
19 
20  The above copyright notice and this permission notice shall be included
21  in all copies or substantial portions of the Software.
22 
23  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
29  IN THE SOFTWARE.
30 
31 */
32 
37 #ifndef RTPTIMEUTILITIES_H
38 
39 #define RTPTIMEUTILITIES_H
40 
41 #include "rtpconfig.h"
42 #include "rtptypes.h"
43 #ifndef WIN32
44  #include <sys/time.h>
45  #include <time.h>
46 #else
47  #ifndef _WIN32_WCE
48  #include <sys/timeb.h>
49  #endif // _WIN32_WINCE
50 #endif // WIN32
51 
52 #define RTP_NTPTIMEOFFSET 2208988800UL
53 
54 namespace jrtplib
55 {
56 
62 {
63 public:
65  RTPNTPTime(uint32_t m,uint32_t l) { msw = m ; lsw = l; }
66 
68  uint32_t GetMSW() const { return msw; }
69 
71  uint32_t GetLSW() const { return lsw; }
72 private:
73  uint32_t msw,lsw;
74 };
75 
80 class RTPTime
81 {
82 public:
87  static RTPTime CurrentTime();
88 
90  static void Wait(const RTPTime &delay);
91 
93  RTPTime(double t);
94 
100  RTPTime(RTPNTPTime ntptime);
101 
103  RTPTime(uint32_t seconds, uint32_t microseconds) { sec = seconds; microsec = microseconds; }
104 
106  uint32_t GetSeconds() const { return sec; }
107 
109  uint32_t GetMicroSeconds() const { return microsec; }
110 
112  double GetDouble() const { return (((double)sec)+(((double)microsec)/1000000.0)); }
113 
115  RTPNTPTime GetNTPTime() const;
116 
117  RTPTime &operator-=(const RTPTime &t);
118  RTPTime &operator+=(const RTPTime &t);
119  bool operator<(const RTPTime &t) const;
120  bool operator>(const RTPTime &t) const;
121  bool operator<=(const RTPTime &t) const;
122  bool operator>=(const RTPTime &t) const;
123 private:
124 #if (defined(WIN32) || defined(_WIN32_WCE))
125  static inline unsigned __int64 CalculateMicroseconds(unsigned __int64 performancecount,unsigned __int64 performancefrequency);
126 #endif // WIN32 || _WIN32_WCE
127 
128  uint32_t sec,microsec;
129 };
130 
131 inline RTPTime::RTPTime(double t)
132 {
133  sec = (uint32_t)t;
134 
135  double t2 = t-((double)sec);
136  t2 *= 1000000.0;
137  microsec = (uint32_t)t2;
138 }
139 
141 {
142  if (ntptime.GetMSW() < RTP_NTPTIMEOFFSET)
143  {
144  sec = 0;
145  microsec = 0;
146  }
147  else
148  {
149  sec = ntptime.GetMSW() - RTP_NTPTIMEOFFSET;
150 
151  double x = (double)ntptime.GetLSW();
152  x /= (65536.0*65536.0);
153  x *= 1000000.0;
154  microsec = (uint32_t)x;
155  }
156 }
157 
158 #if (defined(WIN32) || defined(_WIN32_WCE))
159 
160 inline unsigned __int64 RTPTime::CalculateMicroseconds(unsigned __int64 performancecount,unsigned __int64 performancefrequency)
161 {
162  unsigned __int64 f = performancefrequency;
163  unsigned __int64 a = performancecount;
164  unsigned __int64 b = a/f;
165  unsigned __int64 c = a%f; // a = b*f+c => (a*1000000)/f = b*1000000+(c*1000000)/f
166 
167  return b*1000000ui64+(c*1000000ui64)/f;
168 }
169 
170 inline RTPTime RTPTime::CurrentTime()
171 {
172  static int inited = 0;
173  static unsigned __int64 microseconds, initmicroseconds;
174  static LARGE_INTEGER performancefrequency;
175 
176  unsigned __int64 emulate_microseconds, microdiff;
177  SYSTEMTIME systemtime;
178  FILETIME filetime;
179 
180  LARGE_INTEGER performancecount;
181 
182  QueryPerformanceCounter(&performancecount);
183 
184  if(!inited){
185  inited = 1;
186  QueryPerformanceFrequency(&performancefrequency);
187  GetSystemTime(&systemtime);
188  SystemTimeToFileTime(&systemtime,&filetime);
189  microseconds = ( ((unsigned __int64)(filetime.dwHighDateTime) << 32) + (unsigned __int64)(filetime.dwLowDateTime) ) / 10ui64;
190  microseconds-= 11644473600000000ui64; // EPOCH
191  initmicroseconds = CalculateMicroseconds(performancecount.QuadPart, performancefrequency.QuadPart);
192  }
193 
194  emulate_microseconds = CalculateMicroseconds(performancecount.QuadPart, performancefrequency.QuadPart);
195 
196  microdiff = emulate_microseconds - initmicroseconds;
197 
198  return RTPTime((uint32_t)((microseconds + microdiff) / 1000000ui64),((uint32_t)((microseconds + microdiff) % 1000000ui64)));
199 }
200 
201 inline void RTPTime::Wait(const RTPTime &delay)
202 {
203  DWORD t;
204 
205  t = ((DWORD)delay.GetSeconds())*1000+(((DWORD)delay.GetMicroSeconds())/1000);
206  Sleep(t);
207 }
208 
209 class RTPTimeInitializer
210 {
211 public:
212  RTPTimeInitializer();
213  void Dummy() { dummy++; }
214 private:
215  int dummy;
216 };
217 
218 extern RTPTimeInitializer timeinit;
219 
220 #else // unix style
221 
223 {
224  struct timeval tv;
225 
226  gettimeofday(&tv,0);
227  return RTPTime((uint32_t)tv.tv_sec,(uint32_t)tv.tv_usec);
228 }
229 
230 inline void RTPTime::Wait(const RTPTime &delay)
231 {
232  struct timespec req,rem;
233 
234  req.tv_sec = (time_t)delay.sec;
235  req.tv_nsec = ((long)delay.microsec)*1000;
236  nanosleep(&req,&rem);
237 }
238 
239 #endif // WIN32
240 
241 inline RTPTime &RTPTime::operator-=(const RTPTime &t)
242 {
243  sec -= t.sec;
244  if (t.microsec > microsec)
245  {
246  sec--;
247  microsec += 1000000;
248  }
249  microsec -= t.microsec;
250  return *this;
251 }
252 
253 inline RTPTime &RTPTime::operator+=(const RTPTime &t)
254 {
255  sec += t.sec;
256  microsec += t.microsec;
257  if (microsec >= 1000000)
258  {
259  sec++;
260  microsec -= 1000000;
261  }
262  return *this;
263 }
264 
266 {
267  uint32_t msw = sec+RTP_NTPTIMEOFFSET;
268  uint32_t lsw;
269  double x;
270 
271  x = microsec/1000000.0;
272  x *= (65536.0*65536.0);
273  lsw = (uint32_t)x;
274 
275  return RTPNTPTime(msw,lsw);
276 }
277 
278 inline bool RTPTime::operator<(const RTPTime &t) const
279 {
280  if (sec < t.sec)
281  return true;
282  if (sec > t.sec)
283  return false;
284  if (microsec < t.microsec)
285  return true;
286  return false;
287 }
288 
289 inline bool RTPTime::operator>(const RTPTime &t) const
290 {
291  if (sec > t.sec)
292  return true;
293  if (sec < t.sec)
294  return false;
295  if (microsec > t.microsec)
296  return true;
297  return false;
298 }
299 
300 inline bool RTPTime::operator<=(const RTPTime &t) const
301 {
302  if (sec < t.sec)
303  return true;
304  if (sec > t.sec)
305  return false;
306  if (microsec <= t.microsec)
307  return true;
308  return false;
309 }
310 
311 inline bool RTPTime::operator>=(const RTPTime &t) const
312 {
313  if (sec > t.sec)
314  return true;
315  if (sec < t.sec)
316  return false;
317  if (microsec >= t.microsec)
318  return true;
319  return false;
320 }
321 
322 } // end namespace
323 
324 #endif // RTPTIMEUTILITIES_H
325 
uint32_t GetMicroSeconds() const
Returns the number of microseconds stored in this instance.
Definition: rtptimeutilities.h:109
RTPNTPTime GetNTPTime() const
Returns the NTP time corresponding to the time stored in this instance.
Definition: rtptimeutilities.h:265
This is a simple wrapper for the most significant word (MSW) and least significant word (LSW) of an N...
Definition: rtptimeutilities.h:61
RTPNTPTime(uint32_t m, uint32_t l)
This constructor creates and instance with MSW m and LSW l.
Definition: rtptimeutilities.h:65
RTPTime(uint32_t seconds, uint32_t microseconds)
Creates an instance corresponding to seconds and microseconds.
Definition: rtptimeutilities.h:103
double GetDouble() const
Returns the time stored in this instance, expressed in units of seconds.
Definition: rtptimeutilities.h:112
RTPTime(double t)
Creates an RTPTime instance representing t, which is expressed in units of seconds.
Definition: rtptimeutilities.h:131
This class is used to specify wallclock time, delay intervals etc.
Definition: rtptimeutilities.h:80
uint32_t GetLSW() const
Returns the least significant word.
Definition: rtptimeutilities.h:71
uint32_t GetMSW() const
Returns the most significant word.
Definition: rtptimeutilities.h:68
uint32_t GetSeconds() const
Returns the number of seconds stored in this instance.
Definition: rtptimeutilities.h:106
static void Wait(const RTPTime &delay)
This function waits the amount of time specified in delay.
Definition: rtptimeutilities.h:230
static RTPTime CurrentTime()
Returns an RTPTime instance representing the current wallclock time.
Definition: rtptimeutilities.h:222