summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-05-26 14:01:23 +0200
committerwm4 <wm4@nowhere>2015-05-26 14:01:23 +0200
commit88249baf5bb66e164b17bc53e10441c3c3111e45 (patch)
tree0157e34bc549da73fdcd08a7c8c1b8666d8afad0 /player
parentbdcd25d3c23b49704f3abe78dc0c523f20a71d45 (diff)
downloadmpv-88249baf5bb66e164b17bc53e10441c3c3111e45.tar.bz2
mpv-88249baf5bb66e164b17bc53e10441c3c3111e45.tar.xz
player: fix crashes when adding external tracks before loading main file
Adding an external audio track before loading the main file didn't work right. For one, mp_switch_track() assumes it is called after the main file is loaded. (The difference is that decoders are only initialized once the main file is loaded, and we avoid doing this before that for whatever reason.) To avoid further messiness, just allow mp_switch_track() to be called at any time. Also make it do what mp_mark_user_track_selection() did, since the latter requires current_track to be set. (One could probably simply allow current_track to be set at this point, but it'd interfere with default track selection anyway and thus would be pointless.) Fixes #1984.
Diffstat (limited to 'player')
-rw-r--r--player/client.c2
-rw-r--r--player/command.c33
-rw-r--r--player/core.h7
-rw-r--r--player/loadfile.c28
4 files changed, 30 insertions, 40 deletions
diff --git a/player/client.c b/player/client.c
index afc4f32a68..8fb2d6f768 100644
--- a/player/client.c
+++ b/player/client.c
@@ -1664,7 +1664,7 @@ void kill_video(struct mp_client_api *client_api)
{
struct MPContext *mpctx = client_api->mpctx;
mp_dispatch_lock(mpctx->dispatch);
- mp_switch_track(mpctx, STREAM_VIDEO, NULL);
+ mp_switch_track(mpctx, STREAM_VIDEO, NULL, 0);
uninit_video_out(mpctx);
mp_dispatch_unlock(mpctx->dispatch);
}
diff --git a/player/command.c b/player/command.c
index e0259b5038..1fdf6654be 100644
--- a/player/command.c
+++ b/player/command.c
@@ -1795,18 +1795,13 @@ static int property_switch_track(struct m_property *prop, int action, void *arg,
case M_PROPERTY_SWITCH: {
struct m_property_switch_arg *sarg = arg;
mp_switch_track_n(mpctx, order, type,
- track_next(mpctx, order, type, sarg->inc >= 0 ? +1 : -1, track));
- mp_mark_user_track_selection(mpctx, order, type);
+ track_next(mpctx, order, type, sarg->inc >= 0 ? +1 : -1, track),
+ FLAG_MARK_SELECTION);
return M_PROPERTY_OK;
}
case M_PROPERTY_SET:
- if (mpctx->num_sources) {
- track = mp_track_by_tid(mpctx, type, *(int *)arg);
- mp_switch_track_n(mpctx, order, type, track);
- mp_mark_user_track_selection(mpctx, order, type);
- } else {
- mpctx->opts->stream_id[order][type] = *(int *)arg;
- }
+ track = mp_track_by_tid(mpctx, type, *(int *)arg);
+ mp_switch_track_n(mpctx, order, type, track, FLAG_MARK_SELECTION);
return M_PROPERTY_OK;
}
return mp_property_generic_option(mpctx, prop, action, arg);
@@ -1837,7 +1832,7 @@ static int property_switch_track_ff(void *ctx, struct m_property *prop,
}
if (!track && id >= 0)
return M_PROPERTY_ERROR;
- mp_switch_track_n(mpctx, 0, type, track);
+ mp_switch_track_n(mpctx, 0, type, track, 0);
} else {
mpctx->opts->stream_id_ff[type] = *(int *)arg;
}
@@ -1986,11 +1981,11 @@ static int mp_property_program(void *ctx, struct m_property *prop,
return M_PROPERTY_ERROR;
}
mp_switch_track(mpctx, STREAM_VIDEO,
- find_track_by_demuxer_id(mpctx, STREAM_VIDEO, prog.vid));
+ find_track_by_demuxer_id(mpctx, STREAM_VIDEO, prog.vid), 0);
mp_switch_track(mpctx, STREAM_AUDIO,
- find_track_by_demuxer_id(mpctx, STREAM_AUDIO, prog.aid));
+ find_track_by_demuxer_id(mpctx, STREAM_AUDIO, prog.aid), 0);
mp_switch_track(mpctx, STREAM_SUB,
- find_track_by_demuxer_id(mpctx, STREAM_VIDEO, prog.sid));
+ find_track_by_demuxer_id(mpctx, STREAM_VIDEO, prog.sid), 0);
return M_PROPERTY_OK;
case M_PROPERTY_GET_TYPE:
*(struct m_option *)arg = (struct m_option){
@@ -4583,8 +4578,7 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re
struct track *t = find_track_with_url(mpctx, type,
cmd->args[0].v.s);
if (t) {
- mp_switch_track(mpctx, t->type, t);
- mp_mark_user_track_selection(mpctx, 0, t->type);
+ mp_switch_track(mpctx, t->type, t, FLAG_MARK_SELECTION);
return 0;
}
}
@@ -4594,8 +4588,7 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re
if (cmd->args[1].v.i == 1) {
t->no_default = true;
} else {
- mp_switch_track(mpctx, t->type, t);
- mp_mark_user_track_selection(mpctx, 0, t->type);
+ mp_switch_track(mpctx, t->type, t, FLAG_MARK_SELECTION);
}
char *title = cmd->args[2].v.s;
if (title && title[0])
@@ -4630,7 +4623,7 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re
talloc_free(filename);
}
if (nt) {
- mp_switch_track(mpctx, nt->type, nt);
+ mp_switch_track(mpctx, nt->type, nt, 0);
print_track_list(mpctx);
return 0;
}
@@ -4645,10 +4638,10 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re
// somewhat fuzzy and not ideal
struct track *a = select_default_track(mpctx, 0, STREAM_AUDIO);
if (a && a->is_external)
- mp_switch_track(mpctx, STREAM_AUDIO, a);
+ mp_switch_track(mpctx, STREAM_AUDIO, a, 0);
struct track *s = select_default_track(mpctx, 0, STREAM_SUB);
if (s && s->is_external)
- mp_switch_track(mpctx, STREAM_SUB, s);
+ mp_switch_track(mpctx, STREAM_SUB, s, 0);
print_track_list(mpctx);
}
diff --git a/player/core.h b/player/core.h
index 2ae6a4ae65..7c9c13c257 100644
--- a/player/core.h
+++ b/player/core.h
@@ -381,13 +381,12 @@ bool mp_nav_mouse_on_button(struct MPContext *mpctx);
void uninit_player(struct MPContext *mpctx, unsigned int mask);
struct track *mp_add_external_file(struct MPContext *mpctx, char *filename,
enum stream_type filter);
+#define FLAG_MARK_SELECTION 1
void mp_switch_track(struct MPContext *mpctx, enum stream_type type,
- struct track *track);
+ struct track *track, int flags);
void mp_switch_track_n(struct MPContext *mpctx, int order,
- enum stream_type type, struct track *track);
+ enum stream_type type, struct track *track, int flags);
void mp_deselect_track(struct MPContext *mpctx, struct track *track);
-void mp_mark_user_track_selection(struct MPContext *mpctx, int order,
- enum stream_type type);
struct track *mp_track_by_tid(struct MPContext *mpctx, enum stream_type type,
int tid);
double timeline_set_from_time(struct MPContext *mpctx, double pts, bool *need_reset);
diff --git a/player/loadfile.c b/player/loadfile.c
index a60b1b8638..b3fc08094e 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -527,11 +527,20 @@ static void check_previous_track_selection(struct MPContext *mpctx)
}
void mp_switch_track_n(struct MPContext *mpctx, int order, enum stream_type type,
- struct track *track)
+ struct track *track, int flags)
{
assert(!track || track->type == type);
assert(order >= 0 && order < NUM_PTRACKS);
+ // 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;
+
+ // No decoder should be initialized yet.
+ if (!mpctx->demuxer)
+ return;
+
struct track *current = mpctx->current_track[order][type];
if (track == current)
return;
@@ -592,30 +601,19 @@ void mp_switch_track_n(struct MPContext *mpctx, int order, enum stream_type type
}
void mp_switch_track(struct MPContext *mpctx, enum stream_type type,
- struct track *track)
+ struct track *track, int flags)
{
- mp_switch_track_n(mpctx, 0, type, track);
+ mp_switch_track_n(mpctx, 0, type, track, flags);
}
void mp_deselect_track(struct MPContext *mpctx, struct track *track)
{
if (track && track->selected) {
for (int t = 0; t < NUM_PTRACKS; t++)
- mp_switch_track_n(mpctx, t, track->type, NULL);
+ mp_switch_track_n(mpctx, t, track->type, NULL, 0);
}
}
-// Mark the current track selection as explicitly user-requested. (This is
-// different from auto-selection or disabling a track due to errors.)
-void mp_mark_user_track_selection(struct MPContext *mpctx, int order,
- enum stream_type type)
-{
- struct track *track = mpctx->current_track[order][type];
- int user_tid = track ? track->user_tid : -2;
-
- mpctx->opts->stream_id[order][type] = user_tid;
-}
-
struct track *mp_track_by_tid(struct MPContext *mpctx, enum stream_type type,
int tid)
{