mirror of https://github.com/mpv-player/mpv
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.
This commit is contained in:
parent
2b87415f6f
commit
9292f537d6
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -115,8 +115,10 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask)
|
|||
talloc_free(mpctx->tracks[i]);
|
||||
}
|
||||
mpctx->num_tracks = 0;
|
||||
for (int r = 0; r < NUM_PTRACKS; r++) {
|
||||
for (int t = 0; t < STREAM_TYPE_COUNT; t++)
|
||||
mpctx->current_track[t] = NULL;
|
||||
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,15 +584,17 @@ static void check_previous_track_selection(struct MPContext *mpctx)
|
|||
talloc_free(h);
|
||||
}
|
||||
|
||||
void mp_switch_track(struct MPContext *mpctx, enum stream_type type,
|
||||
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 (order == 0) {
|
||||
if (type == STREAM_VIDEO) {
|
||||
int uninit = INITIALIZED_VCODEC;
|
||||
if (!mpctx->opts->force_vo)
|
||||
|
@ -601,13 +605,14 @@ void mp_switch_track(struct MPContext *mpctx, enum stream_type type,
|
|||
} else if (type == STREAM_SUB) {
|
||||
uninit_player(mpctx, INITIALIZED_SUB);
|
||||
}
|
||||
}
|
||||
|
||||
if (current)
|
||||
current->selected = false;
|
||||
|
||||
reselect_demux_streams(mpctx);
|
||||
|
||||
mpctx->current_track[type] = track;
|
||||
mpctx->current_track[order][type] = track;
|
||||
|
||||
if (track)
|
||||
track->selected = true;
|
||||
|
@ -615,6 +620,7 @@ void mp_switch_track(struct MPContext *mpctx, enum stream_type type,
|
|||
reselect_demux_streams(mpctx);
|
||||
|
||||
int user_tid = track ? track->user_tid : -2;
|
||||
if (order == 0) {
|
||||
if (type == STREAM_VIDEO) {
|
||||
mpctx->opts->video_id = user_tid;
|
||||
reinit_video_chain(mpctx);
|
||||
|
@ -628,22 +634,31 @@ void mp_switch_track(struct MPContext *mpctx, enum stream_type type,
|
|||
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
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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 &&
|
||||
|
|
Loading…
Reference in New Issue