mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
pulse: improve support for !ADJUST_LATENCY streams
When a stream does not specify ADJUST_LATENCY, use some slightly different metrics to implement the readable_size. We want the app to fill as much space as possible. Makes mplayer work and paplay use the right amount of buffering.
This commit is contained in:
parent
9639f32db5
commit
30254977c6
1 changed files with 46 additions and 32 deletions
|
|
@ -210,6 +210,20 @@ static void patch_buffer_attr(pa_stream *s, pa_buffer_attr *attr, pa_stream_flag
|
|||
*flags |= PA_STREAM_ADJUST_LATENCY;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags && !SPA_FLAG_IS_SET(*flags, PA_STREAM_ADJUST_LATENCY)) {
|
||||
if (attr->maxlength == 0)
|
||||
attr->maxlength = -1;
|
||||
if (attr->tlength == 0)
|
||||
attr->tlength = -1;
|
||||
if (attr->minreq == 0)
|
||||
attr->minreq = -1;
|
||||
if (attr->prebuf == 0)
|
||||
attr->prebuf = -1;
|
||||
if (attr->fragsize == 0)
|
||||
attr->prebuf = -1;
|
||||
}
|
||||
|
||||
dump_buffer_attr(s, attr);
|
||||
|
||||
stride = pa_frame_size(&s->sample_spec);
|
||||
|
|
@ -454,7 +468,10 @@ static inline uint32_t queued_size(const pa_stream *s, uint64_t elapsed)
|
|||
}
|
||||
static inline uint32_t target_queue(const pa_stream *s)
|
||||
{
|
||||
return s->buffer_attr.tlength;
|
||||
if (SPA_FLAG_IS_SET(s->flags, PA_STREAM_ADJUST_LATENCY))
|
||||
return s->buffer_attr.tlength;
|
||||
else
|
||||
return s->buffer_attr.maxlength;
|
||||
}
|
||||
|
||||
static inline uint32_t wanted_size(const pa_stream *s, uint32_t queued, uint32_t target)
|
||||
|
|
@ -462,16 +479,31 @@ static inline uint32_t wanted_size(const pa_stream *s, uint32_t queued, uint32_t
|
|||
return target - SPA_MIN(queued, target);
|
||||
}
|
||||
|
||||
static inline uint32_t writable_size(const pa_stream *s, uint64_t queued)
|
||||
{
|
||||
return s->maxblock - SPA_MIN(queued, s->maxblock);
|
||||
}
|
||||
|
||||
static inline uint32_t required_size(const pa_stream *s)
|
||||
{
|
||||
return s->buffer_attr.minreq;
|
||||
}
|
||||
|
||||
static inline uint32_t writable_size(const pa_stream *s, uint64_t elapsed)
|
||||
{
|
||||
uint32_t queued, target, wanted, required;
|
||||
|
||||
queued = queued_size(s, elapsed);
|
||||
target = target_queue(s);
|
||||
wanted = wanted_size(s, queued, target);
|
||||
required = required_size(s);
|
||||
|
||||
pw_log_trace("stream %p, queued:%u target:%u wanted:%u required:%u",
|
||||
s, queued, target, wanted, required);
|
||||
if (SPA_FLAG_IS_SET(s->flags, PA_STREAM_ADJUST_LATENCY))
|
||||
if (queued >= wanted)
|
||||
wanted = 0;
|
||||
if (wanted < required)
|
||||
wanted = 0;
|
||||
|
||||
return wanted;
|
||||
}
|
||||
|
||||
static void stream_process(void *data)
|
||||
{
|
||||
pa_stream *s = data;
|
||||
|
|
@ -480,21 +512,14 @@ static void stream_process(void *data)
|
|||
update_timing_info(s);
|
||||
|
||||
if (s->direction == PA_STREAM_PLAYBACK) {
|
||||
uint32_t queued, target, wanted, required;
|
||||
uint32_t writable;
|
||||
|
||||
queue_output(s);
|
||||
|
||||
queued = queued_size(s, 0);
|
||||
target = target_queue(s);
|
||||
wanted = wanted_size(s, queued, target);
|
||||
required = required_size(s);
|
||||
writable = writable_size(s, 0);
|
||||
|
||||
pw_log_trace("stream %p, queued:%u target:%u wanted:%u required:%u",
|
||||
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);
|
||||
if (s->write_callback && s->state == PA_STREAM_READY && writable > 0)
|
||||
s->write_callback(s, writable, s->write_userdata);
|
||||
}
|
||||
else {
|
||||
pull_input(s);
|
||||
|
|
@ -894,6 +919,7 @@ static int create_stream(pa_stream_direction_t direction,
|
|||
s->n_channel_volumes = 0;
|
||||
}
|
||||
s->mute = false;
|
||||
s->flags = flags;
|
||||
|
||||
pa_stream_set_state(s, PA_STREAM_CREATING);
|
||||
|
||||
|
|
@ -950,7 +976,7 @@ static int create_stream(pa_stream_direction_t direction,
|
|||
if (!pa_sample_spec_valid(&s->sample_spec))
|
||||
return -EINVAL;
|
||||
|
||||
patch_buffer_attr(s, &s->buffer_attr, &flags);
|
||||
patch_buffer_attr(s, &s->buffer_attr, &s->flags);
|
||||
|
||||
if (direction == PA_STREAM_RECORD)
|
||||
devid = s->direct_on_input;
|
||||
|
|
@ -1285,7 +1311,7 @@ SPA_EXPORT
|
|||
size_t pa_stream_writable_size(PA_CONST pa_stream *s)
|
||||
{
|
||||
const pa_timing_info *i;
|
||||
uint64_t now, then, queued, target, wanted, elapsed, required;
|
||||
uint64_t now, then, elapsed;
|
||||
struct timespec ts;
|
||||
|
||||
spa_assert(s);
|
||||
|
|
@ -1307,19 +1333,7 @@ size_t pa_stream_writable_size(PA_CONST pa_stream *s)
|
|||
elapsed = 0;
|
||||
}
|
||||
|
||||
queued = queued_size(s, elapsed);
|
||||
target = target_queue(s);
|
||||
wanted = wanted_size(s, queued, target);
|
||||
required = required_size(s);
|
||||
|
||||
pw_log_debug("stream %p: queued:%"PRIu64" target:%"PRIu64
|
||||
" wanted:%"PRIu64" required:%"PRIu64, s,
|
||||
queued, target, wanted, required);
|
||||
|
||||
if (queued >= wanted || wanted < required)
|
||||
wanted = 0;
|
||||
|
||||
return wanted;
|
||||
return writable_size(s, elapsed);
|
||||
}
|
||||
|
||||
SPA_EXPORT
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue