mirror of
https://github.com/mpv-player/mpv
synced 2024-12-26 17:12:36 +00:00
player: account for minor VO underruns
If the player sends a frame with duration==0 to the VO, it can trivially underrun. Don't panic, but keep the correct time. Also, returning the absolute time from vo_get_next_frame_start_time() just to turn it into a float with relative time was silly. Rename it and make it return what the caller needs.
This commit is contained in:
parent
542d88472f
commit
a790009a63
@ -1025,8 +1025,8 @@ static void handle_display_sync_frame(struct MPContext *mpctx,
|
||||
|
||||
// Estimate the video position, so we can calculate a good A/V difference
|
||||
// value below. This is used to estimate A/V drift.
|
||||
double time_left = (vo_get_next_frame_start_time(vo) - mp_time_us()) / 1e6;
|
||||
time_left = MPMAX(time_left, 0);
|
||||
double time_left = vo_get_delay(vo);
|
||||
|
||||
// We also know that the timing is (necessarily) off, because we have to
|
||||
// align frame timings on the vsync boundaries. This is unavoidable, and
|
||||
// for the sake of the A/V sync calculations we pretend it's perfect.
|
||||
|
@ -868,8 +868,11 @@ void vo_set_paused(struct vo *vo, bool paused)
|
||||
pthread_mutex_lock(&in->lock);
|
||||
if (in->paused != paused) {
|
||||
in->paused = paused;
|
||||
if (in->paused && in->dropped_frame)
|
||||
in->request_redraw = true;
|
||||
if (in->paused) {
|
||||
if (in->dropped_frame)
|
||||
in->request_redraw = true;
|
||||
in->last_flip = 0;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&in->lock);
|
||||
vo_control(vo, paused ? VOCTRL_PAUSE : VOCTRL_RESUME, NULL);
|
||||
@ -913,11 +916,13 @@ bool vo_want_redraw(struct vo *vo)
|
||||
|
||||
void vo_seek_reset(struct vo *vo)
|
||||
{
|
||||
pthread_mutex_lock(&vo->in->lock);
|
||||
struct vo_internal *in = vo->in;
|
||||
pthread_mutex_lock(&in->lock);
|
||||
forget_frames(vo);
|
||||
vo->in->send_reset = true;
|
||||
in->last_flip = 0;
|
||||
in->send_reset = true;
|
||||
wakeup_locked(vo);
|
||||
pthread_mutex_unlock(&vo->in->lock);
|
||||
pthread_mutex_unlock(&in->lock);
|
||||
}
|
||||
|
||||
// Return true if there is still a frame being displayed (or queued).
|
||||
@ -1026,12 +1031,13 @@ int64_t vo_get_vsync_interval(struct vo *vo)
|
||||
return res;
|
||||
}
|
||||
|
||||
// Get the mp_time_us() time at which the currently rendering frame will end
|
||||
// (i.e. time of the last flip call needed to display it).
|
||||
// Get the time in seconds at after which the currently rendering frame will
|
||||
// end. Returns positive values if the frame is yet to be finished, negative
|
||||
// values if it already finished.
|
||||
// This can only be called while no new frame is queued (after
|
||||
// vo_is_ready_for_frame). Returns 0 for non-display synced frames, or if the
|
||||
// deadline for continuous display was missed.
|
||||
int64_t vo_get_next_frame_start_time(struct vo *vo)
|
||||
double vo_get_delay(struct vo *vo)
|
||||
{
|
||||
struct vo_internal *in = vo->in;
|
||||
pthread_mutex_lock(&in->lock);
|
||||
@ -1047,7 +1053,7 @@ int64_t vo_get_next_frame_start_time(struct vo *vo)
|
||||
res = 0;
|
||||
}
|
||||
pthread_mutex_unlock(&in->lock);
|
||||
return res;
|
||||
return res ? (res - mp_time_us()) / 1e6 : 0;
|
||||
}
|
||||
|
||||
int64_t vo_get_delayed_count(struct vo *vo)
|
||||
|
@ -342,7 +342,7 @@ void vo_set_queue_params(struct vo *vo, int64_t offset_us, bool vsync_timed,
|
||||
int vo_get_num_req_frames(struct vo *vo);
|
||||
int64_t vo_get_vsync_interval(struct vo *vo);
|
||||
double vo_get_display_fps(struct vo *vo);
|
||||
int64_t vo_get_next_frame_start_time(struct vo *vo);
|
||||
double vo_get_delay(struct vo *vo);
|
||||
|
||||
void vo_wakeup(struct vo *vo);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user