summaryrefslogtreecommitdiffstats
path: root/src/pulsecore/memblockq.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pulsecore/memblockq.c')
-rw-r--r--src/pulsecore/memblockq.c102
1 files changed, 61 insertions, 41 deletions
diff --git a/src/pulsecore/memblockq.c b/src/pulsecore/memblockq.c
index 1d9583e1..947c69a2 100644
--- a/src/pulsecore/memblockq.c
+++ b/src/pulsecore/memblockq.c
@@ -55,7 +55,7 @@ struct pa_memblockq {
size_t maxlength, tlength, base, prebuf, minreq, maxrewind;
int64_t read_index, write_index;
pa_bool_t in_prebuf;
- pa_memblock *silence;
+ pa_memchunk silence;
pa_mcalign *mcalign;
int64_t missing;
size_t requested;
@@ -69,7 +69,7 @@ pa_memblockq* pa_memblockq_new(
size_t prebuf,
size_t minreq,
size_t maxrewind,
- pa_memblock *silence) {
+ pa_memchunk *silence) {
pa_memblockq* bq;
@@ -98,7 +98,12 @@ pa_memblockq* pa_memblockq_new(
pa_log_debug("memblockq sanitized: maxlength=%lu, tlength=%lu, base=%lu, prebuf=%lu, minreq=%lu maxrewind=%lu",
(unsigned long) bq->maxlength, (unsigned long) bq->tlength, (unsigned long) bq->base, (unsigned long) bq->prebuf, (unsigned long) bq->minreq, (unsigned long) bq->maxrewind);
- bq->silence = silence ? pa_memblock_ref(silence) : NULL;
+ if (silence) {
+ bq->silence = *silence;
+ pa_memblock_ref(bq->silence.memblock);
+ } else
+ pa_memchunk_reset(&bq->silence);
+
bq->mcalign = pa_mcalign_new(bq->base);
return bq;
@@ -109,8 +114,8 @@ void pa_memblockq_free(pa_memblockq* bq) {
pa_memblockq_flush(bq);
- if (bq->silence)
- pa_memblock_unref(bq->silence);
+ if (bq->silence.memblock)
+ pa_memblock_unref(bq->silence.memblock);
if (bq->mcalign)
pa_mcalign_free(bq->mcalign);
@@ -420,7 +425,7 @@ finish:
return 0;
}
-static pa_bool_t memblockq_check_prebuf(pa_memblockq *bq) {
+pa_bool_t pa_memblockq_prebuf_active(pa_memblockq *bq) {
pa_assert(bq);
if (bq->in_prebuf) {
@@ -447,7 +452,7 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) {
pa_assert(chunk);
/* We need to pre-buffer */
- if (memblockq_check_prebuf(bq))
+ if (pa_memblockq_prebuf_active(bq))
return -1;
fix_current_read(bq);
@@ -466,13 +471,12 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) {
length = 0;
/* We need to return silence, since no data is yet available */
- if (bq->silence) {
- size_t l;
-
- chunk->memblock = pa_memblock_ref(bq->silence);
+ if (bq->silence.memblock) {
+ *chunk = bq->silence;
+ pa_memblock_ref(chunk->memblock);
- l = pa_memblock_get_length(chunk->memblock);
- chunk->length = (length <= 0 || length > l) ? l : length;
+ if (length > 0 && length < chunk->length)
+ chunk->length = length;
} else {
@@ -511,7 +515,7 @@ void pa_memblockq_drop(pa_memblockq *bq, size_t length) {
while (length > 0) {
/* Do not drop any data when we are in prebuffering mode */
- if (memblockq_check_prebuf(bq))
+ if (pa_memblockq_prebuf_active(bq))
break;
fix_current_read(bq);
@@ -546,10 +550,20 @@ void pa_memblockq_drop(pa_memblockq *bq, size_t length) {
bq->missing += delta;
}
+void pa_memblockq_rewind(pa_memblockq *bq, size_t length) {
+ pa_assert(bq);
+ pa_assert(length % bq->base == 0);
+
+ /* This is kind of the inverse of pa_memblockq_drop() */
+
+ bq->read_index -= length;
+ bq->missing -= length;
+}
+
pa_bool_t pa_memblockq_is_readable(pa_memblockq *bq) {
pa_assert(bq);
- if (memblockq_check_prebuf(bq))
+ if (pa_memblockq_prebuf_active(bq))
return FALSE;
if (pa_memblockq_get_length(bq) <= 0)
@@ -621,10 +635,7 @@ void pa_memblockq_flush(pa_memblockq *bq) {
int64_t old, delta;
pa_assert(bq);
- while (bq->blocks)
- drop_block(bq, bq->blocks);
-
- pa_assert(bq->n_blocks == 0);
+ pa_memblockq_silence(bq);
old = bq->write_index;
bq->write_index = bq->read_index;
@@ -757,18 +768,17 @@ void pa_memblockq_set_tlength(pa_memblockq *bq, size_t tlength) {
size_t old_tlength;
pa_assert(bq);
- old_tlength = bq->tlength;
-
if (tlength <= 0)
tlength = bq->maxlength;
+ old_tlength = bq->tlength;
bq->tlength = ((tlength+bq->base-1)/bq->base)*bq->base;
if (bq->tlength > bq->maxlength)
bq->tlength = bq->maxlength;
- if (bq->minreq > bq->tlength - bq->prebuf)
- pa_memblockq_set_minreq(bq, bq->tlength - bq->prebuf);
+ if (bq->minreq > bq->tlength)
+ pa_memblockq_set_minreq(bq, bq->tlength);
bq->missing += (int64_t) bq->tlength - (int64_t) old_tlength;
}
@@ -776,8 +786,10 @@ void pa_memblockq_set_tlength(pa_memblockq *bq, size_t tlength) {
void pa_memblockq_set_prebuf(pa_memblockq *bq, size_t prebuf) {
pa_assert(bq);
- bq->prebuf = (prebuf == (size_t) -1) ? bq->tlength : prebuf;
- bq->prebuf = ((bq->prebuf+bq->base-1)/bq->base)*bq->base;
+ 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;
@@ -788,8 +800,8 @@ void pa_memblockq_set_prebuf(pa_memblockq *bq, size_t prebuf) {
if (bq->prebuf <= 0 || pa_memblockq_get_length(bq) >= bq->prebuf)
bq->in_prebuf = FALSE;
- if (bq->minreq > bq->tlength - bq->prebuf)
- pa_memblockq_set_minreq(bq, bq->tlength - bq->prebuf);
+ if (bq->minreq > bq->prebuf)
+ pa_memblockq_set_minreq(bq, bq->prebuf);
}
void pa_memblockq_set_minreq(pa_memblockq *bq, size_t minreq) {
@@ -797,8 +809,11 @@ void pa_memblockq_set_minreq(pa_memblockq *bq, size_t minreq) {
bq->minreq = (minreq/bq->base)*bq->base;
- if (bq->minreq > bq->tlength - bq->prebuf)
- bq->minreq = bq->tlength - bq->prebuf;
+ 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;
@@ -810,14 +825,6 @@ void pa_memblockq_set_maxrewind(pa_memblockq *bq, size_t maxrewind) {
bq->maxrewind = (maxrewind/bq->base)*bq->base;
}
-void pa_memblockq_rewind(pa_memblockq *bq, size_t length) {
- pa_assert(bq);
- pa_assert(length % bq->base == 0);
-
- bq->read_index -= length;
- bq->missing -= length;
-}
-
int pa_memblockq_splice(pa_memblockq *bq, pa_memblockq *source) {
pa_assert(bq);
@@ -859,13 +866,17 @@ void pa_memblockq_willneed(pa_memblockq *bq) {
pa_memchunk_will_need(&q->chunk);
}
-void pa_memblockq_set_silence(pa_memblockq *bq, pa_memblock *silence) {
+void pa_memblockq_set_silence(pa_memblockq *bq, pa_memchunk *silence) {
pa_assert(bq);
- if (bq->silence)
- pa_memblock_unref(bq->silence);
+ if (bq->silence.memblock)
+ pa_memblock_unref(bq->silence.memblock);
- bq->silence = silence ? pa_memblock_ref(silence) : NULL;
+ if (silence) {
+ bq->silence = *silence;
+ pa_memblock_ref(bq->silence.memblock);
+ } else
+ pa_memchunk_reset(&bq->silence);
}
pa_bool_t pa_memblockq_is_empty(pa_memblockq *bq) {
@@ -873,3 +884,12 @@ pa_bool_t pa_memblockq_is_empty(pa_memblockq *bq) {
return !bq->blocks;
}
+
+void pa_memblockq_silence(pa_memblockq *bq) {
+ pa_assert(bq);
+
+ while (bq->blocks)
+ drop_block(bq, bq->blocks);
+
+ pa_assert(bq->n_blocks == 0);
+}