summaryrefslogtreecommitdiffstats
path: root/demux/demux_lavf.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-02-22 20:21:03 +0100
committerwm4 <wm4@nowhere>2016-02-22 20:21:13 +0100
commit0e298bb95a67f59c1afb4669c33d66d5ac99fc6e (patch)
treed09e117f476ad8384c607274a7e09c5896bed08a /demux/demux_lavf.c
parent7c181e5b9b3e429d3202a6d28264a36cbd7d9699 (diff)
downloadmpv-0e298bb95a67f59c1afb4669c33d66d5ac99fc6e.tar.bz2
mpv-0e298bb95a67f59c1afb4669c33d66d5ac99fc6e.tar.xz
demux_lavf: adjust seeks by maximum codec delay
Fixes relative seeks. Without this, a seek back could skip so much data that the seek would effectively jump forward. (Or insert silence for files with video.) There's the question whether the frontend should do this instead (by using information from the decoders), but for now this seems more proper. demux_mkv.c does this already, sort of. libavformat doesn't for seeks in .ogg (aka .opus), but might be doing it for mkv. Seems to be a mess as well.
Diffstat (limited to 'demux/demux_lavf.c')
-rw-r--r--demux/demux_lavf.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index 8cd525b685..518dd0f8dd 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -170,6 +170,7 @@ typedef struct lavf_priv {
int cur_program;
char *mime_type;
bool merge_track_metadata;
+ double seek_delay;
} lavf_priv_t;
// At least mp4 has name="mov,mp4,m4a,3gp,3g2,mj2", so we split the name
@@ -564,6 +565,11 @@ static void handle_new_stream(demuxer_t *demuxer, int i)
sh->codec->samplerate = codec->sample_rate;
sh->codec->bitrate = codec->bit_rate;
+ double delay = 0;
+ if (codec->sample_rate > 0)
+ delay = codec->delay / (double)codec->sample_rate;
+ priv->seek_delay = MPMAX(priv->seek_delay, delay);
+
export_replaygain(demuxer, sh->codec, st);
break;
@@ -957,6 +963,8 @@ static void demux_seek_lavf(demuxer_t *demuxer, double rel_seek_secs, int flags)
priv->last_pts = rel_seek_secs * priv->avfc->duration;
}
} else {
+ if (flags & SEEK_BACKWARD)
+ rel_seek_secs -= priv->seek_delay;
priv->last_pts += rel_seek_secs * AV_TIME_BASE;
}