📄 mtime.c
字号:
i_wrap_counts = 0; } EnterCriticalSection( &date_lock );#if defined( WIN32 ) res = INT64_C(1000) * (i_wrap_counts * INT64_C(0x100000000) + timeGetTime());#else res = INT64_C(1000) * (i_wrap_counts * INT64_C(0x100000000) + GetTickCount());#endif if( i_previous_time > res ) { /* Counter wrapped */ i_wrap_counts++; res += INT64_C(0x100000000) * 1000; } i_previous_time = res; LeaveCriticalSection( &date_lock ); }#else struct timeval tv_date; /* gettimeofday() cannot fail given &tv_date is a valid address */ (void)gettimeofday( &tv_date, NULL ); res = (mtime_t) tv_date.tv_sec * 1000000 + (mtime_t) tv_date.tv_usec;#endif return res;}/** * Wait for a date * * This function uses select() and an system date function to wake up at a * precise date. It should be used for process synchronization. If current date * is posterior to wished date, the function returns immediately. * \param date The date to wake up at */void mwait( mtime_t date ){ /* If the deadline is already elapsed, or within the clock precision, * do not even bother the system timer. */ date -= mprec();#if defined (HAVE_CLOCK_NANOSLEEP) lldiv_t d = lldiv( date, 1000000 ); struct timespec ts = { d.quot, d.rem * 1000 }; int val; while( ( val = clock_nanosleep( CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL ) ) == EINTR ); if( val == EINVAL ) { ts.tv_sec = d.quot; ts.tv_nsec = d.rem * 1000; while( clock_nanosleep( CLOCK_REALTIME, 0, &ts, NULL ) == EINTR ); }#else mtime_t delay = date - mdate(); if( delay > 0 ) msleep( delay );#endif}/** * More precise sleep() * * Portable usleep() function. * \param delay the amount of time to sleep */void msleep( mtime_t delay ){#if defined( HAVE_CLOCK_NANOSLEEP ) lldiv_t d = lldiv( delay, 1000000 ); struct timespec ts = { d.quot, d.rem * 1000 }; int val; while( ( val = clock_nanosleep( CLOCK_MONOTONIC, 0, &ts, &ts ) ) == EINTR ); if( val == EINVAL ) { ts.tv_sec = d.quot; ts.tv_nsec = d.rem * 1000; while( clock_nanosleep( CLOCK_REALTIME, 0, &ts, &ts ) == EINTR ); }#elif defined( HAVE_KERNEL_OS_H ) snooze( delay );#elif defined( WIN32 ) || defined( UNDER_CE ) for (delay /= 1000; delay > 0x7fffffff; delay -= 0x7fffffff) Sleep (0x7fffffff); Sleep (delay);#elif defined( HAVE_NANOSLEEP ) struct timespec ts_delay; ts_delay.tv_sec = delay / 1000000; ts_delay.tv_nsec = (delay % 1000000) * 1000; while( nanosleep( &ts_delay, &ts_delay ) && ( errno == EINTR ) );#else struct timeval tv_delay; tv_delay.tv_sec = delay / 1000000; tv_delay.tv_usec = delay % 1000000; /* If a signal is caught, you are screwed. Update your OS to nanosleep() * or clock_nanosleep() if this is an issue. */ select( 0, NULL, NULL, NULL, &tv_delay );#endif}/* * Date management (internal and external) *//** * Initialize a date_t. * * \param date to initialize * \param divider (sample rate) numerator * \param divider (sample rate) denominator */void date_Init( date_t *p_date, uint32_t i_divider_n, uint32_t i_divider_d ){ p_date->date = 0; p_date->i_divider_num = i_divider_n; p_date->i_divider_den = i_divider_d; p_date->i_remainder = 0;}/** * Change a date_t. * * \param date to change * \param divider (sample rate) numerator * \param divider (sample rate) denominator */void date_Change( date_t *p_date, uint32_t i_divider_n, uint32_t i_divider_d ){ /* change time scale of remainder */ p_date->i_remainder = p_date->i_remainder * i_divider_n / p_date->i_divider_num; p_date->i_divider_num = i_divider_n; p_date->i_divider_den = i_divider_d;}/** * Set the date value of a date_t. * * \param date to set * \param date value */void date_Set( date_t *p_date, mtime_t i_new_date ){ p_date->date = i_new_date; p_date->i_remainder = 0;}/** * Get the date of a date_t * * \param date to get * \return date value */mtime_t date_Get( const date_t *p_date ){ return p_date->date;}/** * Move forwards or backwards the date of a date_t. * * \param date to move * \param difference value */void date_Move( date_t *p_date, mtime_t i_difference ){ p_date->date += i_difference;}/** * Increment the date and return the result, taking into account * rounding errors. * * \param date to increment * \param incrementation in number of samples * \return date value */mtime_t date_Increment( date_t *p_date, uint32_t i_nb_samples ){ mtime_t i_dividend = (mtime_t)i_nb_samples * 1000000 * p_date->i_divider_den; p_date->date += i_dividend / p_date->i_divider_num; p_date->i_remainder += (int)(i_dividend % p_date->i_divider_num); if( p_date->i_remainder >= p_date->i_divider_num ) { /* This is Bresenham algorithm. */ assert( p_date->i_remainder < 2*p_date->i_divider_num); p_date->date += 1; p_date->i_remainder -= p_date->i_divider_num; } return p_date->date;}#ifndef HAVE_GETTIMEOFDAY#ifdef WIN32/* * Number of micro-seconds between the beginning of the Windows epoch * (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970). * * This assumes all Win32 compilers have 64-bit support. */#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) || defined(__WATCOMC__)# define DELTA_EPOCH_IN_USEC 11644473600000000Ui64#else# define DELTA_EPOCH_IN_USEC 11644473600000000ULL#endifstatic uint64_t filetime_to_unix_epoch (const FILETIME *ft){ uint64_t res = (uint64_t) ft->dwHighDateTime << 32; res |= ft->dwLowDateTime; res /= 10; /* from 100 nano-sec periods to usec */ res -= DELTA_EPOCH_IN_USEC; /* from Win epoch to Unix epoch */ return (res);}static int gettimeofday (struct timeval *tv, void *tz ){ FILETIME ft; uint64_t tim; if (!tv) { return VLC_EGENERIC; } GetSystemTimeAsFileTime (&ft); tim = filetime_to_unix_epoch (&ft); tv->tv_sec = (long) (tim / 1000000L); tv->tv_usec = (long) (tim % 1000000L); return (0);}#endif#endif/** * @return NTP 64-bits timestamp in host byte order. */uint64_t NTPtime64 (void){ struct timespec ts;#if defined (CLOCK_REALTIME) clock_gettime (CLOCK_REALTIME, &ts);#else { struct timeval tv; gettimeofday (&tv, NULL); ts.tv_sec = tv.tv_sec; ts.tv_nsec = tv.tv_usec * 1000; }#endif /* Convert nanoseconds to 32-bits fraction (232 picosecond units) */ uint64_t t = (uint64_t)(ts.tv_nsec) << 32; t /= 1000000000; /* There is 70 years (incl. 17 leap ones) offset to the Unix Epoch. * No leap seconds during that period since they were not invented yet. */ assert (t < 0x100000000); t |= ((70LL * 365 + 17) * 24 * 60 * 60 + ts.tv_sec) << 32; return t;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -