mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -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? */
 | 
			
		||||
    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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue