Bug 615134 - Adjust ALSA start threshold to reduce the chance of deadlocking when recovering from underruns. r=cpearce a=roc
authorMatthew Gregan <kinetik@flim.org>
Thu, 02 Dec 2010 12:41:19 +1300
changeset 58524 d748232921a59df4a5fb7d8f4ddb209360d41c82
parent 58523 95af6190017f0f997409fc07aae5c69d06d92086
child 58525 318d60678767e973b872f2cb0aa518ca456993f6
push id17334
push usercpearce@mozilla.com
push dateFri, 03 Dec 2010 01:21:22 +0000
treeherdermozilla-central@d748232921a5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce, roc
bugs615134
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 615134 - Adjust ALSA start threshold to reduce the chance of deadlocking when recovering from underruns. r=cpearce a=roc
media/libsydneyaudio/src/sydney_audio_alsa.c
--- a/media/libsydneyaudio/src/sydney_audio_alsa.c
+++ b/media/libsydneyaudio/src/sydney_audio_alsa.c
@@ -123,16 +123,20 @@ sa_stream_create_pcm(
 }
 
 
 int
 sa_stream_open(sa_stream_t *s) {
   snd_output_t* out;
   char* buf;
   size_t bufsz;
+  snd_pcm_hw_params_t* hwparams;
+  snd_pcm_sw_params_t* swparams;
+  int dir;
+  snd_pcm_uframes_t period;
 
   if (s == NULL) {
     return SA_ERROR_NO_INIT;
   }
   if (s->output_unit != NULL) {
     return SA_ERROR_INVALID;
   }
 
@@ -170,16 +174,25 @@ sa_stream_open(sa_stream_t *s) {
   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);
 
+  snd_pcm_hw_params_alloca(&hwparams);
+  snd_pcm_hw_params_current(s->output_unit, hwparams);
+  snd_pcm_hw_params_get_period_size(hwparams, &period, &dir);
+
+  snd_pcm_sw_params_alloca(&swparams);
+  snd_pcm_sw_params_current(s->output_unit, swparams);
+  snd_pcm_sw_params_set_start_threshold(s->output_unit, swparams, period);
+  snd_pcm_sw_params(s->output_unit, swparams);
+
   pthread_mutex_unlock(&sa_alsa_mutex);
 
   return SA_SUCCESS;
 }
 
 
 int
 sa_stream_destroy(sa_stream_t *s) {
@@ -276,36 +289,27 @@ sa_stream_get_write_size(sa_stream_t *s,
 
   *size = snd_pcm_frames_to_bytes(s->output_unit, avail);
 
   return SA_SUCCESS;
 }
 
 int
 sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos) {
-  snd_pcm_state_t state;
   snd_pcm_sframes_t delay;
   
   if (s == NULL || s->output_unit == NULL) {
     return SA_ERROR_NO_INIT;
   }
 
   if (position != SA_POSITION_WRITE_SOFTWARE) {
     return SA_ERROR_NOT_SUPPORTED;
   }
 
-  state = snd_pcm_state(s->output_unit);
-  if (state == SND_PCM_STATE_XRUN) {
-    if (snd_pcm_recover(s->output_unit, -EPIPE, 1) < 0) {
-      return SA_ERROR_SYSTEM;
-    }
-    state = snd_pcm_state(s->output_unit);
-  }
-
-  if (state != SND_PCM_STATE_RUNNING) {
+  if (snd_pcm_state(s->output_unit) != SND_PCM_STATE_RUNNING) {
     *pos = s->last_position;
     return SA_SUCCESS;
   }
 
   if (snd_pcm_delay(s->output_unit, &delay) != 0) {
     return SA_ERROR_SYSTEM;
   }