summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/options.rst12
-rw-r--r--options/options.c6
-rw-r--r--options/options.h2
-rw-r--r--player/loadfile.c21
-rw-r--r--sub/sd_ass.c6
-rw-r--r--sub/sd_lavc.c2
6 files changed, 40 insertions, 9 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 5245e18cae..30ea5d7ce1 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -135,6 +135,11 @@ Track Selection
Note that if ``--lavfi-complex`` is set before playback is started, the
referenced tracks are always selected.
+``--subs-with-matching-audio=<yes|no>``
+ When autoselecting a subtitle track, select a non-forced one even if the selected
+ audio stream matches your preferred subtitle language (default: yes). Disable this
+ if you'd like to only show subtitles for foreign audio or onscreen text.
+
Playback Control
----------------
@@ -2487,9 +2492,12 @@ Subtitles
subtitles (if the difference is smaller than 210 ms, the gap or overlap
is removed).
-``--sub-forced-only``
+``--sub-forced-only=<auto|yes|no>``
Display only forced subtitles for the DVD subtitle stream selected by e.g.
- ``--slang``.
+ ``--slang`` (default: ``auto``). When set to ``auto``, enabled when the
+ ``--subs-with-matching-audio`` option is on and a non-forced stream is selected.
+ Enabling this will hide all subtitles in streams that don't make a distinction
+ between forced and unforced events within a stream.
``--sub-fps=<rate>``
Specify the framerate of the subtitle file (default: video fps). Affects
diff --git a/options/options.c b/options/options.c
index 6e22de0a07..35b23abce3 100644
--- a/options/options.c
+++ b/options/options.c
@@ -228,7 +228,8 @@ const struct m_sub_options mp_subtitle_sub_opts = {
{"sub-fps", OPT_FLOAT(sub_fps)},
{"sub-speed", OPT_FLOAT(sub_speed)},
{"sub-visibility", OPT_FLAG(sub_visibility)},
- {"sub-forced-only", OPT_FLAG(forced_subs_only)},
+ {"sub-forced-only", OPT_CHOICE(forced_subs_only,
+ {"auto", -1}, {"no", 0}, {"yes", 1})},
{"stretch-dvd-subs", OPT_FLAG(stretch_dvd_subs)},
{"stretch-image-subs-to-screen", OPT_FLAG(stretch_image_subs)},
{"image-subs-video-resolution", OPT_FLAG(image_subs_video_res)},
@@ -269,6 +270,7 @@ const struct m_sub_options mp_subtitle_sub_opts = {
.size = sizeof(OPT_BASE_STRUCT),
.defaults = &(OPT_BASE_STRUCT){
.sub_visibility = 1,
+ .forced_subs_only = -1,
.sub_pos = 100,
.sub_speed = 1.0,
.ass_enabled = 1,
@@ -489,6 +491,7 @@ static const m_option_t mp_opts[] = {
{"slang", OPT_STRINGLIST(stream_lang[STREAM_SUB])},
{"vlang", OPT_STRINGLIST(stream_lang[STREAM_VIDEO])},
{"track-auto-selection", OPT_FLAG(stream_auto_sel)},
+ {"subs-with-matching-audio", OPT_FLAG(subs_with_matching_audio)},
{"lavfi-complex", OPT_STRING(lavfi_complex), .flags = UPDATE_LAVFI_COMPLEX},
@@ -992,6 +995,7 @@ static const struct MPOpts mp_default_opts = {
[STREAM_VIDEO] = -2,
[STREAM_SUB] = -2, }, },
.stream_auto_sel = 1,
+ .subs_with_matching_audio = 1,
.audio_display = 1,
.audio_output_format = 0, // AF_FORMAT_UNKNOWN
.playback_speed = 1.,
diff --git a/options/options.h b/options/options.h
index 00b58dfbff..62eef010d7 100644
--- a/options/options.h
+++ b/options/options.h
@@ -73,6 +73,7 @@ struct mp_subtitle_opts {
float sub_fps;
float sub_speed;
int forced_subs_only;
+ int forced_subs_only_current;
int stretch_dvd_subs;
int stretch_image_subs;
int image_subs_video_res;
@@ -252,6 +253,7 @@ typedef struct MPOpts {
int stream_id[2][STREAM_TYPE_COUNT];
char **stream_lang[STREAM_TYPE_COUNT];
int stream_auto_sel;
+ int subs_with_matching_audio;
int audio_display;
char **display_tags;
diff --git a/player/loadfile.c b/player/loadfile.c
index 97ae9328f1..f8d5327acf 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -453,17 +453,19 @@ static int match_lang(char **langs, char *lang)
* 1) track is external (no_default cancels this)
* 1b) track was passed explicitly (is not an auto-loaded subtitle)
* 2) earlier match in lang list
- * 3a) track is marked forced
- * 3b) track is marked default
+ * 3a) track is marked forced and we're preferring forced tracks
+ * 3b) track is marked non-forced and we're preferring non-forced tracks
+ * 3c) track is marked default
* 4) attached picture, HLS bitrate
* 5) lower track number
* If select_fallback is not set, 5) is only used to determine whether a
* matching track is preferred over another track. Otherwise, always pick a
* track (if nothing else matches, return the track with lowest ID).
+ * Forced tracks are preferred when the user prefers not to display subtitles
*/
// Return whether t1 is preferred over t2
static bool compare_track(struct track *t1, struct track *t2, char **langs,
- struct MPOpts *opts)
+ int prefer_forced, struct MPOpts *opts)
{
if (!opts->autoload_files && t1->is_external != t2->is_external)
return !t1->is_external;
@@ -477,7 +479,7 @@ static bool compare_track(struct track *t1, struct track *t2, char **langs,
if (l1 != l2)
return l1 > l2;
if (t1->forced_track != t2->forced_track)
- return t1->forced_track;
+ return prefer_forced ? t1->forced_track : !t1->forced_track;
if (t1->default_track != t2->default_track)
return t1->default_track;
if (t1->attached_picture != t2->attached_picture)
@@ -512,6 +514,10 @@ struct track *select_default_track(struct MPContext *mpctx, int order,
struct MPOpts *opts = mpctx->opts;
int tid = opts->stream_id[order][type];
char **langs = opts->stream_lang[type];
+ int prefer_forced = type != STREAM_SUB ||
+ (!opts->subs_with_matching_audio &&
+ mpctx->current_track[0][STREAM_AUDIO] &&
+ match_lang(langs, mpctx->current_track[0][STREAM_AUDIO]->lang));
if (tid == -2)
return NULL;
bool select_fallback = type == STREAM_VIDEO || type == STREAM_AUDIO;
@@ -528,7 +534,7 @@ struct track *select_default_track(struct MPContext *mpctx, int order,
continue;
if (duplicate_track(mpctx, order, type, track))
continue;
- if (!pick || compare_track(track, pick, langs, mpctx->opts))
+ if (!pick || compare_track(track, pick, langs, prefer_forced, mpctx->opts))
pick = track;
}
if (pick && !select_fallback && !(pick->is_external && !pick->no_default)
@@ -539,6 +545,9 @@ struct track *select_default_track(struct MPContext *mpctx, int order,
pick = NULL;
if (pick && !opts->autoload_files && pick->is_external)
pick = NULL;
+ if (pick && type == STREAM_SUB && prefer_forced && !pick->forced_track &&
+ opts->subs_rend->forced_subs_only == -1)
+ opts->subs_rend->forced_subs_only_current = 1;
return pick;
}
@@ -1522,6 +1531,8 @@ static void play_current_file(struct MPContext *mpctx)
if (reinit_complex_filters(mpctx, false) < 0)
goto terminate_playback;
+ opts->subs_rend->forced_subs_only_current = (opts->subs_rend->forced_subs_only == 1) ? 1 : 0;
+
for (int t = 0; t < STREAM_TYPE_COUNT; t++) {
for (int i = 0; i < num_ptracks[t]; i++) {
struct track *sel = NULL;
diff --git a/sub/sd_ass.c b/sub/sd_ass.c
index 7c40a01faf..eae1536df8 100644
--- a/sub/sd_ass.c
+++ b/sub/sd_ass.c
@@ -533,6 +533,12 @@ static struct sub_bitmaps *get_bitmaps(struct sd *sd, struct mp_osd_res dim,
if (pts == MP_NOPTS_VALUE || !renderer)
goto done;
+ // Currently no supported text sub formats support a distinction between forced
+ // and unforced lines, so we just assume everything's unforced and discard everything.
+ // If we ever see a format that makes this distinction, we can add support here.
+ if (opts->forced_subs_only_current)
+ goto done;
+
double scale = dim.display_par;
if (!converted && (!opts->ass_style_override ||
opts->ass_vsfilter_aspect_compat))
diff --git a/sub/sd_lavc.c b/sub/sd_lavc.c
index 81906ceb23..77877fdbd1 100644
--- a/sub/sd_lavc.c
+++ b/sub/sd_lavc.c
@@ -191,7 +191,7 @@ static void read_sub_bitmaps(struct sd *sd, struct sub *sub)
MP_ERR(sd, "unsupported subtitle type from libavcodec\n");
continue;
}
- if (!(r->flags & AV_SUBTITLE_FLAG_FORCED) && opts->forced_subs_only)
+ if (!(r->flags & AV_SUBTITLE_FLAG_FORCED) && opts->forced_subs_only_current)
continue;
if (r->w <= 0 || r->h <= 0)
continue;