diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index 589856329a..45aaf99515 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -63,6 +63,8 @@ Interface changes - deprecate encoding mode (lack of maintainer) - remove deprecated --input-file option, add --input-ipc-client, which is vaguely a replacement of the removed option, but not the same + - change another detail for track selection options (see --aid manpage + entry) --- mpv 0.32.0 --- - change behavior when using legacy option syntax with options that start with two dashes (``--`` instead of a ``-``). Now, using the recommended diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 871561cde3..347a6bbcc4 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -49,6 +49,35 @@ Track Selection ``--aid=no`` or ``--audio=no`` or ``--no-audio`` disables audio playback. (The latter variant does not work with the client API.) + .. note:: + + The track selection options (``--aid`` but also ``--sid`` and the + others) sometimes expose behavior that may appear strange. Also, the + behavior tends to change around with each mpv release. + + The track selection properties will return the option value outside of + playback (as expected), but during playbac, the affective track + selection is returned. For example, with ``--aid=auto``, the ``aid`` + property will suddenly return ``2`` after playback initialization + (assuming the file has at least 2 audio tracks, and the second is the + default). + + At mpv 0.32.0 (and some releases before), if you passed a track value + for which a corresponding track didn't exist (e.g. ``--aid=2`` and there + was only 1 audio track), the ``aid`` property returned ``no``. However if + another audio track was added during playback, and you tried to set the + ``aid`` property to ``2``, nothing happened, because the ``aid`` option + still had the value ``2``, and writing the same value has no effect. + + With mpv 0.33.0, the behavior was changed. Now track selection options + are reset to ``auto`` at playback initialization, if the option had + tries to select a track that does not exist. The same is done if the + track exists, but fails to initialize. The consequence is that unlike + before mpv 0.33.0, the user's track selection parameters are clobbered + in certain situations. + + Most likely this is not the end. + ``--sid=`` Display the subtitle stream specified by ````. ``auto`` selects the default, ``no`` disables subtitles. diff --git a/player/loadfile.c b/player/loadfile.c index b922a46cc9..8e40992a04 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -448,9 +448,8 @@ static int match_lang(char **langs, char *lang) * tid is the track ID requested by the user (-2: deselect, -1: default) * lang is a string list, NULL is same as empty list * Sort tracks based on the following criteria, and pick the first: - * 0a) track matches ff-index (always wins) - * 0b) track matches tid (almost always wins) - * 0c) track is not from --external-file + *0a) track matches tid (always wins) + * 0b) track is not from --external-file * 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 @@ -585,6 +584,15 @@ static void check_previous_track_selection(struct MPContext *mpctx) talloc_free(h); } +static void mark_track_selection(struct MPContext *mpctx, int order, + enum stream_type type, int value) +{ + assert(order >= 0 && order < NUM_PTRACKS); + mpctx->opts->stream_id[order][type] = value; + m_config_notify_change_opt_ptr(mpctx->mconfig, + &mpctx->opts->stream_id[order][type]); +} + void mp_switch_track_n(struct MPContext *mpctx, int order, enum stream_type type, struct track *track, int flags) { @@ -593,11 +601,8 @@ void mp_switch_track_n(struct MPContext *mpctx, int order, enum stream_type type // Mark the current track selection as explicitly user-requested. (This is // different from auto-selection or disabling a track due to errors.) - if (flags & FLAG_MARK_SELECTION) { - mpctx->opts->stream_id[order][type] = track ? track->user_tid : -2; - m_config_notify_change_opt_ptr(mpctx->mconfig, - &mpctx->opts->stream_id[order][type]); - } + if (flags & FLAG_MARK_SELECTION) + mark_track_selection(mpctx, order, type, track ? track->user_tid : -2); // No decoder should be initialized yet. if (!mpctx->demuxer) @@ -609,19 +614,19 @@ void mp_switch_track_n(struct MPContext *mpctx, int order, enum stream_type type if (current && current->sink) { MP_ERR(mpctx, "Can't disable input to complex filter.\n"); - return; + goto error; } if ((type == STREAM_VIDEO && mpctx->vo_chain && !mpctx->vo_chain->track) || (type == STREAM_AUDIO && mpctx->ao_chain && !mpctx->ao_chain->track)) { MP_ERR(mpctx, "Can't switch away from complex filter output.\n"); - return; + goto error; } if (track && track->selected) { // Track has been selected in a different order parameter. MP_ERR(mpctx, "Track %d is already selected.\n", track->user_tid); - return; + goto error; } if (order == 0) { @@ -666,6 +671,10 @@ void mp_switch_track_n(struct MPContext *mpctx, int order, enum stream_type type talloc_free(mpctx->track_layout_hash); mpctx->track_layout_hash = talloc_steal(mpctx, track_layout_hash(mpctx)); + + return; +error: + mark_track_selection(mpctx, order, type, -1); } void mp_switch_track(struct MPContext *mpctx, enum stream_type type, @@ -677,8 +686,10 @@ void mp_switch_track(struct MPContext *mpctx, enum stream_type type, void mp_deselect_track(struct MPContext *mpctx, struct track *track) { if (track && track->selected) { - for (int t = 0; t < NUM_PTRACKS; t++) + for (int t = 0; t < NUM_PTRACKS; t++) { mp_switch_track_n(mpctx, t, track->type, NULL, 0); + mark_track_selection(mpctx, t, track->type, -1); // default + } } } @@ -1523,16 +1534,23 @@ static void play_current_file(struct MPContext *mpctx) } for (int t = 0; t < STREAM_TYPE_COUNT; t++) { for (int i = 0; i < NUM_PTRACKS; i++) { + // One track can strictly feed at most 1 decoder struct track *track = mpctx->current_track[i][t]; if (track) { if (track->selected) { MP_ERR(mpctx, "Track %d can't be selected twice.\n", track->user_tid); mpctx->current_track[i][t] = NULL; + mark_track_selection(mpctx, i, t, -2); // disable } else { track->selected = true; } } + + // Revert selection of unselected tracks to default. This is needed + // because track properties have inconsistent behavior. + if (!track && opts->stream_id[i][t] >= 0) + mark_track_selection(mpctx, i, t, -1); // default } }