Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

gather.c

00001 /*****************************************************************************
00002  * gather.c: gathering stream output module
00003  *****************************************************************************
00004  * Copyright (C) 2003-2004 the VideoLAN team
00005  * $Id: gather.c 11664 2005-07-09 06:17:09Z courmisch $
00006  *
00007  * Authors: Laurent Aimar <[email protected]>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00022  *****************************************************************************/
00023 
00024 /*****************************************************************************
00025  * Preamble
00026  *****************************************************************************/
00027 #include <stdlib.h>
00028 
00029 #include <vlc/vlc.h>
00030 #include <vlc/input.h>
00031 #include <vlc/sout.h>
00032 
00033 /*****************************************************************************
00034  * Module descriptor
00035  *****************************************************************************/
00036 static int      Open    ( vlc_object_t * );
00037 static void     Close   ( vlc_object_t * );
00038 
00039 vlc_module_begin();
00040     set_description( _("Gathering stream output") );
00041     set_capability( "sout stream", 50 );
00042     add_shortcut( "gather" );
00043     set_category( CAT_SOUT );
00044     set_subcategory( SUBCAT_SOUT_STREAM );
00045     set_callbacks( Open, Close );
00046 vlc_module_end();
00047 
00048 /*****************************************************************************
00049  * Exported prototypes
00050  *****************************************************************************/
00051 static sout_stream_id_t *Add ( sout_stream_t *, es_format_t * );
00052 static int               Del ( sout_stream_t *, sout_stream_id_t * );
00053 static int               Send( sout_stream_t *, sout_stream_id_t *,
00054                                block_t* );
00055 
00056 struct sout_stream_id_t
00057 {
00058     vlc_bool_t    b_used;
00059 
00060     es_format_t fmt;
00061     void          *id;
00062 };
00063 
00064 struct sout_stream_sys_t
00065 {
00066     sout_stream_t   *p_out;
00067 
00068     int              i_id;
00069     sout_stream_id_t **id;
00070 };
00071 
00072 /*****************************************************************************
00073  * Open:
00074  *****************************************************************************/
00075 static int Open( vlc_object_t *p_this )
00076 {
00077     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
00078     sout_stream_sys_t *p_sys;
00079 
00080     p_stream->p_sys = p_sys = malloc( sizeof( sout_stream_sys_t ) );
00081     p_sys->p_out    = sout_StreamNew( p_stream->p_sout, p_stream->psz_next );
00082     if( p_sys->p_out == NULL )
00083     {
00084         free( p_sys );
00085         return VLC_EGENERIC;
00086     }
00087     p_sys->i_id         = 0;
00088     p_sys->id           = NULL;
00089 
00090     p_stream->pf_add    = Add;
00091     p_stream->pf_del    = Del;
00092     p_stream->pf_send   = Send;
00093 
00094     return VLC_SUCCESS;
00095 }
00096 
00097 /*****************************************************************************
00098  * Close:
00099  *****************************************************************************/
00100 static void Close( vlc_object_t * p_this )
00101 {
00102     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
00103     sout_stream_sys_t *p_sys = p_stream->p_sys;
00104     int i;
00105 
00106     for( i = 0; i < p_sys->i_id; i++ )
00107     {
00108         p_sys->p_out->pf_del( p_sys->p_out, p_sys->id[i]->id );
00109         free( p_sys->id[i] );
00110     }
00111     free( p_sys->id );
00112 
00113     sout_StreamDelete( p_sys->p_out );
00114     free( p_sys );
00115 }
00116 
00117 /*****************************************************************************
00118  * Add:
00119  *****************************************************************************/
00120 static sout_stream_id_t * Add( sout_stream_t *p_stream, es_format_t *p_fmt )
00121 {
00122     sout_stream_sys_t *p_sys = p_stream->p_sys;
00123     sout_stream_id_t  *id;
00124     int i;
00125 
00126     /* search a output compatible */
00127     for( i = 0; i < p_sys->i_id; i++ )
00128     {
00129         id = p_sys->id[i];
00130         if( !id->b_used &&
00131             id->fmt.i_cat == p_fmt->i_cat &&
00132             id->fmt.i_codec == p_fmt->i_codec &&
00133             ( ( id->fmt.i_cat == AUDIO_ES &&
00134                 id->fmt.audio.i_rate == p_fmt->audio.i_rate &&
00135                 id->fmt.audio.i_channels == p_fmt->audio.i_channels &&
00136                 id->fmt.audio.i_blockalign == p_fmt->audio.i_blockalign ) ||
00137               ( id->fmt.i_cat == VIDEO_ES &&
00138                 id->fmt.video.i_width == p_fmt->video.i_width &&
00139                 id->fmt.video.i_height == p_fmt->video.i_height ) ) )
00140         {
00141             msg_Dbg( p_stream, "reusing already opened output" );
00142             id->b_used = VLC_TRUE;
00143             return id;
00144         }
00145     }
00146 
00147     /* destroy all output of the same categorie */
00148     for( i = 0; i < p_sys->i_id; i++ )
00149     {
00150         id = p_sys->id[i];
00151         if( !id->b_used && id->fmt.i_cat == p_fmt->i_cat )
00152         {
00153             TAB_REMOVE( p_sys->i_id, p_sys->id, id );
00154             p_sys->p_out->pf_del( p_sys->p_out, id );
00155             free( id );
00156 
00157             i = 0;
00158             continue;
00159         }
00160     }
00161 
00162     id = malloc( sizeof( sout_stream_id_t ) );
00163     msg_Dbg( p_stream, "creating new output" );
00164     memcpy( &id->fmt, p_fmt, sizeof( es_format_t ) );
00165     id->fmt.i_extra = 0;
00166     id->fmt.p_extra = NULL;
00167     id->b_used           = VLC_TRUE;
00168     id->id               = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
00169     if( id->id == NULL )
00170     {
00171         free( id );
00172         return NULL;
00173     }
00174     TAB_APPEND( p_sys->i_id, p_sys->id, id );
00175 
00176     return id;
00177 }
00178 
00179 /*****************************************************************************
00180  * Del:
00181  *****************************************************************************/
00182 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
00183 {
00184     id->b_used = VLC_FALSE;
00185     return VLC_SUCCESS;
00186 }
00187 
00188 /*****************************************************************************
00189  * Send:
00190  *****************************************************************************/
00191 static int Send( sout_stream_t *p_stream,
00192                  sout_stream_id_t *id, block_t *p_buffer )
00193 {
00194     sout_stream_sys_t *p_sys = p_stream->p_sys;
00195 
00196     return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
00197 }

Generated on Tue Dec 20 10:14:49 2005 for vlc-0.8.4a by  doxygen 1.4.2