mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
Make sure we don't get stuck when prebuf is too high
If prebuf is greater than tlength minus minreq we might end up waiting for the buffer to fill up further however without ever asking for more data from the client since less minreq bytes might be missing. This fixes bug #440
This commit is contained in:
parent
ff8d66d82e
commit
e61728e67a
2 changed files with 32 additions and 35 deletions
|
|
@ -90,8 +90,8 @@ pa_memblockq* pa_memblockq_new(
|
|||
|
||||
pa_memblockq_set_maxlength(bq, maxlength);
|
||||
pa_memblockq_set_tlength(bq, tlength);
|
||||
pa_memblockq_set_prebuf(bq, prebuf);
|
||||
pa_memblockq_set_minreq(bq, minreq);
|
||||
pa_memblockq_set_prebuf(bq, prebuf);
|
||||
pa_memblockq_set_maxrewind(bq, maxrewind);
|
||||
|
||||
pa_log_debug("memblockq sanitized: maxlength=%lu, tlength=%lu, base=%lu, prebuf=%lu, minreq=%lu maxrewind=%lu",
|
||||
|
|
@ -784,16 +784,13 @@ void pa_memblockq_set_maxlength(pa_memblockq *bq, size_t maxlength) {
|
|||
|
||||
if (bq->tlength > bq->maxlength)
|
||||
pa_memblockq_set_tlength(bq, bq->maxlength);
|
||||
|
||||
if (bq->prebuf > bq->maxlength)
|
||||
pa_memblockq_set_prebuf(bq, bq->maxlength);
|
||||
}
|
||||
|
||||
void pa_memblockq_set_tlength(pa_memblockq *bq, size_t tlength) {
|
||||
size_t old_tlength;
|
||||
pa_assert(bq);
|
||||
|
||||
if (tlength <= 0)
|
||||
if (tlength <= 0 || tlength == (size_t) -1)
|
||||
tlength = bq->maxlength;
|
||||
|
||||
old_tlength = bq->tlength;
|
||||
|
|
@ -802,36 +799,15 @@ void pa_memblockq_set_tlength(pa_memblockq *bq, size_t tlength) {
|
|||
if (bq->tlength > bq->maxlength)
|
||||
bq->tlength = bq->maxlength;
|
||||
|
||||
if (bq->prebuf > bq->tlength)
|
||||
pa_memblockq_set_prebuf(bq, bq->tlength);
|
||||
|
||||
if (bq->minreq > bq->tlength)
|
||||
pa_memblockq_set_minreq(bq, bq->tlength);
|
||||
|
||||
if (bq->prebuf > bq->tlength+bq->base-bq->minreq)
|
||||
pa_memblockq_set_prebuf(bq, bq->tlength+bq->base-bq->minreq);
|
||||
|
||||
bq->missing += (int64_t) bq->tlength - (int64_t) old_tlength;
|
||||
}
|
||||
|
||||
void pa_memblockq_set_prebuf(pa_memblockq *bq, size_t prebuf) {
|
||||
pa_assert(bq);
|
||||
|
||||
if (prebuf == (size_t) -1)
|
||||
prebuf = bq->tlength;
|
||||
|
||||
bq->prebuf = ((prebuf+bq->base-1)/bq->base)*bq->base;
|
||||
|
||||
if (prebuf > 0 && bq->prebuf < bq->base)
|
||||
bq->prebuf = bq->base;
|
||||
|
||||
if (bq->prebuf > bq->tlength)
|
||||
bq->prebuf = bq->tlength;
|
||||
|
||||
if (bq->prebuf <= 0 || pa_memblockq_get_length(bq) >= bq->prebuf)
|
||||
bq->in_prebuf = FALSE;
|
||||
|
||||
if (bq->minreq > bq->prebuf)
|
||||
pa_memblockq_set_minreq(bq, bq->prebuf);
|
||||
}
|
||||
|
||||
void pa_memblockq_set_minreq(pa_memblockq *bq, size_t minreq) {
|
||||
pa_assert(bq);
|
||||
|
||||
|
|
@ -840,11 +816,29 @@ void pa_memblockq_set_minreq(pa_memblockq *bq, size_t minreq) {
|
|||
if (bq->minreq > bq->tlength)
|
||||
bq->minreq = bq->tlength;
|
||||
|
||||
if (bq->minreq > bq->prebuf)
|
||||
bq->minreq = bq->prebuf;
|
||||
|
||||
if (bq->minreq < bq->base)
|
||||
bq->minreq = bq->base;
|
||||
|
||||
if (bq->prebuf > bq->tlength+bq->base-bq->minreq)
|
||||
pa_memblockq_set_prebuf(bq, bq->tlength+bq->base-bq->minreq);
|
||||
}
|
||||
|
||||
void pa_memblockq_set_prebuf(pa_memblockq *bq, size_t prebuf) {
|
||||
pa_assert(bq);
|
||||
|
||||
if (prebuf == (size_t) -1)
|
||||
prebuf = bq->tlength+bq->base-bq->minreq;
|
||||
|
||||
bq->prebuf = ((prebuf+bq->base-1)/bq->base)*bq->base;
|
||||
|
||||
if (prebuf > 0 && bq->prebuf < bq->base)
|
||||
bq->prebuf = bq->base;
|
||||
|
||||
if (bq->prebuf > bq->tlength+bq->base-bq->minreq)
|
||||
bq->prebuf = bq->tlength+bq->base-bq->minreq;
|
||||
|
||||
if (bq->prebuf <= 0 || pa_memblockq_get_length(bq) >= bq->prebuf)
|
||||
bq->in_prebuf = FALSE;
|
||||
}
|
||||
|
||||
void pa_memblockq_set_maxrewind(pa_memblockq *bq, size_t maxrewind) {
|
||||
|
|
|
|||
|
|
@ -850,7 +850,7 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata,
|
|||
|
||||
/* Called from main context */
|
||||
static void fix_playback_buffer_attr(playback_stream *s) {
|
||||
size_t frame_size;
|
||||
size_t frame_size, max_prebuf;
|
||||
pa_usec_t orig_tlength_usec, tlength_usec, orig_minreq_usec, minreq_usec, sink_usec;
|
||||
|
||||
pa_assert(s);
|
||||
|
|
@ -976,8 +976,11 @@ static void fix_playback_buffer_attr(playback_stream *s) {
|
|||
if (s->buffer_attr.tlength <= s->buffer_attr.minreq)
|
||||
s->buffer_attr.tlength = s->buffer_attr.minreq*2 + (uint32_t) frame_size;
|
||||
|
||||
if (s->buffer_attr.prebuf == (uint32_t) -1 || s->buffer_attr.prebuf > s->buffer_attr.tlength)
|
||||
s->buffer_attr.prebuf = s->buffer_attr.tlength;
|
||||
max_prebuf = s->buffer_attr.tlength + (uint32_t)frame_size - s->buffer_attr.minreq;
|
||||
|
||||
if (s->buffer_attr.prebuf == (uint32_t) -1 ||
|
||||
s->buffer_attr.prebuf > max_prebuf)
|
||||
s->buffer_attr.prebuf = max_prebuf;
|
||||
}
|
||||
|
||||
/* Called from main context */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue