src/posixtimer.c

00001 /*
00002   The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
00003   Copyright (C) 2001  Simon MORLAT simon.morlat@linphone.org
00004 
00005   This library is free software; you can redistribute it and/or
00006   modify it under the terms of the GNU Lesser General Public
00007   License as published by the Free Software Foundation; either
00008   version 2.1 of the License, or (at your option) any later version.
00009 
00010   This library is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013   Lesser General Public License for more details.
00014 
00015   You should have received a copy of the GNU Lesser General Public
00016   License along with this library; if not, write to the Free Software
00017   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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;             /*in milisecond */
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         /* this kind of select is not supported on windows */
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         // Check timerId
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         // If timer have expired while we where out of this method
00141         // Try to run after lost time.
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

Generated on Mon Sep 3 00:46:33 2007 for oRTP by  doxygen 1.5.2