Changeset f8bf106d7ee040b01217ea54e8594f0677ba6b18

Show
Ignore:
Timestamp:
12/14/02 22:32:42 (6 years ago)
Author:
Laurent Aimar <fenrir@videolan.org>
git-committer:
Laurent Aimar <fenrir@videolan.org> 1039901562 +0000
git-parent:

[3f12686417f9fac0a3ba8ff83477381b0f39117a]

git-author:
Laurent Aimar <fenrir@videolan.org> 1039901562 +0000
Message:

Added stream output. (common work with titer).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • configure.ac.in

    r3f7b412 rf8bf106  
    136136        LDFLAGS_access_rtp="${LDFLAGS_access_rtp} -lws2_32" 
    137137        LDFLAGS_access_udp="${LDFLAGS_access_udp} -lws2_32" 
     138        LDFLAGS_access_output_udp="${LDFLAGS_access_output_udp} -lws2_32" 
    138139        LDFLAGS_rc="${LDFLAGS_rc} -lws2_32" 
    139140        LDFLAGS_sap="${LDFLAGS_sap} -lws2_32" 
     
    274275    LDFLAGS_access_udp="${LDFLAGS_access_udp} -lsocket" 
    275276    LDFLAGS_sap="${LDFLAGS_sap} -lsocket" 
     277    LDFLAGS_access_output_udp="${LDFLAGS_access_output_udp} -lsocket" 
    276278)]) 
    277279 
     
    865867[  --enable-release        activate extra optimizations (default disabled)]) 
    866868AM_CONDITIONAL(RELEASE, test "x${enable_release}" = "xyes") 
     869 
     870dnl 
     871dnl Stream output 
     872dnl 
     873AC_ARG_ENABLE(sout, 
     874  [  --enable-sout           Stream output modules (default enabled)]) 
     875if test "x${enable_sout}" != "xno" 
     876then 
     877  PLUGINS="${PLUGINS} access_output_dummy access_output_udp access_output_file" 
     878  PLUGINS="${PLUGINS} mux_ts mux_ps mux_dummy" 
     879  PLUGINS="${PLUGINS} packetizer_mpegaudio packetizer_mpegvideo packetizer_a52" 
     880  PLUGINS="${PLUGINS} packetizer_mpeg4video packetizer_copy" 
     881fi 
     882 
    867883 
    868884dnl 
  • include/stream_output.h

    r8d5c85f rf8bf106  
    33 ***************************************************************************** 
    44 * Copyright (C) 2002 VideoLAN 
    5  * $Id: stream_output.h,v 1.1 2002/08/12 22:12:50 massiot Exp $ 
     5 * $Id: stream_output.h,v 1.2 2002/12/14 21:32:41 fenrir Exp $ 
    66 * 
    77 * Authors: Christophe Massiot <massiot@via.ecp.fr> 
     8 *          Laurent Aimar <fenrir@via.ecp.fr> 
     9 *          Eric Petit <titer@videolan.org> 
    810 * 
    911 * This program is free software; you can redistribute it and/or modify 
     
    1113 * the Free Software Foundation; either version 2 of the License, or 
    1214 * (at your option) any later version. 
    13  *  
     15 * 
    1416 * This program is distributed in the hope that it will be useful, 
    1517 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
     
    2527 * sout_instance_t: stream output thread descriptor 
    2628 *****************************************************************************/ 
     29 
     30struct sout_buffer_t 
     31{ 
     32    size_t                  i_allocated_size; 
     33    byte_t                  *p_buffer; 
     34 
     35    size_t                  i_size; 
     36//    mtime_t                 i_date; 
     37    mtime_t                 i_length; 
     38 
     39    mtime_t                 i_dts; 
     40    mtime_t                 i_pts; 
     41 
     42    int                     i_bitrate; 
     43 
     44    struct sout_buffer_t    *p_next; 
     45}; 
     46 
     47struct sout_packet_format_t 
     48{ 
     49    int             i_cat;      // AUDIO_ES, VIDEO_ES, SPU_ES 
     50    vlc_fourcc_t    i_fourcc; 
     51 
     52    void            *p_format;  // WAVEFORMATEX or BITMAPINFOHEADER 
     53 
     54}; 
     55 
     56struct sout_fifo_t 
     57{ 
     58    vlc_mutex_t         lock;                         /* fifo data lock */ 
     59    vlc_cond_t          wait;         /* fifo data conditional variable */ 
     60 
     61    int                 i_depth; 
     62    sout_buffer_t       *p_first; 
     63    sout_buffer_t       **pp_last; 
     64}; 
     65 
     66struct sout_input_t 
     67{ 
     68    vlc_mutex_t             lock; 
     69 
     70    sout_instance_t         *p_sout; 
     71 
     72    sout_packet_format_t    input_format; 
     73    sout_fifo_t             *p_fifo; 
     74 
     75    void                    *p_mux_data; 
     76}; 
     77 
     78#define SOUT_METHOD_NONE        0x00 
     79#define SOUT_METHOD_FILE        0x10 
     80#define SOUT_METHOD_NETWORK     0x20 
     81 
    2782struct sout_instance_t 
    2883{ 
     
    3489    char * psz_name; 
    3590 
    36     module_t * p_access; 
    37     module_t * p_mux; 
     91    module_t                *p_access; 
     92    int                     i_method; 
     93    void                    *p_access_data; 
     94    int                     (* pf_write )( sout_instance_t *, sout_buffer_t * ); 
     95    int                     (* pf_seek  )( sout_instance_t *, off_t ); 
     96 
     97    module_t                *p_mux; 
     98    void                    *p_mux_data; 
     99    int                     (* pf_mux_addstream )( sout_instance_t *, 
     100                                                   sout_input_t * ); 
     101    int                     (* pf_mux_delstream )( sout_instance_t *, 
     102                                                   sout_input_t * ); 
     103    int                     (* pf_mux )          ( sout_instance_t * ); 
     104 
     105 
     106    vlc_mutex_t             lock; 
     107 
     108    int                     i_nb_inputs; 
     109    sout_input_t            **pp_inputs; 
    38110}; 
     111 
     112 
     113 
    39114 
    40115/***************************************************************************** 
     
    45120VLC_EXPORT( void,              sout_DeleteInstance, ( sout_instance_t * ) ); 
    46121 
    47 sout_fifo_t *   sout_CreateFifo     ( void ); 
    48 void            sout_DestroyFifo    ( sout_fifo_t * ); 
    49 void            sout_FreeFifo       ( sout_fifo_t * ); 
     122VLC_EXPORT( sout_fifo_t *,   sout_FifoCreate,     ( sout_instance_t * ) ); 
     123VLC_EXPORT( void,            sout_FifoDestroy,    ( sout_instance_t *, sout_fifo_t * ) ); 
     124VLC_EXPORT( void,            sout_FifoFree,       ( sout_instance_t *,sout_fifo_t * ) ); 
    50125 
     126VLC_EXPORT( void,            sout_FifoPut,        ( sout_fifo_t *, sout_buffer_t* ) ); 
     127VLC_EXPORT( sout_buffer_t *, sout_FifoGet,        ( sout_fifo_t * ) ); 
     128VLC_EXPORT( sout_buffer_t *, sout_FifoShow,       ( sout_fifo_t * ) ); 
     129 
     130 
     131#define sout_InputNew( a, b ) __sout_InputNew( VLC_OBJECT(a), b ) 
     132VLC_EXPORT( sout_input_t *, __sout_InputNew,       ( vlc_object_t *, sout_packet_format_t * ) ); 
     133VLC_EXPORT( int,            sout_InputDelete,      ( sout_input_t * ) ); 
     134VLC_EXPORT( int,            sout_InputSendBuffer,  ( sout_input_t *, sout_buffer_t* ) ); 
     135 
     136VLC_EXPORT( sout_buffer_t*, sout_BufferNew,    ( sout_instance_t *, size_t ) ); 
     137VLC_EXPORT( int,            sout_BufferRealloc,( sout_instance_t *, sout_buffer_t*, size_t ) ); 
     138VLC_EXPORT( int,            sout_BufferDelete, ( sout_instance_t *, sout_buffer_t* ) ); 
     139VLC_EXPORT( sout_buffer_t*, sout_BufferDuplicate,(sout_instance_t *, sout_buffer_t * ) ); 
  • include/vlc_common.h

    ra71b1c8 rf8bf106  
    44 ***************************************************************************** 
    55 * Copyright (C) 1998, 1999, 2000 VideoLAN 
    6  * $Id: vlc_common.h,v 1.43 2002/12/13 01:56:29 gbazin Exp $ 
     6 * $Id: vlc_common.h,v 1.44 2002/12/14 21:32:41 fenrir Exp $ 
    77 * 
    88 * Authors: Samuel Hocevar <sam@via.ecp.fr> 
     
    242242typedef struct sout_instance_t sout_instance_t; 
    243243typedef struct sout_fifo_t sout_fifo_t; 
     244typedef struct sout_input_t sout_input_t; 
     245typedef struct sout_buffer_t sout_buffer_t; 
     246typedef struct sout_packet_format_t sout_packet_format_t; 
    244247 
    245248/* Decoders */ 
  • modules/Makefile.am

    r62fd025 rf8bf106  
    99    access/v4l/Modules.am \ 
    1010    access/vcd/Modules.am \ 
     11    access_output/Modules.am \ 
    1112    audio_filter/channel_mixer/Modules.am \ 
    1213    audio_filter/converter/Modules.am \ 
     
    5455    misc/network/Modules.am \ 
    5556    misc/testsuite/Modules.am \ 
     57    mux/Modules.am \ 
     58    mux/mpeg/Modules.am \ 
     59    packetizer/Modules.am \ 
    5660    video_chroma/Modules.am \ 
    5761    video_filter/Modules.am \ 
  • src/input/input_dec.c

    rade615b rf8bf106  
    33 ***************************************************************************** 
    44 * Copyright (C) 1999-2001 VideoLAN 
    5  * $Id: input_dec.c,v 1.52 2002/12/06 16:34:08 sam Exp $ 
     5 * $Id: input_dec.c,v 1.53 2002/12/14 21:32:42 fenrir Exp $ 
    66 * 
    77 * Authors: Christophe Massiot <massiot@via.ecp.fr> 
     
    4545                                   es_descriptor_t * p_es ) 
    4646{ 
     47    char           *psz_sout; 
    4748    decoder_fifo_t *p_fifo; 
    4849    int i_priority; 
     
    5758    } 
    5859 
     60    p_fifo->p_module = NULL; 
     61    /* If we are in sout mode, search first for packetizer module then 
     62     * codec to do transcoding */ 
     63    psz_sout = config_GetPsz( p_input, "sout" ); 
     64    if( psz_sout != NULL && *psz_sout != 0 ) 
     65    { 
     66        p_fifo->p_module = module_Need( p_fifo, "packetizer", "$packetizer" ); 
     67    } 
     68    /* default Get a suitable decoder module */ 
     69    if( p_fifo->p_module == NULL ) 
     70    { 
     71        p_fifo->p_module = module_Need( p_fifo, "decoder", "$codec" ); 
     72    } 
     73#if 0 
    5974    /* Get a suitable module */ 
    6075    p_fifo->p_module = module_Need( p_fifo, "decoder", "$codec" ); 
     76#endif 
    6177    if( p_fifo->p_module == NULL ) 
    6278    { 
  • src/libvlc.h

    r84ae579 rf8bf106  
    33 ***************************************************************************** 
    44 * Copyright (C) 1998-2002 VideoLAN 
    5  * $Id: libvlc.h,v 1.28 2002/12/09 00:52:42 babal Exp $ 
     5 * $Id: libvlc.h,v 1.29 2002/12/14 21:32:42 fenrir Exp $ 
    66 * 
    77 * Authors: Vincent Seguin <seguin@via.ecp.fr> 
     
    284284#define SOUT_LONGTEXT N_( \ 
    285285    "Empty if no stream output.") 
     286#define PACKETIZER_TEXT N_("choose prefered packetizer list") 
     287#define PACKETIZER_LONGTEXT N_( \ 
     288    "This allows you to select the order in which vlc will choose its " \ 
     289    "packetizers."  ) 
     290#define MUX_TEXT N_("mux module") 
     291#define MUX_LONGTEXT N_( \ 
     292    "This is a legacy entry to let you configure mux modules") 
     293#define ACCESS_OUTPUT_TEXT N_("access output module") 
     294#define ACCESS_OUTPUT_LONGTEXT N_( \ 
     295    "This is a legacy entry to let you configure access output modules") 
     296 
    286297 
    287298#define MMX_TEXT N_("enable CPU MMX support") 
     
    476487    add_module( "codec", "decoder", NULL, NULL, CODEC_TEXT, CODEC_LONGTEXT ); 
    477488 
     489    /* Stream output */ 
     490    add_category_hint( N_("Stream output"), NULL ); 
     491    add_module( "packetizer", "packetizer", NULL, NULL, PACKETIZER_TEXT, PACKETIZER_LONGTEXT ); 
     492    add_module( "mux", "mux", NULL, NULL, MUX_TEXT, MUX_LONGTEXT ); 
     493    add_module( "access_output", "access_output", NULL, NULL, ACCESS_OUTPUT_TEXT, ACCESS_OUTPUT_LONGTEXT ); 
     494    add_string( "sout", NULL, NULL, SOUT_TEXT, SOUT_LONGTEXT ); 
     495 
    478496    /* CPU options */ 
    479497    add_category_hint( N_("CPU"), NULL ); 
     
    505523    add_module( "access", "access", NULL, NULL, ACCESS_TEXT, ACCESS_LONGTEXT ); 
    506524    add_module( "demux", "demux", NULL, NULL, DEMUX_TEXT, DEMUX_LONGTEXT ); 
    507     add_string( "sout", NULL, NULL, SOUT_TEXT, SOUT_LONGTEXT ); 
    508525 
    509526#if defined(WIN32) 
  • src/stream_output/stream_output.c

    rbc061e8 rf8bf106  
    33 ***************************************************************************** 
    44 * Copyright (C) 2002 VideoLAN 
    5  * $Id: stream_output.c,v 1.5 2002/11/11 14:39:12 sam Exp $ 
     5 * $Id: stream_output.c,v 1.6 2002/12/14 21:32:42 fenrir Exp $ 
    66 * 
    77 * Authors: Christophe Massiot <massiot@via.ecp.fr> 
     8 *          Laurent Aimar <fenrir@via.ecp.fr> 
     9 *          Erioc Petit <titer@videolan.org> 
    810 * 
    911 * This program is free software; you can redistribute it and/or modify 
     
    3234 
    3335#include <vlc/sout.h> 
    34  
     36#undef DEBUG_BUFFER 
    3537/***************************************************************************** 
    3638 * Local prototypes 
     
    5456    } 
    5557 
    56     p_sout->psz_dest = psz_dest; 
     58    p_sout->psz_dest = strdup( psz_dest ); 
     59 
    5760    if ( InitInstance( p_sout ) == -1 ) 
    5861    { 
     
    6063        return NULL; 
    6164    } 
     65 
     66    vlc_object_attach( p_sout, p_parent ); 
    6267 
    6368    return p_sout; 
     
    7277    /* This code is identical to input.c:InitThread. FIXME : factorize it ? */ 
    7378    char * psz_parser = p_sout->psz_dest; 
     79 
     80    p_sout->psz_access = ""; 
     81    p_sout->psz_mux = ""; 
     82    p_sout->psz_name = ""; 
     83    p_sout->p_access = NULL; 
     84    p_sout->p_mux = NULL; 
     85    p_sout->i_nb_inputs = 0; 
     86    p_sout->pp_inputs = NULL; 
     87    vlc_mutex_init( p_sout, &p_sout->lock ); 
    7488 
    7589    /* Skip the plug-in names */ 
     
    171185    } 
    172186 
     187    p_sout->i_nb_inputs = 0; 
     188    p_sout->pp_inputs = NULL; 
     189 
    173190    return 0; 
    174191} 
     
    182199    /* Unlink object */ 
    183200    vlc_object_detach( p_sout ); 
     201    if( p_sout->p_mux ) 
     202    { 
     203        module_Unneed( p_sout, p_sout->p_mux ); 
     204    } 
     205    if( p_sout->p_access ) 
     206    { 
     207        module_Unneed( p_sout, p_sout->p_access ); 
     208    } 
     209 
     210    vlc_mutex_destroy( &p_sout->lock ); 
    184211 
    185212    /* Free structure */ 
     
    187214} 
    188215 
     216 
     217/***************************************************************************** 
     218 * 
     219 *****************************************************************************/ 
     220sout_input_t *__sout_InputNew( vlc_object_t *p_this, 
     221                                sout_packet_format_t *p_format ) 
     222{ 
     223    sout_instance_t *p_sout = NULL; 
     224    sout_input_t    *p_input; 
     225    int             i_try; 
     226 
     227    /* search an stream output */ 
     228    for( i_try = 0; i_try < 200; i_try++ ) 
     229    { 
     230        p_sout = vlc_object_find( p_this, VLC_OBJECT_SOUT, FIND_ANYWHERE ); 
     231        if( !p_sout ) 
     232        { 
     233            msleep( 100*1000 ); 
     234            msg_Dbg( p_this, "waiting for sout" ); 
     235        } 
     236        else 
     237        { 
     238            break; 
     239        } 
     240    } 
     241 
     242    if( !p_sout ) 
     243    { 
     244        msg_Err( p_this, "cannot find any stream ouput" ); 
     245        return( NULL ); 
     246    } 
     247 
     248    msg_Dbg( p_sout, "adding a new input" ); 
     249 
     250    /* create a new sout input */ 
     251    p_input = malloc( sizeof( sout_input_t ) ); 
     252 
     253    p_input->p_sout = p_sout; 
     254    vlc_mutex_init( p_sout, &p_input->lock ); 
     255    memcpy( &p_input->input_format, 
     256            p_format, 
     257            sizeof( sout_packet_format_t ) ); 
     258    p_input->p_fifo = sout_FifoCreate( p_sout ); 
     259    p_input->p_mux_data = NULL; 
     260 
     261    /* add this new one to p_sout */ 
     262    vlc_mutex_lock( &p_sout->lock ); 
     263    if( p_sout->i_nb_inputs == 0 ) 
     264    { 
     265        p_sout->pp_inputs = malloc( sizeof( sout_input_t * ) ); 
     266    } 
     267    else 
     268    { 
     269        p_sout->pp_inputs = realloc( p_sout->pp_inputs, 
     270                                    sizeof( sout_input_t * ) * 
     271                                            ( p_sout->i_nb_inputs + 1 ) ); 
     272    } 
     273    p_sout->pp_inputs[p_sout->i_nb_inputs] = p_input; 
     274    p_sout->i_nb_inputs++; 
     275 
     276    if( p_sout->pf_mux_addstream( p_sout, p_input ) < 0 ) 
     277    { 
     278        /* vlc_mutex_unlock( &p_sout->lock ); */ 
     279        msg_Err( p_sout, "cannot add this stream" ); 
     280        /* FIXME FIXME */ 
     281    } 
     282    vlc_mutex_unlock( &p_sout->lock ); 
     283 
     284    vlc_object_release( p_sout ); 
     285 
     286    return( p_input ); 
     287} 
     288 
     289 
     290int sout_InputDelete( sout_input_t *p_input ) 
     291{ 
     292    sout_instance_t     *p_sout = p_input->p_sout; 
     293    int                 i_input; 
     294 
     295 
     296    vlc_mutex_lock( &p_sout->lock ); 
     297    for( i_input = 0; i_input < p_sout->i_nb_inputs; i_input++ ) 
     298    { 
     299        if( p_sout->pp_inputs[i_input] == p_input ) 
     300        { 
     301            break; 
     302        } 
     303    } 
     304 
     305    if( i_input >= p_sout->i_nb_inputs ) 
     306    { 
     307        msg_Err( p_sout, "cannot find input to delete" ); 
     308        return( -1 ); 
     309    } 
     310 
     311    msg_Dbg( p_sout, "removing an input" ); 
     312 
     313    if( p_sout->pf_mux_delstream( p_sout, p_input ) < 0 ) 
     314    { 
     315        msg_Err( p_sout, "cannot del this stream" ); 
     316        /* FIXME FIXME */ 
     317    } 
     318 
     319    /* remove the entry */ 
     320    if( p_sout->i_nb_inputs > 1 ) 
     321    { 
     322        memmove( &p_sout->pp_inputs[i_input], 
     323                 &p_sout->pp_inputs[i_input+1], 
     324                 (p_sout->i_nb_inputs - i_input - 1) * sizeof( sout_input_t*) ); 
     325    } 
     326    else 
     327    { 
     328        free( p_sout->pp_inputs ); 
     329    } 
     330    p_sout->i_nb_inputs--; 
     331 
     332    /* FIXME --> send message to mux to declare this stream removing */ 
     333 
     334    sout_FifoDestroy( p_sout, p_input->p_fifo ); 
     335    vlc_mutex_destroy( &p_input->lock ); 
     336    free( p_input ); 
     337 
     338    if( p_sout->i_nb_inputs == 0 ) 
     339    { 
     340        msg_Warn( p_sout, "no more input stream" ); 
     341    } 
     342    vlc_mutex_unlock( &p_sout->lock ); 
     343 
     344    return( 0 ); 
     345} 
     346 
     347 
     348int sout_InputSendBuffer( sout_input_t *p_input, sout_buffer_t *p_buffer ) 
     349{ 
     350/*    msg_Dbg( p_input->p_sout, 
     351             "send buffer, size:%d", p_buffer->i_size ); */ 
     352    sout_FifoPut( p_input->p_fifo, p_buffer ); 
     353 
     354    vlc_mutex_lock( &p_input->p_sout->lock ); 
     355    p_input->p_sout->pf_mux( p_input->p_sout ); 
     356    vlc_mutex_unlock( &p_input->p_sout->lock ); 
     357    return( 0 ); 
     358} 
     359 
     360sout_fifo_t *sout_FifoCreate( sout_instance_t *p_sout ) 
     361{ 
     362    sout_fifo_t *p_fifo; 
     363 
     364    if( !( p_fifo = malloc( sizeof( sout_fifo_t ) ) ) ) 
     365    { 
     366        return( NULL ); 
     367    } 
     368 
     369    vlc_mutex_init( p_sout, &p_fifo->lock ); 
     370    vlc_cond_init ( p_sout, &p_fifo->wait ); 
     371    p_fifo->i_depth = 0; 
     372    p_fifo->p_first = NULL; 
     373    p_fifo->pp_last = &p_fifo->p_first; 
     374 
     375    return( p_fifo ); 
     376} 
     377 
     378void       sout_FifoFree( sout_instance_t *p_sout, sout_fifo_t *p_fifo ) 
     379{ 
     380    sout_buffer_t *p_buffer; 
     381 
     382    vlc_mutex_lock( &p_fifo->lock ); 
     383    p_buffer = p_fifo->p_first; 
     384    while( p_buffer ) 
     385    { 
     386        sout_buffer_t *p_next; 
     387        p_next = p_buffer->p_next; 
     388        sout_BufferDelete( p_sout, p_buffer ); 
     389        p_buffer = p_next; 
     390    } 
     391    vlc_mutex_unlock( &p_fifo->lock ); 
     392 
     393    return; 
     394} 
     395void       sout_FifoDestroy( sout_instance_t *p_sout, sout_fifo_t *p_fifo ) 
     396{ 
     397    sout_FifoFree( p_sout, p_fifo ); 
     398    vlc_mutex_destroy( &p_fifo->lock ); 
     399    vlc_cond_destroy ( &p_fifo->wait ); 
     400 
     401    free( p_fifo ); 
     402} 
     403 
     404void        sout_FifoPut( sout_fifo_t *p_fifo, sout_buffer_t *p_buffer ) 
     405{ 
     406    vlc_mutex_lock( &p_fifo->lock ); 
     407 
     408    do 
     409    { 
     410        *p_fifo->pp_last = p_buffer; 
     411        p_fifo->pp_last = &p_buffer->p_next; 
     412        p_fifo->i_depth++; 
     413 
     414        p_buffer = p_buffer->p_next; 
     415 
     416    } while( p_buffer ); 
     417 
     418    /* warm there is data in this fifo */ 
     419    vlc_cond_signal( &p_fifo->wait ); 
     420    vlc_mutex_unlock( &p_fifo->lock ); 
     421} 
     422 
     423sout_buffer_t *sout_FifoGet( sout_fifo_t *p_fifo ) 
     424{ 
     425    sout_buffer_t *p_buffer; 
     426 
     427    vlc_mutex_lock( &p_fifo->lock ); 
     428 
     429    if( p_fifo->p_first == NULL ) 
     430    { 
     431        vlc_cond_wait( &p_fifo->wait, &p_fifo->lock ); 
     432    } 
     433 
     434    p_buffer = p_fifo->p_first; 
     435 
     436    p_fifo->p_first = p_buffer->p_next; 
     437    p_fifo->i_depth--; 
     438 
     439    if( p_fifo->p_first == NULL ) 
     440    { 
     441        p_fifo->pp_last = &p_fifo->p_first; 
     442    } 
     443 
     444    vlc_mutex_unlock( &p_fifo->lock ); 
     445 
     446    p_buffer->p_next = NULL; 
     447    return( p_buffer ); 
     448} 
     449 
     450sout_buffer_t *sout_FifoShow( sout_fifo_t *p_fifo ) 
     451{ 
     452    sout_buffer_t *p_buffer; 
     453 
     454    vlc_mutex_lock( &p_fifo->lock ); 
     455 
     456    if( p_fifo->p_first == NULL ) 
     457    { 
     458        vlc_cond_wait( &p_fifo->wait, &p_fifo->lock ); 
     459    } 
     460 
     461    p_buffer = p_fifo->p_first; 
     462 
     463    vlc_mutex_unlock( &p_fifo->lock ); 
     464 
     465    return( p_buffer ); 
     466} 
     467 
     468sout_buffer_t *sout_BufferNew( sout_instance_t *p_sout, size_t i_size ) 
     469{ 
     470    sout_buffer_t *p_buffer; 
     471 
     472#ifdef DEBUG_BUFFER 
     473    msg_Dbg( p_sout, "allocating an new buffer, size:%d", (uint32_t)i_size ); 
     474#endif 
     475 
     476    p_buffer = malloc( sizeof( sout_buffer_t ) ); 
     477    if( i_size > 0 ) 
     478    { 
     479        p_buffer->p_buffer = malloc( i_size ); 
     480    } 
     481    else 
     482    { 
     483        p_buffer->p_buffer = NULL; 
     484    } 
     485    p_buffer->i_allocated_size = i_size; 
     486    p_buffer->i_size = i_size; 
     487    p_buffer->p_next = NULL; 
     488 
     489    return( p_buffer ); 
     490} 
     491int sout_BufferRealloc( sout_instance_t *p_sout, sout_buffer_t *p_buffer, size_t i_size ) 
     492{ 
     493#ifdef DEBUG_BUFFER 
     494    msg_Dbg( p_sout, 
     495             "realloc buffer old size:%d new size:%d", 
     496             (uint32_t)p_buffer->i_allocated_size, 
     497             (uint32_t)i_size ); 
     498#endif 
     499    if( !( p_buffer->p_buffer = realloc( p_buffer->p_buffer, i_size ) ) ) 
     500    { 
     501        msg_Err( p_sout, "realloc failed" ); 
     502        p_buffer->i_allocated_size = 0; 
     503        p_buffer->i_size = 0; 
     504 
     505        return( -1 ); 
     506    } 
     507 
     508    p_buffer->i_allocated_size = i_size; 
     509    return( 0 ); 
     510} 
     511 
     512int sout_BufferDelete( sout_instance_t *p_sout, sout_buffer_t *p_buffer ) 
     513{ 
     514#ifdef DEBUG_BUFFER 
     515    msg_Dbg( p_sout, "freeing buffer, size:%d", p_buffer->i_size ); 
     516#endif 
     517    if( p_buffer->p_buffer ) 
     518    { 
     519        free( p_buffer->p_buffer ); 
     520    } 
     521    free( p_buffer ); 
     522    return( 0 ); 
     523} 
     524 
     525sout_buffer_t *sout_BufferDuplicate( sout_instance_t *p_sout, 
     526                                     sout_buffer_t *p_buffer ) 
     527{ 
     528    sout_buffer_t *p_dup; 
     529 
     530    p_dup = sout_BufferNew( p_sout, p_buffer->i_size ); 
     531 
     532    p_dup->i_bitrate= p_buffer->i_bitrate; 
     533    p_dup->i_dts    = p_buffer->i_dts; 
     534    p_dup->i_pts    = p_buffer->i_pts; 
     535    p_dup->i_length = p_buffer->i_length; 
     536    memcpy( p_dup->p_buffer, p_buffer->p_buffer, p_buffer->i_size ); 
     537 
     538    return( p_dup ); 
     539} 
     540