mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-20 04:42:18 +02:00
libobs/util: Fix rounding error with os_sleepto_ns()
os_sleepto_ns() can occasionally return false on times that the processor may not have reached yet. The reason is because the count_target, which converts time_target into a QPC counter, is subject to a rounding error. Using numbers I generated from an actual clock cycle on my own CPU, I can show an example of this occurring: if the clock frequency value is 10000000.0, and you call os_sleepto_ns(42164590320600), it will convert that number first to a double floating point of its QPC value: 421645903205.99994. Then, because it converts that to a LONGLONG integer, it of course strips off the decimal point. If you convert 421645903205 *back* to a time value, the new value will be 42164590320500, which is lower than the original value by approximately 100 nanoseconds. While this may seem insignificant, it was apparently enough to cause the os_sleepto_ns() call in video_sleep() to sometimes return false despite the current time being lower than the target time, which would cause it to incorrectly calculate how many frames were duplicated by subtracting the frame time from the current system time, divide that by the current frame interval, set the vframe_info.count value to 0, and thus cause an infinite loop in the encode_gpu() function because queue_frame now starts returning negative numbers in perpetuity. This change fixes some rare reports of users having their video lock up and disconnect, forcing the user to have to forcibly shut down the program. Thanks to Twitch user SNLabat for having the patience to kindly provide us with a dump file from the freeze, and to Matt for coordinating with that user to obtain it from them.
This commit is contained in:
parent
db3cee0868
commit
2d7cda18e9
@ -20,6 +20,7 @@
|
||||
#include <shlobj.h>
|
||||
#include <intrin.h>
|
||||
#include <psapi.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "base.h"
|
||||
#include "platform.h"
|
||||
@ -333,7 +334,7 @@ bool os_sleepto_ns(uint64_t time_target)
|
||||
{
|
||||
const double freq = (double)get_clockfreq();
|
||||
const LONGLONG count_target =
|
||||
(LONGLONG)((double)time_target * freq / 1000000000.0);
|
||||
(LONGLONG)(round((double)time_target * freq / 1000000000.0));
|
||||
|
||||
LARGE_INTEGER count;
|
||||
QueryPerformanceCounter(&count);
|
||||
|
Loading…
Reference in New Issue
Block a user