X-Git-Url: https://code.delx.au/pulseaudio/blobdiff_plain/061344fbd78f4a643f4e2a12b24c5d1ae1622e04..66cfa72eb4fd4669dfd7e465c07c41bb7e6d3d85:/src/pulsecore/memblockq.c diff --git a/src/pulsecore/memblockq.c b/src/pulsecore/memblockq.c index e6e7b736..2b063fac 100644 --- a/src/pulsecore/memblockq.c +++ b/src/pulsecore/memblockq.c @@ -55,8 +55,7 @@ struct pa_memblockq { pa_bool_t in_prebuf; pa_memchunk silence; pa_mcalign *mcalign; - int64_t missing; - size_t requested; + int64_t missing, requested; }; pa_memblockq* pa_memblockq_new( @@ -84,14 +83,14 @@ pa_memblockq* pa_memblockq_new( pa_log_debug("memblockq requested: maxlength=%lu, tlength=%lu, base=%lu, prebuf=%lu, minreq=%lu maxrewind=%lu", (unsigned long) maxlength, (unsigned long) tlength, (unsigned long) base, (unsigned long) prebuf, (unsigned long) minreq, (unsigned long) maxrewind); - bq->missing = 0; - bq->requested = bq->maxlength = bq->tlength = bq->prebuf = bq->minreq = bq->maxrewind = 0; + bq->missing = bq->requested = 0; + bq->maxlength = bq->tlength = bq->prebuf = bq->minreq = bq->maxrewind = 0; bq->in_prebuf = TRUE; 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", @@ -246,10 +245,36 @@ static pa_bool_t can_push(pa_memblockq *bq, size_t l) { return TRUE; } +static void write_index_changed(pa_memblockq *bq, int64_t old_write_index, pa_bool_t account) { + int64_t delta; + + pa_assert(bq); + + delta = bq->write_index - old_write_index; + + if (account) + bq->requested -= delta; + else + bq->missing -= delta; + + /* pa_log("pushed/seeked %lli: requested counter at %lli, account=%i", (long long) delta, (long long) bq->requested, account); */ +} + +static void read_index_changed(pa_memblockq *bq, int64_t old_read_index) { + int64_t delta; + + pa_assert(bq); + + delta = bq->read_index - old_read_index; + bq->missing += delta; + + /* pa_log("popped %lli: missing counter at %lli", (long long) delta, (long long) bq->missing); */ +} + int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { struct list_item *q, *n; pa_memchunk chunk; - int64_t old, delta; + int64_t old; pa_assert(bq); pa_assert(uchunk); @@ -409,18 +434,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { finish: - delta = bq->write_index - old; - - if (delta >= (int64_t) bq->requested) { - delta -= (int64_t) bq->requested; - bq->requested = 0; - } else { - bq->requested -= (size_t) delta; - delta = 0; - } - - bq->missing -= delta; - + write_index_changed(bq, old, TRUE); return 0; } @@ -514,7 +528,7 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) { } void pa_memblockq_drop(pa_memblockq *bq, size_t length) { - int64_t old, delta; + int64_t old; pa_assert(bq); pa_assert(length % bq->base == 0); @@ -553,19 +567,21 @@ void pa_memblockq_drop(pa_memblockq *bq, size_t length) { } drop_backlog(bq); - - delta = bq->read_index - old; - bq->missing += delta; + read_index_changed(bq, old); } void pa_memblockq_rewind(pa_memblockq *bq, size_t length) { + int64_t old; pa_assert(bq); pa_assert(length % bq->base == 0); + old = bq->read_index; + /* This is kind of the inverse of pa_memblockq_drop() */ bq->read_index -= (int64_t) length; - bq->missing -= (int64_t) length; + + read_index_changed(bq, old); } pa_bool_t pa_memblockq_is_readable(pa_memblockq *bq) { @@ -601,8 +617,8 @@ size_t pa_memblockq_missing(pa_memblockq *bq) { return l >= bq->minreq ? l : 0; } -void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek) { - int64_t old, delta; +void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek, pa_bool_t account) { + int64_t old; pa_assert(bq); old = bq->write_index; @@ -625,22 +641,11 @@ void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek) { } drop_backlog(bq); - - delta = bq->write_index - old; - - if (delta >= (int64_t) bq->requested) { - delta -= (int64_t) bq->requested; - bq->requested = 0; - } else if (delta >= 0) { - bq->requested -= (size_t) delta; - delta = 0; - } - - bq->missing -= delta; + write_index_changed(bq, old, account); } -void pa_memblockq_flush_write(pa_memblockq *bq) { - int64_t old, delta; +void pa_memblockq_flush_write(pa_memblockq *bq, pa_bool_t account) { + int64_t old; pa_assert(bq); pa_memblockq_silence(bq); @@ -649,22 +654,11 @@ void pa_memblockq_flush_write(pa_memblockq *bq) { bq->write_index = bq->read_index; pa_memblockq_prebuf_force(bq); - - delta = bq->write_index - old; - - if (delta >= (int64_t) bq->requested) { - delta -= (int64_t) bq->requested; - bq->requested = 0; - } else if (delta >= 0) { - bq->requested -= (size_t) delta; - delta = 0; - } - - bq->missing -= delta; + write_index_changed(bq, old, account); } void pa_memblockq_flush_read(pa_memblockq *bq) { - int64_t old, delta; + int64_t old; pa_assert(bq); pa_memblockq_silence(bq); @@ -673,9 +667,7 @@ void pa_memblockq_flush_read(pa_memblockq *bq) { bq->read_index = bq->write_index; pa_memblockq_prebuf_force(bq); - - delta = bq->read_index - old; - bq->missing += delta; + read_index_changed(bq, old); } size_t pa_memblockq_get_tlength(pa_memblockq *bq) { @@ -690,6 +682,12 @@ size_t pa_memblockq_get_minreq(pa_memblockq *bq) { return bq->minreq; } +size_t pa_memblockq_get_maxrewind(pa_memblockq *bq) { + pa_assert(bq); + + return bq->maxrewind; +} + int64_t pa_memblockq_get_read_index(pa_memblockq *bq) { pa_assert(bq); @@ -766,8 +764,11 @@ size_t pa_memblockq_pop_missing(pa_memblockq *bq) { return 0; l = (size_t) bq->missing; + + bq->requested += bq->missing; bq->missing = 0; - bq->requested += l; + + /* pa_log("sent %lli: request counter is at %lli", (long long) l, (long long) bq->requested); */ return l; } @@ -782,16 +783,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; @@ -800,49 +798,46 @@ 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_minreq(pa_memblockq *bq, size_t minreq) { + pa_assert(bq); + + bq->minreq = (minreq/bq->base)*bq->base; + + if (bq->minreq > bq->tlength) + bq->minreq = bq->tlength; + + 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; + 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->prebuf = bq->tlength; + 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; - - 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); - - bq->minreq = (minreq/bq->base)*bq->base; - - 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; } void pa_memblockq_set_maxrewind(pa_memblockq *bq, size_t maxrewind) { @@ -895,7 +890,7 @@ int pa_memblockq_splice(pa_memblockq *bq, pa_memblockq *source) { pa_memblock_unref(chunk.memblock); } else - pa_memblockq_seek(bq, (int64_t) chunk.length, PA_SEEK_RELATIVE); + pa_memblockq_seek(bq, (int64_t) chunk.length, PA_SEEK_RELATIVE, TRUE); pa_memblockq_drop(bq, chunk.length); }