ao_alsa: disable ALSA resampling by default again

This partially reverts commit 7d152965. It turns out that at least some
ALSA drivers (at least snd-hda-intel) report incorrect audio delay with
non-native sample rates, even if the sample rate is only very slightly
different from the native one.

For example, 48000Hz is fine on my hda-intel system, while both 8000Hz
and 47999Hz lead to a delay off by 40ms (according to mpv's A/V
difference display), which suggests that something in ALSA is
calculating the delay using the wrong sample rate.

As an additional problem, with ALSA resampling enabled, using
48001Hz/float/2ch fails, while 49000Hz/float/2ch or 48001Hz/s16/2ch
work. With resampling disabled, all these cases work obviously, because
our own resampler doesn't just refuse any of these formats.

Since some people want to use the ALSA resampler (because it's highly
configurable, supports multiple backends, etc.), we still allow enabling
ALSA resampling with an ao_alsa suboption.
This commit is contained in:
wm4 2013-11-29 15:43:39 +01:00
parent 42714f9a99
commit f1072e7629
2 changed files with 13 additions and 1 deletions

View File

@ -23,10 +23,13 @@ in the list. Suboptions are optional and can mostly be omitted.
Available audio output drivers are: Available audio output drivers are:
``alsa`` (Linux only) ``alsa`` (Linux only)
ALSA 0.9/1.x audio output driver ALSA audio output driver
``no-block`` ``no-block``
Sets noblock-mode. Sets noblock-mode.
``resample=yes``
Enable ALSA resampling plugin. (This is disabled by default, because
some drivers report incorrect audio delay in some cases.)
``device=<device>`` ``device=<device>``
Sets the device name. For ac3 output via S/PDIF, use an "iec958" or 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. "spdif" device, unless you really know how to set it correctly.

View File

@ -63,6 +63,7 @@ struct priv {
char *cfg_mixer_device; char *cfg_mixer_device;
char *cfg_mixer_name; char *cfg_mixer_name;
int cfg_mixer_index; int cfg_mixer_index;
int cfg_resample;
}; };
#define BUFFER_TIME 500000 // 0.5 s #define BUFFER_TIME 500000 // 0.5 s
@ -475,6 +476,13 @@ static int init(struct ao *ao)
mp_chmap_from_channels_alsa(&ao->channels, num_channels); mp_chmap_from_channels_alsa(&ao->channels, num_channels);
} }
// Some ALSA drivers have broken delay reporting, so disable the ALSA
// resampling plugin by default.
if (!p->cfg_resample) {
err = snd_pcm_hw_params_set_rate_resample(p->alsa, alsa_hwparams, 0);
CHECK_ALSA_ERROR("Unable to disable resampling");
}
err = snd_pcm_hw_params_set_rate_near err = snd_pcm_hw_params_set_rate_near
(p->alsa, alsa_hwparams, &ao->samplerate, NULL); (p->alsa, alsa_hwparams, &ao->samplerate, NULL);
CHECK_ALSA_ERROR("Unable to set samplerate-2"); CHECK_ALSA_ERROR("Unable to set samplerate-2");
@ -743,6 +751,7 @@ const struct ao_driver audio_out_alsa = {
.cfg_mixer_index = 0, .cfg_mixer_index = 0,
}, },
.options = (const struct m_option[]) { .options = (const struct m_option[]) {
OPT_FLAG("resample", cfg_resample, 0),
OPT_STRING("device", cfg_device, 0), OPT_STRING("device", cfg_device, 0),
OPT_FLAG("block", cfg_block, 0), OPT_FLAG("block", cfg_block, 0),
OPT_STRING("mixer-device", cfg_mixer_device, 0), OPT_STRING("mixer-device", cfg_mixer_device, 0),