diff options
author | Kacper Michajłow <kasper93@gmail.com> | 2024-02-04 16:35:13 +0100 |
---|---|---|
committer | Dudemanguy <random342@airmail.cc> | 2024-02-15 16:39:58 +0000 |
commit | a329bb546c0ce553f6fb3fb398b8b728730d63a7 (patch) | |
tree | f967f666184ba1746c485b5594961cecc277c51b | |
parent | 0bf4da0f5e70bd612644107f1634d2d4763ae4fc (diff) | |
download | mpv-a329bb546c0ce553f6fb3fb398b8b728730d63a7.tar.bz2 mpv-a329bb546c0ce553f6fb3fb398b8b728730d63a7.tar.xz |
Reapply "video: remove another redundant wakeup"
This reverts commit 44c398c3e133379e01f06c89fd78b6692694849c.
-rw-r--r-- | player/video.c | 4 | ||||
-rw-r--r-- | video/out/vo.c | 60 | ||||
-rw-r--r-- | video/out/vo.h | 1 |
3 files changed, 45 insertions, 20 deletions
diff --git a/player/video.c b/player/video.c index 6c93e1f576..6fe9227461 100644 --- a/player/video.c +++ b/player/video.c @@ -1173,8 +1173,10 @@ void write_video(struct MPContext *mpctx) struct mp_image_params *p = &mpctx->next_frames[0]->params; if (!vo->params || video_reconfig_needed(*p, *vo->params)) { // Changing config deletes the current frame; wait until it's finished. - if (vo_still_displaying(vo)) + if (vo_still_displaying(vo)) { + vo_request_wakeup_on_done(vo); return; + } const struct vo_driver *info = mpctx->video_out->driver; char extra[20] = {0}; diff --git a/video/out/vo.c b/video/out/vo.c index 31d96c600f..3bacfcc581 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -134,6 +134,7 @@ struct vo_internal { bool want_redraw; // redraw request from VO to player bool send_reset; // send VOCTRL_RESET bool paused; + bool wakeup_on_done; int queued_events; // event mask for the user int internal_events; // event mask for us @@ -767,6 +768,41 @@ void vo_wakeup(struct vo *vo) mp_mutex_unlock(&in->lock); } +static bool still_displaying(struct vo *vo) +{ + struct vo_internal *in = vo->in; + int64_t now = mp_time_ns(); + int64_t frame_end = 0; + if (in->current_frame) { + frame_end = in->current_frame->pts + MPMAX(in->current_frame->duration, 0); + if (in->current_frame->display_synced) + frame_end = in->current_frame->num_vsyncs > 0 ? INT64_MAX : 0; + } + return (now < frame_end || in->rendering || in->frame_queued) && in->hasframe; +} + +// Return true if there is still a frame being displayed (or queued). +bool vo_still_displaying(struct vo *vo) +{ + mp_mutex_lock(&vo->in->lock); + bool res = still_displaying(vo); + mp_mutex_unlock(&vo->in->lock); + return res; +} + +// Make vo issue a wakeup once vo_still_displaying() becomes true. +void vo_request_wakeup_on_done(struct vo *vo) +{ + struct vo_internal *in = vo->in; + mp_mutex_lock(&vo->in->lock); + if (still_displaying(vo)) { + in->wakeup_on_done = true; + } else { + wakeup_core(vo); + } + mp_mutex_unlock(&vo->in->lock); +} + // Whether vo_queue_frame() can be called. If the VO is not ready yet, the // function will return false, and the VO will call the wakeup callback once // it's ready. @@ -925,6 +961,7 @@ static bool render_frame(struct vo *vo) if (in->dropped_frame) { in->drop_count += 1; + wakeup_core(vo); } else { in->rendering = true; in->hasframe_rendered = true; @@ -996,11 +1033,14 @@ static bool render_frame(struct vo *vo) more_frames = true; mp_cond_broadcast(&in->wakeup); // for vo_wait_frame() - wakeup_core(vo); done: if (!vo->driver->frame_owner || in->dropped_frame) talloc_free(frame); + if (in->wakeup_on_done && !still_displaying(vo)) { + in->wakeup_on_done = false; + wakeup_core(vo); + } mp_mutex_unlock(&in->lock); return more_frames; @@ -1197,24 +1237,6 @@ void vo_seek_reset(struct vo *vo) mp_mutex_unlock(&in->lock); } -// Return true if there is still a frame being displayed (or queued). -// If this returns true, a wakeup some time in the future is guaranteed. -bool vo_still_displaying(struct vo *vo) -{ - struct vo_internal *in = vo->in; - mp_mutex_lock(&vo->in->lock); - int64_t now = mp_time_ns(); - int64_t frame_end = 0; - if (in->current_frame) { - frame_end = in->current_frame->pts + MPMAX(in->current_frame->duration, 0); - if (in->current_frame->display_synced) - frame_end = in->current_frame->num_vsyncs > 0 ? INT64_MAX : 0; - } - bool working = now < frame_end || in->rendering || in->frame_queued; - mp_mutex_unlock(&vo->in->lock); - return working && in->hasframe; -} - // Whether at least 1 frame was queued or rendered since last seek or reconfig. bool vo_has_frame(struct vo *vo) { diff --git a/video/out/vo.h b/video/out/vo.h index 2d521d8a69..7c5ed67736 100644 --- a/video/out/vo.h +++ b/video/out/vo.h @@ -510,6 +510,7 @@ bool vo_is_ready_for_frame(struct vo *vo, int64_t next_pts); void vo_queue_frame(struct vo *vo, struct vo_frame *frame); void vo_wait_frame(struct vo *vo); bool vo_still_displaying(struct vo *vo); +void vo_request_wakeup_on_done(struct vo *vo); bool vo_has_frame(struct vo *vo); void vo_redraw(struct vo *vo); void vo_set_want_redraw(struct vo *vo); |