aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMatthew Gregan <[email protected]>2012-07-16 17:02:14 -0400
committerMatthew Gregan <[email protected]>2012-07-16 17:02:14 -0400
commitf3116936eba69aced240df7db77264269f3f95ae (patch)
tree4770131a704564bb17a1ae2cf6e8f0a4bc8461a4
parenta69ff28da1996ab11e6c62cc7e6dd41731bdd549 (diff)
downloadcubeb-f3116936eba69aced240df7db77264269f3f95ae.tar.gz
cubeb-f3116936eba69aced240df7db77264269f3f95ae.zip
alsa: add a dirty hack to detect the PA plugin and round up the requested latency.
-rw-r--r--src/cubeb_alsa.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/cubeb_alsa.c b/src/cubeb_alsa.c
index 84475c4..d7235b6 100644
--- a/src/cubeb_alsa.c
+++ b/src/cubeb_alsa.c
@@ -20,6 +20,8 @@
#define CUBEB_WATCHDOG_MS 10000
#define UNUSED __attribute__ ((__unused__))
+#define ALSA_PA_PLUGIN "ALSA <-> PulseAudio PCM I/O Plugin"
+
/* 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),
@@ -474,6 +476,24 @@ silent_error_handler(char const * file UNUSED, int line UNUSED, char const * fun
{
}
+static int
+pcm_uses_pulseaudio_plugin(snd_pcm_t * pcm)
+{
+ snd_output_t * out;
+ char * buf;
+ size_t bufsz;
+ int r;
+
+ snd_output_buffer_open(&out);
+ snd_pcm_dump(pcm, out);
+ bufsz = snd_output_buffer_string(out, &buf);
+ r = bufsz >= strlen(ALSA_PA_PLUGIN) &&
+ strncmp(buf, ALSA_PA_PLUGIN, strlen(ALSA_PA_PLUGIN)) == 0;
+ snd_output_close(out);
+
+ return r;
+}
+
int
cubeb_init(cubeb ** context, char const * context_name UNUSED)
{
@@ -627,6 +647,12 @@ cubeb_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name
r = snd_pcm_nonblock(stm->pcm, 1);
assert(r == 0);
+ /* Ugly hack: the PA ALSA plugin allows buffer configurations that can't
+ possibly work. See https://bugzilla.mozilla.org/show_bug.cgi?id=761274 */
+ if (pcm_uses_pulseaudio_plugin(stm->pcm)) {
+ latency = latency < 200 ? 200 : latency;
+ }
+
r = snd_pcm_set_params(stm->pcm, format, SND_PCM_ACCESS_RW_INTERLEAVED,
stm->params.channels, stm->params.rate, 1,
latency * 1000);