From b60e60dbaeff9311b3e74a6d54bb3bbb2c1f61e3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 May 2007 00:56:50 +0000 Subject: allow static data in the bufferqs git-svn-id: file:///home/lennart/svn/public/libsydney/trunk@29 9ba3c220-e4d3-45a2-8aa3-73fcc9aff6ce --- bufferq.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 16 deletions(-) (limited to 'bufferq.c') diff --git a/bufferq.c b/bufferq.c index c4c3ec3..5261f35 100644 --- a/bufferq.c +++ b/bufferq.c @@ -4,6 +4,8 @@ #include "macro.h" #include "bufferq.h" +#define SA_BUFFERQ_CONCAT_DATA(x) ((void*) (uint8_t*) (x) + ALIGN(sizeof(sa_bufferq_item_t))) + int sa_bufferq_init(sa_bufferq_t *q, unsigned nchannels, size_t sample_size) { sa_assert(q); sa_assert(sample_size > 0); @@ -42,19 +44,53 @@ void sa_bufferq_done(sa_bufferq_t *q) { sa_free(q->last); } -static sa_bufferq_item_t* bufferq_item_new(size_t size) { +static sa_bufferq_item_t* bufferq_item_new(const void *d, size_t size, int copy) { sa_bufferq_item_t *i; sa_assert(size > 0); + + if (!copy) { + if (!(i = sa_new(sa_bufferq_item_t, 1))) + return i; + i->type = SA_BUFFERQ_ITEM_STATIC; + i->data = (void*) d; + } else { + if (!(i = sa_malloc(ALIGN(sizeof(sa_bufferq_item_t)) + size))) + return i; + i->type = SA_BUFFERQ_ITEM_CONCATENATED; + i->data = SA_BUFFERQ_CONCAT_DATA(i); + memcpy(i->data, d, size); + } + + i->size = size; + SA_LLIST_ITEM_INIT(sa_bufferq_item_t, bufferq, i); + + return i; +} + +static sa_bufferq_item_t* bufferq_item_make_writable(sa_bufferq_item_t *i) { + void *d; + sa_assert(i); - if (!(i = sa_malloc(ALIGN(sizeof(sa_bufferq_item_t)) + size))) + if (i->type == SA_BUFFERQ_ITEM_CONCATENATED || i->type == SA_BUFFERQ_ITEM_DYNAMIC) return i; - SA_LLIST_ITEM_INIT(sa_bufferq_item_t, bufferq, i); + if (!(d = sa_memdup(i->data, i->size))) + return NULL; + i->data = d; + i->type = SA_BUFFERQ_ITEM_DYNAMIC; return i; } -int sa_bufferq_push(sa_bufferq_t *q, unsigned channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence) { +static void bufferq_item_free(sa_bufferq_item_t *i) { + sa_assert(i); + + if (i->type == SA_BUFFERQ_ITEM_DYNAMIC) + sa_free(i->data); + sa_free(i); +} + +int sa_bufferq_push(sa_bufferq_t *q, unsigned channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence, int copy) { int64_t idx; sa_bufferq_item_t *i, *j; @@ -103,13 +139,11 @@ int sa_bufferq_push(sa_bufferq_t *q, unsigned channel, const void *data, size_t if (l > i->idx - idx) l = i->idx - idx; - - if (!(j = bufferq_item_new(l))) - return SA_ERROR_OOM; - memcpy(SA_BUFFERQ_ITEM_DATA(j), data, l); + if (!(j = bufferq_item_new(data, l, copy))) + return SA_ERROR_OOM; + j->idx = idx; - j->size = l; SA_LLIST_INSERT_BEFORE(sa_bufferq_item_t, bufferq, q->items[channel], i, j); @@ -127,7 +161,10 @@ int sa_bufferq_push(sa_bufferq_t *q, unsigned channel, const void *data, size_t if (l > i->idx + i->size - idx) l = i->idx + i->size - idx; - memcpy((uint8_t*) SA_BUFFERQ_ITEM_DATA(i) + (idx - i->idx), data, l); + if (!(i = bufferq_item_make_writable(i))) + return SA_ERROR_OOM; + + memcpy((uint8_t*) i->data + (idx - i->idx), data, l); idx += l; data += l; @@ -138,12 +175,10 @@ int sa_bufferq_push(sa_bufferq_t *q, unsigned channel, const void *data, size_t if (nbytes > 0) { sa_assert(!i); - if (!(j = bufferq_item_new(nbytes))) + if (!(j = bufferq_item_new(data, nbytes, copy))) return SA_ERROR_OOM; - memcpy(SA_BUFFERQ_ITEM_DATA(j), data, nbytes); j->idx = idx; - j->size = nbytes; if (q->last[channel]) SA_LLIST_INSERT_AFTER(sa_bufferq_item_t, bufferq, q->items[channel], q->last[channel], j); @@ -186,7 +221,7 @@ int sa_bufferq_get(sa_bufferq_t *q, void *i[], size_t *bytes) { } else { int64_t l; - i[u] = (uint8_t*) SA_BUFFERQ_ITEM_DATA(q->items[u]) + q->read_index - q->items[u]->idx; + i[u] = (uint8_t*) q->items[u]->data + q->read_index - q->items[u]->idx; l = q->items[u]->size - (q->read_index - q->items[u]->idx); @@ -213,7 +248,6 @@ int sa_bufferq_drop(sa_bufferq_t *q, int64_t bytes) { q->read_index += bytes; for (u = 0; u < q->nchannels; u++) { - sa_bufferq_item_t *i; i = q->items[u]; @@ -223,7 +257,7 @@ int sa_bufferq_drop(sa_bufferq_t *q, int64_t bytes) { SA_LLIST_REMOVE(sa_bufferq_item_t, bufferq, q->items[u], i); - sa_free(i); + bufferq_item_free(i); i = n; } @@ -233,3 +267,25 @@ int sa_bufferq_drop(sa_bufferq_t *q, int64_t bytes) { return SA_SUCCESS; } + +int sa_bufferq_realloc(sa_bufferq_t *q) { + unsigned u; + sa_assert(q); + + for (u = 0; u < q->nchannels; u++) { + sa_bufferq_item_t *i; + + i = q->items[u]; + + while (i) { + + if (!bufferq_item_make_writable(i)) + return SA_ERROR_OOM; + + i = i->bufferq_next; + } + + } + + return SA_SUCCESS; +} -- cgit