summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-04-13 15:42:52 +0200
committerwm4 <wm4@nowhere>2020-04-13 15:56:52 +0200
commite1e714ccc339c24b43179aa36f7f5f61865e2e98 (patch)
treef95a148499b72062325e1ad16f2c9a741ae95c4b
parentdc9135b1642f35772abf14e1566d55e9f9640435 (diff)
downloadmpv-e1e714ccc339c24b43179aa36f7f5f61865e2e98.tar.bz2
mpv-e1e714ccc339c24b43179aa36f7f5f61865e2e98.tar.xz
player: mess with track selection details again
Some time ago, properties and options were mostly unified. However, the track selection properties/options semantics are incompatible to this change. I'm still trying to handle the fallout. There are two things that are in the way: 1. Track properties somehow return the runtime selection, not the option value (all while properties are supposed to be aliases to options with the same name). 2. The user's track options are not supposed to be changed without interaction. If a track is auto-selected, the property should return its ID, but the option value should remain at "auto". Only if the user actually writes to the property the option should change. E.g. playing e.g. an audio-only file and then a normal video file not play the video file with --vid=no just because the audio file had no video track. In addition to each of them being in conflict with the property/option unification, attempt to fix one of them breaks the other one. Today, we're trying to fix parts of this and avoiding an unfortunate case where you can get a conflicting option/property value, and where trying to select a track does nothing if the track to select has the same ID as the option value. This breaks 2. from above in certain situations. See manpage additions. See: #7608
-rw-r--r--DOCS/interface-changes.rst2
-rw-r--r--DOCS/man/options.rst29
-rw-r--r--player/loadfile.c42
3 files changed, 61 insertions, 12 deletions
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=<ID|auto|no>``
Display the subtitle stream specified by ``<ID>``. ``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
}
}