diff options
author | wm4 <wm4@nowhere> | 2014-11-14 23:52:47 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-11-15 00:55:30 +0100 |
commit | a6694d27889b4b65ab6d05641396724ae9696f77 (patch) | |
tree | 3c41306de3089dedd84378c7c3c3c8632ffdfe3a /demux | |
parent | d484cb3f3245573ec024d6a50099d9a5a5e4400d (diff) | |
download | mpv-a6694d27889b4b65ab6d05641396724ae9696f77.tar.bz2 mpv-a6694d27889b4b65ab6d05641396724ae9696f77.tar.xz |
demux_mkv: adjust subtitle preroll again (2)
Make the changes started in commit c827ae5f more eloborate, and provide
an option to control the amount of data read before the seek-target. To
achieve this, rewrite the loop that finds the lowest still acceptable
target cluster. It is now searched by time instead of file position. The
behavior (both with and without preroll option) may be different from
before this change, although it shouldn't be worse.
The change demux_mkv_read_cues() fixes a bug: when seeking after playing
normally, the code would erroneously assume that durations are set. This
doesn't happen if the first operation after loading was a seek instead
of playback.
Diffstat (limited to 'demux')
-rw-r--r-- | demux/demux_mkv.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c index 79e62a112c..100447d1f7 100644 --- a/demux/demux_mkv.c +++ b/demux/demux_mkv.c @@ -717,6 +717,7 @@ static int demux_mkv_read_cues(demuxer_t *demuxer) return -1; mkv_d->num_indexes = 0; + mkv_d->index_has_durations = false; for (int i = 0; i < cues.n_cue_point; i++) { struct ebml_cue_point *cuepoint = &cues.cue_point[i]; @@ -2714,12 +2715,20 @@ static struct mkv_index *seek_with_cues(struct demuxer *demuxer, int seek_id, if (index) { /* We've found an entry. */ uint64_t seek_pos = index->filepos; if (flags & SEEK_SUBPREROLL) { + // Find the cluster with the highest filepos, that has a timestamp + // still lower than min_tc. + double secs = demuxer->opts->mkv_subtitle_preroll_secs; + uint64_t pre = MPMIN(INT64_MAX, secs * 1e9 / mkv_d->tc_scale); + uint64_t min_tc = pre < index->timecode ? index->timecode - pre : 0; uint64_t prev_target = 0; + uint64_t prev_tc = 0; for (size_t i = 0; i < mkv_d->num_indexes; i++) { if (seek_id < 0 || mkv_d->indexes[i].tnum == seek_id) { - uint64_t index_pos = mkv_d->indexes[i].filepos; - if (index_pos > prev_target && index_pos < seek_pos) - prev_target = index_pos; + struct mkv_index *cur = &mkv_d->indexes[i]; + if (cur->timecode <= min_tc && cur->timecode >= prev_tc) { + prev_tc = cur->timecode; + prev_target = cur->filepos; + } } } if (mkv_d->index_has_durations) { |