0
0
mirror of https://github.com/mpv-player/mpv.git synced 2024-09-20 12:02:23 +02:00

ao_alsa: fix 7.1 over HDMI

We need to effectively swap the last channel pair. See commit 4e358a96
and 5a18c5ea for details.

Doing this seems rather strange, as 7.1 just extends 5.1 with 2 new
speakers, and 5.1 doesn't need this change. Going by the HDMI standard
and the Intel HDA sources (cited in the referenced commits), it also
looks like 7.1 should simply append two channels to 5.1 as well. But
swapping them is apparently correct. This is also what XBMC does. (I
didn't find any other applications doing 7.1 PCM using the ALSA channel
map API. VLC seems to ignore the 7.1 case.) Testing reveals that at
least the end result is correct.

"Normal" ALSA 7.1 is unaffected by this, as it reports a different
(and saner) channel layout.
This commit is contained in:
wm4 2015-11-04 13:50:22 +01:00
parent 46f59f25c2
commit be49da72ea

View File

@ -284,6 +284,28 @@ static int find_mp_channel(int alsa_channel)
return MP_SPEAKER_ID_COUNT;
}
#define CHMAP(n, ...) &(struct mp_chmap) MP_CONCAT(MP_CHMAP, n) (__VA_ARGS__)
// Replace each channel in a with b (a->num == b->num)
static void replace_submap(struct mp_chmap *dst, struct mp_chmap *a,
struct mp_chmap *b)
{
struct mp_chmap t = *dst;
if (!mp_chmap_is_valid(&t) || mp_chmap_diffn(a, &t) != 0)
return;
assert(a->num == b->num);
for (int n = 0; n < t.num; n++) {
for (int i = 0; i < a->num; i++) {
if (t.speaker[n] == a->speaker[i]) {
t.speaker[n] = b->speaker[i];
break;
}
}
}
if (mp_chmap_is_valid(&t))
*dst = t;
}
static bool mp_chmap_from_alsa(struct mp_chmap *dst, snd_pcm_chmap_t *src)
{
*dst = (struct mp_chmap) {0};
@ -299,6 +321,10 @@ static bool mp_chmap_from_alsa(struct mp_chmap *dst, snd_pcm_chmap_t *src)
if (dst->num == 1)
dst->speaker[0] = MP_SP(FC);
// Remap weird Intel HDA HDMI 7.1 layouts correctly.
replace_submap(dst, CHMAP(6, FL, FR, BL, BR, SDL, SDR),
CHMAP(6, FL, FR, SL, SR, BL, BR));
return mp_chmap_is_valid(dst);
}