summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-11-28 15:10:51 +0100
committerwm4 <wm4@nowhere>2013-12-01 19:39:21 +0100
commit93518bc6527451d582d757393c6ec028493e25b6 (patch)
tree70c1ef41f4f9d7557e44d1a02b8ddb20f15a137c
parent38885269b326941a4f65450c22390580ce254b3e (diff)
downloadmpv-93518bc6527451d582d757393c6ec028493e25b6.tar.bz2
mpv-93518bc6527451d582d757393c6ec028493e25b6.tar.xz
player: simple hack to make backstep code somewhat more robust
The hr-seek code assumes that when seeking the demuxer, the first image decoded after the seek will have a PTS exactly equal to the demuxer seek target time, or before that target time. Incorrect timestamps, implicitly dropped initial frames, or broken files/demuxers can all break this assumption, and lead to hr-seek missing the seek target. Generally, this is not much a problem (the user won't notice being off by one frame), but it really shows when using the backstep feature. In this case, backstepping would simply hang. Add a simple hack that basically forces a minimal value for the --hr- seek-demuxer-offset option (which is 0 by default) when doing a backstep-seek. The chosen minimum value is arbitrary. There's no perfect value, though in general it should perhaps be slightly longer than the frametime, which the chosen value is more than enough for typical framerates. Conflicts: mpvcore/player/playloop.c
-rw-r--r--mpvcore/mplayer.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/mpvcore/mplayer.c b/mpvcore/mplayer.c
index f2eb2e24dd..0b8b36eb56 100644
--- a/mpvcore/mplayer.c
+++ b/mpvcore/mplayer.c
@@ -2994,6 +2994,15 @@ static int seek(MPContext *mpctx, struct seek_params seek,
if (mpctx->stop_play == AT_END_OF_FILE)
mpctx->stop_play = KEEP_PLAYING;
+
+ double hr_seek_offset = opts->hr_seek_demuxer_offset;
+ // Always try to compensate for possibly bad demuxers in "special"
+ // situations where we need more robustness from the hr-seek code, even
+ // if the user doesn't use --hr-seek-demuxer-offset.
+ // The value is arbitrary, but should be "good enough" in most situations.
+ if (seek.exact > 1)
+ hr_seek_offset = MPMAX(hr_seek_offset, 0.5); // arbitrary
+
bool hr_seek = mpctx->demuxer->accurate_seek && opts->correct_pts;
hr_seek &= seek.exact >= 0 && seek.type != MPSEEK_FACTOR;
hr_seek &= (opts->hr_seek == 0 && seek.type == MPSEEK_ABSOLUTE) ||
@@ -3056,7 +3065,7 @@ static int seek(MPContext *mpctx, struct seek_params seek,
demuxer_style |= SEEK_SUBPREROLL;
if (hr_seek)
- demuxer_amount -= opts->hr_seek_demuxer_offset;
+ demuxer_amount -= hr_seek_offset;
int seekresult = demux_seek(mpctx->demuxer, demuxer_amount, demuxer_style);
if (seekresult == 0) {
if (need_reset) {
@@ -3516,14 +3525,14 @@ static void handle_backstep(struct MPContext *mpctx)
if (demuxer_ok && mpctx->sh_video && current_pts != MP_NOPTS_VALUE) {
double seek_pts = find_previous_pts(mpctx, current_pts);
if (seek_pts != MP_NOPTS_VALUE) {
- queue_seek(mpctx, MPSEEK_ABSOLUTE, seek_pts, 1);
+ queue_seek(mpctx, MPSEEK_ABSOLUTE, seek_pts, 2);
} else {
double last = get_last_frame_pts(mpctx);
if (last != MP_NOPTS_VALUE && last >= current_pts &&
mpctx->backstep_start_seek_ts != mpctx->vo_pts_history_seek_ts)
{
mp_msg(MSGT_CPLAYER, MSGL_ERR, "Backstep failed.\n");
- queue_seek(mpctx, MPSEEK_ABSOLUTE, current_pts, 1);
+ queue_seek(mpctx, MPSEEK_ABSOLUTE, current_pts, 2);
} else if (!mpctx->hrseek_active) {
mp_msg(MSGT_CPLAYER, MSGL_V, "Start backstep indexing.\n");
// Force it to index the video up until current_pts.