summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/interface-changes.rst2
-rw-r--r--DOCS/man/options.rst7
-rw-r--r--audio/decode/ad_spdif.c49
-rw-r--r--audio/decode/dec_audio.c9
-rw-r--r--audio/decode/dec_audio.h3
-rw-r--r--common/codecs.c16
-rw-r--r--common/codecs.h5
-rw-r--r--options/options.c2
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,