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)
|
void close_output(int outmode, audio_output_t *ao)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch(outmode) {
|
switch(outmode) {
|
||||||
case DECODE_AUDIO:
|
case DECODE_AUDIO:
|
||||||
ao->close(ao);
|
ao->close(ao);
|
||||||
|
/* Module frees and closes its resources, but may not reset them. */
|
||||||
|
ao->userptr = NULL;
|
||||||
|
ao->fn = -1;
|
||||||
break;
|
break;
|
||||||
case DECODE_WAV:
|
case DECODE_WAV:
|
||||||
wav_close();
|
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);
|
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 flush_output(int outmode, audio_output_t *ao, unsigned char *bytes, size_t count);
|
||||||
void close_output(int mod, audio_output_t *ao );
|
void close_output(int mod, audio_output_t *ao );
|
||||||
|
int reset_output(audio_output_t *ao);
|
||||||
|
|
||||||
#endif
|
#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])
|
if (xf->wakeme[XF_WRITER])
|
||||||
xfermem_putcmd(my_fd, XF_CMD_WAKEUP);
|
xfermem_putcmd(my_fd, XF_CMD_WAKEUP);
|
||||||
if (param.outmode == DECODE_AUDIO) {
|
ao->rate = xf->buf[0];
|
||||||
ao->close(ao);
|
ao->channels = xf->buf[1];
|
||||||
ao->rate = xf->buf[0];
|
ao->format = xf->buf[2];
|
||||||
ao->channels = xf->buf[1];
|
if (reset_output(ao) < 0) {
|
||||||
ao->format = xf->buf[2];
|
error1("failed to reset audio: %s", strerror(errno));
|
||||||
if (ao->open(ao) < 0) {
|
exit(1);
|
||||||
perror("audio");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( (bytes = xfermem_get_usedspace(xf)) < outburst ) {
|
if ( (bytes = xfermem_get_usedspace(xf)) < outburst ) {
|
||||||
|
|||||||
@@ -419,9 +419,9 @@ static void reset_audio(void)
|
|||||||
* the device's internal buffer before
|
* the device's internal buffer before
|
||||||
* changing the sample rate. [OF]
|
* changing the sample rate. [OF]
|
||||||
*/
|
*/
|
||||||
ao->close(ao);
|
if(reset_output(ao) < 0)
|
||||||
if (ao->open(ao) < 0) {
|
{
|
||||||
error("failed to open audio device");
|
error1("failed to reset audio device: %s", strerror(errno));
|
||||||
safe_exit(1);
|
safe_exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ output_dummy_la_LDFLAGS = -module -avoid-version
|
|||||||
#pkglib_LTLIBRARIES += output_alib.la
|
#pkglib_LTLIBRARIES += output_alib.la
|
||||||
#output_alib_la_SOURCES = alib.c
|
#output_alib_la_SOURCES = alib.c
|
||||||
#output_alib_la_LDFLAGS = -module -avoid-version
|
#output_alib_la_LDFLAGS = -module -avoid-version
|
||||||
|
#output_alib_la_CFLAGS= -I/opt/audio/include
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if HAVE_ALSA
|
if HAVE_ALSA
|
||||||
@@ -90,7 +91,7 @@ if HAVE_PORTAUDIO
|
|||||||
pkglib_LTLIBRARIES += output_portaudio.la
|
pkglib_LTLIBRARIES += output_portaudio.la
|
||||||
output_portaudio_la_SOURCES = portaudio.c
|
output_portaudio_la_SOURCES = portaudio.c
|
||||||
output_portaudio_la_LDFLAGS = -module -avoid-version
|
output_portaudio_la_LDFLAGS = -module -avoid-version
|
||||||
output_portaudio_la_LIBADD = -lportaudio
|
output_portaudio_la_LIBADD = -lportaudio @PORTAUDIO_EXTRA_LIB@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if HAVE_PULSE
|
if HAVE_PULSE
|
||||||
@@ -109,11 +110,12 @@ output_sdl_la_LDFLAGS = -module -avoid-version @SDL_LDFLAGS@
|
|||||||
output_sdl_la_LIBADD = @SDL_LIBS@
|
output_sdl_la_LIBADD = @SDL_LIBS@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#if HAVE_SGI
|
if HAVE_SGI
|
||||||
#pkglib_LTLIBRARIES += output_sgi.la
|
pkglib_LTLIBRARIES += output_sgi.la
|
||||||
#output_sgi_la_SOURCES = sgi.c
|
output_sgi_la_SOURCES = sgi.c
|
||||||
#output_sgi_la_LDFLAGS = -module -avoid-version
|
output_sgi_la_LDFLAGS = -module -avoid-version
|
||||||
#endif
|
output_sgi_la_LIBADD = -laudio
|
||||||
|
endif
|
||||||
|
|
||||||
if HAVE_SUN
|
if HAVE_SUN
|
||||||
pkglib_LTLIBRARIES += output_sun.la
|
pkglib_LTLIBRARIES += output_sun.la
|
||||||
@@ -121,8 +123,9 @@ output_sun_la_SOURCES = sun.c
|
|||||||
output_sun_la_LDFLAGS = -module -avoid-version
|
output_sun_la_LDFLAGS = -module -avoid-version
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#if HAVE_WIN32
|
if HAVE_WIN32
|
||||||
#pkglib_LTLIBRARIES += output_win32.la
|
pkglib_LTLIBRARIES += output_win32.la
|
||||||
#output_win32_la_SOURCES = win32.c
|
output_win32_la_SOURCES = win32.c
|
||||||
#output_win32_la_LDFLAGS = -module -avoid-version
|
output_win32_la_LDFLAGS = -module -avoid-version
|
||||||
#endif
|
output_win32_la_LIBADD= -lwinmm
|
||||||
|
endif
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ static int open_alsa(audio_output_t *ao)
|
|||||||
{
|
{
|
||||||
const char *pcm_name;
|
const char *pcm_name;
|
||||||
snd_pcm_t *pcm=NULL;
|
snd_pcm_t *pcm=NULL;
|
||||||
|
debug1("open_alsa with %p", ao->userptr);
|
||||||
|
|
||||||
pcm_name = ao->device ? ao->device : "default";
|
pcm_name = ao->device ? ao->device : "default";
|
||||||
if (snd_pcm_open(&pcm, pcm_name, SND_PCM_STREAM_PLAYBACK, 0) < 0) {
|
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)
|
static int close_alsa(audio_output_t *ao)
|
||||||
{
|
{
|
||||||
snd_pcm_t *pcm=(snd_pcm_t*)ao->userptr;
|
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(pcm != NULL) /* be really generous for being called without any device opening */
|
||||||
{
|
{
|
||||||
if (snd_pcm_state(pcm) == SND_PCM_STATE_RUNNING)
|
if (snd_pcm_state(pcm) == SND_PCM_STATE_RUNNING)
|
||||||
snd_pcm_drain(pcm);
|
snd_pcm_drain(pcm);
|
||||||
|
ao->userptr = NULL; /* Should alsa do this or the module wrapper? */
|
||||||
return snd_pcm_close(pcm);
|
return snd_pcm_close(pcm);
|
||||||
}
|
}
|
||||||
else return 0;
|
else return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user