summaryrefslogtreecommitdiffstats
path: root/demux/demux_mkv.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-11-14 23:52:47 +0100
committerwm4 <wm4@nowhere>2014-11-15 00:55:30 +0100
commita6694d27889b4b65ab6d05641396724ae9696f77 (patch)
tree3c41306de3089dedd84378c7c3c3c8632ffdfe3a /demux/demux_mkv.c
parentd484cb3f3245573ec024d6a50099d9a5a5e4400d (diff)
downloadmpv-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/demux_mkv.c')
-rw-r--r--demux/demux_mkv.c15
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) {