Skip to content

Commit

Permalink
Bug 573924 - Ugly workaround for alsa-pulse bug that causes hangs aft…
Browse files Browse the repository at this point in the history
…er resuming audio from pause. r=chris.double a=blocking2.0
  • Loading branch information
kinetiknz committed Oct 29, 2010
1 parent d1b9f36 commit ee63d28
Showing 1 changed file with 31 additions and 2 deletions.
33 changes: 31 additions & 2 deletions media/libsydneyaudio/src/sydney_audio_alsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ struct sa_stream {
/* audio format info */
unsigned int rate;
unsigned int n_channels;

/* work around bug 573924 */
int pulseaudio;
int resumed;
};

/*
Expand Down Expand Up @@ -111,6 +115,8 @@ sa_stream_create_pcm(
s->last_position = 0;
s->rate = rate;
s->n_channels = n_channels;
s->pulseaudio = 0;
s->resumed = 0;

*_s = s;
return SA_SUCCESS;
Expand All @@ -119,6 +125,9 @@ sa_stream_create_pcm(

int
sa_stream_open(sa_stream_t *s) {
snd_output_t* out;
char* buf;
size_t bufsz;

if (s == NULL) {
return SA_ERROR_NO_INIT;
Expand Down Expand Up @@ -157,6 +166,15 @@ sa_stream_open(sa_stream_t *s) {
return SA_ERROR_NOT_SUPPORTED;
}

/* ugly alsa-pulse plugin detection */
snd_output_buffer_open(&out);
snd_pcm_dump(s->output_unit, out);
bufsz = snd_output_buffer_string(out, &buf);
if (strncmp(buf, "ALSA <-> PulseAudio PCM I/O Plugin", bufsz) > 0 ) {
s->pulseaudio = 1;
}
snd_output_close(out);

pthread_mutex_unlock(&sa_alsa_mutex);

return SA_SUCCESS;
Expand Down Expand Up @@ -194,7 +212,7 @@ sa_stream_destroy(sa_stream_t *s) {

int
sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes) {
snd_pcm_sframes_t frames, nframes;
snd_pcm_sframes_t frames, nframes, avail;

if (s == NULL || s->output_unit == NULL) {
return SA_ERROR_NO_INIT;
Expand All @@ -206,7 +224,14 @@ sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes) {
nframes = snd_pcm_bytes_to_frames(s->output_unit, nbytes);

while(nframes>0) {
frames = snd_pcm_writei(s->output_unit, data, nframes);
if (s->resumed) {
avail = snd_pcm_avail_update(s->output_unit);
frames = snd_pcm_writei(s->output_unit, data, nframes > avail ? avail : nframes);
avail = snd_pcm_avail_update(s->output_unit);
s->resumed = avail != 0;
} else {
frames = snd_pcm_writei(s->output_unit, data, nframes);
}
if (frames < 0) {
int r = snd_pcm_recover(s->output_unit, frames, 1);
if (r < 0) {
Expand Down Expand Up @@ -322,6 +347,10 @@ sa_stream_resume(sa_stream_t *s) {
return SA_ERROR_NO_INIT;
}

if (s->pulseaudio) {
s->resumed = 1;
}

if (snd_pcm_pause(s->output_unit, 0) != 0)
return SA_ERROR_NOT_SUPPORTED;
return SA_SUCCESS;
Expand Down

0 comments on commit ee63d28

Please sign in to comment.