зеркало из https://github.com/mozilla/gecko-dev.git
Bug 761274 - Work around buffer sizing bug in PulseAudio ALSA plugin. r=doublec
This commit is contained in:
Родитель
a515ca6a14
Коммит
7c54dee4c4
|
@ -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)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче