diff options
author | wm4 <wm4@nowhere> | 2014-08-15 23:33:33 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-08-15 23:33:33 +0200 |
commit | 543ba6c114303c8c3a71b37864f6d901c41808eb (patch) | |
tree | 3735649107f6df38de3adaf9081ecb672546c7a3 /player | |
parent | 22a95290126398c1f416dbadaf596ba79c872996 (diff) |
video: add VO framedropping mode
This mostly uses the same idea as with vo_vdpau.c, but much simplified.
On X11, it tries to get the display framerate with XF86VM, and limits
the frequency of new video frames against it. Note that this is an old
extension, and is confirmed not to work correctly with multi-monitor
setups. But we're using it because it was already around (it is also
used by vo_vdpau).
This attempts to predict the next vsync event by using the time of the
last frame and the display FPS. Even if that goes completely wrong,
the results are still relatively good.
On other systems, or if the X11 code doesn't return a display FPS, a
framerate of 1000 is assumed. This is infinite for all practical
purposes, and means that only frames which are definitely too late are
dropped. This probably has worse results, but is still useful.
"--framedrop=yes" is basically replaced with "--framedrop=decoder". The
old framedropping mode is kept around, and should perhaps be improved.
Dropping on the decoder level is still useful if decoding itself is too
slow.
Diffstat (limited to 'player')
-rw-r--r-- | player/command.c | 11 | ||||
-rw-r--r-- | player/osd.c | 11 | ||||
-rw-r--r-- | player/playloop.c | 12 | ||||
-rw-r--r-- | player/video.c | 8 |
4 files changed, 30 insertions, 12 deletions
diff --git a/player/command.c b/player/command.c index c0800d612d..9ca2ce8812 100644 --- a/player/command.c +++ b/player/command.c @@ -386,6 +386,16 @@ static int mp_property_drop_frame_cnt(void *ctx, struct m_property *prop, return m_property_int_ro(action, arg, mpctx->drop_frame_cnt); } +static int mp_property_vo_drop_frame_count(void *ctx, struct m_property *prop, + int action, void *arg) +{ + MPContext *mpctx = ctx; + if (!mpctx->d_video) + return M_PROPERTY_UNAVAILABLE; + + return m_property_int_ro(action, arg, vo_get_drop_count(mpctx->video_out)); +} + /// Current position in percent (RW) static int mp_property_percent_pos(void *ctx, struct m_property *prop, int action, void *arg) @@ -2686,6 +2696,7 @@ static const struct m_property mp_properties[] = { {"avsync", mp_property_avsync}, {"total-avsync-change", mp_property_total_avsync_change}, {"drop-frame-count", mp_property_drop_frame_cnt}, + {"vo-drop-frame-count", mp_property_vo_drop_frame_count}, {"percent-pos", mp_property_percent_pos}, {"time-start", mp_property_time_start}, {"time-pos", mp_property_time_pos}, diff --git a/player/osd.c b/player/osd.c index 4efac8e7e9..6fba20468e 100644 --- a/player/osd.c +++ b/player/osd.c @@ -39,6 +39,8 @@ #include "demux/demux.h" #include "sub/osd.h" +#include "video/out/vo.h" + #include "core.h" #include "command.h" @@ -219,8 +221,13 @@ void print_status(struct MPContext *mpctx) #endif { // VO stats - if (mpctx->d_video && mpctx->drop_frame_cnt) - saddf(&line, " Late: %d", mpctx->drop_frame_cnt); + if (mpctx->d_video) { + if (mpctx->drop_frame_cnt) + saddf(&line, " Late: %d", mpctx->drop_frame_cnt); + int64_t c = vo_get_drop_count(mpctx->video_out); + if (c > 0) + saddf(&line, " D: %"PRId64, c); + } } float cache = mp_get_cache_percent(mpctx); diff --git a/player/playloop.c b/player/playloop.c index 33e3f050cd..e3d1ada323 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -66,11 +66,10 @@ void pause_player(struct MPContext *mpctx) mpctx->osd_function = 0; mpctx->paused_for_cache = false; - if (mpctx->video_out && mpctx->d_video && mpctx->video_out->config_ok) - vo_control(mpctx->video_out, VOCTRL_PAUSE, NULL); - if (mpctx->ao && mpctx->d_audio) - ao_pause(mpctx->ao); // pause audio, keep data if possible + ao_pause(mpctx->ao); + if (mpctx->video_out) + vo_set_paused(mpctx->video_out, true); // Only print status if there's actually a file being played. if (mpctx->num_sources) @@ -97,8 +96,9 @@ void unpause_player(struct MPContext *mpctx) if (mpctx->ao && mpctx->d_audio) ao_resume(mpctx->ao); - if (mpctx->video_out && mpctx->d_video && mpctx->video_out->config_ok) - vo_control(mpctx->video_out, VOCTRL_RESUME, NULL); // resume video + if (mpctx->video_out) + vo_set_paused(mpctx->video_out, false); + (void)get_relative_time(mpctx); // ignore time that passed during pause end: diff --git a/player/video.c b/player/video.c index 43b51bfd58..ffe24e621c 100644 --- a/player/video.c +++ b/player/video.c @@ -278,8 +278,7 @@ int reinit_video_chain(struct MPContext *mpctx) vo_control(mpctx->video_out, saver_state ? VOCTRL_RESTORE_SCREENSAVER : VOCTRL_KILL_SCREENSAVER, NULL); - vo_control(mpctx->video_out, mpctx->paused ? VOCTRL_PAUSE - : VOCTRL_RESUME, NULL); + vo_set_paused(mpctx->video_out, mpctx->paused); mpctx->sync_audio_to_video = !sh->attached_picture; mpctx->vo_pts_history_seek_ts++; @@ -343,7 +342,7 @@ static int check_framedrop(struct MPContext *mpctx) if (d < -mpctx->dropped_frames * frame_time - 0.100) { mpctx->drop_frame_cnt++; mpctx->dropped_frames++; - return mpctx->opts->frame_dropping; + return !!(mpctx->opts->frame_dropping & 2); } else mpctx->dropped_frames = 0; } @@ -576,7 +575,8 @@ static int update_video(struct MPContext *mpctx, double endpts) } - bool vo_framedrop = !!mpctx->video_out->driver->flip_page_timed; + //bool vo_framedrop = !!mpctx->video_out->driver->flip_page_timed; + bool vo_framedrop = !!(mpctx->opts->frame_dropping & 1); int min_frames = vo_framedrop ? 2 : 1; // framedrop needs duration // Already enough video buffered? |