X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmisc%2Fblock.c;h=0cf8345ddba3151a39eaefb28a73f8c7fa72cf11;hb=4feb30d653fd402f5fd27f6df7fcd24f0c0d20c3;hp=9d07f63fa4d96d72734a0b7f5780093735aa862f;hpb=d2845b70dc546d14744fb260f469c30b329e4453;p=vlc diff --git a/src/misc/block.c b/src/misc/block.c index 9d07f63fa4..0cf8345ddb 100644 --- a/src/misc/block.c +++ b/src/misc/block.c @@ -25,117 +25,76 @@ * Preamble *****************************************************************************/ #include -#include #include #include "vlc_block.h" +/***************************************************************************** + * Block functions. + *****************************************************************************/ /* private */ struct block_sys_t { - vlc_mutex_t lock; - uint8_t *p_allocated_buffer; int i_allocated_buffer; - - vlc_bool_t b_modify; /* has it been put in modified state */ - int i_duplicated; /* how many times has the content been - * duplicated */ - }; -static void BlockRelease( block_t *p_block ) -{ - vlc_mutex_lock( &p_block->p_sys->lock ); - - p_block->p_sys->i_duplicated--; - if( p_block->p_sys->i_duplicated < 0 ) - { - vlc_mutex_unlock( &p_block->p_sys->lock ); - vlc_mutex_destroy( &p_block->p_sys->lock ); - free( p_block->p_sys->p_allocated_buffer ); - free( p_block->p_sys ); - free( p_block ); - - return; - } - - vlc_mutex_unlock( &p_block->p_sys->lock ); - free( p_block ); -} - -static block_t *__BlockDupContent( block_t *p_block ) -{ - block_t *p_dup; - - p_dup = block_New( p_block->p_manager, p_block->i_buffer ); - memcpy( p_dup->p_buffer, p_block->p_buffer, p_block->i_buffer ); - p_dup->i_flags = p_block->i_flags; - p_dup->i_pts = p_block->i_pts; - p_dup->i_dts = p_block->i_dts; - p_dup->i_length = p_block->i_length; - p_dup->i_rate = p_block->i_rate; +#define BLOCK_PADDING_SIZE 32 +static void BlockRelease( block_t * ); - return p_dup; -} - -static block_t *BlockModify( block_t *p_block, vlc_bool_t b_will_modify ) +block_t *__block_New( vlc_object_t *p_obj, int i_size ) { - block_t *p_mod = p_block; /* by default */ - - vlc_mutex_lock( &p_block->p_sys->lock ); + /* We do only one malloc + * TODO bench if doing 2 malloc but keeping a pool of buffer is better + * 16 -> align on 16 + * 2*BLOCK_PADDING_SIZE -> pre + post padding + */ + const int i_alloc = i_size + 2*BLOCK_PADDING_SIZE + 16; + block_t *p_block = malloc( sizeof( block_t ) + sizeof( block_sys_t ) + i_alloc ); + block_sys_t *p_sys; - if( p_block->p_sys->b_modify == b_will_modify ) - { - vlc_mutex_unlock( &p_block->p_sys->lock ); - return p_block; - } + if( p_block == NULL ) + return NULL; - if( p_block->p_sys->i_duplicated == 0 ) - { - p_block->p_sys->b_modify = b_will_modify; - vlc_mutex_unlock( &p_block->p_sys->lock ); - return p_block; - } - - /* FIXME we could avoid that - * we just need to create a new p_sys with new mem FIXME */ - p_mod = __BlockDupContent( p_block ); - vlc_mutex_unlock( &p_block->p_sys->lock ); + /* Fill opaque data */ + p_sys = (block_sys_t*)( (uint8_t*)p_block + sizeof( block_t ) ); + p_sys->i_allocated_buffer = i_alloc; + p_sys->p_allocated_buffer = (uint8_t*)p_block + sizeof( block_t ) + sizeof( block_sys_t ); - BlockRelease( p_block ); + /* Fill all fields */ + p_block->p_next = NULL; + p_block->i_flags = 0; + p_block->i_pts = 0; + p_block->i_dts = 0; + p_block->i_length = 0; + p_block->i_rate = 0; + p_block->i_buffer = i_size; + p_block->p_buffer = &p_sys->p_allocated_buffer[32+15-((long)p_sys->p_allocated_buffer % 16 )]; + p_block->pf_release = BlockRelease; + p_block->p_manager = VLC_OBJECT( p_obj->p_vlc ); /* Is ok, as no comunication between p_vlc */ + p_block->p_sys = p_sys; - return p_mod; + return p_block; } -static block_t *BlockDuplicate( block_t *p_block ) +block_t *block_Realloc( block_t *p_block, int i_prebody, int i_body ) { - block_t *p_dup; + int i_buffer_size; - vlc_mutex_lock( &p_block->p_sys->lock ); - if( !p_block->p_sys->b_modify ) + if( p_block->pf_release != BlockRelease ) { - p_block->p_sys->i_duplicated++; - vlc_mutex_unlock( &p_block->p_sys->lock ); - p_dup = block_NewEmpty(); - memcpy( p_dup, p_block, sizeof( block_t ) ); - p_dup->p_next = NULL; - return p_dup; + /* Special case when pf_release if overloaded + * TODO if used one day, them implement it in a smarter way */ + block_t *p_dup = block_Duplicate( p_block ); + block_Release( p_block ); + + p_block = p_dup; } - p_dup = __BlockDupContent( p_block ); - vlc_mutex_unlock( &p_block->p_sys->lock ); - return p_dup; -} - -static block_t *BlockRealloc( block_t *p_block, int i_prebody, int i_body ) -{ - int i_buffer_size = i_prebody + i_body; + i_buffer_size = i_prebody + i_body; if( i_body < 0 || i_buffer_size <= 0 ) return NULL; - vlc_mutex_lock( &p_block->p_sys->lock ); - if( i_prebody < ( p_block->p_buffer - p_block->p_sys->p_allocated_buffer + p_block->p_sys->i_allocated_buffer ) || p_block->p_buffer - i_prebody > p_block->p_sys->p_allocated_buffer ) @@ -164,174 +123,19 @@ static block_t *BlockRealloc( block_t *p_block, int i_prebody, int i_body ) memcpy( p_rea->p_buffer + i_prebody, p_block->p_buffer, __MIN( p_block->i_buffer, p_rea->i_buffer - i_prebody ) ); - vlc_mutex_unlock( &p_block->p_sys->lock ); block_Release( p_block ); return p_rea; } - vlc_mutex_unlock( &p_block->p_sys->lock ); - return p_block; } -/***************************************************************************** - * Standard block management - * - *****************************************************************************/ -/* to be used by other block management */ -block_t *block_NewEmpty( void ) -{ - block_t *p_block; - - p_block = malloc( sizeof( block_t ) ); - memset( p_block, 0, sizeof( block_t ) ); - - p_block->p_next = NULL; - p_block->i_flags = 0; - p_block->i_pts = 0; - p_block->i_dts = 0; - p_block->i_length = 0; - p_block->i_rate = 0; - - p_block->i_buffer = 0; - p_block->p_buffer = NULL; - - p_block->pf_release = NULL; - p_block->pf_duplicate = NULL; - p_block->pf_modify = NULL; - p_block->pf_realloc = NULL; - - p_block->p_manager = NULL; - p_block->p_sys = NULL; - return p_block; -} - -block_t *__block_New( vlc_object_t *p_obj, int i_size ) -{ - block_t *p_block; - block_sys_t *p_sys; - - p_block = block_NewEmpty(); - - p_block->pf_release = BlockRelease; - p_block->pf_duplicate = BlockDuplicate; - p_block->pf_modify = BlockModify; - p_block->pf_realloc = BlockRealloc; - - /* that should be ok (no comunication between multiple p_vlc) */ - p_block->p_manager = VLC_OBJECT( p_obj->p_vlc ); - - p_block->p_sys = p_sys = malloc( sizeof( block_sys_t ) ); - vlc_mutex_init( p_obj, &p_sys->lock ); - - /* XXX align on 16 and add 32 prebuffer/posbuffer bytes */ - p_sys->i_allocated_buffer = i_size + 32 + 32 + 16; - p_sys->p_allocated_buffer = malloc( p_sys->i_allocated_buffer ); - p_block->i_buffer = i_size; - p_block->p_buffer = &p_sys->p_allocated_buffer[32+15-((long)p_sys->p_allocated_buffer % 16 )]; - - p_sys->i_duplicated = 0; - p_sys->b_modify = VLC_TRUE; - - return p_block; -} - -void block_ChainAppend( block_t **pp_list, block_t *p_block ) -{ - if( *pp_list == NULL ) - { - *pp_list = p_block; - } - else - { - block_t *p = *pp_list; - - while( p->p_next ) - { - p = p->p_next; - } - p->p_next = p_block; - } -} - -void block_ChainLastAppend( block_t ***ppp_last, block_t *p_block ) -{ - block_t *p_last = p_block; - - /* Append the block */ - **ppp_last = p_block; - - /* Update last pointer */ - while( p_last->p_next ) p_last = p_last->p_next; - *ppp_last = &p_last->p_next; -} - -void block_ChainRelease( block_t *p_block ) -{ - while( p_block ) - { - block_t *p_next; - p_next = p_block->p_next; - p_block->pf_release( p_block ); - p_block = p_next; - } -} - -int block_ChainExtract( block_t *p_list, void *p_data, int i_max ) +static void BlockRelease( block_t *p_block ) { - block_t *b; - int i_total = 0; - uint8_t *p = p_data; - - for( b = p_list; b != NULL; b = b->p_next ) - { - int i_copy; - - i_copy = __MIN( i_max, b->i_buffer ); - if( i_copy > 0 ) - { - memcpy( p, b->p_buffer, i_copy ); - i_max -= i_copy; - i_total += i_copy; - p += i_copy; - - if( i_max == 0 ) - { - return i_total; - } - } - } - return i_total; + free( p_block ); } -block_t *block_ChainGather( block_t *p_list ) -{ - int i_total = 0; - block_t *b, *g; - - if( p_list->p_next == NULL ) - { - /* only one, so no need */ - return p_list; - } - - for( b = p_list; b != NULL; b = b->p_next ) - { - i_total += b->i_buffer; - } - - g = block_New( p_list->p_manager, i_total ); - block_ChainExtract( p_list, g->p_buffer, g->i_buffer ); - - g->i_flags = p_list->i_flags; - g->i_pts = p_list->i_pts; - g->i_dts = p_list->i_dts; - - /* free p_list */ - block_ChainRelease( p_list ); - return g; -} /***************************************************************************** * block_fifo_t management @@ -343,7 +147,7 @@ block_fifo_t *__block_FifoNew( vlc_object_t *p_obj ) p_fifo = malloc( sizeof( vlc_object_t ) ); vlc_mutex_init( p_obj, &p_fifo->lock ); vlc_cond_init( p_obj, &p_fifo->wait ); - p_fifo->i_depth = 0; + p_fifo->i_depth = p_fifo->i_size = 0; p_fifo->p_first = NULL; p_fifo->pp_last = &p_fifo->p_first; @@ -372,7 +176,7 @@ void block_FifoEmpty( block_fifo_t *p_fifo ) b = p_next; } - p_fifo->i_depth = 0; + p_fifo->i_depth = p_fifo->i_size = 0; p_fifo->p_first = NULL; p_fifo->pp_last = &p_fifo->p_first; vlc_mutex_unlock( &p_fifo->lock ); @@ -390,6 +194,7 @@ int block_FifoPut( block_fifo_t *p_fifo, block_t *p_block ) *p_fifo->pp_last = p_block; p_fifo->pp_last = &p_block->p_next; p_fifo->i_depth++; + p_fifo->i_size += p_block->i_buffer; p_block = p_block->p_next; @@ -420,6 +225,7 @@ block_t *block_FifoGet( block_fifo_t *p_fifo ) p_fifo->p_first = b->p_next; p_fifo->i_depth--; + p_fifo->i_size -= b->i_buffer; if( p_fifo->p_first == NULL ) { @@ -429,7 +235,7 @@ block_t *block_FifoGet( block_fifo_t *p_fifo ) vlc_mutex_unlock( &p_fifo->lock ); b->p_next = NULL; - return( b ); + return b; } block_t *block_FifoShow( block_fifo_t *p_fifo )