summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKacper Michajłow <kasper93@gmail.com>2024-02-04 16:35:13 +0100
committerDudemanguy <random342@airmail.cc>2024-02-15 16:39:58 +0000
commita329bb546c0ce553f6fb3fb398b8b728730d63a7 (patch)
treef967f666184ba1746c485b5594961cecc277c51b
parent0bf4da0f5e70bd612644107f1634d2d4763ae4fc (diff)
downloadmpv-a329bb546c0ce553f6fb3fb398b8b728730d63a7.tar.bz2
mpv-a329bb546c0ce553f6fb3fb398b8b728730d63a7.tar.xz
Reapply "video: remove another redundant wakeup"
This reverts commit 44c398c3e133379e01f06c89fd78b6692694849c.
-rw-r--r--player/video.c4
-rw-r--r--video/out/vo.c60
-rw-r--r--video/out/vo.h1
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);