summaryrefslogtreecommitdiffstats
path: root/player
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 /player
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
Diffstat (limited to 'player')
-rw-r--r--player/loadfile.c42
1 files changed, 30 insertions, 12 deletions
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
}
}