Bug 761274 - Work around buffer sizing bug in PulseAudio ALSA plugin. r=doublec

This commit is contained in:
Matthew Gregan 2012-07-16 17:15:24 -04:00
Родитель a515ca6a14
Коммит 7c54dee4c4
8 изменённых файлов: 73 добавлений и 20 удалений

Просмотреть файл

@ -880,13 +880,13 @@ private:
return static_cast<nsBufferedAudioStream*>(aThis)->DataCallback(aBuffer, aFrames);
}
static int StateCallback_S(cubeb_stream*, void* aThis, cubeb_state aState)
static void StateCallback_S(cubeb_stream*, void* aThis, cubeb_state aState)
{
return static_cast<nsBufferedAudioStream*>(aThis)->StateCallback(aState);
static_cast<nsBufferedAudioStream*>(aThis)->StateCallback(aState);
}
long DataCallback(void* aBuffer, long aFrames);
int StateCallback(cubeb_state aState);
void StateCallback(cubeb_state aState);
// Shared implementation of underflow adjusted position calculation.
// Caller must own the monitor.
@ -1268,7 +1268,7 @@ nsBufferedAudioStream::DataCallback(void* aBuffer, long aFrames)
return aFrames - (bytesWanted / mBytesPerFrame);
}
int
void
nsBufferedAudioStream::StateCallback(cubeb_state aState)
{
MonitorAutoLock mon(mMonitor);
@ -1278,7 +1278,6 @@ nsBufferedAudioStream::StateCallback(cubeb_state aState)
mState = ERRORED;
}
mon.NotifyAll();
return CUBEB_OK;
}
#endif

Просмотреть файл

@ -1 +1,2 @@
Matthew Gregan <kinetik@flim.org>
Alexandre Ratchov <alex@caoua.org>

Просмотреть файл

@ -5,4 +5,4 @@ Makefile.in build files for the Mozilla build system.
The cubeb git repository is: git://github.com/kinetiknz/cubeb.git
The git commit ID used was 21d9678eb9755761f7a9d26253189b926258de7c.
The git commit ID used was f3116936eba69aced240df7db77264269f3f95ae.

Просмотреть файл

@ -40,8 +40,8 @@ extern "C" {
cubeb_stream_start(stm);
for (;;) {
cubeb_get_time(stm, &ts);
printf("time=%lu\n", ts);
cubeb_stream_get_position(stm, &ts);
printf("time=%llu\n", ts);
sleep(1);
}
cubeb_stream_stop(stm);
@ -64,10 +64,9 @@ extern "C" {
@endcode
@code
int state_cb(cubeb_stream * stm, void * user, cubeb_state state)
void state_cb(cubeb_stream * stm, void * user, cubeb_state state)
{
printf("state=%d\n", state);
return CUBEB_OK;
}
@endcode
*/
@ -141,12 +140,10 @@ typedef long (* cubeb_data_callback)(cubeb_stream * stream,
/** User supplied state callback.
@param stream
@param user_ptr
@param state
@retval CUBEB_OK
@retval CUBEB_ERROR */
typedef int (* cubeb_state_callback)(cubeb_stream * stream,
void * user_ptr,
cubeb_state state);
@param state */
typedef void (* cubeb_state_callback)(cubeb_stream * stream,
void * user_ptr,
cubeb_state state);
/** Initialize an application context. This will perform any library or
application scoped initialization.
@ -156,6 +153,11 @@ typedef int (* cubeb_state_callback)(cubeb_stream * stream,
@retval CUBEB_ERROR */
int cubeb_init(cubeb ** context, char const * context_name);
/** Get a read-only string identifying this context's current backend.
@param context
@retval Read-only string identifying current backend. */
char const * cubeb_get_backend_id(cubeb * context);
/** Destroy an application context.
@param context */
void cubeb_destroy(cubeb * context);

Просмотреть файл

@ -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)
{
@ -531,6 +551,12 @@ cubeb_init(cubeb ** context, char const * context_name UNUSED)
return CUBEB_OK;
}
char const *
cubeb_get_backend_id(cubeb * ctx UNUSED)
{
return "alsa";
}
void
cubeb_destroy(cubeb * ctx)
{
@ -621,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);

Просмотреть файл

@ -87,6 +87,12 @@ cubeb_init(cubeb ** context, char const * context_name)
return CUBEB_OK;
}
char const *
cubeb_get_backend_id(cubeb * ctx)
{
return "audiounit";
}
void
cubeb_destroy(cubeb * ctx)
{

Просмотреть файл

@ -116,9 +116,9 @@ stream_request_callback(pa_stream * s, size_t nbytes, void * u)
if ((size_t) got < size / frame_size) {
size_t buffer_fill = pa_stream_get_buffer_attr(s)->maxlength - pa_stream_writable_size(s);
double buffer_time = (double) buffer_fill / stm->sample_spec.rate;
pa_usec_t buffer_time = pa_bytes_to_usec(buffer_fill, &stm->sample_spec);
/* pa_stream_drain is useless, see PA bug# 866. this is a workaround. */
stm->drain_timer = pa_context_rttime_new(stm->context->context, pa_rtclock_now() + buffer_time * 1e6, stream_drain_callback, stm);
stm->drain_timer = pa_context_rttime_new(stm->context->context, pa_rtclock_now() + buffer_time, stream_drain_callback, stm);
stm->shutdown = 1;
return;
}
@ -211,6 +211,12 @@ cubeb_init(cubeb ** context, char const * context_name)
return CUBEB_OK;
}
char const *
cubeb_get_backend_id(cubeb * ctx)
{
return "pulse";
}
void
cubeb_destroy(cubeb * ctx)
{
@ -295,7 +301,7 @@ cubeb_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_n
battr.maxlength = -1;
battr.tlength = pa_usec_to_bytes(latency * PA_USEC_PER_MSEC, &stm->sample_spec);
battr.prebuf = -1;
battr.minreq = battr.tlength / 2;
battr.minreq = battr.tlength / 4;
battr.fragsize = -1;
pa_threaded_mainloop_lock(stm->context->mainloop);

Просмотреть файл

@ -1,5 +1,5 @@
/*
* Copyright <EFBFBD>Â<EFBFBD>© 2011 Mozilla Foundation
* Copyright © 2011 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
@ -123,6 +123,7 @@ cubeb_refill_stream(cubeb_stream * stm)
got = stm->data_callback(stm, stm->user_ptr, hdr->lpData, wanted);
EnterCriticalSection(&stm->lock);
if (got < 0) {
LeaveCriticalSection(&stm->lock);
/* XXX handle this case */
assert(0);
return;
@ -226,6 +227,12 @@ cubeb_init(cubeb ** context, char const * context_name)
return CUBEB_OK;
}
char const *
cubeb_get_backend_id(cubeb * ctx)
{
return "winmm";
}
void
cubeb_destroy(cubeb * ctx)
{