From 3546188a41aa8c231e563ac89af68edd2798323b Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 25 May 2013 15:07:05 +0200 Subject: ao_alsa: always unset ALSA error handler, cleanup on init error The ALSA device was not closed when initialization failed. The ALSA error handler (set with snd_lib_error_set_handler()) was not unset when closing ao_alsa. If this is not done, the handler will still be called when other libraries using ALSA cause errors, even though ao_alsa was long closed. Since these messages were prefixed with "[AO_ALSA]", they were misleading and implying ao_alsa was still used. For some reason, our error handler is still called even after doing snd_lib_error_set_handler(NULL), which should be impossible. Checking with the debuggers, inserting printf(), as well as the alsa-lib source code all suggest our error handler should not be called, but it still happens. It's a complete mystery. --- audio/out/ao_alsa.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'audio') diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c index d2e8180608..a8952e4547 100644 --- a/audio/out/ao_alsa.c +++ b/audio/out/ao_alsa.c @@ -75,6 +75,7 @@ struct priv { static float get_delay(struct ao *ao); static int play(struct ao *ao, void *data, int len, int flags); +static void uninit(struct ao *ao, bool immed); static void alsa_error_handler(const char *file, int line, const char *function, int err, const char *format, ...) @@ -436,14 +437,11 @@ static int init(struct ao *ao, char *params) mp_msg(MSGT_AO, MSGL_V, "alsa-init: requested format: %d Hz, %d channels, %x\n", ao->samplerate, ao->channels.num, ao->format); - p->alsa = NULL; - mp_msg(MSGT_AO, MSGL_V, "alsa-init: using ALSA %s\n", snd_asoundlib_version()); + p->prepause_frames = 0; p->delay_before_pause = 0; - snd_lib_error_set_handler(alsa_error_handler); - //subdevice parsing // set defaults block = 1; @@ -478,6 +476,9 @@ static int init(struct ao *ao, char *params) p->can_pause = 1; + mp_msg(MSGT_AO, MSGL_V, "alsa-init: using ALSA %s\n", snd_asoundlib_version()); + snd_lib_error_set_handler(alsa_error_handler); + int open_mode = block ? 0 : SND_PCM_NONBLOCK; int isac3 = AF_FORMAT_IS_IEC61937(ao->format); //modes = 0, SND_PCM_NONBLOCK, SND_PCM_ASYNC @@ -626,6 +627,7 @@ static int init(struct ao *ao, char *params) return 0; alsa_error: + uninit(ao, true); return -1; } // end init @@ -644,13 +646,12 @@ static void uninit(struct ao *ao, bool immed) err = snd_pcm_close(p->alsa); CHECK_ALSA_ERROR("pcm close error"); - p->alsa = NULL; mp_msg(MSGT_AO, MSGL_V, "alsa-uninit: pcm closed\n"); - } else { - mp_tmsg(MSGT_AO, MSGL_ERR, "[AO_ALSA] No handler defined!\n"); } -alsa_error: ; +alsa_error: + p->alsa = NULL; + snd_lib_error_set_handler(NULL); } static void audio_pause(struct ao *ao) -- cgit v1.2.3