]> git.sesse.net Git - vlc/blob - src/stream_output/announce.c
Fully initialize p_session
[vlc] / src / stream_output / announce.c
1 /*****************************************************************************
2  * announce.c : announce handler
3  *****************************************************************************
4  * Copyright (C) 2002-2004 the VideoLAN team
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>                                                /* free() */
28 #include <stdio.h>                                              /* sprintf() */
29 #include <string.h>                                            /* strerror() */
30
31 #include <vlc/vlc.h>
32 #include <vlc/sout.h>
33
34 /****************************************************************************
35  * Sout-side functions
36  ****************************************************************************/
37
38 /**
39  *  Register a new session with the announce handler
40  *
41  * \param p_sout a sout instance structure
42  * \param p_session a session descriptor
43  * \param p_method an announce method descriptor
44  * \return VLC_SUCCESS or an error
45  */
46 int sout_AnnounceRegister( sout_instance_t *p_sout,
47                        session_descriptor_t *p_session,
48                        announce_method_t *p_method )
49 {
50     int i_ret;
51     announce_handler_t *p_announce = (announce_handler_t*)
52                               vlc_object_find( p_sout,
53                                               VLC_OBJECT_ANNOUNCE,
54                                               FIND_ANYWHERE );
55
56     if( !p_announce )
57     {
58         msg_Dbg( p_sout, "No announce handler found, creating one" );
59         p_announce = announce_HandlerCreate( p_sout );
60         if( !p_announce )
61         {
62             msg_Err( p_sout, "Creation failed" );
63             return VLC_ENOMEM;
64         }
65         vlc_object_yield( p_announce );
66         msg_Dbg( p_sout, "creation done" );
67     }
68
69     i_ret = announce_Register( p_announce, p_session, p_method );
70     vlc_object_release( p_announce );
71
72     return i_ret;
73 }
74
75 /**
76  *  Register a new session with the announce handler, using a pregenerated SDP
77  *
78  * \param p_sout a sout instance structure
79  * \param psz_sdp the SDP to register
80  * \param psz_uri session URI (needed for SAP address auto detection
81  * \param p_method an announce method descriptor
82  * \return the new session descriptor structure
83  */
84 session_descriptor_t *sout_AnnounceRegisterSDP( sout_instance_t *p_sout,
85                           const char *psz_sdp, const char *psz_uri,
86                           announce_method_t *p_method )
87 {
88     session_descriptor_t *p_session;
89     announce_handler_t *p_announce = (announce_handler_t*)
90                                      vlc_object_find( p_sout,
91                                               VLC_OBJECT_ANNOUNCE,
92                                               FIND_ANYWHERE );
93     if( !p_announce )
94     {
95         msg_Dbg( p_sout, "no announce handler found, creating one" );
96         p_announce = announce_HandlerCreate( p_sout );
97         if( !p_announce )
98         {
99             msg_Err( p_sout, "Creation failed" );
100             return NULL;
101         }
102         vlc_object_yield( p_announce );
103     }
104
105     if( p_method->i_type != METHOD_TYPE_SAP )
106     {
107         msg_Warn( p_sout, "forcing SAP announcement");
108     }
109
110     p_session = sout_AnnounceSessionCreate();
111     p_session->psz_sdp = strdup( psz_sdp );
112     p_session->psz_uri = strdup( psz_uri );
113     announce_Register( p_announce, p_session, p_method );
114
115     vlc_object_release( p_announce );
116     return p_session;
117 }
118
119 /**
120  *  UnRegister an existing session
121  *
122  * \param p_sout a sout instance structure
123  * \param p_session the session descriptor
124  * \return VLC_SUCCESS or an error
125  */
126 int sout_AnnounceUnRegister( sout_instance_t *p_sout,
127                              session_descriptor_t *p_session )
128 {
129     int i_ret;
130     announce_handler_t *p_announce = (announce_handler_t*)
131                               vlc_object_find( p_sout,
132                                               VLC_OBJECT_ANNOUNCE,
133                                               FIND_ANYWHERE );
134     if( !p_announce )
135     {
136         msg_Dbg( p_sout, "unable to remove announce: no announce handler" );
137         return VLC_ENOOBJ;
138     }
139     i_ret  = announce_UnRegister( p_announce, p_session );
140
141     vlc_object_release( p_announce );
142
143     return i_ret;
144 }
145
146 /**
147  * Create and initialize a session descriptor
148  *
149  * \return a new session descriptor
150  */
151 session_descriptor_t * sout_AnnounceSessionCreate(void)
152 {
153     session_descriptor_t *p_session;
154
155     p_session = (session_descriptor_t *)malloc( sizeof(session_descriptor_t));
156     if (p_session == NULL)
157         return NULL;
158
159     memset (p_session, 0, sizeof (*p_session));
160     return p_session;
161 }
162
163 /**
164  * Destroy a session descriptor and free all
165  *
166  * \param p_session the session to destroy
167  * \return Nothing
168  */
169 void sout_AnnounceSessionDestroy( session_descriptor_t *p_session )
170 {
171     if( p_session )
172     {
173         FREENULL( p_session->psz_name );
174         FREENULL( p_session->psz_group );
175         FREENULL( p_session->psz_uri );
176         FREENULL( p_session->psz_sdp );
177         free( p_session );
178     }
179 }
180
181 /**
182  * Create and initialize an announcement method structure
183  *
184  * \param i_type METHOD_TYPE_SAP
185  * \return a new announce_method structure
186  */
187 announce_method_t * sout_AnnounceMethodCreate( int i_type )
188 {
189     announce_method_t *p_method;
190
191     p_method = (announce_method_t *)malloc( sizeof(announce_method_t) );
192     if( p_method == NULL )
193         return NULL;
194
195     p_method->i_type = i_type;
196     return p_method;
197 }
198
199 /************************************************************************
200  * Announce handler functions (private)
201  ************************************************************************/
202
203 /**
204  * Create the announce handler object
205  *
206  * \param p_this a vlc_object structure
207  * \return the new announce handler or NULL on error
208  */
209 announce_handler_t *__announce_HandlerCreate( vlc_object_t *p_this )
210 {
211     announce_handler_t *p_announce;
212
213     p_announce = vlc_object_create( p_this, VLC_OBJECT_ANNOUNCE );
214
215     if( !p_announce )
216     {
217         msg_Err( p_this, "out of memory" );
218         return NULL;
219     }
220
221     p_announce->p_sap = NULL;
222     vlc_object_attach( p_announce, p_this->p_libvlc);
223
224     return p_announce;
225 }
226
227 /**
228  * Destroy a  announce handler object
229  *
230  * \param p_announce the announce handler to destroy
231  * \return VLC_SUCCESS or an error
232  */
233 int announce_HandlerDestroy( announce_handler_t *p_announce )
234 {
235
236     if( p_announce->p_sap )
237     {
238         p_announce->p_sap->b_die = VLC_TRUE;
239         /* Wait for the SAP thread to exit */
240         vlc_thread_join( p_announce->p_sap );
241         announce_SAPHandlerDestroy( p_announce->p_sap );
242     }
243
244     /* Free the structure */
245     vlc_object_destroy( p_announce );
246
247     return VLC_SUCCESS;
248 }
249
250 /* Register an announce */
251 int announce_Register( announce_handler_t *p_announce,
252                        session_descriptor_t *p_session,
253                        announce_method_t *p_method )
254 {
255
256     msg_Dbg( p_announce, "registering announce");
257     if( p_method->i_type == METHOD_TYPE_SAP )
258     {
259         /* Do we already have a SAP announce handler ? */
260         if( !p_announce->p_sap )
261         {
262             sap_handler_t *p_sap = announce_SAPHandlerCreate( p_announce );
263             msg_Dbg( p_announce, "creating SAP announce handler");
264             if( !p_sap )
265             {
266                 msg_Err( p_announce, "SAP handler creation failed" );
267                 return VLC_ENOOBJ;
268             }
269             p_announce->p_sap = p_sap;
270         }
271         /* this will set p_session->p_sap for later deletion */
272         msg_Dbg( p_announce, "adding SAP session");
273         p_announce->p_sap->pf_add( p_announce->p_sap, p_session );
274     }
275     else
276     {
277         msg_Dbg( p_announce, "announce type unsupported" );
278         return VLC_EGENERIC;
279     }
280     return VLC_SUCCESS;;
281 }
282
283
284 /* Unregister an announce */
285 int announce_UnRegister( announce_handler_t *p_announce,
286                   session_descriptor_t *p_session )
287 {
288     msg_Dbg( p_announce, "unregistering announce" );
289     if( p_session->p_sap != NULL ) /* SAP Announce */
290     {
291         if( !p_announce->p_sap )
292         {
293             msg_Err( p_announce, "can't remove announce, no SAP handler");
294             return VLC_ENOOBJ;
295         }
296         p_announce->p_sap->pf_del( p_announce->p_sap, p_session );
297     }
298     return VLC_SUCCESS;
299 }