summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/interface-changes.rst2
-rw-r--r--DOCS/man/options.rst37
-rw-r--r--audio/decode/dec_audio.c26
-rw-r--r--audio/decode/dec_audio.h3
-rw-r--r--common/codecs.c22
-rw-r--r--common/codecs.h7
-rw-r--r--options/options.c2
-rw-r--r--options/options.h1
-rw-r--r--player/audio.c15
-rw-r--r--player/main.c4
10 files changed, 101 insertions, 18 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst
index c1980940bf..b6a77b6bd5 100644
--- a/DOCS/interface-changes.rst
+++ b/DOCS/interface-changes.rst
@@ -20,6 +20,8 @@ Interface changes
::
--- mpv 0.10.0 will be released ---
+ - deprecate --ad-spdif-dtshd and enabling passthrough via --ad
+ add --audio-spdif as replacement
- remove "get_property" command
- remove --slave-broken
- add vo opengl custom shader suboptions (source-shader, scale-shader,
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index f51b471c01..61cd7058c0 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -855,6 +855,25 @@ Audio
``--af-clr`` exist to modify a previously specified list, but you
should not need these for typical use.
+``--audio-spdif=<codecs>``
+ List of codecs for which compressed audio passthrough should be used. This
+ works for both classic S/PDIF and HDMI.
+
+ 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).
+
+ In general, all codecs in the ``spdif`` family listed with ``--ad=help``
+ are supported in theory.
+
+ .. admonition:: Warning
+
+ There is not much reason to use this. HDMI supports uncompressed
+ multichannel PCM, and mpv supports lossless DTS-HD decoding via
+ FFmpeg's libdcadec wrapper.
+
``--ad=<[+|-]family1:(*|decoder1),[+|-]family2:(*|decoder2),...[-]>``
Specify a priority list of audio decoders to be used, according to their
family and decoder name. Entries like ``family:*`` prioritize all decoders
@@ -882,6 +901,11 @@ Audio
``--ad=help``
List all available decoders.
+ .. admonition:: Warning
+
+ Enabling compressed audio passthrough (AC3 and DTS via SPDIF/HDMI) with
+ this option is deprecated. Use ``--audio-spdif`` instead.
+
``--volume=<value>``
Set the startup volume. 0 means silence, 100 means no volume reduction or
amplification. A value of -1 (the default) will not change the volume. See
@@ -953,17 +977,12 @@ Audio
welcome. A full list of AVOptions can be found in the FFmpeg manual.
``--ad-spdif-dtshd=<yes|no>``, ``--dtshd``, ``--no-dtshd``
- When using DTS pass-through, output any DTS-HD track as-is.
- With ``ad-spdif-dtshd=no`` (the default), only the DTS Core parts will be
- output.
+ If DTS is passed through, use DTS-HD.
- DTS-HD tracks can be sent over HDMI but not over the original
- coax/TOSLINK S/PDIF system.
-
- Some receivers don't accept DTS core-only when ``--ad-spdif-dtshd=yes`` is
- used, even though they accept DTS-HD.
+ .. admonition:: Warning
- ``--dtshd`` and ``--no-dtshd`` are deprecated aliases.
+ This and enabling passthrough via ``--ad`` are deprecated in favor of
+ using ``--audio-spdif=dts-hd``.
``--audio-channels=<number|layout>``
Request a channel layout for audio output (default: auto). This will ask
diff --git a/audio/decode/dec_audio.c b/audio/decode/dec_audio.c
index dfbe32cbdf..19d2c4e3df 100644
--- a/audio/decode/dec_audio.c
+++ b/audio/decode/dec_audio.c
@@ -52,6 +52,7 @@ static const struct ad_functions * const ad_drivers[] = {
static void uninit_decoder(struct dec_audio *d_audio)
{
+ audio_reset_decoding(d_audio);
if (d_audio->ad_driver) {
MP_VERBOSE(d_audio, "Uninit audio decoder.\n");
d_audio->ad_driver->uninit(d_audio);
@@ -59,6 +60,8 @@ static void uninit_decoder(struct dec_audio *d_audio)
d_audio->ad_driver = NULL;
talloc_free(d_audio->priv);
d_audio->priv = NULL;
+ d_audio->afilter->initialized = -1;
+ d_audio->decode_format = (struct mp_audio){0};
}
static int init_audio_codec(struct dec_audio *d_audio, const char *decoder)
@@ -81,11 +84,21 @@ struct mp_decoder_list *audio_decoder_list(void)
return list;
}
-static struct mp_decoder_list *audio_select_decoders(const char *codec,
- char *selection)
+static struct mp_decoder_list *audio_select_decoders(struct dec_audio *d_audio)
{
+ struct MPOpts *opts = d_audio->opts;
+ const char *codec = d_audio->header->codec;
+
struct mp_decoder_list *list = audio_decoder_list();
- struct mp_decoder_list *new = mp_select_decoders(list, codec, selection);
+ struct mp_decoder_list *new =
+ mp_select_decoders(list, codec, opts->audio_decoders);
+ if (d_audio->spdif_passthrough) {
+ struct mp_decoder_list *spdif =
+ mp_select_decoder_list(list, codec, "spdif", opts->audio_spdif);
+ mp_append_decoders(spdif, new);
+ talloc_free(new);
+ new = spdif;
+ }
talloc_free(list);
return new;
}
@@ -99,14 +112,13 @@ static const struct ad_functions *find_driver(const char *name)
return NULL;
}
-int audio_init_best_codec(struct dec_audio *d_audio, char *audio_decoders)
+int audio_init_best_codec(struct dec_audio *d_audio)
{
+ uninit_decoder(d_audio);
assert(!d_audio->ad_driver);
- audio_reset_decoding(d_audio);
struct mp_decoder_entry *decoder = NULL;
- struct mp_decoder_list *list =
- audio_select_decoders(d_audio->header->codec, audio_decoders);
+ struct mp_decoder_list *list = audio_select_decoders(d_audio);
mp_print_decoders(d_audio->log, MSGL_V, "Codec list:", list);
diff --git a/audio/decode/dec_audio.h b/audio/decode/dec_audio.h
index 11e4a24b81..6d7dd18bc8 100644
--- a/audio/decode/dec_audio.h
+++ b/audio/decode/dec_audio.h
@@ -30,6 +30,7 @@ struct dec_audio {
struct mp_log *log;
struct MPOpts *opts;
struct mpv_global *global;
+ bool spdif_passthrough;
const struct ad_functions *ad_driver;
struct sh_stream *header;
struct af_stream *afilter;
@@ -57,7 +58,7 @@ enum {
};
struct mp_decoder_list *audio_decoder_list(void);
-int audio_init_best_codec(struct dec_audio *d_audio, char *audio_decoders);
+int audio_init_best_codec(struct dec_audio *d_audio);
int audio_decode(struct dec_audio *d_audio, struct mp_audio_buffer *outbuf,
int minsamples);
int initial_audio_decode(struct dec_audio *d_audio);
diff --git a/common/codecs.c b/common/codecs.c
index f89ef0c318..35d270989d 100644
--- a/common/codecs.c
+++ b/common/codecs.c
@@ -130,6 +130,28 @@ 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++)
+ add_new(list, &a->entries[n], NULL);
+}
+
void mp_print_decoders(struct mp_log *log, int msgl, const char *header,
struct mp_decoder_list *list)
{
diff --git a/common/codecs.h b/common/codecs.h
index 105aab5a82..a262ed6582 100644
--- a/common/codecs.h
+++ b/common/codecs.h
@@ -37,6 +37,13 @@ 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;
void mp_print_decoders(struct mp_log *log, int msgl, const char *header,
struct mp_decoder_list *list);
diff --git a/options/options.c b/options/options.c
index 65fadc8e94..4ba2db1590 100644
--- a/options/options.c
+++ b/options/options.c
@@ -279,6 +279,8 @@ const m_option_t mp_opts[] = {
OPT_STRING("ad", audio_decoders, 0),
OPT_STRING("vd", video_decoders, 0),
+ OPT_STRING("audio-spdif", audio_spdif, 0),
+
OPT_FLAG("ad-spdif-dtshd", dtshd, 0),
OPT_CHOICE("hwdec", hwdec_api, 0,
diff --git a/options/options.h b/options/options.h
index a8dd1ade97..b5e0e1f624 100644
--- a/options/options.h
+++ b/options/options.h
@@ -109,6 +109,7 @@ typedef struct MPOpts {
char *audio_decoders;
char *video_decoders;
+ char *audio_spdif;
int osd_level;
int osd_duration;
diff --git a/player/audio.c b/player/audio.c
index 559e194218..b354f701ae 100644
--- a/player/audio.c
+++ b/player/audio.c
@@ -190,8 +190,9 @@ void reinit_audio_chain(struct MPContext *mpctx)
mpctx->d_audio->pool = mp_audio_pool_create(mpctx->d_audio);
mpctx->d_audio->afilter = af_new(mpctx->global);
mpctx->d_audio->afilter->replaygain_data = sh->audio->replaygain_data;
+ mpctx->d_audio->spdif_passthrough = true;
mpctx->ao_buffer = mp_audio_buffer_create(NULL);
- if (!audio_init_best_codec(mpctx->d_audio, opts->audio_decoders))
+ if (!audio_init_best_codec(mpctx->d_audio))
goto init_error;
reset_audio_state(mpctx);
@@ -264,6 +265,18 @@ void reinit_audio_chain(struct MPContext *mpctx)
}
if (!mpctx->ao) {
+ // If spdif was used, try to fallback to PCM.
+ if (AF_FORMAT_IS_SPECIAL(afs->output.format) &&
+ mpctx->d_audio->spdif_passthrough)
+ {
+ mpctx->d_audio->spdif_passthrough = false;
+ if (!audio_init_best_codec(mpctx->d_audio))
+ goto init_error;
+ reset_audio_state(mpctx);
+ reinit_audio_chain(mpctx);
+ return;
+ }
+
MP_ERR(mpctx, "Could not open/initialize audio device -> no sound.\n");
mpctx->error_playing = MPV_ERROR_AO_INIT_FAILED;
goto init_error;
diff --git a/player/main.c b/player/main.c
index bb22069bfc..06b1867ebe 100644
--- a/player/main.c
+++ b/player/main.c
@@ -278,6 +278,10 @@ static bool handle_help_options(struct MPContext *mpctx)
talloc_free(list);
opt_exit = 1;
}
+ if (opts->audio_spdif && strcmp(opts->audio_spdif, "help") == 0) {
+ MP_INFO(mpctx, "Choices: ac3,dts-hd,dts (and possibly more)\n");
+ opt_exit = 1;
+ }
if (opts->video_decoders && strcmp(opts->video_decoders, "help") == 0) {
struct mp_decoder_list *list = video_decoder_list();
mp_print_decoders(log, MSGL_INFO, "Video decoders:", list);