mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-04 13:29:59 -05:00
memblockq: implement new call pa_memblockq_peek_fixed_size()
This commit is contained in:
parent
9f52c10646
commit
c524b4c5b5
3 changed files with 107 additions and 13 deletions
|
|
@ -481,7 +481,6 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) {
|
||||||
|
|
||||||
/* Do we need to spit out silence? */
|
/* Do we need to spit out silence? */
|
||||||
if (!bq->current_read || bq->current_read->index > bq->read_index) {
|
if (!bq->current_read || bq->current_read->index > bq->read_index) {
|
||||||
|
|
||||||
size_t length;
|
size_t length;
|
||||||
|
|
||||||
/* How much silence shall we return? */
|
/* How much silence shall we return? */
|
||||||
|
|
@ -527,6 +526,76 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) {
|
||||||
return 0;
|
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) {
|
void pa_memblockq_drop(pa_memblockq *bq, size_t length) {
|
||||||
int64_t old;
|
int64_t old;
|
||||||
pa_assert(bq);
|
pa_assert(bq);
|
||||||
|
|
|
||||||
|
|
@ -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. */
|
* was passed we return the length of the hole in chunk->length. */
|
||||||
int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk);
|
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. */
|
/* Drop the specified bytes from the queue. */
|
||||||
void pa_memblockq_drop(pa_memblockq *bq, size_t length);
|
void pa_memblockq_drop(pa_memblockq *bq, size_t length);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,23 +29,43 @@
|
||||||
#include <pulsecore/memblockq.h>
|
#include <pulsecore/memblockq.h>
|
||||||
#include <pulsecore/log.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) {
|
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 (;;) {
|
for (;;) {
|
||||||
pa_memchunk out;
|
|
||||||
char *e;
|
|
||||||
size_t n;
|
|
||||||
void *q;
|
|
||||||
|
|
||||||
if (pa_memblockq_peek(bq, &out) < 0)
|
if (pa_memblockq_peek(bq, &out) < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
q = pa_memblock_acquire(out.memblock);
|
dump_chunk(&out);
|
||||||
for (e = (char*) q + out.index, n = 0; n < out.length; n++)
|
|
||||||
printf("%c", *e);
|
|
||||||
pa_memblock_release(out.memblock);
|
|
||||||
|
|
||||||
pa_memblock_unref(out.memblock);
|
pa_memblock_unref(out.memblock);
|
||||||
pa_memblockq_drop(bq, out.length);
|
pa_memblockq_drop(bq, out.length);
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +90,7 @@ int main(int argc, char *argv[]) {
|
||||||
silence.index = 0;
|
silence.index = 0;
|
||||||
silence.length = pa_memblock_get_length(silence.memblock);
|
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);
|
assert(bq);
|
||||||
|
|
||||||
chunk1.memblock = pa_memblock_new_fixed(p, (char*) "11", 2, 1);
|
chunk1.memblock = pa_memblock_new_fixed(p, (char*) "11", 2, 1);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue