mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	Client API: Add pa_stream_write_ext_free() function.
New function allows to pass data pointer that is a member of the outer structure that need to be freed too when data is not needed anymore. Signed-off-by: Lukasz Marek <lukasz.m.luki2@gmail.com>
This commit is contained in:
		
							parent
							
								
									594da41d07
								
							
						
					
					
						commit
						78ca8cfc96
					
				
					 5 changed files with 41 additions and 7 deletions
				
			
		| 
						 | 
					@ -330,6 +330,7 @@ pa_stream_update_sample_rate;
 | 
				
			||||||
pa_stream_update_timing_info;
 | 
					pa_stream_update_timing_info;
 | 
				
			||||||
pa_stream_writable_size;
 | 
					pa_stream_writable_size;
 | 
				
			||||||
pa_stream_write;
 | 
					pa_stream_write;
 | 
				
			||||||
 | 
					pa_stream_write_ext_free;
 | 
				
			||||||
pa_strerror;
 | 
					pa_strerror;
 | 
				
			||||||
pa_sw_cvolume_divide;
 | 
					pa_sw_cvolume_divide;
 | 
				
			||||||
pa_sw_cvolume_divide_scalar;
 | 
					pa_sw_cvolume_divide_scalar;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1464,11 +1464,12 @@ int pa_stream_cancel_write(
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pa_stream_write(
 | 
					int pa_stream_write_ext_free(
 | 
				
			||||||
        pa_stream *s,
 | 
					        pa_stream *s,
 | 
				
			||||||
        const void *data,
 | 
					        const void *data,
 | 
				
			||||||
        size_t length,
 | 
					        size_t length,
 | 
				
			||||||
        pa_free_cb_t free_cb,
 | 
					        pa_free_cb_t free_cb,
 | 
				
			||||||
 | 
					        void *free_cb_data,
 | 
				
			||||||
        int64_t offset,
 | 
					        int64_t offset,
 | 
				
			||||||
        pa_seek_mode_t seek) {
 | 
					        pa_seek_mode_t seek) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1519,7 +1520,7 @@ int pa_stream_write(
 | 
				
			||||||
            chunk.index = 0;
 | 
					            chunk.index = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (free_cb && !pa_pstream_get_shm(s->context->pstream)) {
 | 
					            if (free_cb && !pa_pstream_get_shm(s->context->pstream)) {
 | 
				
			||||||
                chunk.memblock = pa_memblock_new_user(s->context->mempool, (void*) t_data, t_length, free_cb, 1);
 | 
					                chunk.memblock = pa_memblock_new_user(s->context->mempool, (void*) t_data, t_length, free_cb, free_cb_data, 1);
 | 
				
			||||||
                chunk.length = t_length;
 | 
					                chunk.length = t_length;
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                void *d;
 | 
					                void *d;
 | 
				
			||||||
| 
						 | 
					@ -1544,7 +1545,7 @@ int pa_stream_write(
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (free_cb && pa_pstream_get_shm(s->context->pstream))
 | 
					        if (free_cb && pa_pstream_get_shm(s->context->pstream))
 | 
				
			||||||
            free_cb((void*) data);
 | 
					            free_cb(free_cb_data);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* This is obviously wrong since we ignore the seeking index . But
 | 
					    /* This is obviously wrong since we ignore the seeking index . But
 | 
				
			||||||
| 
						 | 
					@ -1591,6 +1592,17 @@ int pa_stream_write(
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int pa_stream_write(
 | 
				
			||||||
 | 
					        pa_stream *s,
 | 
				
			||||||
 | 
					        const void *data,
 | 
				
			||||||
 | 
					        size_t length,
 | 
				
			||||||
 | 
					        pa_free_cb_t free_cb,
 | 
				
			||||||
 | 
					        int64_t offset,
 | 
				
			||||||
 | 
					        pa_seek_mode_t seek) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return pa_stream_write_ext_free(s, data, length, free_cb, (void*) data, offset, seek);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pa_stream_peek(pa_stream *s, const void **data, size_t *length) {
 | 
					int pa_stream_peek(pa_stream *s, const void **data, size_t *length) {
 | 
				
			||||||
    pa_assert(s);
 | 
					    pa_assert(s);
 | 
				
			||||||
    pa_assert(PA_REFCNT_VALUE(s) >= 1);
 | 
					    pa_assert(PA_REFCNT_VALUE(s) >= 1);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -554,6 +554,17 @@ int pa_stream_write(
 | 
				
			||||||
        int64_t offset,          /**< Offset for seeking, must be 0 for upload streams */
 | 
					        int64_t offset,          /**< Offset for seeking, must be 0 for upload streams */
 | 
				
			||||||
        pa_seek_mode_t seek      /**< Seek mode, must be PA_SEEK_RELATIVE for upload streams */);
 | 
					        pa_seek_mode_t seek      /**< Seek mode, must be PA_SEEK_RELATIVE for upload streams */);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Function does exactly the same as pa_stream_write() with the difference
 | 
				
			||||||
 | 
					 *  that free_cb_data is passed to free_cb instead of data. \since 6.0 */
 | 
				
			||||||
 | 
					int pa_stream_write_ext_free(
 | 
				
			||||||
 | 
					        pa_stream *p             /**< The stream to use */,
 | 
				
			||||||
 | 
					        const void *data         /**< The data to write */,
 | 
				
			||||||
 | 
					        size_t nbytes            /**< The length of the data to write in bytes */,
 | 
				
			||||||
 | 
					        pa_free_cb_t free_cb     /**< A cleanup routine for the data or NULL to request an internal copy */,
 | 
				
			||||||
 | 
					        void *free_cb_data       /**< Argument passed to free_cb function */,
 | 
				
			||||||
 | 
					        int64_t offset           /**< Offset for seeking, must be 0 for upload streams */,
 | 
				
			||||||
 | 
					        pa_seek_mode_t seek      /**< Seek mode, must be PA_SEEK_RELATIVE for upload streams */);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Read the next fragment from the buffer (for recording streams).
 | 
					/** Read the next fragment from the buffer (for recording streams).
 | 
				
			||||||
 * If there is data at the current read index, \a data will point to
 | 
					 * If there is data at the current read index, \a data will point to
 | 
				
			||||||
 * the actual data and \a nbytes will contain the size of the data in
 | 
					 * the actual data and \a nbytes will contain the size of the data in
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,6 +83,8 @@ struct pa_memblock {
 | 
				
			||||||
        struct {
 | 
					        struct {
 | 
				
			||||||
            /* If type == PA_MEMBLOCK_USER this points to a function for freeing this memory block */
 | 
					            /* If type == PA_MEMBLOCK_USER this points to a function for freeing this memory block */
 | 
				
			||||||
            pa_free_cb_t free_cb;
 | 
					            pa_free_cb_t free_cb;
 | 
				
			||||||
 | 
					            /* If type == PA_MEMBLOCK_USER this is passed as free_cb argument */
 | 
				
			||||||
 | 
					            void *free_cb_data;
 | 
				
			||||||
        } user;
 | 
					        } user;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        struct {
 | 
					        struct {
 | 
				
			||||||
| 
						 | 
					@ -402,7 +404,13 @@ pa_memblock *pa_memblock_new_fixed(pa_mempool *p, void *d, size_t length, bool r
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* No lock necessary */
 | 
					/* No lock necessary */
 | 
				
			||||||
pa_memblock *pa_memblock_new_user(pa_mempool *p, void *d, size_t length, pa_free_cb_t free_cb, bool read_only) {
 | 
					pa_memblock *pa_memblock_new_user(
 | 
				
			||||||
 | 
					        pa_mempool *p,
 | 
				
			||||||
 | 
					        void *d,
 | 
				
			||||||
 | 
					        size_t length,
 | 
				
			||||||
 | 
					        pa_free_cb_t free_cb,
 | 
				
			||||||
 | 
					        void *free_cb_data,
 | 
				
			||||||
 | 
					        bool read_only) {
 | 
				
			||||||
    pa_memblock *b;
 | 
					    pa_memblock *b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_assert(p);
 | 
					    pa_assert(p);
 | 
				
			||||||
| 
						 | 
					@ -425,6 +433,7 @@ pa_memblock *pa_memblock_new_user(pa_mempool *p, void *d, size_t length, pa_free
 | 
				
			||||||
    pa_atomic_store(&b->please_signal, 0);
 | 
					    pa_atomic_store(&b->please_signal, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    b->per_type.user.free_cb = free_cb;
 | 
					    b->per_type.user.free_cb = free_cb;
 | 
				
			||||||
 | 
					    b->per_type.user.free_cb_data = free_cb_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stat_add(b);
 | 
					    stat_add(b);
 | 
				
			||||||
    return b;
 | 
					    return b;
 | 
				
			||||||
| 
						 | 
					@ -536,7 +545,7 @@ static void memblock_free(pa_memblock *b) {
 | 
				
			||||||
    switch (b->type) {
 | 
					    switch (b->type) {
 | 
				
			||||||
        case PA_MEMBLOCK_USER :
 | 
					        case PA_MEMBLOCK_USER :
 | 
				
			||||||
            pa_assert(b->per_type.user.free_cb);
 | 
					            pa_assert(b->per_type.user.free_cb);
 | 
				
			||||||
            b->per_type.user.free_cb(pa_atomic_ptr_load(&b->data));
 | 
					            b->per_type.user.free_cb(b->per_type.user.free_cb_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* Fall through */
 | 
					            /* Fall through */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -670,6 +679,7 @@ static void memblock_make_local(pa_memblock *b) {
 | 
				
			||||||
    /* Humm, not enough space in the pool, so lets allocate the memory with malloc() */
 | 
					    /* Humm, not enough space in the pool, so lets allocate the memory with malloc() */
 | 
				
			||||||
    b->per_type.user.free_cb = pa_xfree;
 | 
					    b->per_type.user.free_cb = pa_xfree;
 | 
				
			||||||
    pa_atomic_ptr_store(&b->data, pa_xmemdup(pa_atomic_ptr_load(&b->data), b->length));
 | 
					    pa_atomic_ptr_store(&b->data, pa_xmemdup(pa_atomic_ptr_load(&b->data), b->length));
 | 
				
			||||||
 | 
					    b->per_type.user.free_cb_data = pa_atomic_ptr_load(&b->data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    b->type = PA_MEMBLOCK_USER;
 | 
					    b->type = PA_MEMBLOCK_USER;
 | 
				
			||||||
    b->read_only = false;
 | 
					    b->read_only = false;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,10 +85,10 @@ pa_memblock *pa_memblock_new(pa_mempool *, size_t length);
 | 
				
			||||||
pa_memblock *pa_memblock_new_pool(pa_mempool *, size_t length);
 | 
					pa_memblock *pa_memblock_new_pool(pa_mempool *, size_t length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Allocate a new memory block of type PA_MEMBLOCK_USER */
 | 
					/* Allocate a new memory block of type PA_MEMBLOCK_USER */
 | 
				
			||||||
pa_memblock *pa_memblock_new_user(pa_mempool *, void *data, size_t length, pa_free_cb_t free_cb, bool read_only);
 | 
					pa_memblock *pa_memblock_new_user(pa_mempool *, void *data, size_t length, pa_free_cb_t free_cb, void *free_cb_data, bool read_only);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* A special case of pa_memblock_new_user: take a memory buffer previously allocated with pa_xmalloc()  */
 | 
					/* A special case of pa_memblock_new_user: take a memory buffer previously allocated with pa_xmalloc()  */
 | 
				
			||||||
#define pa_memblock_new_malloced(p,data,length) pa_memblock_new_user(p, data, length, pa_xfree, 0)
 | 
					#define pa_memblock_new_malloced(p,data,length) pa_memblock_new_user(p, data, length, pa_xfree, data, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Allocate a new memory block of type PA_MEMBLOCK_FIXED */
 | 
					/* Allocate a new memory block of type PA_MEMBLOCK_FIXED */
 | 
				
			||||||
pa_memblock *pa_memblock_new_fixed(pa_mempool *, void *data, size_t length, bool read_only);
 | 
					pa_memblock *pa_memblock_new_fixed(pa_mempool *, void *data, size_t length, bool read_only);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue