FreeBSD Bugzilla – Attachment 150672 Details for
Bug 196051
www/firefox - fix alsa interface to prevent assert-failures
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Change existing files/patch-bug1021761 to do a better job with cubeb_alsa.c
patch-firefox-cubeb_alsa (text/plain), 14.18 KB, created by
Mikhail T.
on 2014-12-17 03:19:54 UTC
(
hide
)
Description:
Change existing files/patch-bug1021761 to do a better job with cubeb_alsa.c
Filename:
MIME Type:
Creator:
Mikhail T.
Created:
2014-12-17 03:19:54 UTC
Size:
14.18 KB
patch
obsolete
>Index: files/patch-bug1021761 >=================================================================== >--- files/patch-bug1021761 (revision 374691) >+++ files/patch-bug1021761 (working copy) >@@ -120,19 +120,20 @@ > }; > int i; > >-diff --git media/libcubeb/src/cubeb_alsa.c media/libcubeb/src/cubeb_alsa.c >-index a962553..1f780f4 100644 >---- media/libcubeb/src/cubeb_alsa.c >-+++ media/libcubeb/src/cubeb_alsa.c >-@@ -11,6 +11,7 @@ >+--- media/libcubeb/src/cubeb_alsa.c 2014-11-26 07:30:16.000000000 -0500 >++++ media/libcubeb/src/cubeb_alsa.c 2014-12-16 22:03:04.000000000 -0500 >+@@ -11,7 +11,10 @@ > #include <sys/time.h> > #include <assert.h> > #include <limits.h> > +#include <dlfcn.h> > #include <poll.h> >++#include <stdlib.h> >++#include <stdio.h> > #include <unistd.h> > #include <alsa/asoundlib.h> >-@@ -24,6 +25,50 @@ >+ #include "cubeb/cubeb.h" >+@@ -24,6 +27,51 @@ > > #define ALSA_PA_PLUGIN "ALSA <-> PulseAudio PCM I/O Plugin" > >@@ -155,6 +156,7 @@ > +MAKE_TYPEDEF(snd_pcm_close); > +MAKE_TYPEDEF(snd_pcm_delay); > +MAKE_TYPEDEF(snd_pcm_drain); >++MAKE_TYPEDEF(snd_pcm_forward); > +MAKE_TYPEDEF(snd_pcm_frames_to_bytes); > +MAKE_TYPEDEF(snd_pcm_get_params); > +/* snd_pcm_hw_params_alloca is actually a macro */ >@@ -183,7 +185,7 @@ > /* ALSA is not thread-safe. snd_pcm_t instances are individually protected > by the owning cubeb_stream's mutex. snd_pcm_t creation and destruction > is not thread-safe until ALSA 1.0.24 (see alsa-lib.git commit 91c9c8f1), >-@@ -64,6 +109,8 @@ struct cubeb { >+@@ -64,6 +112,8 @@ > workaround is not required. */ > snd_config_t * local_config; > int is_pa; >@@ -192,30 +194,62 @@ > }; > > enum stream_state { >-@@ -262,7 +309,7 @@ alsa_refill_stream(cubeb_stream * stm) >+@@ -257,32 +307,35 @@ >+ long got; >+ void * p; >+ int draining; >++ unsigned pipefailures, againfailures; > >+ draining = 0; >+ > pthread_mutex_lock(&stm->mutex); > > - r = snd_pcm_poll_descriptors_revents(stm->pcm, stm->fds, stm->nfds, &revents); >-+ r = WRAP(snd_pcm_poll_descriptors_revents)(stm->pcm, stm->fds, stm->nfds, &revents); >- if (r < 0 || revents != POLLOUT) { >- /* This should be a stream error; it makes no sense for poll(2) to wake >- for this stream and then have the stream report that it's not ready. >-@@ -271,10 +318,10 @@ alsa_refill_stream(cubeb_stream * stm) >- return RUNNING; >- } >- >+- if (r < 0 || revents != POLLOUT) { >+- /* This should be a stream error; it makes no sense for poll(2) to wake >+- for this stream and then have the stream report that it's not ready. >+- Unfortunately, this does happen, so just bail out and try again. */ >+- pthread_mutex_unlock(&stm->mutex); >+- return RUNNING; >+- } >+- > - avail = snd_pcm_avail_update(stm->pcm); >-+ avail = WRAP(snd_pcm_avail_update)(stm->pcm); >- if (avail == -EPIPE) { >+- if (avail == -EPIPE) { > - snd_pcm_recover(stm->pcm, avail, 1); > - avail = snd_pcm_avail_update(stm->pcm); >+- } >++ for (pipefailures = 0;;) { >++ r = WRAP(snd_pcm_poll_descriptors_revents)(stm->pcm, stm->fds, stm->nfds, &revents); >++ if (r < 0 || revents != POLLOUT || >++ (avail = WRAP(snd_pcm_avail_update)(stm->pcm)) == 0) { >++ /* This should be a stream error; it makes no sense for poll(2) to wake >++ for this stream and then have the stream report that it's not ready. >++ Unfortunately, this does happen, so just bail out and try again. */ >++ pthread_mutex_unlock(&stm->mutex); >++ return RUNNING; >++ } >+ >+- /* Failed to recover from an xrun, this stream must be broken. */ >+- if (avail < 0) { >+- pthread_mutex_unlock(&stm->mutex); >+- stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR); >+- return ERROR; >++ if (avail > 0) >++ break; >++ if (pipefailures++ > 11) { >++ fprintf(stderr, "%s: repeated failures from snd_pcm_avail_update, " >++ "giving up\n", __func__); >++ pthread_mutex_unlock(&stm->mutex); >++ stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR); >++ return ERROR; >++ } > + WRAP(snd_pcm_recover)(stm->pcm, avail, 1); >-+ avail = WRAP(snd_pcm_avail_update)(stm->pcm); > } >++ pipefailures = againfailures = 0; > >- /* Failed to recover from an xrun, this stream must be broken. */ >-@@ -293,8 +340,8 @@ alsa_refill_stream(cubeb_stream * stm) >+ /* This should never happen. */ >+ if ((unsigned int) avail > stm->buffer_size) { >+@@ -293,8 +346,8 @@ > available to write. If avail is still zero here, the stream must be in > a funky state, so recover and try again. */ > if (avail == 0) { >@@ -226,7 +260,7 @@ > if (avail <= 0) { > pthread_mutex_unlock(&stm->mutex); > stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR); >-@@ -302,7 +349,7 @@ alsa_refill_stream(cubeb_stream * stm) >+@@ -302,7 +355,7 @@ > } > } > >@@ -235,21 +269,91 @@ > assert(p); > > pthread_mutex_unlock(&stm->mutex); >-@@ -327,10 +374,10 @@ alsa_refill_stream(cubeb_stream * stm) >+@@ -311,10 +364,11 @@ >+ if (got < 0) { >+ pthread_mutex_unlock(&stm->mutex); >+ stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR); >++ free(p); >+ return ERROR; >+ } >+ if (got > 0) { >+- snd_pcm_sframes_t wrote; >++ snd_pcm_sframes_t wrote, towrite = got; >+ >+ if (stm->params.format == CUBEB_SAMPLE_FLOAT32NE) { >+ float * b = (float *) p; >+@@ -327,14 +381,62 @@ > b[i] *= stm->volume; > } > } > - wrote = snd_pcm_writei(stm->pcm, p, got); >-+ wrote = WRAP(snd_pcm_writei)(stm->pcm, p, got); >- if (wrote == -EPIPE) { >+- if (wrote == -EPIPE) { > - snd_pcm_recover(stm->pcm, wrote, 1); > - wrote = snd_pcm_writei(stm->pcm, p, got); >-+ WRAP(snd_pcm_recover)(stm->pcm, wrote, 1); >-+ wrote = WRAP(snd_pcm_writei)(stm->pcm, p, got); >- } >- assert(wrote >= 0 && wrote == got); >- stm->write_position += wrote; >-@@ -342,7 +389,7 @@ alsa_refill_stream(cubeb_stream * stm) >+- } >+- assert(wrote >= 0 && wrote == got); >+- stm->write_position += wrote; >+- gettimeofday(&stm->last_activity, NULL); >++ for (;;) { >++ wrote = WRAP(snd_pcm_writei)(stm->pcm, p, >++ towrite > avail ? avail : towrite); >++ switch(wrote) { >++ case -EPIPE: >++ if (pipefailures++ > 3) { >++ fprintf(stderr, "%s: Too many underflows, giving up\n", __func__); >++ stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR); >++ pthread_mutex_unlock(&stm->mutex); >++ free(p); >++ return ERROR; >++ } >++ WRAP(snd_pcm_recover)(stm->pcm, wrote, 1); >++ continue; >++ case -EAGAIN: >++ if (againfailures++ > 3) { >++ fprintf(stderr, "%s: Too many -EAGAIN errors from snd_pcm_writei, " >++ "giving up\n", __func__); >++ stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR); >++ pthread_mutex_unlock(&stm->mutex); >++ free(p); >++ return ERROR; >++ } >++ continue; >++ case -EBADFD: >++ fprintf(stderr, "%s: snc_pcm_writei returned -%s, giving up\n", >++ __func__, "EBADFD"); >++ free(p); >++ stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR); >++ pthread_mutex_unlock(&stm->mutex); >++ return ERROR; >++ } >++ if (wrote < 0) { >++ fprintf(stderr, "%s: snc_pcm_writei returned unexpected error %lld, " >++ "giving up\n", __func__, (long long)wrote); >++ free(p); >++ stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR); >++ pthread_mutex_unlock(&stm->mutex); >++ return ERROR; >++ } >++ pipefailures = againfailures = 0; >++ stm->write_position += wrote; >++ gettimeofday(&stm->last_activity, NULL); >++ if (wrote > towrite) { >++ fprintf(stderr, "%s: snc_pcm_writei wrote %lld frames, which was more " >++ "than we requested (%lld). This should not happen, giving up\n", >++ __func__, (long long)wrote, (long long)towrite); >++ free(p); >++ stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR); >++ pthread_mutex_unlock(&stm->mutex); >++ return ERROR; >++ } >++ if (towrite == wrote) >++ break; >++ towrite -= wrote; >++ } >+ } >+ if (got != avail) { >+ long buffer_fill = stm->buffer_size - (avail - got); >+@@ -342,7 +444,7 @@ > > /* Fill the remaining buffer with silence to guarantee one full period > has been written. */ >@@ -258,7 +362,7 @@ > > set_timeout(&stm->drain_timeout, buffer_time * 1000); > >-@@ -453,26 +500,26 @@ get_slave_pcm_node(snd_config_t * lconf, snd_config_t * root_pcm) >+@@ -453,26 +555,26 @@ > > slave_def = NULL; > >@@ -290,7 +394,7 @@ > if (r < 0) { > break; > } >-@@ -481,7 +528,7 @@ get_slave_pcm_node(snd_config_t * lconf, snd_config_t * root_pcm) >+@@ -481,7 +583,7 @@ > if (r < 0 || r > (int) sizeof(node_name)) { > break; > } >@@ -299,7 +403,7 @@ > if (r < 0) { > break; > } >-@@ -490,7 +537,7 @@ get_slave_pcm_node(snd_config_t * lconf, snd_config_t * root_pcm) >+@@ -490,7 +592,7 @@ > } while (0); > > if (slave_def) { >@@ -308,7 +412,7 @@ > } > > return NULL; >-@@ -513,22 +560,22 @@ init_local_config_with_workaround(char const * pcm_name) >+@@ -513,22 +615,22 @@ > > lconf = NULL; > >@@ -335,7 +439,7 @@ > if (r < 0) { > break; > } >-@@ -537,7 +584,7 @@ init_local_config_with_workaround(char const * pcm_name) >+@@ -537,7 +639,7 @@ > if (r < 0 || r > (int) sizeof(node_name)) { > break; > } >@@ -344,7 +448,7 @@ > if (r < 0) { > break; > } >-@@ -548,12 +595,12 @@ init_local_config_with_workaround(char const * pcm_name) >+@@ -548,12 +650,12 @@ > } > > /* Fetch the PCM node's type, and bail out if it's not the PulseAudio plugin. */ >@@ -359,7 +463,7 @@ > if (r < 0) { > break; > } >-@@ -564,18 +611,18 @@ init_local_config_with_workaround(char const * pcm_name) >+@@ -564,18 +666,18 @@ > > /* Don't clobber an explicit existing handle_underrun value, set it only > if it doesn't already exist. */ >@@ -381,7 +485,7 @@ > if (r < 0) { > break; > } >-@@ -583,7 +630,7 @@ init_local_config_with_workaround(char const * pcm_name) >+@@ -583,7 +685,7 @@ > return lconf; > } while (0); > >@@ -390,7 +494,7 @@ > > return NULL; > } >-@@ -595,9 +642,9 @@ alsa_locked_pcm_open(snd_pcm_t ** pcm, snd_pcm_stream_t stream, snd_config_t * l >+@@ -595,9 +697,9 @@ > > pthread_mutex_lock(&cubeb_alsa_mutex); > if (local_config) { >@@ -402,7 +506,7 @@ > } > pthread_mutex_unlock(&cubeb_alsa_mutex); > >-@@ -610,7 +657,7 @@ alsa_locked_pcm_close(snd_pcm_t * pcm) >+@@ -610,7 +712,7 @@ > int r; > > pthread_mutex_lock(&cubeb_alsa_mutex); >@@ -411,7 +515,7 @@ > pthread_mutex_unlock(&cubeb_alsa_mutex); > > return r; >-@@ -667,12 +714,65 @@ alsa_init(cubeb ** context, char const * context_name) >+@@ -667,12 +769,65 @@ > pthread_attr_t attr; > snd_pcm_t * dummy; > >@@ -478,7 +582,7 @@ > cubeb_alsa_error_handler_set = 1; > } > pthread_mutex_unlock(&cubeb_alsa_mutex); >-@@ -680,6 +780,8 @@ alsa_init(cubeb ** context, char const * context_name) >+@@ -680,6 +835,8 @@ > ctx = calloc(1, sizeof(*ctx)); > assert(ctx); > >@@ -487,7 +591,7 @@ > ctx->ops = &alsa_ops; > > r = pthread_mutex_init(&ctx->mutex, NULL); >-@@ -729,7 +831,7 @@ alsa_init(cubeb ** context, char const * context_name) >+@@ -729,7 +886,7 @@ > config fails with EINVAL, the PA PCM is too old for this workaround. */ > if (r == -EINVAL) { > pthread_mutex_lock(&cubeb_alsa_mutex); >@@ -496,7 +600,7 @@ > pthread_mutex_unlock(&cubeb_alsa_mutex); > ctx->local_config = NULL; > } else if (r >= 0) { >-@@ -768,9 +870,13 @@ alsa_destroy(cubeb * ctx) >+@@ -768,9 +925,13 @@ > pthread_mutex_destroy(&ctx->mutex); > free(ctx->fds); > >@@ -511,7 +615,7 @@ > pthread_mutex_unlock(&cubeb_alsa_mutex); > } > >-@@ -838,7 +944,7 @@ alsa_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name, >+@@ -838,7 +999,7 @@ > return CUBEB_ERROR; > } > >@@ -520,7 +624,7 @@ > assert(r == 0); > > /* Ugly hack: the PA ALSA plugin allows buffer configurations that can't >-@@ -848,23 +954,23 @@ alsa_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name, >+@@ -848,23 +1009,23 @@ > latency = latency < 500 ? 500 : latency; > } > >@@ -550,7 +654,7 @@ > assert((nfds_t) r == stm->nfds); > > r = pthread_cond_init(&stm->cond, NULL); >-@@ -895,7 +1001,7 @@ alsa_stream_destroy(cubeb_stream * stm) >+@@ -895,7 +1056,7 @@ > pthread_mutex_lock(&stm->mutex); > if (stm->pcm) { > if (stm->state == DRAINING) { >@@ -559,7 +663,7 @@ > } > alsa_locked_pcm_close(stm->pcm); > stm->pcm = NULL; >-@@ -937,12 +1043,12 @@ alsa_get_max_channel_count(cubeb * ctx, uint32_t * max_channels) >+@@ -937,12 +1098,12 @@ > return CUBEB_ERROR; > } > >@@ -574,7 +678,7 @@ > if (rv < 0) { > return CUBEB_ERROR; > } >-@@ -962,34 +1068,34 @@ alsa_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate) { >+@@ -962,34 +1123,34 @@ > > /* get a pcm, disabling resampling, so we get a rate the > * hardware/dmix/pulse/etc. supports. */ >@@ -617,7 +721,7 @@ > > return CUBEB_OK; > } >-@@ -1013,7 +1119,7 @@ alsa_stream_start(cubeb_stream * stm) >+@@ -1013,7 +1174,7 @@ > ctx = stm->context; > > pthread_mutex_lock(&stm->mutex); >@@ -626,7 +730,7 @@ > gettimeofday(&stm->last_activity, NULL); > pthread_mutex_unlock(&stm->mutex); > >-@@ -1047,7 +1153,7 @@ alsa_stream_stop(cubeb_stream * stm) >+@@ -1047,7 +1208,7 @@ > pthread_mutex_unlock(&ctx->mutex); > > pthread_mutex_lock(&stm->mutex); >@@ -635,7 +739,7 @@ > pthread_mutex_unlock(&stm->mutex); > > return CUBEB_OK; >-@@ -1063,8 +1169,8 @@ alsa_stream_get_position(cubeb_stream * stm, uint64_t * position) >+@@ -1063,14 +1224,17 @@ > pthread_mutex_lock(&stm->mutex); > > delay = -1; >@@ -646,7 +750,17 @@ > *position = stm->last_position; > pthread_mutex_unlock(&stm->mutex); > return CUBEB_OK; >-@@ -1089,7 +1195,7 @@ alsa_stream_get_latency(cubeb_stream * stm, uint32_t * latency) >+ } >+ >+- assert(delay >= 0); >++ if (delay < 0) { >++ WRAP(snd_pcm_forward)(stm->pcm, -delay); >++ delay = 0; >++ } >+ >+ *position = 0; >+ if (stm->write_position >= (snd_pcm_uframes_t) delay) { >+@@ -1089,7 +1253,7 @@ > snd_pcm_sframes_t delay; > /* This function returns the delay in frames until a frame written using > snd_pcm_writei is sent to the DAC. The DAC delay should be < 1ms anyways. */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 196051
: 150672