Changeset adff2a8501514d36861150435134522fbef78c33

Show
Ignore:
Timestamp:
16/04/01 14:34:28 (8 years ago)
Author:
Cyril Deguet <asmax@videolan.org>
git-committer:
Cyril Deguet <asmax@videolan.org> 987424468 +0000
git-parent:

[6116299e395a1d8a27c1a7280749a0a7d59d0d66]

git-author:
Cyril Deguet <asmax@videolan.org> 987424468 +0000
Message:

Re-added the new packet allocation method in PS input, using packet caches.
With warning level 1, you can see when a packet is allocated or freed; the
goal is to never call 'malloc' nor 'free', except at the beginning of the
stream.
The size of the different caches can be adjusted in plugins/mpeg/input_ps.h.
If 'free' is called too often, it means that a cache is too small, so try
to increase its size.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • include/input_ext-dec.h

    rf3f860c radff2a8  
    33 ***************************************************************************** 
    44 * Copyright (C) 1999, 2000 VideoLAN 
    5  * $Id: input_ext-dec.h,v 1.27 2001/04/05 16:37:15 asmax Exp $ 
     5 * $Id: input_ext-dec.h,v 1.28 2001/04/16 12:34:28 asmax Exp $ 
    66 * 
    77 * Authors: Christophe Massiot <massiot@via.ecp.fr> 
     
    3434    /* Nothing before this line, the code relies on that */ 
    3535    byte_t *                p_buffer;                     /* raw data packet */ 
     36    long                    l_size;                           /* buffer size */ 
    3637 
    3738    /* Decoders information */ 
  • plugins/mpeg/input_ps.c

    rf11b9a9 radff2a8  
    33 ***************************************************************************** 
    44 * Copyright (C) 1998, 1999, 2000 VideoLAN 
    5  * $Id: input_ps.c,v 1.14 2001/04/13 05:36:12 stef Exp $ 
     5 * $Id: input_ps.c,v 1.15 2001/04/16 12:34:28 asmax Exp $ 
    66 * 
    77 * Authors: Christophe Massiot <massiot@via.ecp.fr> 
     
    144144{ 
    145145    thread_ps_data_t *  p_method; 
     146    packet_cache_t *    p_packet_cache; 
    146147 
    147148    if( (p_method = 
     
    152153        return; 
    153154    } 
    154  
    155155    p_input->p_plugin_data = (void *)p_method; 
    156     p_input->p_method_data = NULL; 
    157  
     156     
     157    /* creates the packet cache structure */ 
     158    p_packet_cache = malloc( sizeof(packet_cache_t) ); 
     159    if ( p_packet_cache == NULL ) 
     160    { 
     161        intf_ErrMsg( "Out of memory" ); 
     162        p_input->b_error = 1; 
     163        return; 
     164    } 
     165    p_input->p_method_data = (void *)p_packet_cache; 
     166     
     167    /* allocates the data cache */ 
     168    p_packet_cache->data.p_stack = malloc( DATA_CACHE_SIZE *  
     169        sizeof(data_packet_t*) ); 
     170    if ( p_packet_cache->data.p_stack == NULL ) 
     171    { 
     172        intf_ErrMsg( "Out of memory" ); 
     173        p_input->b_error = 1; 
     174        return; 
     175    } 
     176    p_packet_cache->data.l_index = 0; 
     177     
     178    /* allocates the PES cache */ 
     179    p_packet_cache->pes.p_stack = malloc( PES_CACHE_SIZE *  
     180        sizeof(pes_packet_t*) ); 
     181    if ( p_packet_cache->pes.p_stack == NULL ) 
     182    { 
     183        intf_ErrMsg( "Out of memory" ); 
     184        p_input->b_error = 1; 
     185        return; 
     186    } 
     187    p_packet_cache->pes.l_index = 0; 
     188     
     189    /* allocates the small buffer cache */ 
     190    p_packet_cache->small.p_stack = malloc( SMALL_CACHE_SIZE *  
     191        sizeof(packet_buffer_t) ); 
     192    if ( p_packet_cache->small.p_stack == NULL ) 
     193    { 
     194        intf_ErrMsg( "Out of memory" ); 
     195        p_input->b_error = 1; 
     196        return; 
     197    } 
     198    p_packet_cache->small.l_index = 0; 
     199     
     200    /* allocates the large buffer cache */ 
     201    p_packet_cache->large.p_stack = malloc( LARGE_CACHE_SIZE *  
     202        sizeof(packet_buffer_t) ); 
     203    if ( p_packet_cache->large.p_stack == NULL ) 
     204    { 
     205        intf_ErrMsg( "Out of memory" ); 
     206        p_input->b_error = 1; 
     207        return; 
     208    } 
     209    p_packet_cache->large.l_index = 0; 
     210     
    158211    /* Re-open the socket as a buffered FILE stream */ 
    159212    if( (p_method->stream = fdopen( p_input->i_handle, "r" )) == NULL ) 
     
    215268        rewind( p_method->stream ); 
    216269        vlc_mutex_lock( &p_input->stream.stream_lock ); 
    217  
    218         /* file input method */ 
    219         p_input->stream.i_method = INPUT_METHOD_FILE; 
    220  
    221270        p_input->stream.p_selected_area->i_tell = 0; 
    222271        if( p_demux_data->b_has_PSM ) 
     
    297346        /* The programs will be added when we read them. */ 
    298347        vlc_mutex_lock( &p_input->stream.stream_lock ); 
    299  
    300         /* file input method */ 
    301         p_input->stream.i_method = INPUT_METHOD_FILE; 
    302  
    303348        p_input->stream.pp_programs[0]->b_is_ok = 0; 
    304349        vlc_mutex_unlock( &p_input->stream.stream_lock ); 
     
    430475 
    431476        /* Fetch a packet of the appropriate size. */ 
    432         if( (p_data = NewPacket( p_input, i_packet_size + 6 )) == NULL ) 
     477        if( (p_data = NewPacket( p_input->p_method_data, i_packet_size + 6 ))  
     478            == NULL ) 
    433479        { 
    434480            intf_ErrMsg( "Out of memory" ); 
     
    491537 * NewPacket: allocates a data packet 
    492538 *****************************************************************************/ 
    493 static struct data_packet_s * NewPacket( void * p_garbage, 
    494                                          size_t i_size ) 
    495 
    496     data_packet_t * p_data; 
    497  
     539static struct data_packet_s * NewPacket( void * p_packet_cache, 
     540                                         size_t l_size ) 
     541{  
     542    packet_cache_t *   p_cache; 
     543    data_packet_t *    p_data; 
     544    long               l_index; 
     545 
     546    if ( (p_cache = (packet_cache_t *)p_packet_cache) == NULL ) 
     547    { 
     548        intf_ErrMsg( "PPacket cache not initialized" ); 
     549        return NULL; 
     550    } 
    498551    /* Safety check */ 
    499     if( i_size > INPUT_MAX_PACKET_SIZE ) 
    500     { 
    501         intf_ErrMsg( "Packet too big (%d)", i_size ); 
     552    if( l_size > INPUT_MAX_PACKET_SIZE ) 
     553    { 
     554        intf_ErrMsg( "Packet too big (%d)", l_size ); 
    502555        return NULL; 
    503556    } 
    504557 
    505     if( (p_data = (data_packet_t *)malloc( sizeof(data_packet_t) )) == NULL ) 
    506     { 
    507         intf_DbgMsg( "Out of memory" ); 
    508         return NULL; 
    509     } 
    510  
    511     if( (p_data->p_buffer = (byte_t *)malloc( i_size )) == NULL ) 
    512     { 
    513         intf_DbgMsg( "Out of memory" ); 
    514         free( p_data ); 
    515         return NULL; 
     558    /* Checks whether the data cache is empty */ 
     559    if( p_cache->data.l_index == 0 ) 
     560    { 
     561        /* Allocates a new packet */ 
     562        if ( (p_data = malloc( sizeof(data_packet_t) )) == NULL ) 
     563        { 
     564            intf_DbgMsg( "Out of memory" ); 
     565            return NULL; 
     566        } 
     567        intf_WarnMsg( 1, "PS input: data packet allocated" ); 
     568    } 
     569    else 
     570    { 
     571        /* Takes the packet out from the cache */ 
     572        if( (p_data = p_cache->data.p_stack[ -- p_cache->data.l_index ])  
     573            == NULL ) 
     574        { 
     575            intf_DbgMsg( "NULL packet in the data cache" ); 
     576            return NULL; 
     577        } 
     578    } 
     579     
     580    if( l_size < MAX_SMALL_SIZE ) 
     581    { 
     582        /* Small buffer */   
     583    
     584        /* Checks whether the buffer cache is empty */ 
     585        if( p_cache->small.l_index == 0 ) 
     586        { 
     587            /* Allocates a new packet */ 
     588            if ( (p_data->p_buffer = malloc( l_size )) == NULL ) 
     589            { 
     590                intf_DbgMsg( "Out of memory" ); 
     591                free( p_data ); 
     592                return NULL; 
     593            } 
     594            intf_WarnMsg( 1, "PS input: small buffer allocated" ); 
     595            p_data->l_size = l_size; 
     596        } 
     597        else 
     598        { 
     599            /* Takes the packet out from the cache */ 
     600            l_index = -- p_cache->small.l_index;     
     601            if( (p_data->p_buffer = p_cache->small.p_stack[l_index].p_data) 
     602                == NULL ) 
     603            { 
     604                intf_DbgMsg( "NULL packet in the small buffer cache" ); 
     605                free( p_data ); 
     606                return NULL; 
     607            } 
     608            /* Reallocates the packet if it is too small or too large */ 
     609            if( p_cache->small.p_stack[l_index].l_size < l_size || 
     610                p_cache->small.p_stack[l_index].l_size > 2*l_size ) 
     611            { 
     612                p_data->p_buffer = realloc( p_data->p_buffer, l_size ); 
     613                p_data->l_size = l_size; 
     614            } 
     615            else 
     616            { 
     617                p_data->l_size = p_cache->small.p_stack[l_index].l_size; 
     618            } 
     619        } 
     620    } 
     621    else 
     622    { 
     623        /* Large buffer */   
     624    
     625        /* Checks whether the buffer cache is empty */ 
     626        if( p_cache->large.l_index == 0 ) 
     627        { 
     628            /* Allocates a new packet */ 
     629            if ( (p_data->p_buffer = malloc( l_size )) == NULL ) 
     630            { 
     631                intf_DbgMsg( "Out of memory" ); 
     632                free( p_data ); 
     633                return NULL; 
     634            } 
     635            intf_WarnMsg( 1, "PS input: large buffer allocated" ); 
     636            p_data->l_size = l_size; 
     637        } 
     638        else 
     639        { 
     640            /* Takes the packet out from the cache */ 
     641            l_index = -- p_cache->large.l_index;     
     642            if( (p_data->p_buffer = p_cache->large.p_stack[l_index].p_data) 
     643                == NULL ) 
     644            { 
     645                intf_DbgMsg( "NULL packet in the small buffer cache" ); 
     646                free( p_data ); 
     647                return NULL; 
     648            } 
     649            /* Reallocates the packet if it is too small or too large */ 
     650            if( p_cache->large.p_stack[l_index].l_size < l_size || 
     651                p_cache->large.p_stack[l_index].l_size > 2*l_size ) 
     652            { 
     653                p_data->p_buffer = realloc( p_data->p_buffer, l_size ); 
     654                p_data->l_size = l_size; 
     655            } 
     656            else 
     657            { 
     658                p_data->l_size = p_cache->large.p_stack[l_index].l_size; 
     659            } 
     660        } 
    516661    } 
    517662 
     
    519664    p_data->p_next = NULL; 
    520665    p_data->b_discard_payload = 0; 
    521  
    522666    p_data->p_payload_start = p_data->p_buffer; 
    523     p_data->p_payload_end = p_data->p_buffer + i_size; 
     667    p_data->p_payload_end = p_data->p_buffer + l_size; 
    524668 
    525669    return( p_data ); 
    526 
     670     
     671
     672 
    527673 
    528674/***************************************************************************** 
    529675 * NewPES: allocates a pes packet 
    530676 *****************************************************************************/ 
    531 static pes_packet_t * NewPES( void * p_garbage ) 
    532 
    533     pes_packet_t * p_pes; 
    534  
    535     if( (p_pes = (pes_packet_t *)malloc( sizeof(pes_packet_t) )) == NULL ) 
    536     { 
    537         intf_DbgMsg( "Out of memory" ); 
     677static pes_packet_t * NewPES( void * p_packet_cache ) 
     678
     679    packet_cache_t *   p_cache; 
     680    pes_packet_t *     p_pes; 
     681 
     682    if ( (p_cache = (packet_cache_t *)p_packet_cache) == NULL ) 
     683    { 
     684        intf_ErrMsg( "Packet cache not initialized" ); 
    538685        return NULL; 
    539686    } 
    540  
     687    /* Checks whether the PES cache is empty */ 
     688    if( p_cache->pes.l_index == 0 ) 
     689    { 
     690        /* Allocates a new packet */ 
     691        if ( (p_pes = malloc( sizeof(pes_packet_t) )) == NULL ) 
     692        { 
     693            intf_DbgMsg( "Out of memory" ); 
     694            return NULL; 
     695        } 
     696        intf_WarnMsg( 1, "PS input: PES packet allocated" ); 
     697    } 
     698    else 
     699    { 
     700        /* Takes the packet out from the cache */ 
     701        if( (p_pes = p_cache->pes.p_stack[ -- p_cache->pes.l_index ])  
     702            == NULL ) 
     703        { 
     704            intf_DbgMsg( "NULL packet in the data cache" ); 
     705            return NULL; 
     706        } 
     707    } 
     708     
    541709    p_pes->b_data_alignment = p_pes->b_discontinuity = 
    542710        p_pes->i_pts = p_pes->i_dts = 0; 
     
    545713 
    546714    return( p_pes ); 
     715     
    547716} 
    548717 
     
    550719 * DeletePacket: deletes a data packet 
    551720 *****************************************************************************/ 
    552 static void DeletePacket( void * p_garbage, 
     721static void DeletePacket( void * p_packet_cache, 
    553722                          data_packet_t * p_data ) 
    554723{ 
    555     ASSERT(p_data); 
    556     ASSERT(p_data->p_buffer); 
    557     free( p_data->p_buffer ); 
    558     free( p_data ); 
     724    packet_cache_t *   p_cache; 
     725     
     726    if ( (p_cache = (packet_cache_t *)p_packet_cache) == NULL ) 
     727    { 
     728        intf_ErrMsg( "Packet cache not initialized" ); 
     729        return; 
     730    } 
     731 
     732    ASSERT( p_data ); 
     733 
     734    /* Checks whether the data cache is full */ 
     735    if ( p_cache->data.l_index < DATA_CACHE_SIZE ) 
     736    { 
     737        /* Cache not full: store the packet in it */ 
     738        p_cache->data.p_stack[ p_cache->data.l_index ++ ] = p_data; 
     739        /* Small buffer or large buffer? */ 
     740        if ( p_data->l_size < MAX_SMALL_SIZE ) 
     741        { 
     742            /* Checks whether the small buffer cache is full */ 
     743            if ( p_cache->small.l_index < SMALL_CACHE_SIZE ) 
     744            { 
     745                p_cache->small.p_stack[ p_cache->small.l_index ].l_size =  
     746                    p_data->l_size; 
     747                p_cache->small.p_stack[ p_cache->small.l_index ++ ].p_data =  
     748                    p_data->p_buffer; 
     749            } 
     750            else 
     751            { 
     752                ASSERT( p_data->p_buffer ); 
     753                free( p_data->p_buffer ); 
     754                intf_WarnMsg( 1, "PS input: small buffer freed" ); 
     755            } 
     756        } 
     757        else 
     758        { 
     759            /* Checks whether the large buffer cache is full */ 
     760            if ( p_cache->large.l_index < LARGE_CACHE_SIZE ) 
     761            { 
     762                p_cache->large.p_stack[ p_cache->large.l_index ].l_size =  
     763                    p_data->l_size; 
     764                p_cache->large.p_stack[ p_cache->large.l_index ++ ].p_data =  
     765                    p_data->p_buffer; 
     766            } 
     767            else 
     768            { 
     769                ASSERT( p_data->p_buffer ); 
     770                free( p_data->p_buffer ); 
     771                intf_WarnMsg( 1, "PS input: large buffer freed" ); 
     772            } 
     773        } 
     774    } 
     775    else 
     776    { 
     777        /* Cache full: the packet must be freed */ 
     778        free( p_data->p_buffer ); 
     779        free( p_data ); 
     780        intf_WarnMsg( 1, "PS input: data packet freed" ); 
     781    } 
     782 
    559783} 
    560784 
     
    562786 * DeletePES: deletes a PES packet and associated data packets 
    563787 *****************************************************************************/ 
    564 static void DeletePES( void * p_garbage, pes_packet_t * p_pes ) 
    565 
     788static void DeletePES( void * p_packet_cache, pes_packet_t * p_pes ) 
     789
     790    packet_cache_t *    p_cache; 
    566791    data_packet_t *     p_data; 
    567792    data_packet_t *     p_next; 
    568793 
     794    if ( (p_cache = (packet_cache_t *)p_packet_cache) == NULL ) 
     795    { 
     796        intf_ErrMsg( "Packet cache not initialized" ); 
     797        return; 
     798    } 
     799 
     800    ASSERT( p_pes); 
     801 
    569802    p_data = p_pes->p_first; 
    570803 
     
    572805    { 
    573806        p_next = p_data->p_next; 
    574         free( p_data->p_buffer ); 
    575         free( p_data ); 
     807        DeletePacket( p_cache, p_data ); 
    576808        p_data = p_next; 
    577809    } 
    578810 
    579     free( p_pes ); 
    580 
    581  
     811    /* Checks whether the PES cache is full */ 
     812    if ( p_cache->pes.l_index < PES_CACHE_SIZE ) 
     813    { 
     814        /* Cache not full: store the packet in it */ 
     815        p_cache->pes.p_stack[ p_cache->pes.l_index ++ ] = p_pes; 
     816    } 
     817    else 
     818    { 
     819        /* Cache full: the packet must be freed */ 
     820        free( p_pes ); 
     821        intf_WarnMsg( 1, "PS input: PES packet freed" ); 
     822    } 
     823
     824 
  • plugins/mpeg/input_ps.h

    rf3f860c radff2a8  
    33 ***************************************************************************** 
    44 * Copyright (C) 1999, 2000 VideoLAN 
    5  * $Id: input_ps.h,v 1.4 2001/04/05 16:37:15 asmax Exp $ 
     5 * $Id: input_ps.h,v 1.5 2001/04/16 12:34:28 asmax Exp $ 
    66 * 
    77 * Authors: Christophe Massiot <massiot@via.ecp.fr> 
     8 *          Cyril Deguet <asmax@via.ecp.fr> 
    89 * 
    910 * This program is free software; you can redistribute it and/or modify 
     
    3031    FILE *                  stream; 
    3132} thread_ps_data_t; 
     33 
     34 
     35#define DATA_CACHE_SIZE 150 
     36#define PES_CACHE_SIZE 150 
     37#define SMALL_CACHE_SIZE 150 
     38#define LARGE_CACHE_SIZE 150 
     39#define MAX_SMALL_SIZE 50     // frontier between small and large packets 
     40 
     41typedef struct 
     42{ 
     43    data_packet_t **        p_stack; 
     44    long                    l_index; 
     45} data_packet_cache_t; 
     46 
     47 
     48typedef struct 
     49{ 
     50    pes_packet_t **         p_stack; 
     51    long                    l_index; 
     52} pes_packet_cache_t; 
     53 
     54 
     55typedef struct 
     56{ 
     57    byte_t *                p_data; 
     58    long                    l_size; 
     59} packet_buffer_t; 
     60 
     61 
     62typedef struct 
     63{ 
     64    packet_buffer_t *       p_stack; 
     65    long                    l_index; 
     66} small_buffer_cache_t; 
     67 
     68 
     69typedef struct 
     70{ 
     71    packet_buffer_t *       p_stack; 
     72    long                    l_index; 
     73} large_buffer_cache_t; 
     74 
     75 
     76typedef struct 
     77{ 
     78    data_packet_cache_t     data; 
     79    pes_packet_cache_t      pes; 
     80    small_buffer_cache_t    small; 
     81    large_buffer_cache_t    large; 
     82} packet_cache_t; 
     83 
     84