summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-11-28 15:10:51 +0100
committerwm4 <wm4@nowhere>2013-11-28 15:20:33 +0100
commit5411fbdb2341433dfa3241034390c19c257ce57e (patch)
tree20f1651bc7e0dddb91bf9aa6e3809c03e635c4c1
parentdc0b2046cdeb0bbf78e7012d9eafa29a2888b1ec (diff)
downloadmpv-5411fbdb2341433dfa3241034390c19c257ce57e.tar.bz2
mpv-5411fbdb2341433dfa3241034390c19c257ce57e.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.
-rw-r--r--mpvcore/player/playloop.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/mpvcore/player/playloop.c b/mpvcore/player/playloop.c
index 9ec62834b4..a0127f7339 100644
--- a/mpvcore/player/playloop.c
+++ b/mpvcore/player/playloop.c
@@ -219,6 +219,15 @@ static int mp_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) ||
@@ -279,7 +288,7 @@ static int mp_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)
@@ -795,14 +804,14 @@ static void handle_backstep(struct MPContext *mpctx)
if (demuxer_ok && mpctx->d_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_ERR(mpctx, "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_VERBOSE(mpctx, "Start backstep indexing.\n");
// Force it to index the video up until current_pts.