From 08547adb52080e6eddbdd7a0e9f6847859631d8a Mon Sep 17 00:00:00 2001 From: Oschowa Date: Sat, 20 Feb 2021 09:28:03 +0100 Subject: [PATCH] pulseaudio: Add "zerocopy" playback path --- src/audio/pulseaudio/SDL_pulseaudio.c | 22 ++++++++++++++++++++-- src/audio/pulseaudio/SDL_pulseaudio.h | 6 ++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/audio/pulseaudio/SDL_pulseaudio.c b/src/audio/pulseaudio/SDL_pulseaudio.c index eded4b6d1..25dba67d3 100644 --- a/src/audio/pulseaudio/SDL_pulseaudio.c +++ b/src/audio/pulseaudio/SDL_pulseaudio.c @@ -103,6 +103,8 @@ static int (*PULSEAUDIO_pa_stream_connect_record) (pa_stream *, const char *, static pa_stream_state_t (*PULSEAUDIO_pa_stream_get_state) (pa_stream *); static size_t (*PULSEAUDIO_pa_stream_writable_size) (pa_stream *); static size_t (*PULSEAUDIO_pa_stream_readable_size) (pa_stream *); +static int (*PULSEAUDIO_pa_stream_begin_write) (pa_stream *, void **, size_t*); +static int (*PULSEAUDIO_pa_stream_cancel_write) (pa_stream *); static int (*PULSEAUDIO_pa_stream_write) (pa_stream *, const void *, size_t, pa_free_cb_t, int64_t, pa_seek_mode_t); static pa_operation * (*PULSEAUDIO_pa_stream_drain) (pa_stream *, @@ -216,6 +218,8 @@ load_pulseaudio_syms(void) SDL_PULSEAUDIO_SYM(pa_stream_writable_size); SDL_PULSEAUDIO_SYM(pa_stream_readable_size); SDL_PULSEAUDIO_SYM(pa_stream_write); + SDL_PULSEAUDIO_SYM(pa_stream_begin_write); + SDL_PULSEAUDIO_SYM(pa_stream_cancel_write); SDL_PULSEAUDIO_SYM(pa_stream_drain); SDL_PULSEAUDIO_SYM(pa_stream_disconnect); SDL_PULSEAUDIO_SYM(pa_stream_peek); @@ -366,7 +370,7 @@ PULSEAUDIO_PlayDevice(_THIS) /* Write the audio data */ struct SDL_PrivateAudioData *h = this->hidden; if (SDL_AtomicGet(&this->enabled)) { - if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) { + if (PULSEAUDIO_pa_stream_write(h->stream, h->pabuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) { SDL_OpenedAudioDeviceDisconnected(this); } } @@ -375,7 +379,21 @@ PULSEAUDIO_PlayDevice(_THIS) static Uint8 * PULSEAUDIO_GetDeviceBuf(_THIS) { - return (this->hidden->mixbuf); + struct SDL_PrivateAudioData *h = this->hidden; + size_t nbytes = h->mixlen; + int ret; + + ret = PULSEAUDIO_pa_stream_begin_write(h->stream, &h->pabuf, &nbytes); + + if (ret != 0) { + /* fall back it intermediate buffer */ + h->pabuf = h->mixbuf; + } else if (nbytes < h->mixlen) { + PULSEAUDIO_pa_stream_cancel_write(h->stream); + h->pabuf = h->mixbuf; + } + + return (Uint8 *)h->pabuf; } diff --git a/src/audio/pulseaudio/SDL_pulseaudio.h b/src/audio/pulseaudio/SDL_pulseaudio.h index d06e62085..4b8755cfd 100644 --- a/src/audio/pulseaudio/SDL_pulseaudio.h +++ b/src/audio/pulseaudio/SDL_pulseaudio.h @@ -43,6 +43,12 @@ struct SDL_PrivateAudioData Uint8 *mixbuf; int mixlen; + /* Pointer to the actual buffer in use in the current + GetDeviceBuf() -> PlayDevice() iteration. + Can be either the pointer returned by pa_stream_begin_write() + or mixbuf */ + void *pabuf; + const Uint8 *capturebuf; int capturelen; };