summaryrefslogtreecommitdiffstats
path: root/player/playloop.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-08-21 15:37:07 +0200
committerwm4 <wm4@nowhere>2015-08-21 15:37:07 +0200
commit2e3ce738f566cfa8fbb8b7eb5826fe2fe6b8b8f6 (patch)
treefc4116ca095f4dfa6fa02ba2974054fccfaf7936 /player/playloop.c
parent8a9fc9398d24e7ebb205172d36ea74b9191f68a1 (diff)
downloadmpv-2e3ce738f566cfa8fbb8b7eb5826fe2fe6b8b8f6.tar.bz2
mpv-2e3ce738f566cfa8fbb8b7eb5826fe2fe6b8b8f6.tar.xz
player: return better guess for playback time during seeks
Always compute the estimated absolute time of the seek target, and display this as playback time during seeks. Improves behavior with e.g. .ts files, for which we try to avoid seeks by timestamp.
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