From 9292f537d661af16321fd35eb0016e830594863b Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 24 Dec 2013 17:46:08 +0100 Subject: player: add infrastructure to select multiple tracks at once Of course this does not allow decoding multiple tracks at once; it just adds some minor infrastructure, which could be used to achieve this. --- player/audio.c | 2 +- player/command.c | 2 +- player/core.h | 8 ++++- player/loadfile.c | 87 ++++++++++++++++++++++++++++++++----------------------- player/sub.c | 4 +-- player/video.c | 4 +-- 6 files changed, 64 insertions(+), 43 deletions(-) diff --git a/player/audio.c b/player/audio.c index 69fcb1d38e..79d064940b 100644 --- a/player/audio.c +++ b/player/audio.c @@ -104,7 +104,7 @@ int reinit_audio_filters(struct MPContext *mpctx) void reinit_audio_chain(struct MPContext *mpctx) { struct MPOpts *opts = mpctx->opts; - struct track *track = mpctx->current_track[STREAM_AUDIO]; + struct track *track = mpctx->current_track[0][STREAM_AUDIO]; struct sh_stream *sh = init_demux_stream(mpctx, track); if (!sh) { uninit_player(mpctx, INITIALIZED_AO); diff --git a/player/command.c b/player/command.c index a3da05a5c7..3d15d96676 100644 --- a/player/command.c +++ b/player/command.c @@ -1009,7 +1009,7 @@ static int property_switch_track(m_option_t *prop, int action, void *arg, { if (!mpctx->num_sources) return M_PROPERTY_UNAVAILABLE; - struct track *track = mpctx->current_track[type]; + struct track *track = mpctx->current_track[0][type]; switch (action) { case M_PROPERTY_GET: diff --git a/player/core.h b/player/core.h index 2f0622de7c..cad18a6b36 100644 --- a/player/core.h +++ b/player/core.h @@ -147,6 +147,8 @@ enum { MAX_NUM_VO_PTS = 100, }; +#define NUM_PTRACKS 2 + typedef struct MPContext { struct mpv_global *global; struct MPOpts *opts; @@ -200,7 +202,9 @@ typedef struct MPContext { char *track_layout_hash; // Selected tracks. NULL if no track selected. - struct track *current_track[STREAM_TYPE_COUNT]; + // There can be NUM_PTRACKS of the same STREAM_TYPE selected at once. + // Currently, this is used for the secondary subtitle track only. + struct track *current_track[NUM_PTRACKS][STREAM_TYPE_COUNT]; struct dec_video *d_video; struct dec_audio *d_audio; @@ -369,6 +373,8 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask); struct track *mp_add_subtitles(struct MPContext *mpctx, char *filename); void mp_switch_track(struct MPContext *mpctx, enum stream_type type, struct track *track); +void mp_switch_track_n(struct MPContext *mpctx, int order, + enum stream_type type, struct track *track); void mp_deselect_track(struct MPContext *mpctx, struct track *track); struct track *mp_track_by_tid(struct MPContext *mpctx, enum stream_type type, int tid); diff --git a/player/loadfile.c b/player/loadfile.c index 2ebea2bd32..8bf29f22f3 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -115,8 +115,10 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask) talloc_free(mpctx->tracks[i]); } mpctx->num_tracks = 0; - for (int t = 0; t < STREAM_TYPE_COUNT; t++) - mpctx->current_track[t] = NULL; + for (int r = 0; r < NUM_PTRACKS; r++) { + for (int t = 0; t < STREAM_TYPE_COUNT; t++) + mpctx->current_track[r][t] = NULL; + } assert(!mpctx->d_video && !mpctx->d_audio && !mpctx->d_sub); mpctx->master_demuxer = NULL; for (int i = 0; i < mpctx->num_sources; i++) { @@ -582,24 +584,27 @@ static void check_previous_track_selection(struct MPContext *mpctx) talloc_free(h); } -void mp_switch_track(struct MPContext *mpctx, enum stream_type type, - struct track *track) +void mp_switch_track_n(struct MPContext *mpctx, int order, enum stream_type type, + struct track *track) { assert(!track || track->type == type); + assert(order >= 0 && order < NUM_PTRACKS); - struct track *current = mpctx->current_track[type]; + struct track *current = mpctx->current_track[order][type]; if (track == current) return; - if (type == STREAM_VIDEO) { - int uninit = INITIALIZED_VCODEC; - if (!mpctx->opts->force_vo) - uninit |= mpctx->opts->fixed_vo && track ? 0 : INITIALIZED_VO; - uninit_player(mpctx, uninit); - } else if (type == STREAM_AUDIO) { - uninit_player(mpctx, INITIALIZED_AO | INITIALIZED_ACODEC); - } else if (type == STREAM_SUB) { - uninit_player(mpctx, INITIALIZED_SUB); + if (order == 0) { + if (type == STREAM_VIDEO) { + int uninit = INITIALIZED_VCODEC; + if (!mpctx->opts->force_vo) + uninit |= mpctx->opts->fixed_vo && track ? 0 : INITIALIZED_VO; + uninit_player(mpctx, uninit); + } else if (type == STREAM_AUDIO) { + uninit_player(mpctx, INITIALIZED_AO | INITIALIZED_ACODEC); + } else if (type == STREAM_SUB) { + uninit_player(mpctx, INITIALIZED_SUB); + } } if (current) @@ -607,7 +612,7 @@ void mp_switch_track(struct MPContext *mpctx, enum stream_type type, reselect_demux_streams(mpctx); - mpctx->current_track[type] = track; + mpctx->current_track[order][type] = track; if (track) track->selected = true; @@ -615,35 +620,45 @@ void mp_switch_track(struct MPContext *mpctx, enum stream_type type, reselect_demux_streams(mpctx); int user_tid = track ? track->user_tid : -2; - if (type == STREAM_VIDEO) { - mpctx->opts->video_id = user_tid; - reinit_video_chain(mpctx); - mp_notify_property(mpctx, "vid"); - } else if (type == STREAM_AUDIO) { - mpctx->opts->audio_id = user_tid; - reinit_audio_chain(mpctx); - mp_notify_property(mpctx, "aid"); - } else if (type == STREAM_SUB) { - mpctx->opts->sub_id = user_tid; - reinit_subs(mpctx); - mp_notify_property(mpctx, "sid"); + if (order == 0) { + if (type == STREAM_VIDEO) { + mpctx->opts->video_id = user_tid; + reinit_video_chain(mpctx); + mp_notify_property(mpctx, "vid"); + } else if (type == STREAM_AUDIO) { + mpctx->opts->audio_id = user_tid; + reinit_audio_chain(mpctx); + mp_notify_property(mpctx, "aid"); + } else if (type == STREAM_SUB) { + mpctx->opts->sub_id = user_tid; + reinit_subs(mpctx); + mp_notify_property(mpctx, "sid"); + } } talloc_free(mpctx->track_layout_hash); mpctx->track_layout_hash = talloc_steal(mpctx, track_layout_hash(mpctx)); } +void mp_switch_track(struct MPContext *mpctx, enum stream_type type, + struct track *track) +{ + mp_switch_track_n(mpctx, 0, type, track); +} + void mp_deselect_track(struct MPContext *mpctx, struct track *track) { - if (track && track->selected) - mp_switch_track(mpctx, track->type, NULL); + if (track && track->selected) { + for (int t = 0; t < NUM_PTRACKS; t++) + mp_switch_track_n(mpctx, t, track->type, NULL); + } } struct track *mp_track_by_tid(struct MPContext *mpctx, enum stream_type type, int tid) { if (tid == -1) - return mpctx->current_track[type]; + return mpctx->current_track[0][type]; for (int n = 0; n < mpctx->num_tracks; n++) { struct track *track = mpctx->tracks[n]; if (track->type == type && track->user_tid == tid) @@ -1148,17 +1163,17 @@ goto_reopen_demuxer: ; check_previous_track_selection(mpctx); - mpctx->current_track[STREAM_VIDEO] = + mpctx->current_track[0][STREAM_VIDEO] = select_track(mpctx, STREAM_VIDEO, mpctx->opts->video_id, NULL); - mpctx->current_track[STREAM_AUDIO] = + mpctx->current_track[0][STREAM_AUDIO] = select_track(mpctx, STREAM_AUDIO, mpctx->opts->audio_id, mpctx->opts->audio_lang); - mpctx->current_track[STREAM_SUB] = + mpctx->current_track[0][STREAM_SUB] = select_track(mpctx, STREAM_SUB, mpctx->opts->sub_id, mpctx->opts->sub_lang); for (int t = 0; t < mpctx->num_tracks; t++) { struct track *track = mpctx->tracks[t]; - track->selected = track == mpctx->current_track[track->type]; + track->selected = track == mpctx->current_track[0][track->type]; } reselect_demux_streams(mpctx); @@ -1166,9 +1181,9 @@ goto_reopen_demuxer: ; print_file_properties(mpctx); #if HAVE_ENCODING - if (mpctx->encode_lavc_ctx && mpctx->current_track[STREAM_VIDEO]) + if (mpctx->encode_lavc_ctx && mpctx->current_track[0][STREAM_VIDEO]) encode_lavc_expect_stream(mpctx->encode_lavc_ctx, AVMEDIA_TYPE_VIDEO); - if (mpctx->encode_lavc_ctx && mpctx->current_track[STREAM_AUDIO]) + if (mpctx->encode_lavc_ctx && mpctx->current_track[0][STREAM_AUDIO]) encode_lavc_expect_stream(mpctx->encode_lavc_ctx, AVMEDIA_TYPE_AUDIO); #endif diff --git a/player/sub.c b/player/sub.c index a2455589db..3593bab710 100644 --- a/player/sub.c +++ b/player/sub.c @@ -80,7 +80,7 @@ void update_subtitles(struct MPContext *mpctx) if (!(mpctx->initialized_flags & INITIALIZED_SUB)) return; - struct track *track = mpctx->current_track[STREAM_SUB]; + struct track *track = mpctx->current_track[0][STREAM_SUB]; struct dec_sub *dec_sub = mpctx->d_sub; assert(track && dec_sub); @@ -172,7 +172,7 @@ static void set_dvdsub_fake_extradata(struct dec_sub *dec_sub, struct stream *st void reinit_subs(struct MPContext *mpctx) { struct MPOpts *opts = mpctx->opts; - struct track *track = mpctx->current_track[STREAM_SUB]; + struct track *track = mpctx->current_track[0][STREAM_SUB]; assert(!(mpctx->initialized_flags & INITIALIZED_SUB)); diff --git a/player/video.c b/player/video.c index 38e86a395b..9df3caa940 100644 --- a/player/video.c +++ b/player/video.c @@ -136,7 +136,7 @@ int reinit_video_chain(struct MPContext *mpctx) struct MPOpts *opts = mpctx->opts; assert(!(mpctx->initialized_flags & INITIALIZED_VCODEC)); assert(!mpctx->d_video); - struct track *track = mpctx->current_track[STREAM_VIDEO]; + struct track *track = mpctx->current_track[0][STREAM_VIDEO]; struct sh_stream *sh = init_demux_stream(mpctx, track); if (!sh) goto no_video; @@ -318,7 +318,7 @@ void video_execute_format_change(struct MPContext *mpctx) static int check_framedrop(struct MPContext *mpctx, double frame_time) { struct MPOpts *opts = mpctx->opts; - struct track *t_audio = mpctx->current_track[STREAM_AUDIO]; + struct track *t_audio = mpctx->current_track[0][STREAM_AUDIO]; struct sh_stream *sh_audio = t_audio ? t_audio->stream : NULL; // check for frame-drop: if (mpctx->d_audio && !mpctx->ao->untimed && sh_audio && -- cgit v1.2.3