summaryrefslogtreecommitdiffstats
path: root/player/playloop.c
diff options
context:
space:
mode:
Diffstat (limited to 'player/playloop.c')
-rw-r--r--player/playloop.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/player/playloop.c b/player/playloop.c
index 2ab5f39dac..2ebfa9d2ef 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -190,25 +190,40 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
if (hr_seek_very_exact)
hr_seek_offset = MPMAX(hr_seek_offset, 0.5); // arbitrary
+ double target_time = MP_NOPTS_VALUE;
+ int direction = 0;
+
+ switch (seek.type) {
+ case MPSEEK_ABSOLUTE:
+ target_time = seek.amount;
+ break;
+ case MPSEEK_RELATIVE:
+ direction = seek.amount > 0 ? 1 : -1;
+ target_time = seek.amount + get_current_time(mpctx);
+ break;
+ case MPSEEK_FACTOR: ;
+ double len = get_time_length(mpctx);
+ if (len >= 0)
+ target_time = seek.amount * len + get_start_time(mpctx);
+ break;
+ }
+
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;
if (seek.type == MPSEEK_FACTOR || seek.amount < 0 ||
(seek.type == MPSEEK_ABSOLUTE && seek.amount < mpctx->last_chapter_pts))
mpctx->last_chapter_seek = -2;
- if (seek.type == MPSEEK_FACTOR && !mpctx->demuxer->ts_resets_possible) {
- double len = get_time_length(mpctx);
- if (len >= 0) {
- seek.amount = seek.amount * len + get_start_time(mpctx);
- seek.type = MPSEEK_ABSOLUTE;
- }
- }
- int direction = 0;
- if (seek.type == MPSEEK_RELATIVE && (!mpctx->demuxer->rel_seeks || hr_seek)) {
+
+ // 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 && (!mpctx->demuxer->rel_seeks || hr_seek)))
+ {
seek.type = MPSEEK_ABSOLUTE;
- direction = seek.amount > 0 ? 1 : -1;
- seek.amount += get_current_time(mpctx);
+ seek.amount = target_time;
}
+
hr_seek &= seek.type == MPSEEK_ABSOLUTE; // otherwise, no target PTS known
double demuxer_amount = seek.amount;
@@ -273,8 +288,7 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
/* 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)
- mpctx->last_seek_pts = seek.amount;
+ mpctx->last_seek_pts = target_time;
// The hr_seek==false case is for skipping frames with PTS before the
// current timeline chapter start. It's not really known where the demuxer