summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-08-04 11:26:57 +0200
committerwm4 <wm4@nowhere>2016-08-04 11:26:57 +0200
commit3c3361217c96337270b112e52f9eb6cc5931b390 (patch)
treeb1133f42294800b4da44730c6869db2ec589f80f
parent356e703510170151a1678e9b1deab2ffdd5c92fb (diff)
downloadmpv-3c3361217c96337270b112e52f9eb6cc5931b390.tar.bz2
mpv-3c3361217c96337270b112e52f9eb6cc5931b390.tar.xz
player: offset demuxer on start/seek properly with audio/sub delay
Assume you use a large value like --audio-delay=20. Then until now the player would just have seeked normally to a "too late" position, and played silence for about 20 seconds until audio in the correct time range is coming again. Change this by offsetting seeks by the right amount. This works for both external and muxed files. If a seek isn't precise, then it works only for external files. This might cause issues with very large delay options. Hr-seek skipping could take a lot of time (especially because it affects video too), the demuxer queue could overflow, and other weird corner cases could appear. But we just try this on best-effort basis, and if the user uses extreme values we don't guarantee good behavior.
-rw-r--r--player/core.h1
-rw-r--r--player/loadfile.c1
-rw-r--r--player/misc.c12
-rw-r--r--player/playloop.c8
4 files changed, 22 insertions, 0 deletions
diff --git a/player/core.h b/player/core.h
index f2a9f191fa..1dc6da7331 100644
--- a/player/core.h
+++ b/player/core.h
@@ -486,6 +486,7 @@ int stream_dump(struct MPContext *mpctx, const char *source_filename);
int mpctx_run_reentrant(struct MPContext *mpctx, void (*thread_fn)(void *arg),
void *thread_arg);
struct mpv_global *create_sub_global(struct MPContext *mpctx);
+double get_track_seek_offset(struct MPContext *mpctx, struct track *track);
// osd.c
void set_osd_bar(struct MPContext *mpctx, int type,
diff --git a/player/loadfile.c b/player/loadfile.c
index 94d0b2bd5d..3d04a3720d 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -208,6 +208,7 @@ void reselect_demux_stream(struct MPContext *mpctx, struct track *track)
double pts = get_current_time(mpctx);
if (pts == MP_NOPTS_VALUE)
pts = 0;
+ pts += get_track_seek_offset(mpctx, track);
demux_seek(track->demuxer, pts, 0);
}
}
diff --git a/player/misc.c b/player/misc.c
index 941c493cf2..a9174c41a9 100644
--- a/player/misc.c
+++ b/player/misc.c
@@ -93,6 +93,18 @@ double get_play_end_pts(struct MPContext *mpctx)
return end;
}
+double get_track_seek_offset(struct MPContext *mpctx, struct track *track)
+{
+ struct MPOpts *opts = mpctx->opts;
+ if (track->selected) {
+ if (track->type == STREAM_AUDIO)
+ return -opts->audio_delay;
+ if (track->type == STREAM_SUB)
+ return -opts->sub_delay;
+ }
+ return 0;
+}
+
float mp_get_cache_percent(struct MPContext *mpctx)
{
struct stream_cache_info info = {0};
diff --git a/player/playloop.c b/player/playloop.c
index fd16c78e68..da3e995975 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -247,6 +247,12 @@ static void mp_seek(MPContext *mpctx, struct seek_params seek)
// 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
+ for (int n = 0; n < mpctx->num_tracks; n++) {
+ double offset = 0;
+ if (!mpctx->tracks[n]->is_external)
+ offset += get_track_seek_offset(mpctx, mpctx->tracks[n]);
+ hr_seek_offset = MPMAX(hr_seek_offset, -offset);
+ }
demux_pts -= hr_seek_offset;
demux_flags = (demux_flags | SEEK_HR | SEEK_BACKWARD) & ~SEEK_FORWARD;
}
@@ -258,6 +264,8 @@ static void mp_seek(MPContext *mpctx, struct seek_params seek)
struct track *track = mpctx->tracks[t];
if (track->selected && track->is_external && track->demuxer) {
double main_new_pos = demux_pts;
+ if (!hr_seek || track->is_external)
+ main_new_pos += get_track_seek_offset(mpctx, track);
if (demux_flags & SEEK_FACTOR)
main_new_pos = seek_pts;
demux_seek(track->demuxer, main_new_pos, 0);