memblockq: implement new call pa_memblockq_peek_fixed_size()

This commit is contained in:
Lennart Poettering 2010-02-25 02:10:45 +01:00
parent 5030852c8e
commit 87cc741d0e
4 changed files with 109 additions and 17 deletions

View file

@ -220,7 +220,6 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk
pa_assert(tchunk.length > 0);
fs = pa_frame_size(&i->sample_spec);
//n = (unsigned) (PA_MIN(tchunk.length, u->block_size) / fs);
n = (unsigned) (tchunk.length / fs);
pa_assert(n > 0);
@ -228,7 +227,6 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk
chunk->index = 0;
chunk->length = n*fs;
chunk->memblock = pa_memblock_new(i->sink->core->mempool, chunk->length);
pa_assert( chunk->memblock );
pa_memblockq_drop(u->memblockq, chunk->length);
@ -240,8 +238,8 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk
/* As an example, copy input to output */
for (c = 0; c < u->channels; c++) {
pa_sample_clamp(PA_SAMPLE_FLOAT32NE,
dst+c, u->channels*sizeof(float),
src+c, u->channels*sizeof(float),
dst+c, u->channels * sizeof(float),
src+c, u->channels * sizeof(float),
n);
}

View file

@ -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);

View file

@ -95,6 +95,11 @@ void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek, pa
* was passed we return the length of the hole in chunk->length. */
int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk);
/* Much like pa_memblockq_peek, but guarantees that the returned chunk
* will have a length of the block size passed. You must configure a
* silence memchunk for this memblockq if you use this call. */
int pa_memblockq_peek_fixed_size(pa_memblockq *bq, size_t block_size, pa_memchunk *chunk);
/* Drop the specified bytes from the queue. */
void pa_memblockq_drop(pa_memblockq *bq, size_t length);

View file

@ -29,23 +29,43 @@
#include <pulsecore/memblockq.h>
#include <pulsecore/log.h>
static void dump_chunk(const pa_memchunk *chunk) {
size_t n;
void *q;
char *e;
pa_assert(chunk);
printf("[");
q = pa_memblock_acquire(chunk->memblock);
for (e = (char*) q + chunk->index, n = 0; n < chunk->length; n++, e++)
printf("%c", *e);
pa_memblock_release(chunk->memblock);
printf("]");
}
static void dump(pa_memblockq *bq) {
printf(">");
pa_memchunk out;
pa_assert(bq);
/* First let's dump this as fixed block */
printf("FIXED >");
pa_memblockq_peek_fixed_size(bq, 64, &out);
dump_chunk(&out);
pa_memblock_unref(out.memblock);
printf("<\n");
/* Then let's dump the queue manually */
printf("MANUAL>");
for (;;) {
pa_memchunk out;
char *e;
size_t n;
void *q;
if (pa_memblockq_peek(bq, &out) < 0)
break;
q = pa_memblock_acquire(out.memblock);
for (e = (char*) q + out.index, n = 0; n < out.length; n++)
printf("%c", *e);
pa_memblock_release(out.memblock);
dump_chunk(&out);
pa_memblock_unref(out.memblock);
pa_memblockq_drop(bq, out.length);
}
@ -70,7 +90,7 @@ int main(int argc, char *argv[]) {
silence.index = 0;
silence.length = pa_memblock_get_length(silence.memblock);
bq = pa_memblockq_new(0, 40, 10, 2, 4, 4, 40, &silence);
bq = pa_memblockq_new(0, 200, 10, 2, 4, 4, 40, &silence);
assert(bq);
chunk1.memblock = pa_memblock_new_fixed(p, (char*) "11", 2, 1);