pulse: tweak buffer attributes some more

Seems to work well with vlc and firefox other apps now.
paplay without ADJUST_LATENCY reports wrong latency still.
This commit is contained in:
Wim Taymans 2020-09-25 17:06:46 +02:00
parent d2d722efb3
commit a79d1fc866

View file

@ -33,7 +33,7 @@
#include "core-format.h" #include "core-format.h"
#include "internal.h" #include "internal.h"
#define MIN_SAMPLES 8u #define MIN_SAMPLES 24u
#define MIN_BUFFERS 8u #define MIN_BUFFERS 8u
#define MAX_BUFFERS 64u #define MAX_BUFFERS 64u
@ -144,11 +144,11 @@ static const struct spa_pod *get_buffers_param(pa_stream *s, pa_buffer_attr *att
blocks = 1; blocks = 1;
stride = pa_frame_size(&s->sample_spec); stride = pa_frame_size(&s->sample_spec);
maxsize = attr->tlength * MAX_BUFFERS; maxsize = attr->tlength;
size = attr->tlength; size = attr->minreq;
buffers = SPA_CLAMP(maxsize / size, MIN_BUFFERS, MAX_BUFFERS); buffers = SPA_CLAMP(maxsize / size, MIN_BUFFERS, MAX_BUFFERS);
pw_log_debug("stream %p: stride %d maxsize %d size %u buffers %d", s, stride, maxsize, pw_log_info("stream %p: stride %d maxsize %d size %u buffers %d", s, stride, maxsize,
size, buffers); size, buffers);
param = spa_pod_builder_add_object(b, param = spa_pod_builder_add_object(b,
@ -222,19 +222,15 @@ static void patch_buffer_attr(pa_stream *s, pa_buffer_attr *attr, pa_stream_flag
attr->tlength = (uint32_t) pa_usec_to_bytes(2*PA_USEC_PER_SEC, &s->sample_spec); attr->tlength = (uint32_t) pa_usec_to_bytes(2*PA_USEC_PER_SEC, &s->sample_spec);
attr->tlength = SPA_MIN(attr->tlength, attr->maxlength); attr->tlength = SPA_MIN(attr->tlength, attr->maxlength);
attr->tlength -= attr->tlength % stride; attr->tlength -= attr->tlength % stride;
attr->tlength = SPA_MAX(attr->tlength, MIN_SAMPLES * stride * MIN_BUFFERS);
if (attr->minreq == (uint32_t) -1) if (attr->minreq == (uint32_t) -1)
attr->minreq = pa_usec_to_bytes(25*PA_USEC_PER_MSEC, &s->sample_spec); attr->minreq = pa_usec_to_bytes(20*PA_USEC_PER_MSEC, &s->sample_spec);
attr->minreq = SPA_MIN(attr->minreq, attr->tlength / MIN_BUFFERS); attr->minreq = SPA_MIN(attr->minreq, attr->tlength / 4);
attr->minreq = SPA_MAX(attr->minreq, MIN_SAMPLES * stride);
attr->minreq -= attr->minreq % stride; attr->minreq -= attr->minreq % stride;
attr->minreq = SPA_MAX(attr->minreq, stride); attr->minreq = SPA_MAX(attr->minreq, stride);
if (attr->fragsize == (uint32_t) -1) attr->tlength = SPA_MAX(attr->tlength, attr->minreq * 4);
attr->fragsize = pa_usec_to_bytes(25*PA_USEC_PER_MSEC, &s->sample_spec);
attr->fragsize = SPA_MIN(attr->fragsize, attr->tlength / MIN_BUFFERS);
attr->fragsize -= attr->fragsize % stride;
attr->fragsize = SPA_MAX(attr->fragsize, stride);
if (attr->prebuf == (uint32_t) -1) if (attr->prebuf == (uint32_t) -1)
attr->prebuf = attr->tlength - attr->minreq; attr->prebuf = attr->tlength - attr->minreq;
@ -242,6 +238,13 @@ static void patch_buffer_attr(pa_stream *s, pa_buffer_attr *attr, pa_stream_flag
attr->prebuf -= attr->prebuf % stride; attr->prebuf -= attr->prebuf % stride;
attr->prebuf = SPA_MAX(attr->prebuf, stride); attr->prebuf = SPA_MAX(attr->prebuf, stride);
if (attr->fragsize == (uint32_t) -1)
attr->fragsize = pa_usec_to_bytes(20*PA_USEC_PER_MSEC, &s->sample_spec);
attr->fragsize = SPA_MIN(attr->fragsize, attr->tlength / 4);
attr->fragsize -= attr->fragsize % stride;
attr->fragsize = SPA_MAX(attr->fragsize, MIN_SAMPLES * stride);
attr->fragsize = SPA_MAX(attr->fragsize, stride);
dump_buffer_attr(s, attr); dump_buffer_attr(s, attr);
} }
@ -451,6 +454,15 @@ static inline uint32_t queued_size(const pa_stream *s, uint64_t elapsed)
queued -= SPA_MIN(queued, elapsed); queued -= SPA_MIN(queued, elapsed);
return queued; return queued;
} }
static inline uint32_t target_queue(const pa_stream *s)
{
return s->buffer_attr.tlength;
}
static inline uint32_t wanted_size(const pa_stream *s, uint32_t queued, uint32_t target)
{
return target - SPA_MIN(queued, target);
}
static inline uint32_t writable_size(const pa_stream *s, uint64_t queued) static inline uint32_t writable_size(const pa_stream *s, uint64_t queued)
{ {
@ -459,7 +471,7 @@ static inline uint32_t writable_size(const pa_stream *s, uint64_t queued)
static inline uint32_t required_size(const pa_stream *s) static inline uint32_t required_size(const pa_stream *s)
{ {
return s->buffer_attr.tlength; return s->buffer_attr.minreq;
} }
static void stream_process(void *data) static void stream_process(void *data)
@ -470,16 +482,22 @@ static void stream_process(void *data)
update_timing_info(s); update_timing_info(s);
if (s->direction == PA_STREAM_PLAYBACK) { if (s->direction == PA_STREAM_PLAYBACK) {
uint64_t queued, writable, required; uint32_t queued, target, wanted, required;
queue_output(s); queue_output(s);
queued = queued_size(s, 0); queued = queued_size(s, 0);
writable = writable_size(s, queued); target = target_queue(s);
wanted = wanted_size(s, queued, target);
required = required_size(s); required = required_size(s);
if (s->write_callback && s->state == PA_STREAM_READY && queued < required && writable >= required) pw_log_trace("stream %p, queued:%u target:%u wanted:%u required:%u",
s->write_callback(s, required, s->write_userdata); s, queued, target, wanted, required);
if (s->write_callback && s->state == PA_STREAM_READY &&
queued < wanted &&
wanted >= required)
s->write_callback(s, wanted, s->write_userdata);
} }
else { else {
pull_input(s); pull_input(s);
@ -986,7 +1004,7 @@ static int create_stream(pa_stream_direction_t direction,
if (monitor) if (monitor)
sprintf(latency, "%u/%u", s->buffer_attr.fragsize / stride, s->sample_spec.rate); sprintf(latency, "%u/%u", s->buffer_attr.fragsize / stride, s->sample_spec.rate);
else else
sprintf(latency, "%u/%u", s->buffer_attr.tlength / 2 / stride, s->sample_spec.rate); sprintf(latency, "%u/%u", s->buffer_attr.minreq * 2 / stride, s->sample_spec.rate);
n_items = 0; n_items = 0;
items[n_items++] = SPA_DICT_ITEM_INIT(PW_KEY_NODE_LATENCY, latency); items[n_items++] = SPA_DICT_ITEM_INIT(PW_KEY_NODE_LATENCY, latency);
items[n_items++] = SPA_DICT_ITEM_INIT(PW_KEY_MEDIA_TYPE, "Audio"); items[n_items++] = SPA_DICT_ITEM_INIT(PW_KEY_MEDIA_TYPE, "Audio");
@ -1293,8 +1311,9 @@ size_t pa_stream_writable_size(PA_CONST pa_stream *s)
writable = writable_size(s, queued); writable = writable_size(s, queued);
required = required_size(s); required = required_size(s);
pw_log_debug("stream %p: %"PRIu64" minreq:%u maxblock:%zu", s, pw_log_debug("stream %p: writable:%"PRIu64" queued:%"PRIu64" required:%"PRIu64, s,
writable, s->buffer_attr.minreq, s->maxblock); writable, queued, required);
if (writable < required) if (writable < required)
writable = 0; writable = 0;