--- swfdec-gtk/swfdec_playback_pa.c 2008/05/07 00:10:52 1.1 +++ swfdec-gtk/swfdec_playback_pa.c 2008/05/07 01:33:42 @@ -117,20 +117,30 @@ swfdec_playback_stream_close (Stream *st /* Pull it off of the active stream list. */ stream->sound->streams = g_list_remove (stream->sound->streams, stream); + stream->no_more = 1; + /* If we have created a PA stream, defer freeing until we drain it. */ if (stream->pa != NULL) { - pa_operation *o; + if (pa_stream_get_state(stream->pa) == PA_STREAM_CREATING) { + return; /* destroy in stream_state_callback */ + } - stream->no_more = 1; + pa_stream_set_state_callback (stream->pa, NULL, NULL); + pa_stream_set_write_callback (stream->pa, NULL, NULL); - o = pa_stream_drain (stream->pa, stream_drain_complete, stream); - if (o != NULL) { - pa_operation_unref (o); - return; - } else { - g_printerr("PA stream drain failed: %s\n", - pa_strerror(pa_context_errno(stream->sound->pa))); + if (pa_stream_get_state(stream->pa) == PA_STREAM_READY) { + pa_operation *o = pa_stream_drain (stream->pa, stream_drain_complete, + stream); + if (o != NULL) { + pa_operation_unref (o); + return; + } else { + g_printerr("PA stream drain failed: %s\n", + pa_strerror(pa_context_errno(stream->sound->pa))); + pa_stream_disconnect (stream->pa); + } } + pa_stream_unref (stream->pa); } g_object_unref (stream->audio); g_free (stream); @@ -139,6 +149,8 @@ swfdec_playback_stream_close (Stream *st static void stream_state_callback (pa_stream *pa, void *data) { + Stream *stream = data; + switch (pa_stream_get_state(pa)) { case PA_STREAM_CREATING: case PA_STREAM_TERMINATED: @@ -152,6 +164,10 @@ stream_state_callback (pa_stream *pa, vo default: break; } + + if (stream->no_more) { + swfdec_playback_stream_close (stream); + } } static void