mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-05 13:30:02 -05:00
pulse-tunnel: handle latency a little better
Set a limit on the buffer size. Announce our latency on the streams.
This commit is contained in:
parent
48f03f85a7
commit
b9efb25605
1 changed files with 30 additions and 3 deletions
|
|
@ -43,6 +43,7 @@
|
||||||
#include <spa/debug/pod.h>
|
#include <spa/debug/pod.h>
|
||||||
#include <spa/pod/builder.h>
|
#include <spa/pod/builder.h>
|
||||||
#include <spa/param/audio/format-utils.h>
|
#include <spa/param/audio/format-utils.h>
|
||||||
|
#include <spa/param/latency-utils.h>
|
||||||
#include <spa/param/audio/raw.h>
|
#include <spa/param/audio/raw.h>
|
||||||
|
|
||||||
#include <pipewire/impl.h>
|
#include <pipewire/impl.h>
|
||||||
|
|
@ -75,6 +76,8 @@ static const struct spa_dict_item module_props[] = {
|
||||||
#define RINGBUFFER_SIZE (1u << 22)
|
#define RINGBUFFER_SIZE (1u << 22)
|
||||||
#define RINGBUFFER_MASK (RINGBUFFER_SIZE-1)
|
#define RINGBUFFER_MASK (RINGBUFFER_SIZE-1)
|
||||||
|
|
||||||
|
#define DEFAULT_LATENCY_USEC (20 * PA_USEC_PER_MSEC)
|
||||||
|
|
||||||
struct impl {
|
struct impl {
|
||||||
struct pw_context *context;
|
struct pw_context *context;
|
||||||
|
|
||||||
|
|
@ -281,9 +284,10 @@ static int create_stream(struct impl *impl)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
uint32_t n_params;
|
uint32_t n_params;
|
||||||
const struct spa_pod *params[1];
|
const struct spa_pod *params[2];
|
||||||
uint8_t buffer[1024];
|
uint8_t buffer[1024];
|
||||||
struct spa_pod_builder b;
|
struct spa_pod_builder b;
|
||||||
|
struct spa_latency_info latency;
|
||||||
|
|
||||||
impl->stream = pw_stream_new(impl->core, "pulse", impl->stream_props);
|
impl->stream = pw_stream_new(impl->core, "pulse", impl->stream_props);
|
||||||
impl->stream_props = NULL;
|
impl->stream_props = NULL;
|
||||||
|
|
@ -313,6 +317,13 @@ static int create_stream(struct impl *impl)
|
||||||
params[n_params++] = spa_format_audio_raw_build(&b,
|
params[n_params++] = spa_format_audio_raw_build(&b,
|
||||||
SPA_PARAM_EnumFormat, &impl->info);
|
SPA_PARAM_EnumFormat, &impl->info);
|
||||||
|
|
||||||
|
spa_zero(latency);
|
||||||
|
latency.direction = impl->mode == MODE_CAPTURE ? PW_DIRECTION_OUTPUT : PW_DIRECTION_INPUT;
|
||||||
|
latency.min_ns = latency.max_ns = DEFAULT_LATENCY_USEC * 1000;
|
||||||
|
|
||||||
|
params[n_params++] = spa_latency_build(&b,
|
||||||
|
SPA_PARAM_Latency, &latency);
|
||||||
|
|
||||||
if ((res = pw_stream_connect(impl->stream,
|
if ((res = pw_stream_connect(impl->stream,
|
||||||
impl->mode == MODE_CAPTURE ? PW_DIRECTION_OUTPUT : PW_DIRECTION_INPUT,
|
impl->mode == MODE_CAPTURE ? PW_DIRECTION_OUTPUT : PW_DIRECTION_INPUT,
|
||||||
PW_ID_ANY,
|
PW_ID_ANY,
|
||||||
|
|
@ -443,6 +454,12 @@ static void stream_write_request_cb(pa_stream *s, size_t length, void *userdata)
|
||||||
static void stream_latency_update_cb(pa_stream *s, void *userdata)
|
static void stream_latency_update_cb(pa_stream *s, void *userdata)
|
||||||
{
|
{
|
||||||
struct impl *impl = userdata;
|
struct impl *impl = userdata;
|
||||||
|
pa_usec_t usec;
|
||||||
|
int negative;
|
||||||
|
|
||||||
|
pa_stream_get_latency(s, &usec, &negative);
|
||||||
|
|
||||||
|
pw_log_debug("latency %ld negative %d", usec, negative);
|
||||||
pa_threaded_mainloop_signal(impl->pa_mainloop, 0);
|
pa_threaded_mainloop_signal(impl->pa_mainloop, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -462,6 +479,7 @@ static int create_pulse_stream(struct impl *impl)
|
||||||
pa_proplist *props = NULL;
|
pa_proplist *props = NULL;
|
||||||
pa_mainloop_api *api;
|
pa_mainloop_api *api;
|
||||||
char stream_name[1024];
|
char stream_name[1024];
|
||||||
|
pa_buffer_attr bufferattr;
|
||||||
int res = -EIO;
|
int res = -EIO;
|
||||||
|
|
||||||
if ((impl->pa_mainloop = pa_threaded_mainloop_new()) == NULL)
|
if ((impl->pa_mainloop = pa_threaded_mainloop_new()) == NULL)
|
||||||
|
|
@ -524,15 +542,24 @@ static int create_pulse_stream(struct impl *impl)
|
||||||
|
|
||||||
remote_node_target = pw_properties_get(impl->props, PW_KEY_NODE_TARGET);
|
remote_node_target = pw_properties_get(impl->props, PW_KEY_NODE_TARGET);
|
||||||
|
|
||||||
|
bufferattr.fragsize = (uint32_t) -1;
|
||||||
|
bufferattr.minreq = (uint32_t) -1;
|
||||||
|
bufferattr.maxlength = (uint32_t) -1;
|
||||||
|
bufferattr.prebuf = (uint32_t) -1;
|
||||||
|
|
||||||
if (impl->mode == MODE_CAPTURE) {
|
if (impl->mode == MODE_CAPTURE) {
|
||||||
|
bufferattr.tlength = pa_usec_to_bytes(DEFAULT_LATENCY_USEC, &ss);
|
||||||
|
|
||||||
res = pa_stream_connect_record(impl->pa_stream,
|
res = pa_stream_connect_record(impl->pa_stream,
|
||||||
remote_node_target, NULL,
|
remote_node_target, &bufferattr,
|
||||||
PA_STREAM_INTERPOLATE_TIMING |
|
PA_STREAM_INTERPOLATE_TIMING |
|
||||||
PA_STREAM_ADJUST_LATENCY |
|
PA_STREAM_ADJUST_LATENCY |
|
||||||
PA_STREAM_AUTO_TIMING_UPDATE);
|
PA_STREAM_AUTO_TIMING_UPDATE);
|
||||||
} else {
|
} else {
|
||||||
|
bufferattr.fragsize = pa_usec_to_bytes(DEFAULT_LATENCY_USEC, &ss);
|
||||||
|
|
||||||
res = pa_stream_connect_playback(impl->pa_stream,
|
res = pa_stream_connect_playback(impl->pa_stream,
|
||||||
remote_node_target, NULL,
|
remote_node_target, &bufferattr,
|
||||||
PA_STREAM_INTERPOLATE_TIMING |
|
PA_STREAM_INTERPOLATE_TIMING |
|
||||||
PA_STREAM_ADJUST_LATENCY |
|
PA_STREAM_ADJUST_LATENCY |
|
||||||
PA_STREAM_AUTO_TIMING_UPDATE,
|
PA_STREAM_AUTO_TIMING_UPDATE,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue