# HG changeset patch # User cladisch # Date 1139831309 0 # Node ID d9c518932302cdf91bbecddb61d9dca37589a756 # Parent dd4db8c43d9230fe959d4d17d9ecc7cb54f10e36 Fix the error handling in the play() function: add a handler for EINTR, improve the reporting of other errors, and don't try to call snd_pcm_writei() repeatedly when it aborts after a partial write due to an error. diff -r dd4db8c43d92 -r d9c518932302 libao2/ao_alsa.c --- a/libao2/ao_alsa.c Mon Feb 13 11:43:25 2006 +0000 +++ b/libao2/ao_alsa.c Mon Feb 13 11:48:29 2006 +0000 @@ -739,10 +739,7 @@ static int play(void* data, int len, int flags) { - - //bytes_per_sample is always 4 for 2 chn S16_LE int num_frames = len / bytes_per_sample; - char *output_samples = (char *)data; snd_pcm_sframes_t res = 0; //mp_msg(MSGT_AO,MSGL_ERR,"alsa-play: frames=%i, len=%i\n",num_frames,len); @@ -752,39 +749,33 @@ return 0; } - while (num_frames > 0) { + if (num_frames == 0) + return 0; + + do { + res = snd_pcm_writei(alsa_handler, data, num_frames); - res = snd_pcm_writei(alsa_handler, (void *)output_samples, num_frames); - - if (res == -ESTRPIPE) { /* suspend */ + if (res == -EINTR) { + /* nothing to do */ + res = 0; + } + else if (res == -ESTRPIPE) { /* suspend */ mp_msg(MSGT_AO,MSGL_INFO,"alsa-play: pcm in suspend mode. trying to resume\n"); while ((res = snd_pcm_resume(alsa_handler)) == -EAGAIN) sleep(1); } - else if (res < 0) { - mp_msg(MSGT_AO,MSGL_INFO,"alsa-play: unknown status, trying to reset soundcard\n"); + if (res < 0) { + mp_msg(MSGT_AO,MSGL_ERR,"alsa-play: write error: %s\n", snd_strerror(res)); + mp_msg(MSGT_AO,MSGL_INFO,"alsa-play: trying to reset soundcard\n"); if ((res = snd_pcm_prepare(alsa_handler)) < 0) { - mp_msg(MSGT_AO,MSGL_ERR,"alsa-play: snd prepare error"); + mp_msg(MSGT_AO,MSGL_ERR,"alsa-play: pcm prepare error: %s\n", snd_strerror(res)); return(0); break; } } - - if (res > 0) { - - /* output_samples += ao_data.channels * res; */ - output_samples += res * bytes_per_sample; + } while (res == 0); - num_frames -= res; - } - - } //end while - - if (res < 0) { - mp_msg(MSGT_AO,MSGL_ERR,"alsa-play: write error %s", snd_strerror(res)); - return 0; - } - return len - len % bytes_per_sample; + return res < 0 ? res : res * bytes_per_sample; } /* how many byes are free in the buffer */