[MPlayer-dev-eng] [PATCH] mplayer.c: Improved timing for long duration video-only.

Reimar Döffinger Reimar.Doeffinger at gmx.de
Tue Mar 7 22:35:41 EET 2017


In particularly when double-buffering is disabled, but
also when vo_gl needs to refresh, a buffered frame will
be displayed before it is time to do so.
To reduce the impact of this, buffer at most 0.5s ahead.
Also fix a bug where the duration of the buffered frame
would be added on top of time for the currently displayed
time.

Fixes the later samples of issue #2315, but probably
not the original issue.
---
 mp_core.h |  1 +
 mplayer.c | 17 ++++++++++++++---
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/mp_core.h b/mp_core.h
index 91d121b5f..b54dab4ca 100644
--- a/mp_core.h
+++ b/mp_core.h
@@ -91,6 +91,7 @@ typedef struct MPContext {
     // This is really a vo variable but currently there's no suitable vo
     // struct.
     int num_buffered_frames;
+    double buffered_frame_time; // duration of frame buffered for flip
 
     // used to retry decoding after startup/seeking to compensate for codec delay
     int startup_decode_retry;
diff --git a/mplayer.c b/mplayer.c
index b0d1f1f19..5042c7d33 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -3793,7 +3793,7 @@ goto_enable_cache:
                 update_osd_msg();
             } else {
                 int frame_time_remaining = 0;
-                int blit_frame = 1;
+                int blit_frame = mpctx->num_buffered_frames > 0;
                 // skip timing after seek
                 int skip_timing = mpctx->startup_decode_retry > 0;
 
@@ -3802,7 +3802,16 @@ goto_enable_cache:
                 vo_pts = mpctx->sh_video->timer * 90000.0;
                 vo_fps = mpctx->sh_video->fps;
 
-                if (!mpctx->num_buffered_frames) {
+                // Do not update the vo if a lot of time is left.
+                // If double-buffering is disabled, that would result
+                // in displaying the frame too early, so use a very tight limit
+                // (50ms) in that case.
+                // If double-buffering is enabled we should still not completely
+                // mess up timing if either the vo is buggy or (like vo_gl when
+                // a redraw is required) in some cases might use the next frame
+                // before a flip.
+                mpctx->time_frame -= GetRelativeTime();
+                if (!mpctx->num_buffered_frames && mpctx->time_frame < (vo_doublebuffering ? 0.5 : 0.05)) {
                     double frame_time = update_video(&blit_frame);
                     while (!blit_frame && mpctx->startup_decode_retry > 0) {
                         double delay = mpctx->delay;
@@ -3830,7 +3839,7 @@ goto_enable_cache:
                     } else {
                         // might return with !eof && !blit_frame if !correct_pts
                         mpctx->num_buffered_frames += blit_frame;
-                        mpctx->time_frame += frame_time / playback_speed; // for nosound
+                        mpctx->buffered_frame_time = frame_time;
                     }
                 }
 
@@ -3873,6 +3882,8 @@ goto_enable_cache:
                         if (vo_config_count)
                             mpctx->video_out->flip_page();
                         mpctx->num_buffered_frames--;
+                        mpctx->time_frame += mpctx->buffered_frame_time / playback_speed; // for nosound
+                        mpctx->buffered_frame_time = 0;
 
                         vout_time_usage += (GetTimer() - t2) * 0.000001;
                     }
-- 
2.11.0



More information about the MPlayer-dev-eng mailing list