summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-04-06 23:36:00 +0200
committerwm4 <wm4@nowhere>2013-05-12 21:24:55 +0200
commitbf014677cecbc5ff425f0ad9f23e41c19be4ad3d (patch)
treebf6a85321c4f28034988c02076407259a3ece734 /audio
parent4b5cee4617d0decbf93d06df4f45097fd7e00105 (diff)
downloadmpv-bf014677cecbc5ff425f0ad9f23e41c19be4ad3d.tar.bz2
mpv-bf014677cecbc5ff425f0ad9f23e41c19be4ad3d.tar.xz
ao_pulse: try to set correct channel layout
Like most other AOs, ao_pulse set the channel count only, always using a default layout. Try to set the exact layout. For this, we need a big lookup table to map waveex/lavc/mpv speaker position to PulseAudio's, since PA_CHANNEL_POSITION_ is apparently not compatible to waveext, and I haven't seen any API functions that would help mapping them. Completely untested. (Let's leave that to someone else...)
Diffstat (limited to 'audio')
-rw-r--r--audio/out/ao_pulse.c56
1 files changed, 54 insertions, 2 deletions
diff --git a/audio/out/ao_pulse.c b/audio/out/ao_pulse.c
index 7f3619386e..dedb067357 100644
--- a/audio/out/ao_pulse.c
+++ b/audio/out/ao_pulse.c
@@ -143,6 +143,50 @@ static const struct format_map {
{AF_FORMAT_UNKNOWN, 0}
};
+static const int speaker_map[][2] = {
+ {PA_CHANNEL_POSITION_MONO, MP_SPEAKER_ID_FC},
+ {PA_CHANNEL_POSITION_FRONT_LEFT, MP_SPEAKER_ID_FL},
+ {PA_CHANNEL_POSITION_FRONT_RIGHT, MP_SPEAKER_ID_FR},
+ {PA_CHANNEL_POSITION_FRONT_CENTER, MP_SPEAKER_ID_FC},
+ {PA_CHANNEL_POSITION_REAR_CENTER, MP_SPEAKER_ID_BC},
+ {PA_CHANNEL_POSITION_REAR_LEFT, MP_SPEAKER_ID_BL},
+ {PA_CHANNEL_POSITION_REAR_RIGHT, MP_SPEAKER_ID_BR},
+ {PA_CHANNEL_POSITION_LFE, MP_SPEAKER_ID_LFE},
+ {PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, MP_SPEAKER_ID_FLC},
+ {PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, MP_SPEAKER_ID_FRC},
+ {PA_CHANNEL_POSITION_SIDE_LEFT, MP_SPEAKER_ID_SL},
+ {PA_CHANNEL_POSITION_SIDE_RIGHT, MP_SPEAKER_ID_SR},
+ {PA_CHANNEL_POSITION_TOP_CENTER, MP_SPEAKER_ID_TC},
+ {PA_CHANNEL_POSITION_TOP_FRONT_LEFT, MP_SPEAKER_ID_TFL},
+ {PA_CHANNEL_POSITION_TOP_FRONT_RIGHT, MP_SPEAKER_ID_TFR},
+ {PA_CHANNEL_POSITION_TOP_FRONT_CENTER, MP_SPEAKER_ID_TFC},
+ {PA_CHANNEL_POSITION_TOP_REAR_LEFT, MP_SPEAKER_ID_TBL},
+ {PA_CHANNEL_POSITION_TOP_REAR_RIGHT, MP_SPEAKER_ID_TBR},
+ {PA_CHANNEL_POSITION_TOP_REAR_CENTER, MP_SPEAKER_ID_TBC},
+ {PA_CHANNEL_POSITION_INVALID, -1}
+};
+
+static bool chmap_pa_from_mp(pa_channel_map *dst, struct mp_chmap *src)
+{
+ if (src->num > PA_CHANNELS_MAX)
+ return false;
+ dst->channels = src->num;
+ for (int n = 0; n < src->num; n++) {
+ int mp_speaker = src->speaker[n];
+ int pa_speaker = PA_CHANNEL_POSITION_INVALID;
+ for (int i = 0; speaker_map[i][1] != -1; i++) {
+ if (speaker_map[i][1] == mp_speaker) {
+ pa_speaker = speaker_map[i][0];
+ break;
+ }
+ }
+ if (pa_speaker == PA_CHANNEL_POSITION_INVALID)
+ return false;
+ dst->map[n] = pa_speaker;
+ }
+ return true;
+}
+
static void uninit(struct ao *ao, bool cut_audio)
{
struct priv *priv = ao->priv;
@@ -230,8 +274,16 @@ static int init(struct ao *ao, char *params)
goto fail;
}
- mp_chmap_reorder_to_waveext(&ao->channels);
- pa_channel_map_init_auto(&map, ss.channels, PA_CHANNEL_MAP_WAVEEX);
+ if (!chmap_pa_from_mp(&map, &ao->channels)) {
+ char *name = mp_chmap_to_str(&ao->channels);
+ mp_msg(MSGT_AO, MSGL_ERR, "AO: [pulse] Can't map %s channel layout\n",
+ name);
+ talloc_free(name);
+ // Not a really good fallback, since this doesn't trigger if the
+ // channel map is valid, but unsupported by the output device.
+ ao->channels = (struct mp_chmap) MP_CHMAP_INIT_STEREO;
+ pa_channel_map_init_stereo(&map);
+ }
ao->bps = pa_bytes_per_second(&ss);