mirror of
https://github.com/mpv-player/mpv
synced 2025-03-22 11:18:32 +00:00
ao_alsa: fix 7.1 over HDMI
We need to effectively swap the last channel pair. See commit4e358a96
and5a18c5ea
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:
parent
46f59f25c2
commit
be49da72ea
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user