diff options
author | wm4 <wm4@nowhere> | 2016-02-22 20:21:03 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-02-22 20:21:13 +0100 |
commit | 0e298bb95a67f59c1afb4669c33d66d5ac99fc6e (patch) | |
tree | d09e117f476ad8384c607274a7e09c5896bed08a /demux | |
parent | 7c181e5b9b3e429d3202a6d28264a36cbd7d9699 (diff) |
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')
-rw-r--r-- | demux/demux_lavf.c | 8 |
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; } |