ao_alsa: change sub-options to global options
Same deal as with vo_opengl. Also edit the outdated information about multichannel output a little.
This commit is contained in:
1 parent
eb14b18a33
commit
a85eecfe40
8 files changed
+117
-99
No files matched your search
@@ -41,6 +41,7 @@ Interface changes
|
||||
- remove all vo_opengl suboptions. Use global options with the same name
|
||||
instead, e.g.: --vo=opengl:scale=nearest => --scale=nearest
|
||||
Some options are prefixed with "opengl-", e.g. --opengl-pbo.
|
||||
The same change is applied to ao_alsa.
|
||||
- remove --vo=opengl-hq. Set --profile=opengl-hq instead. Note that this
|
||||
profile does not force the VO. This means if you use the --vo option to
|
||||
set another VO, it won't work. But this also means it can be used with
|
||||
|
||||
+4
-68
@@ -34,76 +34,12 @@ Available audio output drivers are:
|
||||
``alsa`` (Linux only)
|
||||
ALSA audio output driver
|
||||
|
||||
``device=<device>``
|
||||
Sets the device name. For ac3 output via S/PDIF, use an "iec958" or
|
||||
"spdif" device, unless you really know how to set it correctly.
|
||||
``resample=yes``
|
||||
Enable ALSA resampling plugin. (This is disabled by default, because
|
||||
some drivers report incorrect audio delay in some cases.)
|
||||
``mixer-device=<device>``
|
||||
Set the mixer device used with ``--no-softvol`` (default: ``default``).
|
||||
``mixer-name=<name>``
|
||||
Set the name of the mixer element (default: ``Master``). This is for
|
||||
example ``PCM`` or ``Master``.
|
||||
``mixer-index=<number>``
|
||||
Set the index of the mixer channel (default: 0). Consider the output of
|
||||
"``amixer scontrols``", then the index is the number that follows the
|
||||
name of the element.
|
||||
``non-interleaved``
|
||||
Allow output of non-interleaved formats (if the audio decoder uses
|
||||
this format). Currently disabled by default, because some popular
|
||||
ALSA plugins are utterly broken with non-interleaved formats.
|
||||
``ignore-chmap``
|
||||
Don't read or set the channel map of the ALSA device - only request the
|
||||
required number of channels, and then pass the audio as-is to it. This
|
||||
option most likely should not be used. It can be useful for debugging,
|
||||
or for static setups with a specially engineered ALSA configuration (in
|
||||
this case you should always force the same layout with ``--audio-channels``,
|
||||
or it will work only for files which use the layout implicit to your
|
||||
ALSA device).
|
||||
|
||||
.. note::
|
||||
|
||||
MPlayer and mplayer2 required you to replace any ',' with '.' and
|
||||
any ':' with '=' in the ALSA device name. mpv does not do this anymore.
|
||||
Instead, quote the device name:
|
||||
|
||||
``--ao=alsa:device=[plug:surround50]``
|
||||
|
||||
Note that the ``[`` and ``]`` simply quote the device name. With some
|
||||
shells (like zsh), you have to quote the option string to prevent the
|
||||
shell from interpreting the brackets instead of passing them to mpv.
|
||||
|
||||
Actually, you should use the ``--audio-device`` option, instead of
|
||||
setting the device directly.
|
||||
|
||||
.. warning::
|
||||
|
||||
Handling of multichannel/surround audio changed in mpv 0.8.0 from the
|
||||
behavior in MPlayer/mplayer2 and older versions of mpv.
|
||||
|
||||
The old behavior is that the player always downmixed to stereo by
|
||||
default. The ``--audio-channels`` (or ``--channels`` before that) option
|
||||
had to be set to get multichannel audio. Then playing stereo would
|
||||
use the ``default`` device (which typically allows multiple programs
|
||||
to play audio at the same time via dmix), while playing anything with
|
||||
more channels would open one of the hardware devices, e.g. via the
|
||||
``surround51`` alias (typically with exclusive access). Whether the
|
||||
player would use exclusive access or not would depend on the file
|
||||
being played.
|
||||
|
||||
The new behavior since mpv 0.8.0 always enables multichannel audio,
|
||||
i.e. ``--audio-channels=auto`` is the default. However, since ALSA
|
||||
provides no good way to play multichannel audio in a non-exclusive
|
||||
way (without blocking other applications from using audio), the player
|
||||
is restricted to the capabilities of the ``default`` device by default,
|
||||
which means it supports only stereo and mono (at least with current
|
||||
typical ALSA configurations). But if a hardware device is selected,
|
||||
then multichannel audio will typically work.
|
||||
|
||||
The short story is: if you want multichannel audio with ALSA, use
|
||||
``--audio-device`` to select the device (use ``--audio-device=help``
|
||||
to get a list of all devices and their mpv name).
|
||||
To get multichannel/surround audio, use ``--audio-channels=auto``. The
|
||||
default for this option is ``auto-safe``, which makes this audio otuput
|
||||
explicitly reject multichannel output, as there is no way to detect
|
||||
whether a certain channel layout is actually supported.
|
||||
|
||||
You can also try `using the upmix plugin <http://git.io/vfuAy>`_.
|
||||
This setup enables multichannel audio on the ``default`` device
|
||||
|
||||
@@ -3597,6 +3597,60 @@ DVB
|
||||
|
||||
Default: ``no``
|
||||
|
||||
ALSA audio output options
|
||||
-------------------------
|
||||
|
||||
|
||||
``--alsa-device=<device>``
|
||||
Sets the device name. For ac3 output via S/PDIF, use an "iec958" or
|
||||
"spdif" device, unless you really know how to set it correctly.
|
||||
|
||||
.. note::
|
||||
|
||||
MPlayer and mplayer2 required you to replace any ',' with '.' and
|
||||
any ':' with '=' in the ALSA device name. mpv does not do this anymore.
|
||||
Instead, quote the device name:
|
||||
|
||||
``--ao=alsa:device=[plug:surround50]``
|
||||
|
||||
Note that the ``[`` and ``]`` simply quote the device name. With some
|
||||
shells (like zsh), you have to quote the option string to prevent the
|
||||
shell from interpreting the brackets instead of passing them to mpv.
|
||||
|
||||
Actually, you should use the ``--audio-device`` option, instead of
|
||||
setting the device directly.
|
||||
|
||||
``--alsa-resample=yes``
|
||||
Enable ALSA resampling plugin. (This is disabled by default, because
|
||||
some drivers report incorrect audio delay in some cases.)
|
||||
|
||||
``--alsa-mixer-device=<device>``
|
||||
Set the mixer device used with ``ao-volume`` (default: ``default``).
|
||||
|
||||
``--alsa-mixer-name=<name>``
|
||||
Set the name of the mixer element (default: ``Master``). This is for
|
||||
example ``PCM`` or ``Master``.
|
||||
|
||||
``--alsa-mixer-index=<number>``
|
||||
Set the index of the mixer channel (default: 0). Consider the output of
|
||||
"``amixer scontrols``", then the index is the number that follows the
|
||||
name of the element.
|
||||
|
||||
``--alsa-non-interleaved``
|
||||
Allow output of non-interleaved formats (if the audio decoder uses
|
||||
this format). Currently disabled by default, because some popular
|
||||
ALSA plugins are utterly broken with non-interleaved formats.
|
||||
|
||||
``--alsa-ignore-chmap``
|
||||
Don't read or set the channel map of the ALSA device - only request the
|
||||
required number of channels, and then pass the audio as-is to it. This
|
||||
option most likely should not be used. It can be useful for debugging,
|
||||
or for static setups with a specially engineered ALSA configuration (in
|
||||
this case you should always force the same layout with ``--audio-channels``,
|
||||
or it will work only for files which use the layout implicit to your
|
||||
ALSA device).
|
||||
|
||||
|
||||
OpenGL renderer options
|
||||
-----------------------
|
||||
|
||||
|
||||
@@ -140,6 +140,7 @@ static struct ao *ao_alloc(bool probing, struct mpv_global *global,
|
||||
*ao = (struct ao) {
|
||||
.driver = desc.p,
|
||||
.probing = probing,
|
||||
.global = global,
|
||||
.input_ctx = input_ctx,
|
||||
.log = mp_log_new(ao, log, name),
|
||||
.def_buffer = opts->audio_buffer,
|
||||
|
||||
+51
-31
@@ -35,6 +35,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "options/options.h"
|
||||
#include "options/m_config.h"
|
||||
#include "options/m_option.h"
|
||||
#include "common/msg.h"
|
||||
#include "osdep/endian.h"
|
||||
@@ -48,6 +49,37 @@
|
||||
#include "internal.h"
|
||||
#include "audio/format.h"
|
||||
|
||||
struct ao_alsa_opts {
|
||||
char *device;
|
||||
char *mixer_device;
|
||||
char *mixer_name;
|
||||
int mixer_index;
|
||||
int resample;
|
||||
int ni;
|
||||
int ignore_chmap;
|
||||
};
|
||||
|
||||
#define OPT_BASE_STRUCT struct ao_alsa_opts
|
||||
const struct m_sub_options ao_alsa_conf = {
|
||||
.opts = (const struct m_option[]) {
|
||||
OPT_STRING("alsa-device", device, 0),
|
||||
OPT_FLAG("alsa-resample", resample, 0),
|
||||
OPT_STRING("alsa-mixer-device", mixer_device, 0),
|
||||
OPT_STRING("alsa-mixer-name", mixer_name, 0),
|
||||
OPT_INTRANGE("alsa-mixer-index", mixer_index, 0, 0, 99),
|
||||
OPT_FLAG("alsa-non-interleaved", ni, 0),
|
||||
OPT_FLAG("alsa-ignore-chmap", ignore_chmap, 0),
|
||||
{0}
|
||||
},
|
||||
.defaults = &(const struct ao_alsa_opts) {
|
||||
.mixer_device = "default",
|
||||
.mixer_name = "Master",
|
||||
.mixer_index = 0,
|
||||
.ni = 0,
|
||||
},
|
||||
.size = sizeof(struct ao_alsa_opts),
|
||||
};
|
||||
|
||||
struct priv {
|
||||
snd_pcm_t *alsa;
|
||||
bool device_lost;
|
||||
@@ -61,13 +93,7 @@ struct priv {
|
||||
|
||||
snd_output_t *output;
|
||||
|
||||
char *cfg_device;
|
||||
char *cfg_mixer_device;
|
||||
char *cfg_mixer_name;
|
||||
int cfg_mixer_index;
|
||||
int cfg_resample;
|
||||
int cfg_ni;
|
||||
int cfg_ignore_chmap;
|
||||
struct ao_alsa_opts *opts;
|
||||
};
|
||||
|
||||
#define BUFFER_TIME 250000 // 250ms
|
||||
@@ -125,13 +151,13 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
|
||||
|
||||
snd_mixer_selem_id_alloca(&sid);
|
||||
|
||||
snd_mixer_selem_id_set_index(sid, p->cfg_mixer_index);
|
||||
snd_mixer_selem_id_set_name(sid, p->cfg_mixer_name);
|
||||
snd_mixer_selem_id_set_index(sid, p->opts->mixer_index);
|
||||
snd_mixer_selem_id_set_name(sid, p->opts->mixer_name);
|
||||
|
||||
err = snd_mixer_open(&handle, 0);
|
||||
CHECK_ALSA_ERROR("Mixer open error");
|
||||
|
||||
err = snd_mixer_attach(handle, p->cfg_mixer_device);
|
||||
err = snd_mixer_attach(handle, p->opts->mixer_device);
|
||||
CHECK_ALSA_ERROR("Mixer attach error");
|
||||
|
||||
err = snd_mixer_selem_register(handle, NULL, NULL);
|
||||
@@ -447,7 +473,7 @@ static int set_chmap(struct ao *ao, struct mp_chmap *dev_chmap, int num_channels
|
||||
|
||||
MP_VERBOSE(ao, "which we understand as: %s\n", mp_chmap_to_str(&chmap));
|
||||
|
||||
if (p->cfg_ignore_chmap) {
|
||||
if (p->opts->ignore_chmap) {
|
||||
MP_VERBOSE(ao, "user set ignore-chmap; ignoring the channel map.\n");
|
||||
} else if (af_fmt_is_spdif(ao->format)) {
|
||||
MP_VERBOSE(ao, "using spdif passthrough; ignoring the channel map.\n");
|
||||
@@ -615,8 +641,8 @@ static int init_device(struct ao *ao, int mode)
|
||||
const char *device = "default";
|
||||
if (ao->device)
|
||||
device = ao->device;
|
||||
if (p->cfg_device && p->cfg_device[0])
|
||||
device = p->cfg_device;
|
||||
if (p->opts->device && p->opts->device[0])
|
||||
device = p->opts->device;
|
||||
|
||||
err = try_open_device(ao, device, mode);
|
||||
CHECK_ALSA_ERROR("Playback open error");
|
||||
@@ -641,7 +667,7 @@ static int init_device(struct ao *ao, int mode)
|
||||
|
||||
// Some ALSA drivers have broken delay reporting, so disable the ALSA
|
||||
// resampling plugin by default.
|
||||
if (!p->cfg_resample) {
|
||||
if (!p->opts->resample) {
|
||||
err = snd_pcm_hw_params_set_rate_resample(p->alsa, alsa_hwparams, 0);
|
||||
CHECK_ALSA_ERROR("Unable to disable resampling");
|
||||
}
|
||||
@@ -684,7 +710,7 @@ static int init_device(struct ao *ao, int mode)
|
||||
dump_hw_params(ao, MSGL_DEBUG, "HW params after format:\n", alsa_hwparams);
|
||||
|
||||
struct mp_chmap dev_chmap = ao->channels;
|
||||
if (af_fmt_is_spdif(ao->format) || p->cfg_ignore_chmap) {
|
||||
if (af_fmt_is_spdif(ao->format) || p->opts->ignore_chmap) {
|
||||
dev_chmap.num = 0; // disable chmap API
|
||||
} else if (dev_chmap.num == 1 && dev_chmap.speaker[0] == MP_SPEAKER_ID_FC) {
|
||||
// As yet another ALSA API inconsistency, mono is not reported correctly.
|
||||
@@ -806,7 +832,9 @@ alsa_error:
|
||||
static int init(struct ao *ao)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
if (!p->cfg_ni)
|
||||
p->opts = mp_get_config_group(ao, ao->global, &ao_alsa_conf);
|
||||
|
||||
if (!p->opts->ni)
|
||||
ao->format = af_fmt_from_planar(ao->format);
|
||||
|
||||
MP_VERBOSE(ao, "using ALSA version: %s\n", snd_asoundlib_version());
|
||||
@@ -1125,8 +1153,6 @@ static void list_devs(struct ao *ao, struct ao_device_list *list)
|
||||
snd_device_name_free_hint(hints);
|
||||
}
|
||||
|
||||
#define OPT_BASE_STRUCT struct priv
|
||||
|
||||
const struct ao_driver audio_out_alsa = {
|
||||
.description = "ALSA audio output",
|
||||
.name = "alsa",
|
||||
@@ -1144,20 +1170,14 @@ const struct ao_driver audio_out_alsa = {
|
||||
.wakeup = ao_wakeup_poll,
|
||||
.list_devs = list_devs,
|
||||
.priv_size = sizeof(struct priv),
|
||||
.priv_defaults = &(const struct priv) {
|
||||
.cfg_mixer_device = "default",
|
||||
.cfg_mixer_name = "Master",
|
||||
.cfg_mixer_index = 0,
|
||||
.cfg_ni = 0,
|
||||
},
|
||||
.options = (const struct m_option[]) {
|
||||
OPT_STRING("device", cfg_device, 0),
|
||||
OPT_FLAG("resample", cfg_resample, 0),
|
||||
OPT_STRING("mixer-device", cfg_mixer_device, 0),
|
||||
OPT_STRING("mixer-name", cfg_mixer_name, 0),
|
||||
OPT_INTRANGE("mixer-index", cfg_mixer_index, 0, 0, 99),
|
||||
OPT_FLAG("non-interleaved", cfg_ni, 0),
|
||||
OPT_FLAG("ignore-chmap", cfg_ignore_chmap, 0),
|
||||
OPT_SUBOPT_LEGACY("device", "alsa-device"),
|
||||
OPT_SUBOPT_LEGACY("resample", "alsa-resample"),
|
||||
OPT_SUBOPT_LEGACY("mixer-device", "alsa-mixer-device"),
|
||||
OPT_SUBOPT_LEGACY("mixer-name", "alsa-mixer-name"),
|
||||
OPT_SUBOPT_LEGACY("mixer-index", "alsa-mixer-index"),
|
||||
OPT_SUBOPT_LEGACY("non-interleaved", "alsa-non-interleaved"),
|
||||
OPT_SUBOPT_LEGACY("ignore-chmap", "alsa-ignore-chmap"),
|
||||
{0}
|
||||
},
|
||||
};
|
||||
@@ -40,6 +40,7 @@ struct ao {
|
||||
const struct ao_driver *api; // entrypoints to the wrapper (push.c/pull.c)
|
||||
const struct ao_driver *driver;
|
||||
void *priv;
|
||||
struct mpv_global *global;
|
||||
struct encode_lavc_context *encode_lavc_ctx;
|
||||
struct input_ctx *input_ctx;
|
||||
struct mp_log *log; // Using e.g. "[ao/coreaudio]" as prefix
|
||||
|
||||
@@ -75,6 +75,7 @@ extern const struct m_sub_options encode_config;
|
||||
extern const struct m_sub_options image_writer_conf;
|
||||
extern const struct m_sub_options gl_video_conf;
|
||||
extern const struct m_sub_options vo_opengl_conf;
|
||||
extern const struct m_sub_options ao_alsa_conf;
|
||||
|
||||
extern const struct m_obj_list vf_obj_list;
|
||||
extern const struct m_obj_list af_obj_list;
|
||||
@@ -648,6 +649,9 @@ const m_option_t mp_opts[] = {
|
||||
OPT_SUBSTRUCT("", gl_video_opts, gl_video_conf, 0),
|
||||
OPT_SUBSTRUCT("", vo_opengl_opts, vo_opengl_conf, 0),
|
||||
#endif
|
||||
#if HAVE_ALSA
|
||||
OPT_SUBSTRUCT("", ao_alsa_opts, ao_alsa_conf, 0),
|
||||
#endif
|
||||
|
||||
#if HAVE_ENCODING
|
||||
OPT_SUBSTRUCT("", encode_opts, encode_config, 0),
|
||||
|
||||
@@ -334,6 +334,7 @@ typedef struct MPOpts {
|
||||
|
||||
struct gl_video_opts *gl_video_opts;
|
||||
struct vo_opengl_opts *vo_opengl_opts;
|
||||
struct ao_alsa_opts *ao_alsa_opts;
|
||||
} MPOpts;
|
||||
|
||||
extern const m_option_t mp_opts[];
|
||||
|
||||
Reference in new issue
Block a user