mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-07-15 07:44:10 +00:00
libobs: Fix pulseaudio monitor playback stuttering
This commit is contained in:
parent
ed00d7402f
commit
9de1ffe32b
|
@ -8,7 +8,7 @@ struct audio_monitor {
|
|||
obs_source_t *source;
|
||||
pa_stream *stream;
|
||||
char *device;
|
||||
|
||||
pa_buffer_attr attr;
|
||||
enum speaker_layout speakers;
|
||||
pa_sample_format_t format;
|
||||
uint_fast32_t samples_per_sec;
|
||||
|
@ -22,8 +22,8 @@ struct audio_monitor {
|
|||
audio_resampler_t *resampler;
|
||||
size_t buffer_size;
|
||||
size_t bytesRemaining;
|
||||
|
||||
size_t bytes_per_channel;
|
||||
|
||||
bool ignore;
|
||||
pthread_mutex_t playback_mutex;
|
||||
};
|
||||
|
@ -191,6 +191,21 @@ static void pulseaudio_stream_write(pa_stream *p, size_t nbytes, void *userdata)
|
|||
pulseaudio_signal(0);
|
||||
}
|
||||
|
||||
static void pulseaudio_underflow(pa_stream *p, void *userdata)
|
||||
{
|
||||
UNUSED_PARAMETER(p);
|
||||
PULSE_DATA(userdata);
|
||||
|
||||
pthread_mutex_lock(&data->playback_mutex);
|
||||
if (obs_source_active(data->source))
|
||||
data->attr.tlength = (data->attr.tlength * 3) / 2;
|
||||
|
||||
pa_stream_set_buffer_attr(data->stream, &data->attr, NULL, NULL);
|
||||
pthread_mutex_unlock(&data->playback_mutex);
|
||||
|
||||
pulseaudio_signal(0);
|
||||
}
|
||||
|
||||
static void pulseaudio_server_info(pa_context *c, const pa_server_info *i,
|
||||
void *userdata)
|
||||
{
|
||||
|
@ -362,17 +377,17 @@ static bool audio_monitor_init(struct audio_monitor *monitor,
|
|||
return false;
|
||||
}
|
||||
|
||||
pa_buffer_attr attr;
|
||||
attr.fragsize = (uint32_t) -1;
|
||||
attr.maxlength = (uint32_t) -1;
|
||||
attr.minreq = (uint32_t) -1;
|
||||
attr.prebuf = (uint32_t) -1;
|
||||
attr.tlength = pa_usec_to_bytes(25000, &spec);
|
||||
monitor->attr.fragsize = (uint32_t) -1;
|
||||
monitor->attr.maxlength = (uint32_t) -1;
|
||||
monitor->attr.minreq = (uint32_t) -1;
|
||||
monitor->attr.prebuf = (uint32_t) -1;
|
||||
monitor->attr.tlength = pa_usec_to_bytes(25000, &spec);
|
||||
|
||||
monitor->buffer_size =
|
||||
monitor->bytes_per_frame * pa_usec_to_bytes(100, &spec);
|
||||
monitor->buffer_size = monitor->bytes_per_frame *
|
||||
pa_usec_to_bytes(5000, &spec);
|
||||
|
||||
pa_stream_flags_t flags = PA_STREAM_ADJUST_LATENCY;
|
||||
pa_stream_flags_t flags = PA_STREAM_INTERPOLATE_TIMING |
|
||||
PA_STREAM_AUTO_TIMING_UPDATE;
|
||||
|
||||
if (pthread_mutex_init(&monitor->playback_mutex, NULL) != 0) {
|
||||
blog(LOG_WARNING, "%s: %s", __FUNCTION__,
|
||||
|
@ -381,7 +396,7 @@ static bool audio_monitor_init(struct audio_monitor *monitor,
|
|||
}
|
||||
|
||||
int_fast32_t ret = pulseaudio_connect_playback(monitor->stream,
|
||||
monitor->device, &attr, flags);
|
||||
monitor->device, &monitor->attr, flags);
|
||||
if (ret < 0) {
|
||||
pulseaudio_stop_playback(monitor);
|
||||
blog(LOG_ERROR, "Unable to connect to stream");
|
||||
|
@ -402,6 +417,9 @@ static void audio_monitor_init_final(struct audio_monitor *monitor)
|
|||
|
||||
pulseaudio_write_callback(monitor->stream, pulseaudio_stream_write,
|
||||
(void *) monitor);
|
||||
|
||||
pulseaudio_set_underflow_callback(monitor->stream, pulseaudio_underflow,
|
||||
(void *) monitor);
|
||||
}
|
||||
|
||||
static inline void audio_monitor_free(struct audio_monitor *monitor)
|
||||
|
|
|
@ -328,3 +328,14 @@ void pulseaudio_write_callback(pa_stream *p, pa_stream_request_cb_t cb,
|
|||
pa_stream_set_write_callback(p, cb, userdata);
|
||||
pulseaudio_unlock();
|
||||
}
|
||||
|
||||
void pulseaudio_set_underflow_callback(pa_stream *p, pa_stream_notify_cb_t cb,
|
||||
void *userdata)
|
||||
{
|
||||
if (pulseaudio_context_ready() < 0)
|
||||
return;
|
||||
|
||||
pulseaudio_lock();
|
||||
pa_stream_set_underflow_callback(p, cb, userdata);
|
||||
pulseaudio_unlock();
|
||||
}
|
||||
|
|
|
@ -173,3 +173,13 @@ int_fast32_t pulseaudio_connect_playback(pa_stream *s, const char *name,
|
|||
*/
|
||||
void pulseaudio_write_callback(pa_stream *p, pa_stream_request_cb_t cb,
|
||||
void *userdata);
|
||||
|
||||
/**
|
||||
* Sets a callback function for when an underflow happen
|
||||
*
|
||||
* @param p pa_stream to connect to. NULL for default
|
||||
* @param cb pa_stream_notify_cb_t
|
||||
* @param userdata pointer to userdata the callback will be called with
|
||||
*/
|
||||
void pulseaudio_set_underflow_callback(pa_stream *p, pa_stream_notify_cb_t cb,
|
||||
void *userdata);
|
||||
|
|
Loading…
Reference in a new issue