jrtplib  3.8.1
rtptimeutilities.h
Go to the documentation of this file.
1 /*
2 
3  This file is a part of JRTPLIB
4  Copyright (c) 1999-2010 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 
59 {
60 public:
62  RTPNTPTime(uint32_t m,uint32_t l) { msw = m ; lsw = l; }
63 
65  uint32_t GetMSW() const { return msw; }
66 
68  uint32_t GetLSW() const { return lsw; }
69 private:
70  uint32_t msw,lsw;
71 };
72 
77 class RTPTime
78 {
79 public:
84  static RTPTime CurrentTime();
85 
87  static void Wait(const RTPTime &delay);
88 
90  RTPTime(double t);
91 
97  RTPTime(RTPNTPTime ntptime);
98 
100  RTPTime(uint32_t seconds, uint32_t microseconds) { sec = seconds; microsec = microseconds; }
101 
103  uint32_t GetSeconds() const { return sec; }
104 
106  uint32_t GetMicroSeconds() const { return microsec; }
107 
109  double GetDouble() const { return (((double)sec)+(((double)microsec)/1000000.0)); }
110 
112  RTPNTPTime GetNTPTime() const;
113 
114  RTPTime &operator-=(const RTPTime &t);
115  RTPTime &operator+=(const RTPTime &t);
116  bool operator<(const RTPTime &t) const;
117  bool operator>(const RTPTime &t) const;
118  bool operator<=(const RTPTime &t) const;
119  bool operator>=(const RTPTime &t) const;
120 private:
121 #if (defined(WIN32) || defined(_WIN32_WCE))
122  static inline unsigned __int64 CalculateMicroseconds(unsigned __int64 performancecount,unsigned __int64 performancefrequency);
123 #endif // WIN32 || _WIN32_WCE
124 
125  uint32_t sec,microsec;
126 };
127 
128 inline RTPTime::RTPTime(double t)
129 {
130  sec = (uint32_t)t;
131 
132  double t2 = t-((double)sec);
133  t2 *= 1000000.0;
134  microsec = (uint32_t)t2;
135 }
136 
138 {
139  if (ntptime.GetMSW() < RTP_NTPTIMEOFFSET)
140  {
141  sec = 0;
142  microsec = 0;
143  }
144  else
145  {
146  sec = ntptime.GetMSW() - RTP_NTPTIMEOFFSET;
147 
148  double x = (double)ntptime.GetLSW();
149  x /= (65536.0*65536.0);
150  x *= 1000000.0;
151  microsec = (uint32_t)x;
152  }
153 }
154 
155 #if (defined(WIN32) || defined(_WIN32_WCE))
156 
157 inline unsigned __int64 RTPTime::CalculateMicroseconds(unsigned __int64 performancecount,unsigned __int64 performancefrequency)
158 {
159  unsigned __int64 f = performancefrequency;
160  unsigned __int64 a = performancecount;
161  unsigned __int64 b = a/f;
162  unsigned __int64 c = a%f; // a = b*f+c => (a*1000000)/f = b*1000000+(c*1000000)/f
163 
164  return b*1000000ui64+(c*1000000ui64)/f;
165 }
166 
168 {
169  static int inited = 0;
170  static unsigned __int64 microseconds, initmicroseconds;
171  static LARGE_INTEGER performancefrequency;
172 
173  unsigned __int64 emulate_microseconds, microdiff;
174  SYSTEMTIME systemtime;
175  FILETIME filetime;
176 
177  LARGE_INTEGER performancecount;
178 
179  QueryPerformanceCounter(&performancecount);
180 
181  if(!inited){
182  inited = 1;
183  QueryPerformanceFrequency(&performancefrequency);
184  GetSystemTime(&systemtime);
185  SystemTimeToFileTime(&systemtime,&filetime);
186  microseconds = ( ((unsigned __int64)(filetime.dwHighDateTime) << 32) + (unsigned __int64)(filetime.dwLowDateTime) ) / 10ui64;
187  microseconds-= 11644473600000000ui64; // EPOCH
188  initmicroseconds = CalculateMicroseconds(performancecount.QuadPart, performancefrequency.QuadPart);
189  }
190 
191  emulate_microseconds = CalculateMicroseconds(performancecount.QuadPart, performancefrequency.QuadPart);
192 
193  microdiff = emulate_microseconds - initmicroseconds;
194 
195  return RTPTime((uint32_t)((microseconds + microdiff) / 1000000ui64),((uint32_t)((microseconds + microdiff) % 1000000ui64)));
196 }
197 
198 inline void RTPTime::Wait(const RTPTime &delay)
199 {
200  DWORD t;
201 
202  t = ((DWORD)delay.GetSeconds())*1000+(((DWORD)delay.GetMicroSeconds())/1000);
203  Sleep(t);
204 }
205 
206 class RTPTimeInitializer
207 {
208 public:
209  RTPTimeInitializer();
210  void Dummy() { dummy++; }
211 private:
212  int dummy;
213 };
214 
215 extern RTPTimeInitializer timeinit;
216 
217 #else // unix style
218 
220 {
221  struct timeval tv;
222 
223  gettimeofday(&tv,0);
224  return RTPTime((uint32_t)tv.tv_sec,(uint32_t)tv.tv_usec);
225 }
226 
227 inline void RTPTime::Wait(const RTPTime &delay)
228 {
229  struct timespec req,rem;
230 
231  req.tv_sec = (time_t)delay.sec;
232  req.tv_nsec = ((long)delay.microsec)*1000;
233  nanosleep(&req,&rem);
234 }
235 
236 #endif // WIN32
237 
238 inline RTPTime &RTPTime::operator-=(const RTPTime &t)
239 {
240  sec -= t.sec;
241  if (t.microsec > microsec)
242  {
243  sec--;
244  microsec += 1000000;
245  }
246  microsec -= t.microsec;
247  return *this;
248 }
249 
250 inline RTPTime &RTPTime::operator+=(const RTPTime &t)
251 {
252  sec += t.sec;
253  microsec += t.microsec;
254  if (microsec >= 1000000)
255  {
256  sec++;
257  microsec -= 1000000;
258  }
259  return *this;
260 }
261 
263 {
264  uint32_t msw = sec+RTP_NTPTIMEOFFSET;
265  uint32_t lsw;
266  double x;
267 
268  x = microsec/1000000.0;
269  x *= (65536.0*65536.0);
270  lsw = (uint32_t)x;
271 
272  return RTPNTPTime(msw,lsw);
273 }
274 
275 inline bool RTPTime::operator<(const RTPTime &t) const
276 {
277  if (sec < t.sec)
278  return true;
279  if (sec > t.sec)
280  return false;
281  if (microsec < t.microsec)
282  return true;
283  return false;
284 }
285 
286 inline bool RTPTime::operator>(const RTPTime &t) const
287 {
288  if (sec > t.sec)
289  return true;
290  if (sec < t.sec)
291  return false;
292  if (microsec > t.microsec)
293  return true;
294  return false;
295 }
296 
297 inline bool RTPTime::operator<=(const RTPTime &t) const
298 {
299  if (sec < t.sec)
300  return true;
301  if (sec > t.sec)
302  return false;
303  if (microsec <= t.microsec)
304  return true;
305  return false;
306 }
307 
308 inline bool RTPTime::operator>=(const RTPTime &t) const
309 {
310  if (sec > t.sec)
311  return true;
312  if (sec < t.sec)
313  return false;
314  if (microsec >= t.microsec)
315  return true;
316  return false;
317 }
318 #endif // RTPTIMEUTILITIES_H
319 
uint32_t GetLSW() const
Returns the least significant word.
Definition: rtptimeutilities.h:68
RTPNTPTime(uint32_t m, uint32_t l)
This constructor creates and instance with MSW m and LSW l.
Definition: rtptimeutilities.h:62
This class is used to specify wallclock time, delay intervals etc.
Definition: rtptimeutilities.h:77
RTPTime(uint32_t seconds, uint32_t microseconds)
Creates an instance corresponding to seconds and microseconds.
Definition: rtptimeutilities.h:100
RTPNTPTime GetNTPTime() const
Returns the NTP time corresponding to the time stored in this instance.
Definition: rtptimeutilities.h:262
uint32_t GetMSW() const
Returns the most significant word.
Definition: rtptimeutilities.h:65
double GetDouble() const
Returns the time stored in this instance, expressed in units of seconds.
Definition: rtptimeutilities.h:109
RTPTime(double t)
Creates an RTPTime instance representing t, which is expressed in units of seconds.
Definition: rtptimeutilities.h:128
uint32_t GetMicroSeconds() const
Returns the number of microseconds 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:227
static RTPTime CurrentTime()
Returns an RTPTime instance representing the current wallclock time.
Definition: rtptimeutilities.h:219
This is a simple wrapper for the most significant word (MSW) and least significant word (LSW) of an N...
Definition: rtptimeutilities.h:58
uint32_t GetSeconds() const
Returns the number of seconds stored in this instance.
Definition: rtptimeutilities.h:103