00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdlib.h>
00028
00029 #include <vlc/vlc.h>
00030 #include <vlc/input.h>
00031 #include <vlc/sout.h>
00032
00033
00034
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
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
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
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
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
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
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
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
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 }