diff options
author | wm4 <wm4@nowhere> | 2016-01-12 23:49:00 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-01-12 23:49:00 +0100 |
commit | e420464ba693a5920d4dc172b3f7e9a0c725e3d4 (patch) | |
tree | e149445377e94da3274f7d3f588449ed24ece3c1 /player/video.c | |
parent | 6fc0fe4426c1b71630d281cbc9e0406f8ad7deee (diff) | |
download | mpv-e420464ba693a5920d4dc172b3f7e9a0c725e3d4.tar.bz2 mpv-e420464ba693a5920d4dc172b3f7e9a0c725e3d4.tar.xz |
player: simplify backstepping
Basically reimplement it. The old implementation was quite stupid, and
was probably done this way because video filtering and output used to be
way less decoupled. Now we can reimplement it in a very simple way: when
backstepping, seek to current time, but keep the last frame that was
supposed to be discarded when reaching the target time. When the seek
finishes, prepend the saved frame to the video frame queue.
A disadvantage is that the new implementation fails to skip over
timeline boundaries (ordered chapters etc.), but this never worked
properly anyway. It's possible that this will be fixed some time in the
future.
Diffstat (limited to 'player/video.c')
-rw-r--r-- | player/video.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/player/video.c b/player/video.c index 28c6ac4d5c..33f3b4b970 100644 --- a/player/video.c +++ b/player/video.c @@ -310,7 +310,6 @@ int reinit_video_chain(struct MPContext *mpctx) vo_set_paused(mpctx->video_out, mpctx->paused); mpctx->sync_audio_to_video = !sh->attached_picture; - mpctx->vo_pts_history_seek_ts++; // If we switch on video again, ensure audio position matches up. if (mpctx->d_audio) @@ -603,7 +602,7 @@ static int get_req_frames(struct MPContext *mpctx, bool eof) return mpctx->opts->video_sync == VS_DEFAULT ? 1 : 2; int req = vo_get_num_req_frames(mpctx->video_out); - return MPCLAMP(req, 2, MP_ARRAY_SIZE(mpctx->next_frames)); + return MPCLAMP(req, 2, MP_ARRAY_SIZE(mpctx->next_frames) - 1); } // Whether it's fine to call add_new_frame() now. @@ -615,7 +614,7 @@ static bool needs_new_frame(struct MPContext *mpctx) // Queue a frame to mpctx->next_frames[]. Call only if needs_new_frame() signals ok. static void add_new_frame(struct MPContext *mpctx, struct mp_image *frame) { - assert(needs_new_frame(mpctx)); + assert(mpctx->num_next_frames < MP_ARRAY_SIZE(mpctx->next_frames)); assert(frame); mpctx->next_frames[mpctx->num_next_frames++] = frame; if (mpctx->num_next_frames == 1) @@ -662,9 +661,6 @@ static int video_output_image(struct MPContext *mpctx, double endpts) return r; // error struct mp_image *img = vf_read_output_frame(mpctx->d_video->vfilter); if (img) { - // Always add these; they make backstepping after seeking faster. - add_frame_pts(mpctx, img->pts); - if (endpts != MP_NOPTS_VALUE && img->pts >= endpts) { r = VD_EOF; } else if (mpctx->max_frames == 0) { @@ -672,8 +668,19 @@ static int video_output_image(struct MPContext *mpctx, double endpts) } else if (hrseek && mpctx->hrseek_lastframe) { mp_image_setrefp(&mpctx->saved_frame, img); } else if (hrseek && img->pts < mpctx->hrseek_pts - .005) { - /* just skip */ + /* just skip - but save if backstep active */ + if (mpctx->hrseek_backstep) + mp_image_setrefp(&mpctx->saved_frame, img); } else { + if (mpctx->hrseek_backstep) { + if (mpctx->saved_frame) { + add_new_frame(mpctx, mpctx->saved_frame); + mpctx->saved_frame = NULL; + } else { + MP_WARN(mpctx, "Backstep failed.\n"); + } + mpctx->hrseek_backstep = false; + } add_new_frame(mpctx, img); img = NULL; } |