From 9e6c6c08975c03b771adc1d2b524d91a985ed2b9 Mon Sep 17 00:00:00 2001 From: rcombs Date: Sun, 16 Jul 2023 17:43:45 -0700 Subject: [PATCH] loadfile: compute audio lang for sub selection when using lavfi-complex When using lavfi-complex, no single track populates current_track for audio. We work around this by iterating over the list of tracks and using the first non-null language from a selected track. If multiple tracks are selected (i.e. used by the filter) and have conflicting language tags, we'll ignore them all and maintain the previous behavior (null). --- player/loadfile.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/player/loadfile.c b/player/loadfile.c index 83097a24bd..a534ec6344 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -579,6 +579,35 @@ static char **process_langs(char **in) return out; } +const char *get_audio_lang(struct MPContext *mpctx) +{ + // If we have a single current audio track, this is simple. + if (mpctx->current_track[0][STREAM_AUDIO]) + return mpctx->current_track[0][STREAM_AUDIO]->lang; + + const char *ret = NULL; + + // Otherwise, we may be using a filter with multiple inputs. + // Iterate over the tracks and find the ones in use. + for (int i = 0; i < mpctx->num_tracks; i++) { + const struct track *t = mpctx->tracks[i]; + if (t->type != STREAM_AUDIO || !t->selected) + continue; + + // If we have input in multiple audio languages, bail out; + // we don't have a meaningful single language. + // Partial matches (e.g. en-US vs en-GB) are acceptable here. + if (ret && t->lang && !mp_match_lang_single(t->lang, ret)) + return NULL; + + // We'll return the first non-null tag we see + if (!ret) + ret = t->lang; + } + + return ret; +} + struct track *select_default_track(struct MPContext *mpctx, int order, enum stream_type type) { @@ -589,9 +618,7 @@ struct track *select_default_track(struct MPContext *mpctx, int order, if (tid == -2) return NULL; char **langs = process_langs(opts->stream_lang[type]); - const char *audio_lang = mpctx->current_track[0][STREAM_AUDIO] ? - mpctx->current_track[0][STREAM_AUDIO]->lang : - NULL; + const char *audio_lang = get_audio_lang(mpctx); bool audio_matches = match_lang(langs, audio_lang); int prefer_forced = type == STREAM_SUB && !opts->subs_with_matching_audio && audio_matches; bool select_fallback = type == STREAM_VIDEO || type == STREAM_AUDIO || (type == STREAM_SUB && opts->subs_fallback == 2);