command: add vsync-ratio property

This is very "illustrative", unlike the video-speed-correction
property, and thus useful. It can also be used to observe scheduling
errors, which are not detected by the core. (These happen due to
rounding errors; possibly not evne our fault, but coming from
files with rounded timestamps and so on.)
This commit is contained in:
wm4 2015-11-13 22:48:32 +01:00
parent 62b386c2fd
commit d5981924fe
5 changed files with 42 additions and 6 deletions

View File

@ -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 ---

View File

@ -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

View File

@ -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",

View File

@ -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 {

View File

@ -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) {