diff options
-rw-r--r-- | DOCS/interface-changes.rst | 2 | ||||
-rw-r--r-- | DOCS/man/options.rst | 7 | ||||
-rw-r--r-- | audio/decode/ad_spdif.c | 49 | ||||
-rw-r--r-- | audio/decode/dec_audio.c | 9 | ||||
-rw-r--r-- | audio/decode/dec_audio.h | 3 | ||||
-rw-r--r-- | common/codecs.c | 16 | ||||
-rw-r--r-- | common/codecs.h | 5 | ||||
-rw-r--r-- | options/options.c | 2 |
8 files changed, 54 insertions, 39 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index fae6605dae..d2c8536fd4 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -43,6 +43,8 @@ Interface changes - --sub-codepage=<codepage> does not force the codepage anymore (this requires different and new syntax) - remove --fs-black-out-screens option for macOS + - change how spdif codecs are selected. You can't enable spdif passthrough + with --ad anymore. This was deprecated; use --audio-spdif instead. --- mpv 0.22.0 --- - the "audio-device-list" property now sets empty device description to the device name as a fallback diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index a81646f6a4..bc33edc13d 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -1121,11 +1121,10 @@ Audio Possible codecs are ``ac3``, ``dts``, ``dts-hd``. Multiple codecs can be specified by separating them with ``,``. ``dts`` refers to low bitrate DTS core, while ``dts-hd`` refers to DTS MA (receiver and OS support varies). - You should only use either ``dts`` or ``dts-hd`` (if both are specified, - and ``dts`` comes first, only ``dts`` will be used). + If both ``dts`` and ``dts-hd`` are specified, it behaves equivalent to + specifying ``dts-hd`` only. - In general, all codecs in the ``spdif`` family listed with ``--ad=help`` - are supported in theory. + In earlier mpv versions .. admonition:: Warning diff --git a/audio/decode/ad_spdif.c b/audio/decode/ad_spdif.c index 60aef3b18f..30c7883bf4 100644 --- a/audio/decode/ad_spdif.c +++ b/audio/decode/ad_spdif.c @@ -83,12 +83,10 @@ static int init(struct dec_audio *da, const char *decoder) spdif_ctx->use_dts_hd = da->opts->dtshd; spdif_ctx->pool = mp_audio_pool_create(spdif_ctx); - if (strcmp(decoder, "dts-hd") == 0) { - decoder = "dts"; + if (strcmp(decoder, "spdif_dts_hd") == 0) spdif_ctx->use_dts_hd = true; - } - spdif_ctx->codec_id = mp_codec_to_av_codec_id(decoder); + spdif_ctx->codec_id = mp_codec_to_av_codec_id(da->codec->codec); return spdif_ctx->codec_id != AV_CODEC_ID_NONE; } @@ -296,22 +294,53 @@ static const int codecs[] = { AV_CODEC_ID_NONE }; -static void add_decoders(struct mp_decoder_list *list) +static bool find_codec(const char *name) { for (int n = 0; codecs[n] != AV_CODEC_ID_NONE; n++) { const char *format = mp_codec_from_av_codec_id(codecs[n]); - if (format) { - mp_add_decoder(list, "spdif", format, format, - "libavformat/spdifenc audio pass-through decoder"); + if (format && name && strcmp(format, name) == 0) + return true; + } + return false; +} + +// codec is the libavcodec name of the source audio codec. +// pref is a ","-separated list of names, some of them which do not match with +// libavcodec names (like dts-hd). +struct mp_decoder_list *select_spdif_codec(const char *codec, const char *pref) +{ + struct mp_decoder_list *list = talloc_zero(NULL, struct mp_decoder_list); + + if (!find_codec(codec)) + return list; + + bool spdif_allowed = false, dts_hd_allowed = false; + bstr sel = bstr0(pref); + while (sel.len) { + bstr decoder; + bstr_split_tok(sel, ",", &decoder, &sel); + if (decoder.len) { + if (bstr_equals0(decoder, codec)) + spdif_allowed = true; + if (bstr_equals0(decoder, "dts-hd") && strcmp(codec, "dts") == 0) + spdif_allowed = dts_hd_allowed = true; } } - mp_add_decoder(list, "spdif", "dts", "dts-hd", + + if (!spdif_allowed) + return list; + + const char *suffix_name = dts_hd_allowed ? "dts_hd" : codec; + char name[80]; + snprintf(name, sizeof(name), "spdif_%s", suffix_name); + mp_add_decoder(list, "spdif", codec, name, "libavformat/spdifenc audio pass-through decoder"); + return list; } const struct ad_functions ad_spdif = { .name = "spdif", - .add_decoders = add_decoders, + .add_decoders = NULL, .init = init, .uninit = uninit, .control = control, diff --git a/audio/decode/dec_audio.c b/audio/decode/dec_audio.c index 39e867cf42..c98d42f556 100644 --- a/audio/decode/dec_audio.c +++ b/audio/decode/dec_audio.c @@ -43,11 +43,12 @@ #include "audio/filter/af.h" extern const struct ad_functions ad_lavc; + +// Not a real codec - specially treated. extern const struct ad_functions ad_spdif; static const struct ad_functions * const ad_drivers[] = { &ad_lavc, - &ad_spdif, NULL }; @@ -91,9 +92,9 @@ static struct mp_decoder_list *audio_select_decoders(struct dec_audio *d_audio) struct mp_decoder_list *list = audio_decoder_list(); struct mp_decoder_list *new = mp_select_decoders(list, codec, opts->audio_decoders); - if (d_audio->try_spdif) { + if (d_audio->try_spdif && codec) { struct mp_decoder_list *spdif = - mp_select_decoder_list(list, codec, "spdif", opts->audio_spdif); + select_spdif_codec(codec, opts->audio_spdif); mp_append_decoders(spdif, new); talloc_free(new); new = spdif; @@ -108,6 +109,8 @@ static const struct ad_functions *find_driver(const char *name) if (strcmp(ad_drivers[i]->name, name) == 0) return ad_drivers[i]; } + if (strcmp(name, "spdif") == 0) + return &ad_spdif; return NULL; } diff --git a/audio/decode/dec_audio.h b/audio/decode/dec_audio.h index 7bc8b00b0f..ebe7c8ae5b 100644 --- a/audio/decode/dec_audio.h +++ b/audio/decode/dec_audio.h @@ -59,4 +59,7 @@ int audio_get_frame(struct dec_audio *d_audio, struct mp_audio **out_frame); void audio_reset_decoding(struct dec_audio *d_audio); +// ad_spdif.c +struct mp_decoder_list *select_spdif_codec(const char *codec, const char *pref); + #endif /* MPLAYER_DEC_AUDIO_H */ diff --git a/common/codecs.c b/common/codecs.c index c0d99eb959..463811066c 100644 --- a/common/codecs.c +++ b/common/codecs.c @@ -130,22 +130,6 @@ struct mp_decoder_list *mp_select_decoders(struct mp_decoder_list *all, return list; } -// selection is a ","-separated list of decoders, all in the given family. -struct mp_decoder_list *mp_select_decoder_list(struct mp_decoder_list *all, - const char *codec, - const char *family, - const char *selection) -{ - struct mp_decoder_list *list = talloc_zero(NULL, struct mp_decoder_list); - bstr sel = bstr0(selection); - while (sel.len) { - bstr decoder; - bstr_split_tok(sel, ",", &decoder, &sel); - add_new(list, find_decoder(all, bstr0(family), decoder), codec); - } - return list; -} - void mp_append_decoders(struct mp_decoder_list *list, struct mp_decoder_list *a) { for (int n = 0; n < a->num_entries; n++) diff --git a/common/codecs.h b/common/codecs.h index 17316c85e9..3e9408eaad 100644 --- a/common/codecs.h +++ b/common/codecs.h @@ -37,11 +37,6 @@ struct mp_decoder_list *mp_select_decoders(struct mp_decoder_list *all, const char *codec, const char *selection); -struct mp_decoder_list *mp_select_decoder_list(struct mp_decoder_list *all, - const char *codec, - const char *family, - const char *selection); - void mp_append_decoders(struct mp_decoder_list *list, struct mp_decoder_list *a); struct mp_log; diff --git a/options/options.c b/options/options.c index 76fabca256..108c805de7 100644 --- a/options/options.c +++ b/options/options.c @@ -804,7 +804,7 @@ const struct MPOpts mp_default_opts = { .use_terminal = 1, .msg_color = 1, .audio_driver_list = NULL, - .audio_decoders = "-spdif:*", // never select spdif by default + .audio_decoders = NULL, .video_decoders = NULL, .deinterlace = -1, .softvol = SOFTVOL_AUTO, |