summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2006-03-08 12:16:51 +0000
committerTakashi Iwai <tiwai@suse.de>2006-03-08 12:16:51 +0000
commit8c65cdcb6e1872470f66a97a1c70418a688d4490 (patch)
tree68a24a2cb18ed320a71d1c257b26538633e1ab72
parent9dd5f99aaa41c94b0ca89701282a9564f24e88fe (diff)
Properly terminate stream in polypaudio plugin
Some applications like to call prepare over and over again, recreating the stream each time. Previously we just cleaned up the local end each time, but this makes sure the server also releases its resources. Signed-off-by: Pierre Ossman <ossman@cendio.se>
-rw-r--r--polyp/pcm_polyp.c31
-rw-r--r--polyp/polyp.c26
-rw-r--r--polyp/polyp.h1
3 files changed, 39 insertions, 19 deletions
diff --git a/polyp/pcm_polyp.c b/polyp/pcm_polyp.c
index 84e3c34..96f0baf 100644
--- a/polyp/pcm_polyp.c
+++ b/polyp/pcm_polyp.c
@@ -335,6 +335,8 @@ static int polyp_prepare(snd_pcm_ioplug_t *io)
return err;
if (pcm->stream) {
+ pa_stream_disconnect(pcm->stream);
+ polyp_wait_stream_state(pcm->p, pcm->stream, PA_STREAM_TERMINATED);
pa_stream_unref(pcm->stream);
pcm->stream = NULL;
}
@@ -356,18 +358,12 @@ static int polyp_prepare(snd_pcm_ioplug_t *io)
else
pa_stream_connect_record(pcm->stream, pcm->device, &pcm->buffer_attr, 0);
- while (1) {
- state = pa_stream_get_state(pcm->stream);
-
- if (state == PA_STREAM_FAILED)
- goto error;
-
- if (state == PA_STREAM_READY)
- break;
-
- err = pa_mainloop_iterate(pcm->p->mainloop, 1, NULL);
- if (err < 0)
- return -EIO;
+ err = polyp_wait_stream_state(pcm->p, pcm->stream, PA_STREAM_READY);
+ if (err < 0) {
+ fprintf(stderr, "*** POLYPAUDIO: Unable to create stream.\n");
+ pa_stream_unref(pcm->stream);
+ pcm->stream = NULL;
+ return err;
}
pcm->last_size = 0;
@@ -375,12 +371,6 @@ static int polyp_prepare(snd_pcm_ioplug_t *io)
pcm->offset = 0;
return 0;
-
-error:
- fprintf(stderr, "*** POLYPAUDIO: Unable to create stream.\n");
- pa_stream_unref(pcm->stream);
- pcm->stream = NULL;
- return -EIO;
}
static int polyp_hw_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params)
@@ -437,8 +427,11 @@ static int polyp_close(snd_pcm_ioplug_t *io)
assert(pcm);
- if (pcm->stream)
+ if (pcm->stream) {
+ pa_stream_disconnect(pcm->stream);
+ polyp_wait_stream_state(pcm->p, pcm->stream, PA_STREAM_TERMINATED);
pa_stream_unref(pcm->stream);
+ }
if (pcm->p)
polyp_free(pcm->p);
diff --git a/polyp/polyp.c b/polyp/polyp.c
index 0b25ae5..c6bc5e1 100644
--- a/polyp/polyp.c
+++ b/polyp/polyp.c
@@ -182,6 +182,32 @@ int polyp_wait_operation(snd_polyp_t *p, pa_operation *o)
return 0;
}
+int polyp_wait_stream_state(snd_polyp_t *p, pa_stream *stream, pa_stream_state_t target)
+{
+ int err;
+ pa_stream_state_t state;
+
+ assert(p && stream && (p->state == POLYP_STATE_READY));
+
+ while (1) {
+ state = pa_stream_get_state(stream);
+
+ if (state == PA_STREAM_FAILED)
+ return -EIO;
+
+ if (state == target)
+ break;
+
+ p->state = POLYP_STATE_POLLING;
+ err = pa_mainloop_iterate(p->mainloop, 1, NULL);
+ p->state = POLYP_STATE_READY;
+ if (err < 0)
+ return -EIO;
+ }
+
+ return 0;
+}
+
snd_polyp_t *polyp_new()
{
snd_polyp_t *p;
diff --git a/polyp/polyp.h b/polyp/polyp.h
index 60cf872..8c2ab95 100644
--- a/polyp/polyp.h
+++ b/polyp/polyp.h
@@ -48,6 +48,7 @@ int polyp_finish_poll(snd_polyp_t *p);
int polyp_check_connection(snd_polyp_t *p);
int polyp_wait_operation(snd_polyp_t *p, pa_operation *o);
+int polyp_wait_stream_state(snd_polyp_t *p, pa_stream *stream, pa_stream_state_t target);
snd_polyp_t *polyp_new();
void polyp_free(snd_polyp_t *p);