You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
2.2KB

  1. #include <stdint.h>
  2. #include <assert.h>
  3. #include <time.h>
  4. #if defined(OS_WINDOWS)
  5. #include <Windows.h>
  6. #else
  7. #include <sys/time.h>
  8. #if defined(OS_MAC)
  9. #include <sys/param.h>
  10. #include <sys/sysctl.h>
  11. #include <mach/mach_time.h>
  12. #endif
  13. #endif
  14. /// same as system_time except ms -> us
  15. /// @return microseconds since the Epoch(1970-01-01 00:00:00 +0000 (UTC))
  16. uint64_t rtpclock()
  17. {
  18. #if defined(OS_WINDOWS)
  19. uint64_t t;
  20. FILETIME ft;
  21. GetSystemTimeAsFileTime(&ft);
  22. t = (uint64_t)ft.dwHighDateTime << 32 | ft.dwLowDateTime;
  23. return t / 10 - 11644473600000000; /* Jan 1, 1601 */
  24. #elif defined(OS_MAC)
  25. uint64_t tick;
  26. mach_timebase_info_data_t timebase;
  27. tick = mach_absolute_time();
  28. mach_timebase_info(&timebase);
  29. return tick * timebase.numer / timebase.denom / 1000;
  30. #else
  31. #if defined(CLOCK_MONOTONIC)
  32. struct timespec tp;
  33. clock_gettime(CLOCK_MONOTONIC, &tp);
  34. return (uint64_t)tp.tv_sec * 1000000 + tp.tv_nsec / 1000;
  35. #else
  36. // POSIX.1-2008 marks gettimeofday() as obsolete, recommending the use of clock_gettime(2) instead.
  37. struct timeval tv;
  38. gettimeofday(&tv, NULL);
  39. return (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec;
  40. #endif
  41. #endif
  42. }
  43. /// us(microsecond) -> ntp
  44. uint64_t clock2ntp(uint64_t clock)
  45. {
  46. uint64_t ntp;
  47. // high 32 bits in seconds
  48. ntp = ((clock/1000000)+0x83AA7E80) << 32; // 1/1/1970 -> 1/1/1900
  49. // low 32 bits in picosecond
  50. // us * 2^32 / 10^6
  51. // 10^6 = 2^6 * 15625
  52. // => us * 2^26 / 15625
  53. ntp |= (uint32_t)(((clock % 1000000) << 26) / 15625);
  54. return ntp;
  55. }
  56. /// ntp -> us(microsecond)
  57. uint64_t ntp2clock(uint64_t ntp)
  58. {
  59. uint64_t clock;
  60. // high 32 bits in seconds
  61. clock = ((uint64_t)((unsigned int)(ntp >> 32) - 0x83AA7E80)) * 1000000; // 1/1/1900 -> 1/1/1970
  62. // low 32 bits in picosecond
  63. clock += ((ntp & 0xFFFFFFFF) * 15625) >> 26;
  64. return clock;
  65. }
  66. #if defined(_DEBUG) || defined(DEBUG)
  67. void rtp_time_test(void)
  68. {
  69. const uint64_t ntp = 0xe2e1d897e9c38b05ULL;
  70. uint64_t clock;
  71. struct tm* tm;
  72. time_t t;
  73. clock = ntp2clock(ntp);
  74. t = (time_t)(clock / 1000000);
  75. tm = gmtime(&t);
  76. assert(tm->tm_year + 1900 == 2020 && tm->tm_mon == 7 && tm->tm_mday == 15 && tm->tm_hour == 3 && tm->tm_min == 44 && tm->tm_sec == 23);
  77. assert(clock2ntp(clock) == 0xe2e1d897e9c38b04ULL);
  78. }
  79. #endif