summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-12-23 18:03:16 +0100
committerwm4 <wm4@nowhere>2016-12-23 18:10:07 +0100
commitc560f6ff0ab9aec70e53a268e2ff388a85ec3ca0 (patch)
tree04e7afab982139d2351f00814be7ee127d5290dc
parent17d6ba7f776d6fd0ebc7a9881a999299c3fa9471 (diff)
downloadmpv-c560f6ff0ab9aec70e53a268e2ff388a85ec3ca0.tar.bz2
mpv-c560f6ff0ab9aec70e53a268e2ff388a85ec3ca0.tar.xz
audio: change how spdif codecs are selected
Remove ad_spdif from the normal codec list, and select it explicitly. One goal was to decouple this from the normal codec selection, so they're less entangled and the decoder selection code can be simplified in the far future. This means spdif codec selection is now done explicitly via select_spdif_codec(). We can also remove the weird requirements on "dts" and "dts-hd" for the --audio-spdif option, and it can just do the right thing. Now both video and audio codecs consist of a single codec family each, vd_lavc and ad_lavc.
-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,