]> git.sesse.net Git - vlc/blob - modules/stream_out/standard.c
* all: as announce calls non-standard functions (SLP), remove it from
[vlc] / modules / stream_out / standard.c
1 /*****************************************************************************
2  * standard.c
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: standard.c,v 1.12 2003/08/14 20:02:55 zorglub Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
30
31 #include <vlc/vlc.h>
32 #include <vlc/sout.h>
33 #include "announce.h"
34
35 #define DEFAULT_IPV6_SCOPE "8"
36
37 /*****************************************************************************
38  * Exported prototypes
39  *****************************************************************************/
40 static int      Open    ( vlc_object_t * );
41 static void     Close   ( vlc_object_t * );
42
43 static sout_stream_id_t *Add ( sout_stream_t *, sout_format_t * );
44 static int               Del ( sout_stream_t *, sout_stream_id_t * );
45 static int               Send( sout_stream_t *, sout_stream_id_t *, sout_buffer_t* );
46
47 /*****************************************************************************
48  * Module descriptor
49  *****************************************************************************/
50 vlc_module_begin();
51     set_description( _("Standard stream") );
52     set_capability( "sout stream", 50 );
53     add_shortcut( "standard" );
54     add_shortcut( "std" );
55     set_callbacks( Open, Close );
56 vlc_module_end();
57
58 struct sout_stream_sys_t
59 {
60     sout_mux_t           *p_mux;
61     slp_session_t        *p_slp;
62     sap_session_t        *p_sap;
63 };
64
65 /*****************************************************************************
66  * Open:
67  *****************************************************************************/
68 static int Open( vlc_object_t *p_this )
69 {
70     sout_stream_t       *p_stream = (sout_stream_t*)p_this;
71     sout_instance_t     *p_sout = p_stream->p_sout;
72     sout_stream_sys_t   *p_sys = malloc( sizeof( sout_stream_sys_t) );
73
74     char *psz_mux      = sout_cfg_find_value( p_stream->p_cfg, "mux" );
75     char *psz_access   = sout_cfg_find_value( p_stream->p_cfg, "access" );
76     char *psz_url      = sout_cfg_find_value( p_stream->p_cfg, "url" );
77     char *psz_ipv      = sout_cfg_find_value( p_stream->p_cfg, "sap_ipv" );
78     char *psz_v6_scope = sout_cfg_find_value( p_stream->p_cfg, "sap_v6scope" );
79     
80     sout_cfg_t *p_sap_cfg = sout_cfg_find( p_stream->p_cfg, "sap" );
81 #ifdef HAVE_SLP_H
82     sout_cfg_t *p_slp_cfg = sout_cfg_find( p_stream->p_cfg, "slp" );
83 #endif
84     
85     sout_access_out_t   *p_access;
86     sout_mux_t          *p_mux;    
87
88     /* SAP is only valid for UDP or RTP streaming */
89     if( psz_access == NULL ) psz_access = "udp";
90
91     /* Get SAP IP version to use */
92     if(psz_ipv == NULL) psz_ipv = "4";
93     if(psz_v6_scope == NULL) psz_v6_scope = DEFAULT_IPV6_SCOPE;
94     p_sys->p_sap = NULL;
95     p_sys->p_slp = NULL;
96
97     msg_Dbg( p_this, "creating `%s/%s://%s'",
98              psz_access, psz_mux, psz_url );
99
100     /* *** find and open appropriate access module *** */
101     p_access = sout_AccessOutNew( p_sout, psz_access, psz_url );
102     if( p_access == NULL )
103     {
104         msg_Err( p_stream, "no suitable sout access module for `%s/%s://%s'",
105                  psz_access, psz_mux, psz_url );
106         return( VLC_EGENERIC );
107     }
108     msg_Dbg( p_stream, "access opened" );
109
110     /* *** find and open appropriate mux module *** */
111     p_mux = sout_MuxNew( p_sout, psz_mux, p_access );
112     if( p_mux == NULL )
113     {
114         msg_Err( p_stream, "no suitable sout mux module for `%s/%s://%s'",
115                  psz_access, psz_mux, psz_url );
116
117         sout_AccessOutDelete( p_access );
118         return( VLC_EGENERIC );
119     }
120     msg_Dbg( p_stream, "mux opened" );
121
122     /*  *** Create the SAP Session structure *** */
123     if( p_sap_cfg && ( strstr( psz_access, "udp" ) ||
124                        strstr( psz_access ,  "rtp" ) ) )
125     {
126         msg_Info( p_this, "SAP Enabled");
127         msg_Dbg( p_sout , "Creating SAP with IPv%i", atoi(psz_ipv) );
128
129         p_sys->p_sap = sout_SAPNew( p_sout , psz_url ,
130             p_sap_cfg->psz_value ? p_sap_cfg->psz_value : psz_url,
131             atoi(psz_ipv), psz_v6_scope );
132
133         if( !p_sys->p_sap )
134             msg_Err( p_sout,"Unable to initialize SAP. SAP disabled");
135     }   
136
137     /* *** Register with slp *** */
138 #ifdef HAVE_SLP_H
139     if( p_slp_cfg && ( strstr( psz_access, "udp" ) ||
140                        strstr( psz_access ,  "rtp" ) ) )
141     {
142         msg_Info( p_this, "SLP Enabled");
143         if( sout_SLPReg( p_sout, psz_url, 
144             p_slp_cfg->psz_value ? p_slp_cfg->psz_value : psz_url) )
145         {
146            msg_Warn( p_sout, "SLP Registering failed");
147         }
148         else
149         {
150             p_sys->p_slp = (slp_session_t*)malloc(sizeof(slp_session_t));
151             if(!p_sys->p_slp)
152             {
153                 msg_Warn(p_sout,"Out of memory");
154                 return -1;        
155             }
156             p_sys->p_slp->psz_url= strdup(psz_url);
157             p_sys->p_slp->psz_name = strdup(
158                     p_slp_cfg->psz_value ? p_slp_cfg->psz_value : psz_url);
159         }
160     }        
161 #endif
162     
163     /* XXX beurk */
164     p_sout->i_preheader = __MAX( p_sout->i_preheader, p_mux->i_preheader );
165
166
167     p_sys->p_mux = p_mux;
168
169     p_stream->pf_add    = Add;
170     p_stream->pf_del    = Del;
171     p_stream->pf_send   = Send;
172
173     p_stream->p_sys     = p_sys;
174     return VLC_SUCCESS;
175 }
176
177 /*****************************************************************************
178  * Close:
179  *****************************************************************************/
180
181 static void Close( vlc_object_t * p_this )
182 {
183     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
184     sout_stream_sys_t *p_sys    = p_stream->p_sys;
185     sout_access_out_t *p_access = p_sys->p_mux->p_access;
186
187     if( p_sys->p_sap )
188         sout_SAPDelete( (sout_instance_t *)p_this , p_sys->p_sap ); 
189
190 #ifdef HAVE_SLP_H
191     if( p_sys->p_slp )
192     {
193             sout_SLPDereg( (sout_instance_t *)p_this, 
194                         p_sys->p_slp->psz_url,
195                         p_sys->p_slp->psz_name);
196             free( p_sys->p_slp);
197     }
198 #endif
199     
200     
201     sout_MuxDelete( p_sys->p_mux );
202     sout_AccessOutDelete( p_access );
203
204     free( p_sys );
205 }
206
207 struct sout_stream_id_t
208 {
209     sout_input_t *p_input;
210 };
211
212
213 static sout_stream_id_t * Add( sout_stream_t *p_stream, sout_format_t *p_fmt )
214 {
215     sout_stream_sys_t *p_sys = p_stream->p_sys;
216     sout_stream_id_t  *id;
217
218     id = malloc( sizeof( sout_stream_id_t ) );
219     if( ( id->p_input = sout_MuxAddStream( p_sys->p_mux, p_fmt ) ) == NULL )
220     {
221         free( id );
222
223         return NULL;
224     }
225
226     return id;
227 }
228
229 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
230 {
231     sout_stream_sys_t *p_sys = p_stream->p_sys;
232
233     sout_MuxDeleteStream( p_sys->p_mux, id->p_input );
234
235     free( id );
236
237     return VLC_SUCCESS;
238 }
239
240 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
241                  sout_buffer_t *p_buffer )
242 {
243     sout_stream_sys_t *p_sys = p_stream->p_sys;
244     sout_instance_t   *p_sout = p_stream->p_sout;
245
246     sout_MuxSendBuffer( p_sys->p_mux, id->p_input, p_buffer );
247
248     if( p_sys->p_sap )
249        sout_SAPSend( p_sout , p_sys->p_sap );
250
251     return VLC_SUCCESS;
252 }