summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-04-25 14:56:01 +0200
committerwm4 <wm4@nowhere>2013-04-25 15:09:20 +0200
commit9d9d6517d26f0c6407d2f850f0d3417068d58291 (patch)
tree3dc4d46415dc726c6faaf864e6b01ab1c73a0968
parent55262a442762f82fe818241dfe3dbecc1f42e295 (diff)
downloadmpv-9d9d6517d26f0c6407d2f850f0d3417068d58291.tar.bz2
mpv-9d9d6517d26f0c6407d2f850f0d3417068d58291.tar.xz
core: fix backstepping with ordered chapters
There were two problems. First, frames past the end of the current segment were added to the index, which messed up backstepping. Check for the endpts before added a frame to the index. Second, it wasn't possible to step over segments which change the file. Changing a file causes decoder reinitialization, which (rightfully) is treated as discontinuity (and vo_pts_history_seek_ts was changed). Add some extra code to pretend that a segment-switching seek/reinit does not introduce discontinuities. There's still a weird corner case: sometimes, you can frame step forward on the last frame of a segment without reaching the next segment immediately. This is because the playloop switches into audio-only mode. The segment is switched when both audio and video have ended, so the frame stepping will play random sized chunks of audio until the segment will be switched. This gives the impression that backstepping doesn't work perfectly, even though it's the other way around and frame stepping behaves weird. This is a consequence of wanting to make frame stepping work with audio, and is not really a bug.
-rw-r--r--core/mplayer.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/core/mplayer.c b/core/mplayer.c
index 08a3d8256d..36d0d59998 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -2549,7 +2549,7 @@ static void determine_frame_pts(struct MPContext *mpctx)
sh_video->codec_reordered_pts : sh_video->sorted_pts;
}
-static double update_video(struct MPContext *mpctx)
+static double update_video(struct MPContext *mpctx, double endpts)
{
struct sh_video *sh_video = mpctx->sh_video;
struct vo *video_out = mpctx->video_out;
@@ -2606,7 +2606,8 @@ static double update_video(struct MPContext *mpctx)
if (pts == MP_NOPTS_VALUE)
pts = sh_video->last_pts;
}
- add_frame_pts(mpctx, pts);
+ if (endpts != MP_NOPTS_VALUE && pts < endpts)
+ add_frame_pts(mpctx, pts);
if (mpctx->hrseek_active && pts < mpctx->hrseek_pts - .005) {
vo_skip_frame(video_out);
return 0;
@@ -2745,8 +2746,6 @@ static void seek_reset(struct MPContext *mpctx, bool reset_ao, bool reset_ac)
mpctx->drop_frame_cnt = 0;
mpctx->dropped_frames = 0;
mpctx->playback_pts = MP_NOPTS_VALUE;
- mpctx->vo_pts_history_seek_ts++;
- mpctx->backstep_active = false;
#ifdef CONFIG_ENCODING
encode_lavc_discontinuity(mpctx->encode_lavc_ctx);
@@ -2809,6 +2808,7 @@ static int seek(MPContext *mpctx, struct seek_params seek,
bool timeline_fallthrough)
{
struct MPOpts *opts = &mpctx->opts;
+ uint64_t prev_seek_ts = mpctx->vo_pts_history_seek_ts;
if (!mpctx->demuxer)
return -1;
@@ -2915,6 +2915,14 @@ static int seek(MPContext *mpctx, struct seek_params seek,
* and resetting could lose audio some decoders produce during init. */
seek_reset(mpctx, !timeline_fallthrough, !need_reset);
+ if (timeline_fallthrough) {
+ // Important if video reinit happens.
+ mpctx->vo_pts_history_seek_ts = prev_seek_ts;
+ } else {
+ mpctx->vo_pts_history_seek_ts++;
+ mpctx->backstep_active = false;
+ }
+
/* Use the target time as "current position" for further relative
* seeks etc until a new video frame has been decoded */
if (seek.type == MPSEEK_ABSOLUTE) {
@@ -3266,7 +3274,7 @@ static void run_playloop(struct MPContext *mpctx)
video_left = vo->hasframe || vo->frame_loaded;
if (!vo->frame_loaded && (!mpctx->paused || mpctx->restart_playback)) {
- double frame_time = update_video(mpctx);
+ double frame_time = update_video(mpctx, endpts);
mp_dbg(MSGT_AVSYNC, MSGL_DBG2, "*** ftime=%5.3f ***\n", frame_time);
if (mpctx->sh_video->vf_initialized < 0) {
mp_tmsg(MSGT_CPLAYER, MSGL_FATAL,