00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #if defined(WIN32) || defined(_WIN32_WCE)
00021 #include "ortp-config-win32.h"
00022 #else
00023 #include "ortp-config.h"
00024 #endif
00025
00026 #include "ortp/ortp.h"
00027 #include "rtptimer.h"
00028
00029 #if !defined(_WIN32) && !defined(_WIN32_WCE)
00030
00031 #ifdef __linux__
00032 #include <sys/select.h>
00033 #endif
00034
00035 #include <sys/time.h>
00036 #include <sys/types.h>
00037 #include <unistd.h>
00038
00039
00040 static struct timeval orig,cur;
00041 static uint32_t posix_timer_time=0;
00042
00043 void posix_timer_init()
00044 {
00045 posix_timer.state=RTP_TIMER_RUNNING;
00046 gettimeofday(&orig,NULL);
00047 posix_timer_time=0;
00048 }
00049
00050
00051
00052
00053 void posix_timer_do()
00054 {
00055 int diff,time;
00056 struct timeval tv;
00057 gettimeofday(&cur,NULL);
00058 time=((cur.tv_usec-orig.tv_usec)/1000 ) + ((cur.tv_sec-orig.tv_sec)*1000 );
00059 if ( (diff=time-posix_timer_time)>50){
00060 ortp_warning("Must catchup %i miliseconds.",diff);
00061 }
00062 while((diff = posix_timer_time-time) > 0)
00063 {
00064 tv.tv_sec = diff/1000;
00065 tv.tv_usec = (diff%1000)*1000;
00066 #if defined(_WIN32) || defined(_WIN32_WCE)
00067
00068 Sleep(tv.tv_usec/1000 + tv.tv_sec * 1000);
00069 #else
00070 select(0,NULL,NULL,NULL,&tv);
00071 #endif
00072 gettimeofday(&cur,NULL);
00073 time=((cur.tv_usec-orig.tv_usec)/1000 ) + ((cur.tv_sec-orig.tv_sec)*1000 );
00074 }
00075 posix_timer_time+=POSIXTIMER_INTERVAL/1000;
00076
00077 }
00078
00079 void posix_timer_uninit()
00080 {
00081 posix_timer.state=RTP_TIMER_STOPPED;
00082 }
00083
00084 RtpTimer posix_timer={ 0,
00085 posix_timer_init,
00086 posix_timer_do,
00087 posix_timer_uninit,
00088 {0,POSIXTIMER_INTERVAL}};
00089
00090
00091 #else //WIN32
00092
00093
00094 #include <windows.h>
00095 #include <mmsystem.h>
00096
00097
00098 MMRESULT timerId;
00099 HANDLE TimeEvent;
00100 int late_ticks;
00101
00102
00103 static DWORD posix_timer_time;
00104 static DWORD offset_time;
00105
00106
00107 #define TIME_INTERVAL 50
00108 #define TIME_RESOLUTION 10
00109 #define TIME_TIMEOUT 100
00110
00111
00112
00113 void CALLBACK timerCb(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
00114 {
00115
00116 if (timerId == uID)
00117 {
00118 SetEvent(TimeEvent);
00119 posix_timer_time += TIME_INTERVAL;
00120 }
00121 }
00122
00123
00124 void win_timer_init(void)
00125 {
00126 timerId = timeSetEvent(TIME_INTERVAL,10,timerCb,0,TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
00127 TimeEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
00128
00129 late_ticks = 0;
00130
00131 offset_time = GetTickCount();
00132 posix_timer_time=0;
00133 }
00134
00135
00136 void win_timer_do(void)
00137 {
00138 DWORD diff;
00139
00140
00141
00142 if (late_ticks > 0)
00143 {
00144 late_ticks--;
00145 posix_timer_time+=TIME_INTERVAL;
00146 return;
00147 }
00148
00149
00150 diff = GetTickCount() - posix_timer_time - offset_time;
00151 if( diff>TIME_INTERVAL && (diff<(1<<31)))
00152 {
00153 late_ticks = diff/TIME_INTERVAL;
00154 ortp_warning("we must catchup %i ticks.",late_ticks);
00155 return;
00156 }
00157
00158 WaitForSingleObject(TimeEvent,TIME_TIMEOUT);
00159 return;
00160 }
00161
00162
00163 void win_timer_close(void)
00164 {
00165 timeKillEvent(timerId);
00166 }
00167
00168 RtpTimer toto;
00169
00170 RtpTimer posix_timer={ 0,
00171 win_timer_init,
00172 win_timer_do,
00173 win_timer_close,
00174 {0,TIME_INTERVAL * 1000}};
00175
00176
00177 #endif // _WIN32