summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/options.rst11
-rw-r--r--demux/demux_mkv.c16
2 files changed, 22 insertions, 5 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index e5b8499520..76ae596519 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -2221,7 +2221,7 @@ Demuxer
Encryption key the demuxer should use. This is the raw binary data of
the key converted to a hexadecimal string.
-``--demuxer-mkv-subtitle-preroll``, ``--mkv-subtitle-preroll``
+``--demuxer-mkv-subtitle-preroll=<yes|index|no>``, ``--mkv-subtitle-preroll``
Try harder to show embedded soft subtitles when seeking somewhere. Normally,
it can happen that the subtitle at the seek target is not shown due to how
some container file formats are designed. The subtitles appear only if
@@ -2253,7 +2253,11 @@ Demuxer
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.)
+ target.) If the ``index`` choice (which is the default) is specified, then
+ prerolling will be done only if this information is actually available. If
+ this method is used, the maximum amount of data to skip can be additionally
+ controlled by ``--demuxer-mkv-subtitle-preroll-secs-index`` (it still uses
+ the value of the option without ``-index`` if that is higher).
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,
@@ -2265,6 +2269,9 @@ Demuxer
``--demuxer-mkv-subtitle-preroll-secs=<value>``
See ``--demuxer-mkv-subtitle-preroll``.
+``--demuxer-mkv-subtitle-preroll-secs-index=<value>``
+ See ``--demuxer-mkv-subtitle-preroll``.
+
``--demuxer-mkv-probe-video-duration=<yes|no|full>``
When opening the file, seek to the end of it, and check what timestamp the
last video packet has, and report that as file duration. This is strictly
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index af82dc8deb..4b4e16c4b6 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -202,15 +202,19 @@ typedef struct mkv_demuxer {
struct demux_mkv_opts {
int subtitle_preroll;
double subtitle_preroll_secs;
+ double subtitle_preroll_secs_index;
int probe_duration;
int probe_start_time;
};
const struct m_sub_options demux_mkv_conf = {
.opts = (const m_option_t[]) {
- OPT_FLAG("subtitle-preroll", subtitle_preroll, 0),
+ OPT_CHOICE("subtitle-preroll", subtitle_preroll, 0,
+ ({"no", 0}, {"yes", 1}, {"index", 2})),
OPT_DOUBLE("subtitle-preroll-secs", subtitle_preroll_secs,
M_OPT_MIN, .min = 0),
+ OPT_DOUBLE("subtitle-preroll-secs-index", subtitle_preroll_secs_index,
+ M_OPT_MIN, .min = 0),
OPT_CHOICE("probe-video-duration", probe_duration, 0,
({"no", 0}, {"yes", 1}, {"full", 2})),
OPT_FLAG("probe-start-time", probe_start_time, 0),
@@ -218,7 +222,9 @@ const struct m_sub_options demux_mkv_conf = {
},
.size = sizeof(struct demux_mkv_opts),
.defaults = &(const struct demux_mkv_opts){
+ .subtitle_preroll = 2,
.subtitle_preroll_secs = 1.0,
+ .subtitle_preroll_secs_index = 10.0,
.probe_start_time = 1,
},
};
@@ -2724,6 +2730,8 @@ static struct mkv_index *seek_with_cues(struct demuxer *demuxer, int seek_id,
// Find the cluster with the highest filepos, that has a timestamp
// still lower than min_tc.
double secs = opts->demux_mkv->subtitle_preroll_secs;
+ if (mkv_d->index_has_durations)
+ secs = MPMAX(secs, opts->demux_mkv->subtitle_preroll_secs_index);
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;
@@ -2786,8 +2794,10 @@ static void demux_mkv_seek(demuxer_t *demuxer, double rel_seek_secs, int flags)
int cueflags = (flags & SEEK_BACKWARD) ? FLAG_BACKWARD : 0;
mkv_d->subtitle_preroll = NUM_SUB_PREROLL_PACKETS;
- if (((flags & SEEK_HR) || demuxer->opts->demux_mkv->subtitle_preroll) &&
- st_active[STREAM_SUB] && st_active[STREAM_VIDEO])
+ int preroll_opt = demuxer->opts->demux_mkv->subtitle_preroll;
+ if (((flags & SEEK_HR) || preroll_opt == 1 ||
+ (preroll_opt == 2 && mkv_d->index_has_durations))
+ && st_active[STREAM_SUB] && st_active[STREAM_VIDEO])
cueflags |= FLAG_SUBPREROLL;
// Adjust the target a little bit to catch cases where the target position