精确延迟Sleep
2024-07-02
19
0
这代码是从OBS源码中扣出来的。
realtime.h
uint64_t os_gettime_ns(void);
bool os_sleepto_ns(uint64_t time_target);
realtime.cpp
#include "realSleep.h"
static inline uint64_t util_mul_div64(uint64_t num, uint64_t mul, uint64_t div)
{
#if defined(_MSC_VER) && defined(_M_X64) && (_MSC_VER >= 1920)
unsigned __int64 high;
const unsigned __int64 low = _umul128(num, mul, &high);
unsigned __int64 rem;
return _udiv128(high, low, div, &rem);
#else
const uint64_t rem = num % div;
return (num / div) * mul + (rem * mul) / div;
#endif
}
#define MAX_SZ_LEN 256
static bool have_clockfreq = false;
static LARGE_INTEGER clock_freq;
static uint32_t winver = 0;
static char win_release_id[MAX_SZ_LEN] = "unavailable";
static inline uint64_t get_clockfreq(void)
{
if (!have_clockfreq) {
QueryPerformanceFrequency(&clock_freq);
have_clockfreq = true;
}
return clock_freq.QuadPart;
}
uint64_t os_gettime_ns(void)
{
LARGE_INTEGER current_time;
QueryPerformanceCounter(¤t_time);
return util_mul_div64(current_time.QuadPart, 1000000000,
get_clockfreq());
}
bool os_sleepto_ns(uint64_t time_target)
{
const uint64_t freq = get_clockfreq();
const LONGLONG count_target = util_mul_div64(time_target, freq, 1000000000);
LARGE_INTEGER count;
QueryPerformanceCounter(&count);
const bool stall = count.QuadPart < count_target;
if (stall)
{
const DWORD milliseconds = (DWORD)(((count_target - count.QuadPart) * 1000.0) / freq);
if (milliseconds > 1)
Sleep(milliseconds - 1);
for (;;)
{
QueryPerformanceCounter(&count);
if (count.QuadPart >= count_target)
break;
YieldProcessor();
}
}
return stall;
}
使用方法:
uint64_t cur_time = os_gettime_ns();
uint64_t ms = 1000 * 1000;
ms = ms * 40;
for (int i = 0;; i++)
{
memset(p, i % 256, len);
m_usb.SetYUV2Data(p, len, &rtn);
//40ms
os_sleepto_ns(cur_time += ms);
}