diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index bf8fd991c6..3b64105dc9 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -20,6 +20,7 @@ Interface changes :: --- mpv 0.10.0 will be released --- + - add ``track-list/N/foced`` property - add audio-params/channel-count and ``audio-params-out/channel-count props. - add af volume replaygain-fallback suboption - add video-params/stereo-in property diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst index 0ed259f59b..7f6cb1856c 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -1579,6 +1579,10 @@ Property list ``yes`` if the track has the default flag set in the file, ``no`` otherwise. + ``track-list/N/foced`` + ``yes`` if the track has the forced flag set in the file, ``no`` + otherwise. + ``track-list/N/codec`` The codec name used by this track, for example ``h264``. Unavailable in some rare cases. @@ -1616,6 +1620,7 @@ Property list "lang" MPV_FORMAT_STRING "albumart" MPV_FORMAT_FLAG "default" MPV_FORMAT_FLAG + "forced" MPV_FORMAT_FLAG "external" MPV_FORMAT_FLAG "external-filename" MPV_FORMAT_STRING "codec" MPV_FORMAT_STRING diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c index 659452b5f1..db4c8edac9 100644 --- a/demux/demux_lavf.c +++ b/demux/demux_lavf.c @@ -636,7 +636,9 @@ static void handle_stream(demuxer_t *demuxer, int i) sh->lav_headers = codec; if (st->disposition & AV_DISPOSITION_DEFAULT) - sh->default_track = 1; + sh->default_track = true; + if (st->disposition & AV_DISPOSITION_FORCED) + sh->forced_track = true; if (priv->format_hack.use_stream_ids) sh->demuxer_id = st->id; AVDictionaryEntry *title = av_dict_get(st->metadata, "title", NULL, 0); diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c index cadb1a3a7f..0b2bd719ee 100644 --- a/demux/demux_mkv.c +++ b/demux/demux_mkv.c @@ -114,6 +114,7 @@ typedef struct mkv_track { double codec_delay; int default_track; + int forced_track; unsigned char *private_data; unsigned int private_size; @@ -631,6 +632,11 @@ static void parse_trackentry(struct demuxer *demuxer, track->default_track = 1; } + if (entry->n_flag_forced) { + track->forced_track = entry->flag_forced; + MP_VERBOSE(demuxer, "| + Forced flag: %u\n", track->forced_track); + } + if (entry->n_default_duration) { track->default_duration = entry->default_duration / 1e9; if (entry->default_duration == 0) { @@ -1171,6 +1177,7 @@ static void init_track(demuxer_t *demuxer, mkv_track_t *track, sh->demuxer_id = track->tnum; sh->title = track->name; sh->default_track = track->default_track; + sh->forced_track = track->forced_track; } static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track); diff --git a/demux/stheader.h b/demux/stheader.h index fdb302713c..a615867685 100644 --- a/demux/stheader.h +++ b/demux/stheader.h @@ -58,6 +58,7 @@ struct sh_stream { char *title; char *lang; // language code bool default_track; // container default track flag + bool forced_track; // container forced track flag int hls_bitrate; bool missing_timestamps; diff --git a/player/command.c b/player/command.c index 852f232446..cc6a41946c 100644 --- a/player/command.c +++ b/player/command.c @@ -1872,6 +1872,7 @@ static int get_track_entry(int item, int action, void *arg, void *ctx) .unavailable = !track->lang}, {"albumart", SUB_PROP_FLAG(track->attached_picture)}, {"default", SUB_PROP_FLAG(track->default_track)}, + {"forced", SUB_PROP_FLAG(track->forced_track)}, {"external", SUB_PROP_FLAG(track->is_external)}, {"selected", SUB_PROP_FLAG(track->selected)}, {"external-filename", SUB_PROP_STR(track->external_filename), diff --git a/player/core.h b/player/core.h index 542105ba6e..81cf613abf 100644 --- a/player/core.h +++ b/player/core.h @@ -89,7 +89,7 @@ struct track { int ff_index; // same as stream->ff_index, or 0. char *title; - bool default_track; + bool default_track, forced_track; bool attached_picture; char *lang; diff --git a/player/loadfile.c b/player/loadfile.c index cef35cc485..3f753d1dfd 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -132,6 +132,8 @@ static void print_stream(struct MPContext *mpctx, struct track *t) APPEND(b, " --%s=%s", langopt, t->lang); if (t->default_track) APPEND(b, " (*)"); + if (t->forced_track) + APPEND(b, " (f)"); if (t->attached_picture) APPEND(b, " [P]"); if (t->title) @@ -383,6 +385,7 @@ static struct track *add_stream_track(struct MPContext *mpctx, .ff_index = stream->ff_index, .title = stream->title, .default_track = stream->default_track, + .forced_track = stream->forced_track, .attached_picture = stream->attached_picture != NULL, .lang = stream->lang, .under_timeline = under_timeline, @@ -424,7 +427,8 @@ 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 - * 3) track is marked default + * 3a) track is marked forced + * 3b) 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 @@ -444,6 +448,8 @@ static bool compare_track(struct track *t1, struct track *t2, char **langs, int l1 = match_lang(langs, t1->lang), l2 = match_lang(langs, t2->lang); if (l1 != l2) return l1 > l2; + if (t1->forced_track != t2->forced_track) + return t1->forced_track; if (t1->default_track != t2->default_track) return t1->default_track; if (t1->attached_picture != t2->attached_picture) @@ -480,7 +486,8 @@ struct track *select_default_track(struct MPContext *mpctx, int order, pick = track; } if (pick && !select_fallback && !(pick->is_external && !pick->no_default) - && !match_lang(langs, pick->lang) && !pick->default_track) + && !match_lang(langs, pick->lang) && !pick->default_track + && !pick->forced_track) pick = NULL; if (pick && pick->attached_picture && !mpctx->opts->audio_display) pick = NULL;