summaryrefslogtreecommitdiffstats
path: root/src/rtptimeutilities.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/rtptimeutilities.h')
-rw-r--r--src/rtptimeutilities.h319
1 files changed, 319 insertions, 0 deletions
diff --git a/src/rtptimeutilities.h b/src/rtptimeutilities.h
new file mode 100644
index 0000000..527ef87
--- /dev/null
+++ b/src/rtptimeutilities.h
@@ -0,0 +1,319 @@
+/*
+
+ This file is a part of JRTPLIB
+ Copyright (c) 1999-2007 Jori Liesenborgs
+
+ Contact: jori.liesenborgs@gmail.com
+
+ This library was developed at the "Expertisecentrum Digitale Media"
+ (http://www.edm.uhasselt.be), a research center of the Hasselt University
+ (http://www.uhasselt.be). The library is based upon work done for
+ my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ IN THE SOFTWARE.
+
+*/
+
+/**
+ * \file rtptimeutilities.h
+ */
+
+#ifndef RTPTIMEUTILITIES_H
+
+#define RTPTIMEUTILITIES_H
+
+#include "rtpconfig.h"
+#include "rtptypes.h"
+#ifndef WIN32
+ #include <sys/time.h>
+ #include <time.h>
+#else
+ #ifndef _WIN32_WCE
+ #include <sys/timeb.h>
+ #endif // _WIN32_WINCE
+#endif // WIN32
+
+#define RTP_NTPTIMEOFFSET 2208988800UL
+
+/**
+ * This is a simple wrapper for the most significant word (MSW) and least
+ * significant word (LSW) of an NTP timestamp.
+ */
+class RTPNTPTime
+{
+public:
+ /** This constructor creates and instance with MSW \c m and LSW \c l. */
+ RTPNTPTime(uint32_t m,uint32_t l) { msw = m ; lsw = l; }
+
+ /** Returns the most significant word. */
+ uint32_t GetMSW() const { return msw; }
+
+ /** Returns the least significant word. */
+ uint32_t GetLSW() const { return lsw; }
+private:
+ uint32_t msw,lsw;
+};
+
+/** This class is used to specify wallclock time, delay intervals etc.
+ * This class is used to specify wallclock time, delay intervals etc.
+ * It stores a number of seconds and a number of microseconds.
+ */
+class RTPTime
+{
+public:
+ /** Returns an RTPTime instance representing the current wallclock time.
+ * Returns an RTPTime instance representing the current wallclock time. This is expressed
+ * as a number of seconds since 00:00:00 UTC, January 1, 1970.
+ */
+ static RTPTime CurrentTime();
+
+ /** This function waits the amount of time specified in \c delay. */
+ static void Wait(const RTPTime &delay);
+
+ /** Creates an RTPTime instance representing \c t, which is expressed in units of seconds. */
+ RTPTime(double t);
+
+ /** Creates an instance that corresponds to \c ntptime.
+ * Creates an instance that corresponds to \c ntptime. If
+ * the conversion cannot be made, both the seconds and the
+ * microseconds are set to zero.
+ */
+ RTPTime(RTPNTPTime ntptime);
+
+ /** Creates an instance corresponding to \c seconds and \c microseconds. */
+ RTPTime(uint32_t seconds,uint32_t microseconds) { sec = seconds; microsec = microseconds; }
+
+ /** Returns the number of seconds stored in this instance. */
+ uint32_t GetSeconds() const { return sec; }
+
+ /** Returns the number of microseconds stored in this instance. */
+ uint32_t GetMicroSeconds() const { return microsec; }
+
+ /** Returns the time stored in this instance, expressed in units of seconds. */
+ double GetDouble() const { return (((double)sec)+(((double)microsec)/1000000.0)); }
+
+ /** Returns the NTP time corresponding to the time stored in this instance. */
+ RTPNTPTime GetNTPTime() const;
+
+ RTPTime &operator-=(const RTPTime &t);
+ RTPTime &operator+=(const RTPTime &t);
+ bool operator<(const RTPTime &t) const;
+ bool operator>(const RTPTime &t) const;
+ bool operator<=(const RTPTime &t) const;
+ bool operator>=(const RTPTime &t) const;
+private:
+#if (defined(WIN32) || defined(_WIN32_WCE))
+ static inline unsigned __int64 CalculateMicroseconds(unsigned __int64 performancecount,unsigned __int64 performancefrequency);
+#endif // WIN32 || _WIN32_WCE
+
+ uint32_t sec,microsec;
+};
+
+inline RTPTime::RTPTime(double t)
+{
+ sec = (uint32_t)t;
+
+ double t2 = t-((double)sec);
+ t2 *= 1000000.0;
+ microsec = (uint32_t)t2;
+}
+
+inline RTPTime::RTPTime(RTPNTPTime ntptime)
+{
+ if (ntptime.GetMSW() < RTP_NTPTIMEOFFSET)
+ {
+ sec = 0;
+ microsec = 0;
+ }
+ else
+ {
+ sec = ntptime.GetMSW() - RTP_NTPTIMEOFFSET;
+
+ double x = (double)ntptime.GetLSW();
+ x /= (65536.0*65536.0);
+ x *= 1000000.0;
+ microsec = (uint32_t)x;
+ }
+}
+
+#if (defined(WIN32) || defined(_WIN32_WCE))
+
+inline unsigned __int64 RTPTime::CalculateMicroseconds(unsigned __int64 performancecount,unsigned __int64 performancefrequency)
+{
+ unsigned __int64 f = performancefrequency;
+ unsigned __int64 a = performancecount;
+ unsigned __int64 b = a/f;
+ unsigned __int64 c = a%f; // a = b*f+c => (a*1000000)/f = b*1000000+(c*1000000)/f
+
+ return b*1000000ui64+(c*1000000ui64)/f;
+}
+
+inline RTPTime RTPTime::CurrentTime()
+{
+ static int inited = 0;
+ static unsigned __int64 microseconds, initmicroseconds;
+ static LARGE_INTEGER performancefrequency;
+
+ unsigned __int64 emulate_microseconds, microdiff;
+ SYSTEMTIME systemtime;
+ FILETIME filetime;
+
+ LARGE_INTEGER performancecount;
+
+ QueryPerformanceCounter(&performancecount);
+
+ if(!inited){
+ inited = 1;
+ QueryPerformanceFrequency(&performancefrequency);
+ GetSystemTime(&systemtime);
+ SystemTimeToFileTime(&systemtime,&filetime);
+ microseconds = ( ((unsigned __int64)(filetime.dwHighDateTime) << 32) + (unsigned __int64)(filetime.dwLowDateTime) ) / 10ui64;
+ microseconds-= 11644473600000000ui64; // EPOCH
+ initmicroseconds = CalculateMicroseconds(performancecount.QuadPart, performancefrequency.QuadPart);
+ }
+
+ emulate_microseconds = CalculateMicroseconds(performancecount.QuadPart, performancefrequency.QuadPart);
+
+ microdiff = emulate_microseconds - initmicroseconds;
+
+ return RTPTime((uint32_t)((microseconds + microdiff) / 1000000ui64),((uint32_t)((microseconds + microdiff) % 1000000ui64)));
+}
+
+inline void RTPTime::Wait(const RTPTime &delay)
+{
+ DWORD t;
+
+ t = ((DWORD)delay.GetSeconds())*1000+(((DWORD)delay.GetMicroSeconds())/1000);
+ Sleep(t);
+}
+
+class RTPTimeInitializer
+{
+public:
+ RTPTimeInitializer();
+ void Dummy() { dummy++; }
+private:
+ int dummy;
+};
+
+extern RTPTimeInitializer timeinit;
+
+#else // unix style
+
+inline RTPTime RTPTime::CurrentTime()
+{
+ struct timeval tv;
+
+ gettimeofday(&tv,0);
+ return RTPTime((uint32_t)tv.tv_sec,(uint32_t)tv.tv_usec);
+}
+
+inline void RTPTime::Wait(const RTPTime &delay)
+{
+ struct timespec req,rem;
+
+ req.tv_sec = (time_t)delay.sec;
+ req.tv_nsec = ((long)delay.microsec)*1000;
+ nanosleep(&req,&rem);
+}
+
+#endif // WIN32
+
+inline RTPTime &RTPTime::operator-=(const RTPTime &t)
+{
+ sec -= t.sec;
+ if (t.microsec > microsec)
+ {
+ sec--;
+ microsec += 1000000;
+ }
+ microsec -= t.microsec;
+ return *this;
+}
+
+inline RTPTime &RTPTime::operator+=(const RTPTime &t)
+{
+ sec += t.sec;
+ microsec += t.microsec;
+ if (microsec >= 1000000)
+ {
+ sec++;
+ microsec -= 1000000;
+ }
+ return *this;
+}
+
+inline RTPNTPTime RTPTime::GetNTPTime() const
+{
+ uint32_t msw = sec+RTP_NTPTIMEOFFSET;
+ uint32_t lsw;
+ double x;
+
+ x = microsec/1000000.0;
+ x *= (65536.0*65536.0);
+ lsw = (uint32_t)x;
+
+ return RTPNTPTime(msw,lsw);
+}
+
+inline bool RTPTime::operator<(const RTPTime &t) const
+{
+ if (sec < t.sec)
+ return true;
+ if (sec > t.sec)
+ return false;
+ if (microsec < t.microsec)
+ return true;
+ return false;
+}
+
+inline bool RTPTime::operator>(const RTPTime &t) const
+{
+ if (sec > t.sec)
+ return true;
+ if (sec < t.sec)
+ return false;
+ if (microsec > t.microsec)
+ return true;
+ return false;
+}
+
+inline bool RTPTime::operator<=(const RTPTime &t) const
+{
+ if (sec < t.sec)
+ return true;
+ if (sec > t.sec)
+ return false;
+ if (microsec <= t.microsec)
+ return true;
+ return false;
+}
+
+inline bool RTPTime::operator>=(const RTPTime &t) const
+{
+ if (sec > t.sec)
+ return true;
+ if (sec < t.sec)
+ return false;
+ if (microsec >= t.microsec)
+ return true;
+ return false;
+}
+#endif // RTPTIMEUTILITIES_H
+