0
0
mirror of https://github.com/mpv-player/mpv.git synced 2024-09-20 12:02:23 +02:00

vo: change vsync_interval to double

So strangely enough, estimated_vsync_interval is stored as a double but
nominal_vsync_interval is not and neither is the vsync_interval. Those
are stored as int64_t. This loss of precision can matter even in common
cases. For instance, take a typical 60 Hz monitor. Instead of 16666.6666
(repeating) being calculated as the vsync interval, you would get 16666
since the decimals are truncated. This is not really good at all and
affects the calculated speed values you get when using display sync. For
consistency and better precision, these should all be doubles just like
estimated_vsync_interval. Technically this means that we won't be able
to store as high of an integer value but such values would be absurdly
huge and never actually needed. Also estimated_vsync_interval already
can't handle such a case anyway.
This commit is contained in:
Dudemanguy 2023-09-07 18:15:01 -05:00
parent 9c9ec073bd
commit bda84399ab
2 changed files with 12 additions and 12 deletions

View File

@ -145,14 +145,14 @@ struct vo_internal {
int queued_events; // event mask for the user
int internal_events; // event mask for us
int64_t nominal_vsync_interval;
double nominal_vsync_interval;
int64_t vsync_interval;
double vsync_interval;
int64_t *vsync_samples;
int num_vsync_samples;
int64_t num_total_vsync_samples;
int64_t prev_vsync;
int64_t base_vsync;
double prev_vsync;
double base_vsync;
int drop_point;
double estimated_vsync_interval;
double estimated_vsync_jitter;
@ -415,7 +415,7 @@ static void reset_vsync_timings(struct vo *vo)
in->num_successive_vsyncs = 0;
}
static double vsync_stddef(struct vo *vo, int64_t ref_vsync)
static double vsync_stddef(struct vo *vo, double ref_vsync)
{
struct vo_internal *in = vo->in;
double jitter = 0;
@ -460,7 +460,7 @@ static void check_estimated_display_fps(struct vo *vo)
1e6 / in->nominal_vsync_interval);
}
}
in->vsync_interval = use_estimated ? (int64_t)in->estimated_vsync_interval
in->vsync_interval = use_estimated ? in->estimated_vsync_interval
: in->nominal_vsync_interval;
}
@ -471,7 +471,7 @@ static void vsync_skip_detection(struct vo *vo)
struct vo_internal *in = vo->in;
int window = 4;
int64_t t_r = in->prev_vsync, t_e = in->base_vsync, diff = 0, desync_early = 0;
double t_r = in->prev_vsync, t_e = in->base_vsync, diff = 0.0, desync_early = 0.0;
for (int n = 0; n < in->drop_point; n++) {
diff += t_r - t_e;
t_r -= in->vsync_samples[n];
@ -479,9 +479,9 @@ static void vsync_skip_detection(struct vo *vo)
if (n == window + 1)
desync_early = diff / window;
}
int64_t desync = diff / in->num_vsync_samples;
double desync = diff / in->num_vsync_samples;
if (in->drop_point > window * 2 &&
llabs(desync - desync_early) >= in->vsync_interval * 3 / 4)
fabs(desync - desync_early) >= in->vsync_interval * 3 / 4)
{
// Assume a drop. An underflow can technically speaking not be a drop
// (it's up to the driver what this is supposed to mean), but no reason
@ -1289,11 +1289,11 @@ int vo_get_num_req_frames(struct vo *vo)
return res;
}
int64_t vo_get_vsync_interval(struct vo *vo)
double vo_get_vsync_interval(struct vo *vo)
{
struct vo_internal *in = vo->in;
pthread_mutex_lock(&in->lock);
int64_t res = vo->in->vsync_interval > 1 ? vo->in->vsync_interval : -1;
double res = vo->in->vsync_interval > 1 ? vo->in->vsync_interval : -1;
pthread_mutex_unlock(&in->lock);
return res;
}

View File

@ -526,7 +526,7 @@ int vo_query_and_reset_events(struct vo *vo, int events);
struct mp_image *vo_get_current_frame(struct vo *vo);
void vo_set_queue_params(struct vo *vo, int64_t offset_us, int num_req_frames);
int vo_get_num_req_frames(struct vo *vo);
int64_t vo_get_vsync_interval(struct vo *vo);
double vo_get_vsync_interval(struct vo *vo);
double vo_get_estimated_vsync_interval(struct vo *vo);
double vo_get_estimated_vsync_jitter(struct vo *vo);
double vo_get_display_fps(struct vo *vo);