1ff6ceae4c6d2c5d96c9587d5dd1a8f187a94981
[vlc.git] / modules / stream_out / standard.c
1 /*****************************************************************************
2  * standard.c
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: standard.c,v 1.4 2003/06/12 11:37:48 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 /*****************************************************************************
36  * Exported prototypes
37  *****************************************************************************/
38 static int      Open    ( vlc_object_t * );
39 static void     Close   ( vlc_object_t * );
40
41 static sout_stream_id_t *Add ( sout_stream_t *, sout_format_t * );
42 static int               Del ( sout_stream_t *, sout_stream_id_t * );
43 static int               Send( sout_stream_t *, sout_stream_id_t *, sout_buffer_t* );
44
45 /*****************************************************************************
46  * Module descriptor
47  *****************************************************************************/
48 vlc_module_begin();
49     set_description( _("Standard stream") );
50     set_capability( "sout stream", 50 );
51     add_shortcut( "standard" );
52     add_shortcut( "std" );
53     set_callbacks( Open, Close );
54 vlc_module_end();
55
56 struct sout_stream_sys_t
57 {
58     sout_mux_t           *p_mux;
59     sap_session_t        *p_sap;
60     unsigned int          b_sap;
61 };
62
63 /*****************************************************************************
64  * Open:
65  *****************************************************************************/
66 static int Open( vlc_object_t *p_this )
67 {
68     sout_stream_t       *p_stream = (sout_stream_t*)p_this;
69     sout_instance_t     *p_sout = p_stream->p_sout;
70     sout_stream_sys_t   *p_sys = malloc( sizeof( sout_stream_sys_t) );
71
72     char                *psz_mux    = sout_cfg_find_value( p_stream->p_cfg, "mux" );
73     char                *psz_access = sout_cfg_find_value( p_stream->p_cfg, "access" );
74     char                *psz_url    = sout_cfg_find_value( p_stream->p_cfg, "url" );
75
76     sout_cfg_t          *p_sap_cfg  = sout_cfg_find( p_stream->p_cfg, "sap" );
77
78     char                *psz_sap = NULL;
79
80     char                *psz_port = "1234";
81     
82     sap_session_t       *p_sap = NULL;
83     
84     sout_access_out_t *p_access;
85     sout_mux_t        *p_mux;    
86    
87    p_sys->b_sap=0;
88    /* SAP is only valid for UDP or RTP streaming */
89    if(p_sap_cfg && (strstr(psz_access,"udp") || strstr( psz_access ,  "rtp" )))
90    {
91         msg_Info( p_this, "SAP Enabled");
92         p_sys->b_sap=1;
93         if(p_sap_cfg->psz_value)
94         {
95                 psz_sap = strdup( p_sap_cfg->psz_value );
96         }
97         else
98         {
99                 psz_sap = strdup ( psz_url );
100         }        
101    }
102    msg_Dbg( p_this, "creating `%s/%s://%s'",
103              psz_access, psz_mux, psz_url );
104        
105     /* *** find and open appropriate access module *** */
106     p_access = sout_AccessOutNew( p_sout, psz_access, psz_url );
107     if( p_access == NULL )
108     {
109         msg_Err( p_stream, "no suitable sout access module for `%s/%s://%s'",
110                  psz_access, psz_mux, psz_url );
111         return( VLC_EGENERIC );
112     }
113     msg_Dbg( p_stream, "access opened" );
114
115     /* *** find and open appropriate mux module *** */
116     p_mux = sout_MuxNew( p_sout, psz_mux, p_access );
117     if( p_mux == NULL )
118     {
119         msg_Err( p_stream, "no suitable sout mux module for `%s/%s://%s'",
120                  psz_access, psz_mux, psz_url );
121
122         sout_AccessOutDelete( p_access );
123         return( VLC_EGENERIC );
124     }
125     msg_Dbg( p_stream, "mux opened" );
126
127     /*  *** Create the SAP Session structure *** */
128     if(p_sys->b_sap)
129     {        
130         msg_Dbg( p_sout , "Creating SAP" );
131         p_sap = sout_SAPNew( p_sout , psz_url , psz_port , psz_sap );
132         if(!p_sap)
133         {
134                 msg_Err( p_sout,"Unable to initialize SAP. SAP disabled");
135                 p_sys->b_sap=0;
136         }
137     }   
138     
139     /* XXX beurk */
140     p_sout->i_preheader = __MAX( p_sout->i_preheader, p_mux->i_preheader );
141
142
143     p_sys->p_mux = p_mux;
144     p_sys->p_sap = p_sap;
145     
146     p_stream->pf_add    = Add;
147     p_stream->pf_del    = Del;
148     p_stream->pf_send   = Send;
149
150     p_stream->p_sys     = p_sys;
151     return VLC_SUCCESS;
152 }
153
154 /*****************************************************************************
155  * Close:
156  *****************************************************************************/
157
158 static void Close( vlc_object_t * p_this )
159 {
160     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
161     sout_stream_sys_t *p_sys = p_stream->p_sys;
162
163     sout_access_out_t *p_access = p_sys->p_mux->p_access;
164
165     if(p_sys -> b_sap)
166           sout_SAPDelete( p_this ,p_sys->p_sap ); 
167
168     sout_MuxDelete( p_sys->p_mux );
169     sout_AccessOutDelete( p_access );
170
171     free( p_sys );
172 }
173
174 struct sout_stream_id_t
175 {
176     sout_input_t *p_input;
177 };
178
179
180 static sout_stream_id_t * Add      ( sout_stream_t *p_stream, sout_format_t *p_fmt )
181 {
182     sout_stream_sys_t *p_sys = p_stream->p_sys;
183     sout_stream_id_t  *id;
184
185     id = malloc( sizeof( sout_stream_id_t ) );
186     if( ( id->p_input = sout_MuxAddStream( p_sys->p_mux, p_fmt ) ) == NULL )
187     {
188         free( id );
189
190         return NULL;
191     }
192
193     return id;
194 }
195
196 static int     Del      ( sout_stream_t *p_stream, sout_stream_id_t *id )
197 {
198     sout_stream_sys_t *p_sys = p_stream->p_sys;
199
200     sout_MuxDeleteStream( p_sys->p_mux, id->p_input );
201
202     free( id );
203
204     return VLC_SUCCESS;
205 }
206
207 static int     Send     ( sout_stream_t *p_stream, sout_stream_id_t *id, sout_buffer_t *p_buffer )
208 {
209     sout_stream_sys_t *p_sys = p_stream->p_sys;
210
211         sout_instance_t         *p_sout = p_stream->p_sout;
212
213     
214     sout_MuxSendBuffer( p_sys->p_mux, id->p_input, p_buffer );
215
216     if(p_sys -> b_sap)
217        sout_SAPSend( p_sout , p_sys->p_sap );
218    
219     return VLC_SUCCESS;
220 }
221