summaryrefslogtreecommitdiffstats
path: root/src/pulsecore/memblockq.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-02-25 02:10:45 +0100
committerLennart Poettering <lennart@poettering.net>2010-02-25 02:10:45 +0100
commit87cc741d0e10f58c5d9c4b40a213ba9a689cff14 (patch)
tree06a792c2d0f6f5b165966deadf0f23917231bb32 /src/pulsecore/memblockq.c
parent5030852c8e4c0a24a3a42e5583358daaad7ec0df (diff)
memblockq: implement new call pa_memblockq_peek_fixed_size()
Diffstat (limited to 'src/pulsecore/memblockq.c')
-rw-r--r--src/pulsecore/memblockq.c71
1 files changed, 70 insertions, 1 deletions
diff --git a/src/pulsecore/memblockq.c b/src/pulsecore/memblockq.c
index 2b063fac..c7840484 100644
--- a/src/pulsecore/memblockq.c
+++ b/src/pulsecore/memblockq.c
@@ -481,7 +481,6 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) {
/* Do we need to spit out silence? */
if (!bq->current_read || bq->current_read->index > bq->read_index) {
-
size_t length;
/* How much silence shall we return? */
@@ -527,6 +526,76 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) {
return 0;
}
+int pa_memblockq_peek_fixed_size(pa_memblockq *bq, size_t block_size, pa_memchunk *chunk) {
+ pa_memchunk tchunk, rchunk;
+ int64_t ri;
+ struct list_item *item;
+
+ pa_assert(bq);
+ pa_assert(block_size > 0);
+ pa_assert(chunk);
+ pa_assert(bq->silence.memblock);
+
+ if (pa_memblockq_peek(bq, &tchunk) < 0)
+ return -1;
+
+ if (tchunk.length >= block_size) {
+ *chunk = tchunk;
+ chunk->length = block_size;
+ return 0;
+ }
+
+ rchunk.memblock = pa_memblock_new(pa_memblock_get_pool(tchunk.memblock), block_size);
+ rchunk.index = 0;
+ rchunk.length = tchunk.length;
+
+ pa_memchunk_memcpy(&rchunk, &tchunk);
+ pa_memblock_unref(tchunk.memblock);
+
+ rchunk.index += tchunk.length;
+
+ /* We don't need to call fix_current_read() here, since
+ * pa_memblock_peek() already did that */
+ item = bq->current_read;
+ ri = bq->read_index + tchunk.length;
+
+ while (rchunk.index < block_size) {
+
+ if (!item || item->index > ri) {
+ /* Do we need to append silence? */
+ tchunk = bq->silence;
+
+ if (item)
+ tchunk.length = PA_MIN(tchunk.length, (size_t) (item->index - ri));
+
+ } else {
+ int64_t d;
+
+ /* We can append real data! */
+ tchunk = item->chunk;
+
+ d = ri - item->index;
+ tchunk.index += (size_t) d;
+ tchunk.length -= (size_t) d;
+
+ /* Go to next item for the next iteration */
+ item = item->next;
+ }
+
+ rchunk.length = tchunk.length = PA_MIN(tchunk.length, block_size - rchunk.index);
+ pa_memchunk_memcpy(&rchunk, &tchunk);
+
+ rchunk.index += rchunk.length;
+ ri += rchunk.length;
+ }
+
+ rchunk.index = 0;
+ rchunk.length = block_size;
+
+ *chunk = rchunk;
+ return 0;
+}
+
void pa_memblockq_drop(pa_memblockq *bq, size_t length) {
int64_t old;
pa_assert(bq);