summaryrefslogtreecommitdiffstats
path: root/player/playloop.c
diff options
context:
space:
mode:
Diffstat (limited to 'player/playloop.c')
-rw-r--r--player/playloop.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/player/playloop.c b/player/playloop.c
index e20e088e00..67e7f22001 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -151,6 +151,7 @@ void reset_playback_state(struct MPContext *mpctx)
mpctx->hrseek_active = false;
mpctx->hrseek_framedrop = false;
+ mpctx->hrseek_lastframe = false;
mpctx->playback_pts = MP_NOPTS_VALUE;
mpctx->last_seek_pts = MP_NOPTS_VALUE;
mpctx->cache_wait_time = 0;
@@ -780,6 +781,28 @@ static void handle_loop_file(struct MPContext *mpctx)
}
}
+static void seek_to_last_frame(struct MPContext *mpctx)
+{
+ if (!mpctx->d_video)
+ return;
+ MP_VERBOSE(mpctx, "seeking to last frame...\n");
+ // Approximately seek close to the end of the file.
+ // Usually, it will seek some seconds before end.
+ double end = get_play_end_pts(mpctx);
+ if (end == MP_NOPTS_VALUE)
+ end = get_time_length(mpctx);
+ mp_seek(mpctx, (struct seek_params){
+ .type = MPSEEK_ABSOLUTE,
+ .amount = end,
+ .exact = 2, // "very exact", no framedrop
+ }, false);
+ // Make it exact: stop seek only if last frame was reached.
+ if (mpctx->hrseek_active) {
+ mpctx->hrseek_pts = 1e99; // "infinite"
+ mpctx->hrseek_lastframe = true;
+ }
+}
+
static void handle_keep_open(struct MPContext *mpctx)
{
struct MPOpts *opts = mpctx->opts;
@@ -787,8 +810,11 @@ static void handle_keep_open(struct MPContext *mpctx)
!playlist_get_next(mpctx->playlist, 1) && opts->loop_times < 0)
{
mpctx->stop_play = KEEP_PLAYING;
- if (mpctx->d_video)
+ if (mpctx->d_video) {
+ if (!vo_has_frame(mpctx->video_out)) // EOF not reached normally
+ seek_to_last_frame(mpctx);
mpctx->playback_pts = mpctx->last_vo_pts;
+ }
if (!mpctx->opts->pause)
pause_player(mpctx);
}