]> git.sesse.net Git - vlc/blob - src/stream_output/stream_output.c
* Fixed a variable overflow bug in the audio output.
[vlc] / src / stream_output / stream_output.c
1 /*****************************************************************************
2  * stream_output.c : stream output module
3  *****************************************************************************
4  * Copyright (C) 2002 VideoLAN
5  * $Id: stream_output.c,v 1.1 2002/08/12 22:12:51 massiot Exp $
6  *
7  * Authors: Christophe Massiot <massiot@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 <errno.h>                                                 /* ENOMEM */
28 #include <stdlib.h>                                                /* free() */
29 #include <stdio.h>                                              /* sprintf() */
30 #include <string.h>                                            /* strerror() */
31
32 #include <vlc/vlc.h>
33
34 #include <vlc/sout.h>
35
36 /*****************************************************************************
37  * Local prototypes
38  *****************************************************************************/
39 static int      InitInstance      ( sout_instance_t * );
40
41 /*****************************************************************************
42  * sout_NewInstance: creates a new stream output instance
43  *****************************************************************************/
44 sout_instance_t * __sout_NewInstance ( vlc_object_t *p_parent,
45                                        char * psz_dest )
46 {
47     sout_instance_t * p_sout;
48
49     /* Allocate descriptor */
50     p_sout = vlc_object_create( p_parent, VLC_OBJECT_SOUT );
51     if( p_sout == NULL )
52     {
53         msg_Err( p_parent, "out of memory" );
54         return NULL;
55     }
56
57     p_sout->psz_dest = psz_dest;
58     if ( InitInstance( p_sout ) == -1 )
59     {
60         vlc_object_destroy( p_sout );
61         return NULL;
62     }
63
64     return p_sout;
65 }
66
67 /*****************************************************************************
68  * InitInstance: opens appropriate modules
69  *****************************************************************************/
70 static int InitInstance( sout_instance_t * p_sout )
71 {
72     /* Parse dest string. Syntax : [[<access>][/<mux>]:][<dest>] */
73     /* This code is identical to input.c:InitThread. FIXME : factorize it ? */
74     char * psz_parser = p_sout->psz_dest;
75
76     /* Skip the plug-in names */
77     while( *psz_parser && *psz_parser != ':' )
78     {
79         psz_parser++;
80     }
81 #ifdef WIN32
82     if( psz_parser - psz_dest == 1 )
83     {
84         msg_Warn( p_sout, "drive letter %c: found in source string",
85                            p_sout->psz_dest ) ;
86         psz_parser = "";
87     }
88 #endif
89
90     if( !*psz_parser )
91     {
92         p_sout->psz_access = p_sout->psz_mux = "";
93         p_sout->psz_name = p_sout->psz_dest;
94     }
95     else
96     {
97         *psz_parser++ = '\0';
98
99         /* let's skip '//' */
100         if( psz_parser[0] == '/' && psz_parser[1] == '/' )
101         {
102             psz_parser += 2 ;
103         } 
104
105         p_sout->psz_name = psz_parser ;
106
107         /* Come back to parse the access and mux plug-ins */
108         psz_parser = p_sout->psz_dest;
109
110         if( !*psz_parser )
111         {
112             /* No access */
113             p_sout->psz_access = "";
114         }
115         else if( *psz_parser == '/' )
116         {
117             /* No access */
118             p_sout->psz_access = "";
119             psz_parser++;
120         }
121         else
122         {
123             p_sout->psz_access = psz_parser;
124
125             while( *psz_parser && *psz_parser != '/' )
126             {
127                 psz_parser++;
128             }
129
130             if( *psz_parser == '/' )
131             {
132                 *psz_parser++ = '\0';
133             }
134         }
135
136         if( !*psz_parser )
137         {
138             /* No mux */
139             p_sout->psz_mux = "";
140         }
141         else
142         {
143             p_sout->psz_mux = psz_parser;
144         }
145     }
146
147     msg_Dbg( p_sout, "access `%s', mux `%s', name `%s'",
148              p_sout->psz_access, p_sout->psz_mux, p_sout->psz_name );
149
150
151     /* Find and open appropriate access module */
152     p_sout->p_access =
153         module_Need( p_sout, "sout access", p_sout->psz_access );
154
155     if( p_sout->p_access == NULL )
156     {
157         msg_Err( p_sout, "no suitable sout access module for `%s/%s://%s'",
158                  p_sout->psz_access, p_sout->psz_mux, p_sout->psz_name );
159         return -1;
160     }
161
162     /* Find and open appropriate mux module */
163     p_sout->p_mux =
164         module_Need( p_sout, "sout mux", p_sout->psz_mux );
165
166     if( p_sout->p_mux == NULL )
167     {
168         msg_Err( p_sout, "no suitable mux module for `%s/%s://%s'",
169                  p_sout->psz_access, p_sout->psz_mux, p_sout->psz_name );
170         module_Unneed( p_sout, p_sout->p_access );
171         return -1;
172     }
173 }
174
175
176 /*****************************************************************************
177  * sout_DeleteInstance: delete a previously allocated instance
178  *****************************************************************************/
179 void sout_DeleteInstance( sout_instance_t * p_sout )
180 {
181     /* Unlink object */
182     vlc_object_detach( p_sout );
183
184     /* Free structure */
185     vlc_object_destroy( p_sout );
186 }
187