mirror of
http://mpg123.de/trunk/.git
synced 2025-10-25 04:37:34 +03:00
Fix an alsa (not just there, I guess) crash by making sure the ao->userptr and ao->fn get cleared after close in close_output.
Also removed direct uses of ao->close in mpg123.c and buffer.c . git-svn-id: svn://scm.orgis.org/mpg123/trunk@1044 35dc7657-300d-0410-a2e5-dc2837fedb53
This commit is contained in:
15
src/audio.c
15
src/audio.c
@@ -329,12 +329,16 @@ void flush_output(int outmode, audio_output_t *ao, unsigned char *bytes, size_t
|
||||
}
|
||||
}
|
||||
|
||||
/* is this used? */
|
||||
void close_output(int outmode, audio_output_t *ao)
|
||||
{
|
||||
|
||||
switch(outmode) {
|
||||
case DECODE_AUDIO:
|
||||
ao->close(ao);
|
||||
/* Module frees and closes its resources, but may not reset them. */
|
||||
ao->userptr = NULL;
|
||||
ao->fn = -1;
|
||||
break;
|
||||
case DECODE_WAV:
|
||||
wav_close();
|
||||
@@ -348,3 +352,14 @@ void close_output(int outmode, audio_output_t *ao)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Also for WAV decoding? */
|
||||
int reset_output(audio_output_t *ao)
|
||||
{
|
||||
if(param.outmode == DECODE_AUDIO)
|
||||
{
|
||||
close_output(param.outmode, ao);
|
||||
return ao->open(ao);
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ const char* audio_encoding_name(const int encoding, const int longer);
|
||||
int init_output(audio_output_t *ao, mpg123_handle *mh);
|
||||
void flush_output(int outmode, audio_output_t *ao, unsigned char *bytes, size_t count);
|
||||
void close_output(int mod, audio_output_t *ao );
|
||||
|
||||
int reset_output(audio_output_t *ao);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
15
src/buffer.c
15
src/buffer.c
@@ -141,15 +141,12 @@ void buffer_loop(audio_output_t *ao, sigset_t *oldsigset)
|
||||
*/
|
||||
if (xf->wakeme[XF_WRITER])
|
||||
xfermem_putcmd(my_fd, XF_CMD_WAKEUP);
|
||||
if (param.outmode == DECODE_AUDIO) {
|
||||
ao->close(ao);
|
||||
ao->rate = xf->buf[0];
|
||||
ao->channels = xf->buf[1];
|
||||
ao->format = xf->buf[2];
|
||||
if (ao->open(ao) < 0) {
|
||||
perror("audio");
|
||||
exit(1);
|
||||
}
|
||||
ao->rate = xf->buf[0];
|
||||
ao->channels = xf->buf[1];
|
||||
ao->format = xf->buf[2];
|
||||
if (reset_output(ao) < 0) {
|
||||
error1("failed to reset audio: %s", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if ( (bytes = xfermem_get_usedspace(xf)) < outburst ) {
|
||||
|
||||
@@ -419,9 +419,9 @@ static void reset_audio(void)
|
||||
* the device's internal buffer before
|
||||
* changing the sample rate. [OF]
|
||||
*/
|
||||
ao->close(ao);
|
||||
if (ao->open(ao) < 0) {
|
||||
error("failed to open audio device");
|
||||
if(reset_output(ao) < 0)
|
||||
{
|
||||
error1("failed to reset audio device: %s", strerror(errno));
|
||||
safe_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ output_dummy_la_LDFLAGS = -module -avoid-version
|
||||
#pkglib_LTLIBRARIES += output_alib.la
|
||||
#output_alib_la_SOURCES = alib.c
|
||||
#output_alib_la_LDFLAGS = -module -avoid-version
|
||||
#output_alib_la_CFLAGS= -I/opt/audio/include
|
||||
#endif
|
||||
|
||||
if HAVE_ALSA
|
||||
@@ -90,7 +91,7 @@ if HAVE_PORTAUDIO
|
||||
pkglib_LTLIBRARIES += output_portaudio.la
|
||||
output_portaudio_la_SOURCES = portaudio.c
|
||||
output_portaudio_la_LDFLAGS = -module -avoid-version
|
||||
output_portaudio_la_LIBADD = -lportaudio
|
||||
output_portaudio_la_LIBADD = -lportaudio @PORTAUDIO_EXTRA_LIB@
|
||||
endif
|
||||
|
||||
if HAVE_PULSE
|
||||
@@ -109,11 +110,12 @@ output_sdl_la_LDFLAGS = -module -avoid-version @SDL_LDFLAGS@
|
||||
output_sdl_la_LIBADD = @SDL_LIBS@
|
||||
endif
|
||||
|
||||
#if HAVE_SGI
|
||||
#pkglib_LTLIBRARIES += output_sgi.la
|
||||
#output_sgi_la_SOURCES = sgi.c
|
||||
#output_sgi_la_LDFLAGS = -module -avoid-version
|
||||
#endif
|
||||
if HAVE_SGI
|
||||
pkglib_LTLIBRARIES += output_sgi.la
|
||||
output_sgi_la_SOURCES = sgi.c
|
||||
output_sgi_la_LDFLAGS = -module -avoid-version
|
||||
output_sgi_la_LIBADD = -laudio
|
||||
endif
|
||||
|
||||
if HAVE_SUN
|
||||
pkglib_LTLIBRARIES += output_sun.la
|
||||
@@ -121,8 +123,9 @@ output_sun_la_SOURCES = sun.c
|
||||
output_sun_la_LDFLAGS = -module -avoid-version
|
||||
endif
|
||||
|
||||
#if HAVE_WIN32
|
||||
#pkglib_LTLIBRARIES += output_win32.la
|
||||
#output_win32_la_SOURCES = win32.c
|
||||
#output_win32_la_LDFLAGS = -module -avoid-version
|
||||
#endif
|
||||
if HAVE_WIN32
|
||||
pkglib_LTLIBRARIES += output_win32.la
|
||||
output_win32_la_SOURCES = win32.c
|
||||
output_win32_la_LDFLAGS = -module -avoid-version
|
||||
output_win32_la_LIBADD= -lwinmm
|
||||
endif
|
||||
|
||||
@@ -137,6 +137,7 @@ static int open_alsa(audio_output_t *ao)
|
||||
{
|
||||
const char *pcm_name;
|
||||
snd_pcm_t *pcm=NULL;
|
||||
debug1("open_alsa with %p", ao->userptr);
|
||||
|
||||
pcm_name = ao->device ? ao->device : "default";
|
||||
if (snd_pcm_open(&pcm, pcm_name, SND_PCM_STREAM_PLAYBACK, 0) < 0) {
|
||||
@@ -215,11 +216,12 @@ static void flush_alsa(audio_output_t *ao)
|
||||
static int close_alsa(audio_output_t *ao)
|
||||
{
|
||||
snd_pcm_t *pcm=(snd_pcm_t*)ao->userptr;
|
||||
|
||||
debug1("close_alsa with %p", ao->userptr);
|
||||
if(pcm != NULL) /* be really generous for being called without any device opening */
|
||||
{
|
||||
if (snd_pcm_state(pcm) == SND_PCM_STATE_RUNNING)
|
||||
snd_pcm_drain(pcm);
|
||||
ao->userptr = NULL; /* Should alsa do this or the module wrapper? */
|
||||
return snd_pcm_close(pcm);
|
||||
}
|
||||
else return 0;
|
||||
|
||||
Reference in New Issue
Block a user