From 90010836852927833f1f8afca28489382ff4dd83 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 28 Feb 2016 19:43:07 +0100 Subject: player: simplify mp_seek() --- player/playloop.c | 101 +++++++++++++++++++++++++----------------------------- 1 file changed, 46 insertions(+), 55 deletions(-) diff --git a/player/playloop.c b/player/playloop.c index 07a21e462c..63234812d4 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -185,7 +185,7 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek) { struct MPOpts *opts = mpctx->opts; - if (!mpctx->demuxer) + if (!mpctx->demuxer || seek.type == MPSEEK_NONE || seek.amount == MP_NOPTS_VALUE) return -1; if (!mpctx->demuxer->seekable) { @@ -193,108 +193,99 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek) return -1; } - if (mpctx->stop_play == AT_END_OF_FILE) - mpctx->stop_play = KEEP_PLAYING; - - double hr_seek_offset = opts->hr_seek_demuxer_offset; bool hr_seek_very_exact = seek.exact == MPSEEK_VERY_EXACT; - // 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 (hr_seek_very_exact) - hr_seek_offset = MPMAX(hr_seek_offset, 0.5); // arbitrary - - double target_time = MP_NOPTS_VALUE; - int direction = 0; - bool backstep = false; + double current_time = get_current_time(mpctx); + if (current_time == MP_NOPTS_VALUE) + current_time = 0; + double seek_pts = MP_NOPTS_VALUE; + int demux_flags = 0; switch (seek.type) { case MPSEEK_ABSOLUTE: - target_time = seek.amount; + seek_pts = seek.amount; break; case MPSEEK_BACKSTEP: - seek.type = MPSEEK_ABSOLUTE; - seek.amount = get_current_time(mpctx); - if (seek.amount == MP_NOPTS_VALUE) - seek.amount = 0; - target_time = seek.amount; - backstep = true; + seek_pts = current_time; + hr_seek_very_exact = true; break; case MPSEEK_RELATIVE: - direction = seek.amount > 0 ? 1 : -1; - double cur = get_current_time(mpctx); - target_time = seek.amount + (cur == MP_NOPTS_VALUE ? 0 : cur); + demux_flags = seek.amount > 0 ? SEEK_FORWARD : SEEK_BACKWARD; + seek_pts = current_time + seek.amount; break; case MPSEEK_FACTOR: ; double len = get_time_length(mpctx); if (len >= 0) - target_time = seek.amount * len; + seek_pts = seek.amount * len; + demux_flags = seek_pts > current_time ? SEEK_FORWARD : SEEK_BACKWARD; break; + default: abort(); } - bool hr_seek = opts->correct_pts && seek.exact != MPSEEK_KEYFRAME; - hr_seek &= (opts->hr_seek == 0 && seek.type == MPSEEK_ABSOLUTE) || - opts->hr_seek > 0 || seek.exact >= MPSEEK_EXACT; + double demux_pts = seek_pts; + + bool hr_seek = opts->correct_pts && seek.exact != MPSEEK_KEYFRAME && + ((opts->hr_seek == 0 && seek.type == MPSEEK_ABSOLUTE) || + opts->hr_seek > 0 || seek.exact >= MPSEEK_EXACT) && + seek_pts != MP_NOPTS_VALUE; + if (seek.type == MPSEEK_FACTOR || seek.amount < 0 || (seek.type == MPSEEK_ABSOLUTE && seek.amount < mpctx->last_chapter_pts)) mpctx->last_chapter_seek = -2; - // Prefer doing absolute seeks, unless not possible. - if ((seek.type == MPSEEK_FACTOR && !mpctx->demuxer->ts_resets_possible && - target_time != MP_NOPTS_VALUE) || seek.type == MPSEEK_RELATIVE) + // Under certain circumstances, prefer SEEK_FACTOR. + if (seek.type == MPSEEK_FACTOR && !hr_seek && + (mpctx->demuxer->ts_resets_possible || seek_pts == MP_NOPTS_VALUE)) { - seek.type = MPSEEK_ABSOLUTE; - seek.amount = target_time; + demux_pts = seek.amount; + demux_flags |= SEEK_FACTOR; } - hr_seek &= seek.type == MPSEEK_ABSOLUTE; // otherwise, no target PTS known - - double demuxer_amount = seek.amount; - - int demuxer_style = seek.type == MPSEEK_FACTOR ? SEEK_FACTOR : 0; - if (hr_seek || direction < 0) { - demuxer_style |= SEEK_BACKWARD; - } else if (direction > 0) { - demuxer_style |= SEEK_FORWARD; + if (hr_seek) { + 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 (hr_seek_very_exact) + hr_seek_offset = MPMAX(hr_seek_offset, 0.5); // arbitrary + demux_pts -= hr_seek_offset; + demux_flags = (demux_flags | SEEK_HR | SEEK_BACKWARD) & ~SEEK_FORWARD; } - if (hr_seek) - demuxer_style |= SEEK_HR; - if (hr_seek) - demuxer_amount -= hr_seek_offset; - demux_seek(mpctx->demuxer, demuxer_amount, demuxer_style); + demux_seek(mpctx->demuxer, demux_pts, demux_flags); // Seek external, extra files too: for (int t = 0; t < mpctx->num_tracks; t++) { struct track *track = mpctx->tracks[t]; if (track->selected && track->is_external && track->demuxer) { - double main_new_pos = demuxer_amount; - if (seek.type != MPSEEK_ABSOLUTE) - main_new_pos = target_time; + double main_new_pos = demux_pts; + if (demux_flags & SEEK_FACTOR) + main_new_pos = seek_pts; demux_seek(track->demuxer, main_new_pos, 0); } } clear_audio_output_buffers(mpctx); - reset_playback_state(mpctx); /* Use the target time as "current position" for further relative * seeks etc until a new video frame has been decoded */ - mpctx->last_seek_pts = target_time; + mpctx->last_seek_pts = seek_pts; if (hr_seek) { mpctx->hrseek_active = true; mpctx->hrseek_framedrop = !hr_seek_very_exact && opts->hr_seek_framedrop; - mpctx->hrseek_backstep = backstep; - mpctx->hrseek_pts = seek.amount; + mpctx->hrseek_backstep = seek.type == MPSEEK_BACKSTEP; + mpctx->hrseek_pts = seek_pts; MP_VERBOSE(mpctx, "hr-seek, skipping to %f%s%s\n", mpctx->hrseek_pts, mpctx->hrseek_framedrop ? "" : " (no framedrop)", mpctx->hrseek_backstep ? " (backstep)" : ""); } + if (mpctx->stop_play == AT_END_OF_FILE) + mpctx->stop_play = KEEP_PLAYING; + mpctx->start_timestamp = mp_time_sec(); mpctx->sleeptime = 0; -- cgit v1.2.3