diff options
author | wm4 <wm4@nowhere> | 2013-05-25 15:07:05 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2013-05-26 16:44:18 +0200 |
commit | 3546188a41aa8c231e563ac89af68edd2798323b (patch) | |
tree | 76729cb525bedfd28d7401c8e1b2e3715452079f /audio/out/ao_alsa.c | |
parent | 8db90e18d3e5bb524a1a611f6dd03ba78f315552 (diff) | |
download | mpv-3546188a41aa8c231e563ac89af68edd2798323b.tar.bz2 mpv-3546188a41aa8c231e563ac89af68edd2798323b.tar.xz |
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.
Diffstat (limited to 'audio/out/ao_alsa.c')
-rw-r--r-- | audio/out/ao_alsa.c | 17 |
1 files changed, 9 insertions, 8 deletions
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) |