summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-11-08 17:35:27 +0100
committerwm4 <wm4@nowhere>2016-11-08 17:49:13 +0100
commit1d51dc20eadd0873b1870d14e7156aa03c67e511 (patch)
tree41e5a026f62f85a4cce70dfc21bd1155dee9657f /audio
parent2e113a7391ce4286cab5ac9e1a82ee294dc5b8cb (diff)
downloadmpv-1d51dc20eadd0873b1870d14e7156aa03c67e511.tar.bz2
mpv-1d51dc20eadd0873b1870d14e7156aa03c67e511.tar.xz
ao_alsa: strictly disable chmap use for mono/stereo
If the input is already mono or stereo, or if channel map selection results in mono or stereo, then disable further use of the champ ALSA API (or rather, stop trusting its results). Then we behave like a simple application that only wants to output mono or stereo. See #3045 and #2905. I couldn't actually test these cases, but this commit is supposed to fix them.
Diffstat (limited to 'audio')
-rw-r--r--audio/out/ao_alsa.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c
index 8706c0d30b..f80a46a5cc 100644
--- a/audio/out/ao_alsa.c
+++ b/audio/out/ao_alsa.c
@@ -724,18 +724,27 @@ static int init_device(struct ao *ao, int mode)
CHECK_ALSA_ERROR("Unable to set format");
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->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.
- dev_chmap.num = 0;
- } else if (query_chmaps(ao, &dev_chmap)) {
- ao->channels = dev_chmap;
- } else {
- // Assume only stereo and mono are supported.
- mp_chmap_from_channels(&ao->channels, MPMIN(2, dev_chmap.num));
- dev_chmap.num = 0;
+ // Stereo, or mono if input is 1 channel.
+ struct mp_chmap reduced;
+ mp_chmap_from_channels(&reduced, MPMIN(2, ao->channels.num));
+
+ struct mp_chmap dev_chmap = {0};
+ if (!af_fmt_is_spdif(ao->format) && !p->opts->ignore_chmap &&
+ !mp_chmap_equals(&ao->channels, &reduced))
+ {
+ struct mp_chmap res = ao->channels;
+ if (query_chmaps(ao, &res))
+ dev_chmap = res;
+
+ // Whatever it is, we dumb it down to mono or stereo. Some drivers may
+ // return things like bl-br, but the user (probably) still wants stereo.
+ // This also handles the failure case (dev_chmap.num==0).
+ if (dev_chmap.num <= 2) {
+ dev_chmap.num = 0;
+ ao->channels = reduced;
+ } else if (dev_chmap.num) {
+ ao->channels = dev_chmap;
+ }
}
int num_channels = ao->channels.num;