summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/options.rst19
-rw-r--r--demux/demux_mkv.c15
-rw-r--r--options/options.c3
-rw-r--r--options/options.h1
4 files changed, 35 insertions, 3 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 8cd30d7fcf..feaeac6b30 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -2038,6 +2038,22 @@ Demuxer
and hr-seeks, and this option changes behavior with relative or imprecise
seeks only.
+ You can use the ``--demuxer-mkv-subtitle-preroll-secs`` option to specify
+ how mach data the demuxer should pre-read at most in order to find subtitle
+ packets that may overlap. Setting this to 0 will effectively disable this
+ preroll mechanism. Setting a very large value can make seeking very slow,
+ and an extremely large value would completely reread the entire file from
+ start to seek target on every seek - seeking can become slower towards the
+ end of the file. The details are messy, and the value is actually rounded
+ down to the cluster with the previous video keyframe.
+
+ Some files, especially files muxed with newer mkvmerge versions, have
+ information embedded that can be used to determine what subtitle packets
+ overlap with a seek target. In these cases, mpv will reduce the amount
+ of data read to a minimum. (Although it will still read *all* data between
+ the cluster that contains the first wanted subtitle packet, and the seek
+ target.)
+
See also ``--hr-seek-demuxer-offset`` option. This option can achieve a
similar effect, but only if hr-seek is active. It works with any demuxer,
but makes seeking much slower, as it has to decode audio and video data
@@ -2045,6 +2061,9 @@ Demuxer
``--mkv-subtitle-preroll`` is a deprecated alias.
+``--demuxer-mkv-subtitle-preroll-secs=<value>``
+ See ``--demuxer-mkv-subtitle-preroll``.
+
``--demuxer-rawaudio-channels=<value>``
Number of channels (or channel layout) if ``--demuxer=rawaudio`` is used
(default: stereo).
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) {
diff --git a/options/options.c b/options/options.c
index c15482fd05..ba251f6216 100644
--- a/options/options.c
+++ b/options/options.c
@@ -301,6 +301,8 @@ const m_option_t mp_opts[] = {
OPT_FLAG("demuxer-mkv-subtitle-preroll", mkv_subtitle_preroll, 0),
OPT_FLAG("mkv-subtitle-preroll", mkv_subtitle_preroll, 0), // old alias
+ OPT_DOUBLE("demuxer-mkv-subtitle-preroll-secs", mkv_subtitle_preroll_secs,
+ M_OPT_MIN, .min = 0),
// ------------------------- subtitles options --------------------
@@ -670,6 +672,7 @@ const struct MPOpts mp_default_opts = {
.use_embedded_fonts = 1,
.sub_fix_timing = 1,
.sub_cp = "auto",
+ .mkv_subtitle_preroll_secs = 1.0,
.hwdec_codecs = "h264,vc1,wmv3",
diff --git a/options/options.h b/options/options.h
index f67a3a5c95..9284320f40 100644
--- a/options/options.h
+++ b/options/options.h
@@ -194,6 +194,7 @@ typedef struct MPOpts {
char *audio_demuxer_name;
char *sub_demuxer_name;
int mkv_subtitle_preroll;
+ double mkv_subtitle_preroll_secs;
double demuxer_min_secs_cache;
int cache_pausing;