summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/interface-changes.rst2
-rw-r--r--DOCS/man/input.rst7
-rw-r--r--player/command.c27
-rw-r--r--player/core.h1
-rw-r--r--player/video.c11
5 files changed, 42 insertions, 6 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst
index b81312f8e9..dd42895203 100644
--- a/DOCS/interface-changes.rst
+++ b/DOCS/interface-changes.rst
@@ -19,6 +19,8 @@ Interface changes
::
+ --- mpv 0.14.0 ---
+ - add "vsync-ratio" property
--- mpv 0.13.0 ---
- remove VO opengl-cb frame queue suboptions (no replacement)
--- mpv 0.12.0 ---
diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst
index 50ac4dbfbf..0233dbf057 100644
--- a/DOCS/man/input.rst
+++ b/DOCS/man/input.rst
@@ -921,6 +921,13 @@ Property list
(which can happen especially with bad source timestamps). For example,
using the ``display-desync`` mode should never change this value from 0.
+``vsync-ratio``
+ For how many vsyncs a frame is displayed on average. This is available if
+ display-sync is active only. For 30 FPS video on a 60 Hz screen, this will
+ be 2. This is the moving average of what actually has been scheduled, so
+ 24 FPS on 60 Hz will never remain exactly on 2.5, but jitter depending on
+ the last frame displayed.
+
``vo-delayed-frame-count``
Estimated number of frames delayed due to external circumstances in
display-sync mode. Note that in general, mpv has to guess that this is
diff --git a/player/command.c b/player/command.c
index e3b8feab98..eadcc27296 100644
--- a/player/command.c
+++ b/player/command.c
@@ -567,12 +567,34 @@ static int mp_property_mistimed_frame_count(void *ctx, struct m_property *prop,
int action, void *arg)
{
MPContext *mpctx = ctx;
- if (!mpctx->d_video || !mpctx->display_sync_active)
+ if (!mpctx->d_video || !mpctx->display_sync_active)
return M_PROPERTY_UNAVAILABLE;
return m_property_int_ro(action, arg, mpctx->mistimed_frames_total);
}
+static int mp_property_vsync_ratio(void *ctx, struct m_property *prop,
+ int action, void *arg)
+{
+ MPContext *mpctx = ctx;
+ if (!mpctx->d_video || !mpctx->display_sync_active)
+ return M_PROPERTY_UNAVAILABLE;
+
+ int vsyncs = 0, frames = 0;
+ for (int n = 0; n < mpctx->num_past_frames; n++) {
+ int vsync = mpctx->past_frames[n].num_vsyncs;
+ if (vsync < 0)
+ break;
+ vsyncs += vsync;
+ frames += 1;
+ }
+
+ if (!frames)
+ return M_PROPERTY_UNAVAILABLE;
+
+ return m_property_double_ro(action, arg, vsyncs / (double)frames);
+}
+
static int mp_property_vo_drop_frame_count(void *ctx, struct m_property *prop,
int action, void *arg)
{
@@ -3394,6 +3416,7 @@ static const struct m_property mp_properties[] = {
{"total-avsync-change", mp_property_total_avsync_change},
{"drop-frame-count", mp_property_drop_frame_cnt},
{"mistimed-frame-count", mp_property_mistimed_frame_count},
+ {"vsync-ratio", mp_property_vsync_ratio},
{"vo-drop-frame-count", mp_property_vo_drop_frame_count},
{"vo-delayed-frame-count", mp_property_vo_delayed_frame_count},
{"percent-pos", mp_property_percent_pos},
@@ -3612,7 +3635,7 @@ static const char *const *const mp_event_property_change[] = {
"percent-pos", "time-remaining", "playtime-remaining", "playback-time",
"estimated-vf-fps", "drop-frame-count", "vo-drop-frame-count",
"total-avsync-change", "audio-speed-correction", "video-speed-correction",
- "vo-delayed-frame-count", "mistimed-frame-count"),
+ "vo-delayed-frame-count", "mistimed-frame-count", "vsync-ratio"),
E(MPV_EVENT_VIDEO_RECONFIG, "video-out-params", "video-params",
"video-format", "video-codec", "video-bitrate", "dwidth", "dheight",
"width", "height", "fps", "aspect", "vo-configured", "current-vo",
diff --git a/player/core.h b/player/core.h
index fcdf0e3595..7031efc107 100644
--- a/player/core.h
+++ b/player/core.h
@@ -99,6 +99,7 @@ struct frame_info {
double pts;
double duration; // PTS difference to next frame
double approx_duration; // possibly fixed/smoothed out duration
+ int num_vsyncs; // scheduled vsyncs, if using display-sync
};
struct track {
diff --git a/player/video.c b/player/video.c
index 8ee9c87e93..5ef327aa09 100644
--- a/player/video.c
+++ b/player/video.c
@@ -1001,6 +1001,8 @@ static void handle_display_sync_frame(struct MPContext *mpctx,
mpctx->total_avsync_change = 0;
update_av_diff(mpctx, time_left * opts->playback_speed);
+ mpctx->past_frames[0].num_vsyncs = num_vsyncs;
+
if (resample)
adjust_audio_speed(mpctx, vsync);
@@ -1177,9 +1179,10 @@ void write_video(struct MPContext *mpctx, double endpts)
mpctx->num_past_frames--;
MP_TARRAY_INSERT_AT(mpctx, mpctx->past_frames, mpctx->num_past_frames, 0,
(struct frame_info){0});
- struct frame_info *frame_info = &mpctx->past_frames[0];
-
- frame_info->pts = mpctx->next_frames[0]->pts;
+ mpctx->past_frames[0] = (struct frame_info){
+ .pts = mpctx->next_frames[0]->pts,
+ .num_vsyncs = -1,
+ };
calculate_frame_duration(mpctx);
struct vo_frame dummy = {
@@ -1193,7 +1196,7 @@ void write_video(struct MPContext *mpctx, double endpts)
dummy.frames[n] = mpctx->next_frames[n];
struct vo_frame *frame = vo_frame_ref(&dummy);
- double diff = frame_info->approx_duration;
+ double diff = mpctx->past_frames[0].approx_duration;
if (opts->untimed || vo->driver->untimed)
diff = -1; // disable frame dropping and aspects of frame timing
if (diff >= 0) {